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:
parent
f05a91e18b
commit
0f2529317f
@ -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")
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user