From c995a088887b4ae00a4c85a984117cbc8d86ca3d Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Wed, 13 Jun 2018 11:57:27 -0700 Subject: [PATCH] go/internal/gcimporter: move 1.11 specific tests out of non-1.11 builds (fix build) TBR=adonovan The tests TestImportedTypes and TestIssue25301 are dependent on many 1.11-specific bug fixes that went into go/types. Just move them out of non-1.11 builds. While doing so, also extended the set of test cases run by TestImportedTypes (now matching the corresponding tests cases in the std lib). This also makes it again unnecessary to factor out the embeddedType function into build-specific versions. Removed again. For https://github.com/golang/lint/issues/402. Change-Id: I45eb8c3d1dcca7b392f14a7660bc1599a44a0d41 Reviewed-on: https://go-review.googlesource.com/118567 Reviewed-by: Robert Griesemer --- go/internal/gcimporter/gcimporter11_test.go | 134 ++++++++++++++++++++ go/internal/gcimporter/gcimporter_test.go | 110 ---------------- go/internal/gcimporter/newInterface10.go | 4 - go/internal/gcimporter/newInterface11.go | 4 - 4 files changed, 134 insertions(+), 118 deletions(-) create mode 100644 go/internal/gcimporter/gcimporter11_test.go diff --git a/go/internal/gcimporter/gcimporter11_test.go b/go/internal/gcimporter/gcimporter11_test.go new file mode 100644 index 00000000..787620d6 --- /dev/null +++ b/go/internal/gcimporter/gcimporter11_test.go @@ -0,0 +1,134 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build go1.11 + +package gcimporter + +import ( + "go/types" + "os" + "runtime" + "strings" + "testing" +) + +var importedObjectTests = []struct { + name string + want string +}{ + // non-interfaces + {"crypto.Hash", "type Hash uint"}, + {"go/ast.ObjKind", "type ObjKind int"}, + {"go/types.Qualifier", "type Qualifier func(*Package) string"}, + {"go/types.Comparable", "func Comparable(T Type) bool"}, + {"math.Pi", "const Pi untyped float"}, + {"math.Sin", "func Sin(x float64) float64"}, + {"go/ast.NotNilFilter", "func NotNilFilter(_ string, v reflect.Value) bool"}, + {"go/internal/gcimporter.BImportData", "func BImportData(fset *go/token.FileSet, imports map[string]*go/types.Package, data []byte, path string) (_ int, pkg *go/types.Package, err error)"}, + + // interfaces + {"context.Context", "type Context interface{Deadline() (deadline time.Time, ok bool); Done() <-chan struct{}; Err() error; Value(key interface{}) interface{}}"}, + {"crypto.Decrypter", "type Decrypter interface{Decrypt(rand io.Reader, msg []byte, opts DecrypterOpts) (plaintext []byte, err error); Public() PublicKey}"}, + {"encoding.BinaryMarshaler", "type BinaryMarshaler interface{MarshalBinary() (data []byte, err error)}"}, + {"io.Reader", "type Reader interface{Read(p []byte) (n int, err error)}"}, + {"io.ReadWriter", "type ReadWriter interface{Reader; Writer}"}, + {"go/ast.Node", "type Node interface{End() go/token.Pos; Pos() go/token.Pos}"}, + {"go/types.Type", "type Type interface{String() string; Underlying() Type}"}, +} + +func TestImportedTypes(t *testing.T) { + skipSpecialPlatforms(t) + + // This package only handles gc export data. + if runtime.Compiler != "gc" { + t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler) + } + + 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 := Import(make(map[string]*types.Package), importPath, ".") + if err != nil { + t.Error(err) + continue + } + + obj := pkg.Scope().Lookup(objName) + if obj == nil { + t.Errorf("%s: object not found", test.name) + continue + } + + got := types.ObjectString(obj, types.RelativeTo(pkg)) + if got != test.want { + t.Errorf("%s: got %q; want %q", test.name, got, test.want) + } + + if named, _ := obj.Type().(*types.Named); named != nil { + verifyInterfaceMethodRecvs(t, named, 0) + } + } +} + +// verifyInterfaceMethodRecvs verifies that method receiver types +// are named if the methods belong to a named interface type. +func verifyInterfaceMethodRecvs(t *testing.T, named *types.Named, level int) { + // avoid endless recursion in case of an embedding bug that lead to a cycle + if level > 10 { + t.Errorf("%s: embeds itself", named) + return + } + + iface, _ := named.Underlying().(*types.Interface) + if iface == nil { + return // not an interface + } + + // check explicitly declared methods + for i := 0; i < iface.NumExplicitMethods(); i++ { + m := iface.ExplicitMethod(i) + recv := m.Type().(*types.Signature).Recv() + if recv == nil { + t.Errorf("%s: missing receiver type", m) + continue + } + if recv.Type() != named { + t.Errorf("%s: got recv type %s; want %s", m, recv.Type(), named) + } + } + + // check embedded interfaces (if they are named, too) + for i := 0; i < iface.NumEmbeddeds(); i++ { + // embedding of interfaces cannot have cycles; recursion will terminate + if etype, _ := iface.EmbeddedType(i).(*types.Named); etype != nil { + verifyInterfaceMethodRecvs(t, etype, level+1) + } + } +} +func TestIssue25301(t *testing.T) { + skipSpecialPlatforms(t) + + // This package only handles gc export data. + if runtime.Compiler != "gc" { + t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler) + } + + // On windows, we have to set the -D option for the compiler to avoid having a drive + // letter and an illegal ':' in the import path - just skip it (see also issue #3483). + if runtime.GOOS == "windows" { + t.Skip("avoid dealing with relative paths/drive letters on windows") + } + + if f := compile(t, "testdata", "issue25301.go"); f != "" { + defer os.Remove(f) + } + + importPkg(t, "./testdata/issue25301") +} diff --git a/go/internal/gcimporter/gcimporter_test.go b/go/internal/gcimporter/gcimporter_test.go index dce607fd..bfcb7389 100644 --- a/go/internal/gcimporter/gcimporter_test.go +++ b/go/internal/gcimporter/gcimporter_test.go @@ -252,95 +252,6 @@ func TestImportStdLib(t *testing.T) { t.Logf("tested %d imports", nimports) } -var importedObjectTests = []struct { - name string - want string -}{ - {"math.Pi", "const Pi untyped float"}, - {"io.Reader", "type Reader interface{Read(p []byte) (n int, err error)}"}, - // Go 1.7 and 1.8 don't know about embedded interfaces. Leave this - // test out for now - the code is tested in the std library anyway. - // TODO(gri) enable again once we're off 1.7 and 1.8. - // {"io.ReadWriter", "type ReadWriter interface{Reader; Writer}"}, - {"math.Sin", "func Sin(x float64) float64"}, - // TODO(gri) Add additional tests which are now present in the - // corresponding std library version of this file. -} - -func TestImportedTypes(t *testing.T) { - skipSpecialPlatforms(t) - - // This package only handles gc export data. - if runtime.Compiler != "gc" { - t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler) - } - - 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 := Import(make(map[string]*types.Package), importPath, ".") - if err != nil { - t.Error(err) - continue - } - - obj := pkg.Scope().Lookup(objName) - if obj == nil { - t.Errorf("%s: object not found", test.name) - continue - } - - got := types.ObjectString(obj, types.RelativeTo(pkg)) - if got != test.want { - t.Errorf("%s: got %q; want %q", test.name, got, test.want) - } - - if named, _ := obj.Type().(*types.Named); named != nil { - verifyInterfaceMethodRecvs(t, named, 0) - } - } -} - -// verifyInterfaceMethodRecvs verifies that method receiver types -// are named if the methods belong to a named interface type. -func verifyInterfaceMethodRecvs(t *testing.T, named *types.Named, level int) { - // avoid endless recursion in case of an embedding bug that lead to a cycle - if level > 10 { - t.Errorf("%s: embeds itself", named) - return - } - - iface, _ := named.Underlying().(*types.Interface) - if iface == nil { - return // not an interface - } - - // check explicitly declared methods - for i := 0; i < iface.NumExplicitMethods(); i++ { - m := iface.ExplicitMethod(i) - recv := m.Type().(*types.Signature).Recv() - if recv == nil { - t.Errorf("%s: missing receiver type", m) - continue - } - if recv.Type() != named { - t.Errorf("%s: got recv type %s; want %s", m, recv.Type(), named) - } - } - - // check embedded interfaces (if they are named, too) - for i := 0; i < iface.NumEmbeddeds(); i++ { - // embedding of interfaces cannot have cycles; recursion will terminate - if etype, _ := embeddedType(iface, i).(*types.Named); etype != nil { - verifyInterfaceMethodRecvs(t, etype, level+1) - } - } -} func TestIssue5815(t *testing.T) { skipSpecialPlatforms(t) @@ -556,27 +467,6 @@ func TestIssue20046(t *testing.T) { } } -func TestIssue25301(t *testing.T) { - skipSpecialPlatforms(t) - - // This package only handles gc export data. - if runtime.Compiler != "gc" { - t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler) - } - - // On windows, we have to set the -D option for the compiler to avoid having a drive - // letter and an illegal ':' in the import path - just skip it (see also issue #3483). - if runtime.GOOS == "windows" { - t.Skip("avoid dealing with relative paths/drive letters on windows") - } - - if f := compile(t, "testdata", "issue25301.go"); f != "" { - defer os.Remove(f) - } - - importPkg(t, "./testdata/issue25301") -} - func importPkg(t *testing.T, path string) *types.Package { pkg, err := Import(make(map[string]*types.Package), path, ".") if err != nil { diff --git a/go/internal/gcimporter/newInterface10.go b/go/internal/gcimporter/newInterface10.go index 0aca5711..463f2522 100644 --- a/go/internal/gcimporter/newInterface10.go +++ b/go/internal/gcimporter/newInterface10.go @@ -19,7 +19,3 @@ func newInterface(methods []*types.Func, embeddeds []types.Type) *types.Interfac } return types.NewInterface(methods, named) } - -func embeddedType(iface *types.Interface, i int) types.Type { - return iface.Embedded(i) -} diff --git a/go/internal/gcimporter/newInterface11.go b/go/internal/gcimporter/newInterface11.go index e802f8a3..58d1735e 100644 --- a/go/internal/gcimporter/newInterface11.go +++ b/go/internal/gcimporter/newInterface11.go @@ -11,7 +11,3 @@ import "go/types" func newInterface(methods []*types.Func, embeddeds []types.Type) *types.Interface { return types.NewInterface2(methods, embeddeds) } - -func embeddedType(iface *types.Interface, i int) types.Type { - return iface.EmbeddedType(i) -}