]> Cypherpunks repositories - gostls13.git/commitdiff
exp/types: add more import tests
authorRobert Griesemer <gri@golang.org>
Thu, 9 Aug 2012 18:55:00 +0000 (11:55 -0700)
committerRobert Griesemer <gri@golang.org>
Thu, 9 Aug 2012 18:55:00 +0000 (11:55 -0700)
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
src/pkg/exp/types/gcimporter_test.go

index 8cae85a23bd61686fa6c37d6888a909bfdd14343..64c7b2a09ad3bdf8a8fd023536f33da5bc60ad14 100644 (file)
@@ -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")
index 61a085d847c6bf06e8cbd72e1316d531aa832e96..8954f40859b14b06ecd3f77f6bca889c004920a5 100644 (file)
@@ -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)
+               }
+       }
+}