From 0f2529317f7ab02309589bd493189d6b714f2020 Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Thu, 9 Aug 2012 11:55:00 -0700 Subject: [PATCH] exp/types: add more import tests Also simplified parsing of interface types since they can only contain methods (and no embedded interfaces) in the export data. R=rsc CC=golang-dev https://golang.org/cl/6446084 --- src/pkg/exp/types/gcimporter.go | 30 ++++++-------------- src/pkg/exp/types/gcimporter_test.go | 41 +++++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 22 deletions(-) diff --git a/src/pkg/exp/types/gcimporter.go b/src/pkg/exp/types/gcimporter.go index 8cae85a23b..64c7b2a09a 100644 --- a/src/pkg/exp/types/gcimporter.go +++ b/src/pkg/exp/types/gcimporter.go @@ -507,33 +507,21 @@ func (p *gcParser) parseSignature() *Func { 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") diff --git a/src/pkg/exp/types/gcimporter_test.go b/src/pkg/exp/types/gcimporter_test.go index 61a085d847..8954f40859 100644 --- a/src/pkg/exp/types/gcimporter_test.go +++ b/src/pkg/exp/types/gcimporter_test.go @@ -36,7 +36,7 @@ func init() { 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() @@ -113,3 +113,42 @@ func TestGcImport(t *testing.T) { 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) + } + } +} -- 2.48.1