return &Func{Params: params, Results: results, IsVariadic: isVariadic}
}
-// MethodOrEmbedSpec = Name [ Signature ] .
+// InterfaceType = "interface" "{" [ MethodList ] "}" .
+// MethodList = Method { ";" Method } .
+// Method = Name Signature .
//
-func (p *gcParser) parseMethodOrEmbedSpec() *ast.Object {
- name := p.parseName()
- if p.tok == '(' {
- typ := p.parseSignature()
- obj := ast.NewObj(ast.Fun, name)
- obj.Type = typ
- return obj
- }
- // TODO lookup name and return that type
- return ast.NewObj(ast.Typ, "_")
-}
-
-// InterfaceType = "interface" "{" [ MethodOrEmbedList ] "}" .
-// MethodOrEmbedList = MethodOrEmbedSpec { ";" MethodOrEmbedSpec } .
+// (The methods of embedded interfaces are always "inlined"
+// by the compiler and thus embedded interfaces are never
+// visible in the export data.)
//
func (p *gcParser) parseInterfaceType() Type {
var methods ObjList
parseMethod := func() {
- switch m := p.parseMethodOrEmbedSpec(); m.Kind {
- case ast.Typ:
- // TODO expand embedded methods
- case ast.Fun:
- methods = append(methods, m)
- }
+ obj := ast.NewObj(ast.Fun, p.parseName())
+ obj.Type = p.parseSignature()
+ methods = append(methods, obj)
}
p.expectKeyword("interface")
gcPath = filepath.Join(build.ToolDir, gc)
}
-func compile(t *testing.T, dirname, filename string) (outFn string) {
+func compile(t *testing.T, dirname, filename string) string {
cmd := exec.Command(gcPath, filename)
cmd.Dir = dirname
out, err := cmd.CombinedOutput()
nimports += testDir(t, "", time.Now().Add(maxTime)) // installed packages
t.Logf("tested %d imports", nimports)
}
+
+var importedObjectTests = []struct {
+ name string
+ kind ast.ObjKind
+ typ string
+}{
+ {"unsafe.Pointer", ast.Typ, "Pointer"},
+ {"math.Pi", ast.Con, "basicType"}, // TODO(gri) need to complete BasicType
+ {"io.Reader", ast.Typ, "interface{Read(p []byte) (n int, err error)}"},
+ {"io.ReadWriter", ast.Typ, "interface{Read(p []byte) (n int, err error); Write(p []byte) (n int, err error)}"},
+ {"math.Sin", ast.Fun, "func(x float64) (_ float64)"},
+ // TODO(gri) add more tests
+}
+
+func TestGcImportedTypes(t *testing.T) {
+ for _, test := range importedObjectTests {
+ s := strings.Split(test.name, ".")
+ if len(s) != 2 {
+ t.Fatal("inconsistent test data")
+ }
+ importPath := s[0]
+ objName := s[1]
+
+ pkg, err := GcImport(imports, importPath)
+ if err != nil {
+ t.Error(err)
+ continue
+ }
+
+ obj := pkg.Data.(*ast.Scope).Lookup(objName)
+ if obj.Kind != test.kind {
+ t.Errorf("%s: got kind = %q; want %q", test.name, obj.Kind, test.kind)
+ }
+ typ := TypeString(Underlying(obj.Type.(Type)))
+ if typ != test.typ {
+ t.Errorf("%s: got type = %q; want %q", test.name, typ, test.typ)
+ }
+ }
+}