Hi! I am writing a special linting-like piece of code and struggle dealing with the Implements <https://golang.org/pkg/go/types/#Implements> that doesn't work for my configuration. I made a simplified testing example to show the issue:
- I have package speaker with interface Speaker and its default
implementation.
package speaker
type Default struct{}
func (Default) Speak(Arg) string {
return "speak"
}
type Arg struct{}
type Speaker interface {
Speak(Arg) string
}
-
Now, I have another package, with "Russian speaker":
package ru
import "awesome/speaker"
type Russian struct{}
func (Russian) Speak(speaker.Arg) string {
return "говорить"
}
-
An finally I have a main package
package main
import (
"fmt"
"go/ast"
"go/importer"
"go/parser"
"go/token"
"go/types"
"path/filepath"
"runtime"
)
func getPath() string {
fpcs := make([]uintptr, 5)
frameIter := runtime.CallersFrames(fpcs[:runtime.Callers(1, fpcs)])
var frames []runtime.Frame
frame, more := frameIter.Next()
frames = append(frames, frame)
if !more {
panic("stack frames must exists for a call")
}
return filepath.Dir(frame.File)
}
func getTypes(path ...string) *types.Package {
path = append([]string{getPath()}, path...)
fullpath := filepath.Join(path...)
fset := token.NewFileSet()
pkgs, err := parser.ParseDir(fset, fullpath, nil, parser.ParseComments)
if err != nil {
panic(err)
}
for _, pkg := range pkgs {
config := &types.Config{
IgnoreFuncBodies: false,
FakeImportC: false,
Error: nil,
Importer: importer.Default(),
Sizes: nil,
DisableUnusedImportCheck: false,
}
info := types.Info{
Types: map[ast.Expr]types.TypeAndValue{},
Defs: map[*ast.Ident]types.Object{},
Uses: map[*ast.Ident]types.Object{},
}
var files []*ast.File
for _, file := range pkg.Files {
files = append(files, file)
}
typeInfo, err := config.Check(fullpath, fset, files, &info)
if err != nil {
panic(err)
}
return typeInfo
}
return nil
}
func main() {
mainPkg := getTypes("speaker")
ruPkg := getTypes("ru")
iface :=
mainPkg.Scope().Lookup("Speaker").Type().Underlying().(*types.Interface)
dflt := mainPkg.Scope().Lookup("Default").Type()
russian := ruPkg.Scope().Lookup("Russian").Type()
fmt.Println(types.Implements(dflt, iface))
fmt.Println(types.Implements(russian, iface))
}
Output is:
true
false
The output is true-true without the argument. Is it a feature or a bug? How
can I walk around it?
--
You received this message because you are subscribed to the Google Groups
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.
package.tar.xz
Description: Binary data
