Permalink
Browse files

go/types: fix Info.Implicits entries

Packages of dot imports don't appear in the Info.Implicits map
since they are already taken care of by the Info.Defs map. Fix
documentation.

Implicitly dot-imported objects of a package shouldn't appear
in the Info.Implicits map because the documentation never said
so and there's no way to map multiple objects to the same
*ast.ImportSpec with the current data structure.

Added missing test for Info.Implicits.

The fix is a trivial one-line deletion, the rest is documentation
and test.

Fixes #21591.

Change-Id: I12a37dab85c531911c9363ec3d58daa095c7eb24
Reviewed-on: https://go-review.googlesource.com/60672
Reviewed-by: Alan Donovan <adonovan@google.com>
  • Loading branch information...
griesemer committed Aug 31, 2017
1 parent e3f3ade commit cecba84a0da049db4df9c1e8aef32b936ef986ea
Showing with 71 additions and 15 deletions.
  1. +14 −14 src/go/types/api.go
  2. +57 −0 src/go/types/api_test.go
  3. +0 −1 src/go/types/resolver.go
View
@@ -176,11 +176,11 @@ type Info struct {
// Implicits maps nodes to their implicitly declared objects, if any.
// The following node and object types may appear:
//
// node declared object
// node declared object
//
// *ast.ImportSpec *PkgName for dot-imports and imports without renames
// *ast.CaseClause type-specific *Var for each type switch case clause (incl. default)
// *ast.Field anonymous parameter *Var
// *ast.ImportSpec *PkgName for imports without renames
// *ast.CaseClause type-specific *Var for each type switch case clause (incl. default)
// *ast.Field anonymous parameter *Var
//
Implicits map[ast.Node]Object
@@ -200,16 +200,16 @@ type Info struct {
//
// The following node types may appear in Scopes:
//
// *ast.File
// *ast.FuncType
// *ast.BlockStmt
// *ast.IfStmt
// *ast.SwitchStmt
// *ast.TypeSwitchStmt
// *ast.CaseClause
// *ast.CommClause
// *ast.ForStmt
// *ast.RangeStmt
// *ast.File
// *ast.FuncType
// *ast.BlockStmt
// *ast.IfStmt
// *ast.SwitchStmt
// *ast.TypeSwitchStmt
// *ast.CaseClause
// *ast.CommClause
// *ast.ForStmt
// *ast.RangeStmt
//
Scopes map[ast.Node]*Scope
View
@@ -257,6 +257,63 @@ func TestTypesInfo(t *testing.T) {
}
}
func TestImplicitsInfo(t *testing.T) {
testenv.MustHaveGoBuild(t)
var tests = []struct {
src string
want string
}{
{`package p2; import . "fmt"; var _ = Println`, ""}, // no Implicits entry
{`package p0; import local "fmt"; var _ = local.Println`, ""}, // no Implicits entry
{`package p1; import "fmt"; var _ = fmt.Println`, "importSpec: package fmt"},
{`package p3; func f(x interface{}) { switch x.(type) { case int: } }`, ""}, // no Implicits entry
{`package p4; func f(x interface{}) { switch t := x.(type) { case int: _ = t } }`, "caseClause: var t int"},
{`package p5; func f(x interface{}) { switch t := x.(type) { case int, uint: _ = t } }`, "caseClause: var t interface{}"},
{`package p6; func f(x interface{}) { switch t := x.(type) { default: _ = t } }`, "caseClause: var t interface{}"},
{`package p7; func f(x int) {}`, ""}, // no Implicits entry
{`package p8; func f(int) {}`, "field: var int"},
{`package p9; func f() (complex64) { return 0 }`, "field: var complex64"},
{`package p10; type T struct{}; func (*T) f() {}`, "field: var *p10.T"},
}
for _, test := range tests {
info := Info{
Implicits: make(map[ast.Node]Object),
}
name := mustTypecheck(t, "ImplicitsInfo", test.src, &info)
// the test cases expect at most one Implicits entry
if len(info.Implicits) > 1 {
t.Errorf("package %s: %d Implicits entries found", name, len(info.Implicits))
continue
}
// extract Implicits entry, if any
var got string
for n, obj := range info.Implicits {
switch x := n.(type) {
case *ast.ImportSpec:
got = "importSpec"
case *ast.CaseClause:
got = "caseClause"
case *ast.Field:
got = "field"
default:
t.Fatalf("package %s: unexpected %T", name, x)
}
got += ": " + obj.String()
}
// verify entry
if got != test.want {
t.Errorf("package %s: got %q; want %q", name, got, test.want)
}
}
}
func predString(tv TypeAndValue) string {
var buf bytes.Buffer
pred := func(b bool, s string) {
View
@@ -303,7 +303,6 @@ func (check *Checker) collectObjects() {
// via Config.Packages - may be dot-imported in
// another package!)
check.declare(fileScope, nil, obj, token.NoPos)
check.recordImplicit(s, obj)
}
}
// add position to set of dot-import positions for this file

0 comments on commit cecba84

Please sign in to comment.