1
0
mirror of https://github.com/golang/go synced 2024-11-25 12:57:58 -07:00

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
This commit is contained in:
Robert Griesemer 2012-08-09 11:55:00 -07:00
parent f05a91e18b
commit 0f2529317f
2 changed files with 49 additions and 22 deletions

View 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")

View 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)
}
}
}