mirror of https://github.com/golang/go.git
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>
This commit is contained in:
parent
e3f3adedcd
commit
cecba84a0d
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue