Skip to content

Commit

Permalink
go/internal/gcimporter: move 1.11 specific tests out of non-1.11 buil…
Browse files Browse the repository at this point in the history
…ds (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 golang/lint#402.

Change-Id: I45eb8c3d1dcca7b392f14a7660bc1599a44a0d41
Reviewed-on: https://go-review.googlesource.com/118567
Reviewed-by: Robert Griesemer <gri@golang.org>
  • Loading branch information
griesemer committed Jun 13, 2018
1 parent e580e34 commit c995a08
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 118 deletions.
134 changes: 134 additions & 0 deletions go/internal/gcimporter/gcimporter11_test.go
Original file line number Diff line number Diff line change
@@ -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")
}
110 changes: 0 additions & 110 deletions go/internal/gcimporter/gcimporter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down Expand Up @@ -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 {
Expand Down
4 changes: 0 additions & 4 deletions go/internal/gcimporter/newInterface10.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
4 changes: 0 additions & 4 deletions go/internal/gcimporter/newInterface11.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

0 comments on commit c995a08

Please sign in to comment.