return conf.Check(f.PkgName.Value, []*syntax.File{f}, info)
}
-func mustTypecheck(path, src string, info *Info) string {
+func mustTypecheck(path, src string, info *Info) *Package {
pkg, err := typecheck(path, src, info)
if err != nil {
panic(err) // so we don't need to pass *testing.T
}
- return pkg.Name()
+ return pkg
}
func TestValuesInfo(t *testing.T) {
info := Info{
Types: make(map[syntax.Expr]TypeAndValue),
}
- name := mustTypecheck("ValuesInfo", test.src, &info)
+ name := mustTypecheck("ValuesInfo", test.src, &info).Name()
// look for expression
var expr syntax.Expr
name = pkg.Name()
}
} else {
- name = mustTypecheck("TypesInfo", test.src, &info)
+ name = mustTypecheck("TypesInfo", test.src, &info).Name()
}
// look for expression type
info := Info{
Defs: make(map[*syntax.Name]Object),
}
- name := mustTypecheck("DefsInfo", test.src, &info)
+ name := mustTypecheck("DefsInfo", test.src, &info).Name()
// find object
var def Object
info := Info{
Uses: make(map[*syntax.Name]Object),
}
- name := mustTypecheck("UsesInfo", test.src, &info)
+ name := mustTypecheck("UsesInfo", test.src, &info).Name()
// find object
var use Object
info := Info{
Implicits: make(map[syntax.Node]Object),
}
- name := mustTypecheck("ImplicitsInfo", test.src, &info)
+ name := mustTypecheck("ImplicitsInfo", test.src, &info).Name()
// the test cases expect at most one Implicits entry
if len(info.Implicits) > 1 {
for _, test := range tests {
info := Info{Types: make(map[syntax.Expr]TypeAndValue)}
- name := mustTypecheck("PredicatesInfo", test.src, &info)
+ name := mustTypecheck("PredicatesInfo", test.src, &info).Name()
// look for expression predicates
got := "<missing>"
for _, test := range tests {
info := Info{Scopes: make(map[syntax.Node]*Scope)}
- name := mustTypecheck("ScopesInfo", test.src, &info)
+ name := mustTypecheck("ScopesInfo", test.src, &info).Name()
// number of scopes must match
if len(info.Scopes) != len(test.scopes) {
for _, test := range tests {
info := Info{}
- name := mustTypecheck("InitOrderInfo", test.src, &info)
+ name := mustTypecheck("InitOrderInfo", test.src, &info).Name()
// number of initializers must match
if len(info.InitOrder) != len(test.inits) {
}
for _, test := range tests {
- pkg, err := typecheck("test", "package p;"+test.src, nil)
- if err != nil {
- t.Errorf("%s: incorrect test case: %s", test.src, err)
- continue
- }
+ pkg := mustTypecheck("test", "package p;"+test.src, nil)
obj := pkg.Scope().Lookup("a")
if obj == nil {
}
for _, test := range tests {
- pkg, err := typecheck("test", "package p;"+test.src, nil)
- if err != nil {
- t.Errorf("%s: incorrect test case: %s", test.src, err)
- continue
- }
+ pkg := mustTypecheck("test", "package p;"+test.src, nil)
X := pkg.Scope().Lookup("X")
Y := pkg.Scope().Lookup("Y")
if X == nil || Y == nil {
func TestInstantiate(t *testing.T) {
// eventually we like more tests but this is a start
const src = "package p; type T[P any] *T[P]"
- pkg, err := typecheck(".", src, nil)
- if err != nil {
- t.Fatal(err)
- }
+ pkg := mustTypecheck(".", src, nil)
// type T should have one type parameter
T := pkg.Scope().Lookup("T").Type().(*Named)
for _, test := range tests {
src := "package p; " + test.src
- pkg, err := typecheck(".", src, nil)
- if err != nil {
- t.Fatal(err)
- }
+ pkg := mustTypecheck(".", src, nil)
T := pkg.Scope().Lookup("T").Type().(*Named)
- _, err = Instantiate(nil, T, test.targs, true)
+ _, err := Instantiate(nil, T, test.targs, true)
if err == nil {
t.Fatalf("Instantiate(%v, %v) returned nil error, want non-nil", T, test.targs)
}
func (V4) M()
`
- pkg, err := typecheck("p.go", src, nil)
- if err != nil {
- t.Fatal(err)
- }
+ pkg := mustTypecheck("p.go", src, nil)
T := pkg.Scope().Lookup("T").Type().Underlying().(*Interface)
lookup := func(name string) (*Func, bool) {
}
for _, test := range tests {
- pkg, err := typecheck(".", test.src, nil)
- if err != nil {
- t.Fatal(err)
- }
+ pkg := mustTypecheck(".", test.src, nil)
t.Run(pkg.Name(), func(t *testing.T) {
ctxt := NewContext()
func TestInstantiateNonEquality(t *testing.T) {
const src = "package p; type T[P any] int"
- pkg1, err := typecheck(".", src, nil)
- if err != nil {
- t.Fatal(err)
- }
- pkg2, err := typecheck(".", src, nil)
- if err != nil {
- t.Fatal(err)
- }
+ pkg1 := mustTypecheck(".", src, nil)
+ pkg2 := mustTypecheck(".", src, nil)
// We consider T1 and T2 to be distinct types, so their instances should not
// be deduplicated by the context.
T1 := pkg1.Scope().Lookup("T").Type().(*Named)
for _, test := range tests {
src := prefix + test.decl
- pkg, err := typecheck(".", src, nil)
- if err != nil {
- t.Fatal(err)
- }
+ pkg := mustTypecheck(".", src, nil)
typ := NewPointer(pkg.Scope().Lookup("X").Type())
obj, _, _ := LookupFieldOrMethod(typ, false, pkg, "m")
m, _ := obj.(*Func)
var _ T[int]
`
- pkg, err := typecheck(".", src, nil)
- if err != nil {
- t.Fatal(err)
- }
+ pkg := mustTypecheck(".", src, nil)
typ := pkg.Scope().Lookup("T").Type().(*Named)
obj, _, _ := LookupFieldOrMethod(typ, false, pkg, "m")
if obj == nil {
const asrc = `package a; type I interface{ M() }; type T struct { F interface { I } }`
const bsrc = `package b; import "a"; type T struct { F interface { a.I } }; var _ = a.T(T{})`
- a, err := typecheck("a", asrc, nil)
- if err != nil {
- t.Fatalf("package %s failed to typecheck: %v", a.Name(), err)
- }
+ a := mustTypecheck("a", asrc, nil)
bast := mustParse("", bsrc)
conf := Config{Importer: importHelper{pkg: a}}
csrc = `package c; import ("a"; "html/template"); func _() { a.G(template.Template{}) }`
)
- a, err := typecheck("a", asrc, nil)
- if err != nil {
- t.Fatalf("package a failed to typecheck: %v", err)
- }
+ a := mustTypecheck("a", asrc, nil)
conf := Config{Importer: importHelper{pkg: a, fallback: defaultImporter()}}
// Packages should be fully qualified when there is ambiguity within the
// error string itself.
bast := mustParse("", bsrc)
- _, err = conf.Check(bast.PkgName.Value, []*syntax.File{bast}, nil)
+ _, err := conf.Check(bast.PkgName.Value, []*syntax.File{bast}, nil)
if err == nil {
t.Fatal("package b had no errors")
}
type Inst = G[int]
`
- pkg, err := typecheck("p", src, nil)
- if err != nil {
- b.Fatal(err)
- }
+ pkg := mustTypecheck("p", src, nil)
var (
T = pkg.Scope().Lookup("T").Type()
}
func findStructTypeConfig(t *testing.T, src string, conf *types2.Config) *types2.Struct {
- f := mustParse("x.go", src)
- info := types2.Info{Types: make(map[syntax.Expr]types2.TypeAndValue)}
- _, err := conf.Check("x", []*syntax.File{f}, &info)
- if err != nil {
- t.Fatal(err)
- }
- for _, tv := range info.Types {
+ types := make(map[syntax.Expr]types2.TypeAndValue)
+ mustTypecheck("x", src, &types2.Info{Types: types})
+ for _, tv := range types {
if ts, ok := tv.Type.(*types2.Struct); ok {
return ts
}
}
func TestQualifiedTypeString(t *testing.T) {
- p, _ := typecheck("p.go", "package p; type T int", nil)
- q, _ := typecheck("q.go", "package q", nil)
+ p := mustTypecheck("p.go", "package p; type T int", nil)
+ q := mustTypecheck("q.go", "package q", nil)
pT := p.Scope().Lookup("T").Type()
for _, test := range []struct {
return conf.Check(f.Name.Name, fset, []*ast.File{f}, info)
}
-func mustTypecheck(path, src string, info *Info) string {
+func mustTypecheck(path, src string, info *Info) *Package {
pkg, err := typecheck(path, src, info)
if err != nil {
panic(err) // so we don't need to pass *testing.T
}
- return pkg.Name()
+ return pkg
}
func TestValuesInfo(t *testing.T) {
info := Info{
Types: make(map[ast.Expr]TypeAndValue),
}
- name := mustTypecheck("ValuesInfo", test.src, &info)
+ name := mustTypecheck("ValuesInfo", test.src, &info).Name()
// look for expression
var expr ast.Expr
name = pkg.Name()
}
} else {
- name = mustTypecheck("TypesInfo", test.src, &info)
+ name = mustTypecheck("TypesInfo", test.src, &info).Name()
}
// look for expression type
info := Info{
Defs: make(map[*ast.Ident]Object),
}
- name := mustTypecheck("DefsInfo", test.src, &info)
+ name := mustTypecheck("DefsInfo", test.src, &info).Name()
// find object
var def Object
info := Info{
Uses: make(map[*ast.Ident]Object),
}
- name := mustTypecheck("UsesInfo", test.src, &info)
+ name := mustTypecheck("UsesInfo", test.src, &info).Name()
// find object
var use Object
info := Info{
Implicits: make(map[ast.Node]Object),
}
- name := mustTypecheck("ImplicitsInfo", test.src, &info)
+ name := mustTypecheck("ImplicitsInfo", test.src, &info).Name()
// the test cases expect at most one Implicits entry
if len(info.Implicits) > 1 {
for _, test := range tests {
info := Info{Types: make(map[ast.Expr]TypeAndValue)}
- name := mustTypecheck("PredicatesInfo", test.src, &info)
+ name := mustTypecheck("PredicatesInfo", test.src, &info).Name()
// look for expression predicates
got := "<missing>"
for _, test := range tests {
info := Info{Scopes: make(map[ast.Node]*Scope)}
- name := mustTypecheck("ScopesInfo", test.src, &info)
+ name := mustTypecheck("ScopesInfo", test.src, &info).Name()
// number of scopes must match
if len(info.Scopes) != len(test.scopes) {
for _, test := range tests {
info := Info{}
- name := mustTypecheck("InitOrderInfo", test.src, &info)
+ name := mustTypecheck("InitOrderInfo", test.src, &info).Name()
// number of initializers must match
if len(info.InitOrder) != len(test.inits) {
}
for _, test := range tests {
- pkg, err := typecheck("test", "package p;"+test.src, nil)
- if err != nil {
- t.Errorf("%s: incorrect test case: %s", test.src, err)
- continue
- }
+ pkg := mustTypecheck("test", "package p;"+test.src, nil)
obj := pkg.Scope().Lookup("a")
if obj == nil {
}
for _, test := range tests {
- pkg, err := typecheck("test", "package p;"+test.src, nil)
- if err != nil {
- t.Errorf("%s: incorrect test case: %s", test.src, err)
- continue
- }
+ pkg := mustTypecheck("test", "package p;"+test.src, nil)
X := pkg.Scope().Lookup("X")
Y := pkg.Scope().Lookup("Y")
if X == nil || Y == nil {
func TestInstantiate(t *testing.T) {
// eventually we like more tests but this is a start
const src = "package p; type T[P any] *T[P]"
- pkg, err := typecheck(".", src, nil)
- if err != nil {
- t.Fatal(err)
- }
+ pkg := mustTypecheck(".", src, nil)
// type T should have one type parameter
T := pkg.Scope().Lookup("T").Type().(*Named)
for _, test := range tests {
src := "package p; " + test.src
- pkg, err := typecheck(".", src, nil)
- if err != nil {
- t.Fatal(err)
- }
+ pkg := mustTypecheck(".", src, nil)
T := pkg.Scope().Lookup("T").Type().(*Named)
- _, err = Instantiate(nil, T, test.targs, true)
+ _, err := Instantiate(nil, T, test.targs, true)
if err == nil {
t.Fatalf("Instantiate(%v, %v) returned nil error, want non-nil", T, test.targs)
}
func (V4) M()
`
- pkg, err := typecheck("p.go", src, nil)
- if err != nil {
- t.Fatal(err)
- }
+ pkg := mustTypecheck("p.go", src, nil)
T := pkg.Scope().Lookup("T").Type().Underlying().(*Interface)
lookup := func(name string) (*Func, bool) {
}
for _, test := range tests {
- pkg, err := typecheck(".", test.src, nil)
- if err != nil {
- t.Fatal(err)
- }
+ pkg := mustTypecheck(".", test.src, nil)
t.Run(pkg.Name(), func(t *testing.T) {
ctxt := NewContext()
func TestInstantiateNonEquality(t *testing.T) {
const src = "package p; type T[P any] int"
- pkg1, err := typecheck(".", src, nil)
- if err != nil {
- t.Fatal(err)
- }
- pkg2, err := typecheck(".", src, nil)
- if err != nil {
- t.Fatal(err)
- }
+ pkg1 := mustTypecheck(".", src, nil)
+ pkg2 := mustTypecheck(".", src, nil)
// We consider T1 and T2 to be distinct types, so their instances should not
// be deduplicated by the context.
for _, test := range tests {
src := prefix + test.decl
- pkg, err := typecheck(".", src, nil)
- if err != nil {
- t.Fatal(err)
- }
+ pkg := mustTypecheck(".", src, nil)
typ := NewPointer(pkg.Scope().Lookup("X").Type())
obj, _, _ := LookupFieldOrMethod(typ, false, pkg, "m")
m, _ := obj.(*Func)
var _ T[int]
`
- pkg, err := typecheck(".", src, nil)
- if err != nil {
- t.Fatal(err)
- }
+ pkg := mustTypecheck(".", src, nil)
typ := pkg.Scope().Lookup("T").Type().(*Named)
obj, _, _ := LookupFieldOrMethod(typ, false, pkg, "m")
if obj == nil {
const asrc = `package a; type I interface{ M() }; type T struct { F interface { I } }`
const bsrc = `package b; import "a"; type T struct { F interface { a.I } }; var _ = a.T(T{})`
- a, err := typecheck("a", asrc, nil)
- if err != nil {
- t.Fatalf("package %s failed to typecheck: %v", a.Name(), err)
- }
+ a := mustTypecheck("a", asrc, nil)
bast := mustParse(fset, "", bsrc)
conf := Config{Importer: importHelper{pkg: a}}
`
)
- a, err := typecheck("a", asrc, nil)
- if err != nil {
- t.Fatalf("package a failed to typecheck: %v", err)
- }
+ a := mustTypecheck("a", asrc, nil)
imp := importHelper{pkg: a, fallback: importer.Default()}
testFiles(t, nil, []string{"b.go"}, [][]byte{[]byte(bsrc)}, false, imp)
}
check := func(src string, methods []method, generic bool) {
- pkg, err := typecheck("test", "package p;"+src, nil)
- if err != nil {
- t.Errorf("%s: incorrect test case: %s", src, err)
- return
- }
+ pkg := mustTypecheck("test", "package p;"+src, nil)
scope := pkg.Scope()
if generic {
type Inst = G[int]
`
- pkg, err := typecheck("p", src, nil)
- if err != nil {
- b.Fatal(err)
- }
+ pkg := mustTypecheck("p", src, nil)
var (
T = pkg.Scope().Lookup("T").Type()
}
func findStructTypeConfig(t *testing.T, src string, conf *types.Config) *types.Struct {
- fset := token.NewFileSet()
- f := mustParse(fset, "x.go", src)
- info := types.Info{Types: make(map[ast.Expr]types.TypeAndValue)}
- _, err := conf.Check("x", fset, []*ast.File{f}, &info)
- if err != nil {
- t.Fatal(err)
- }
- for _, tv := range info.Types {
+ types_ := make(map[ast.Expr]types.TypeAndValue)
+ mustTypecheck("x", src, &types.Info{Types: types_})
+ for _, tv := range types_ {
if ts, ok := tv.Type.(*types.Struct); ok {
return ts
}
}
func TestQualifiedTypeString(t *testing.T) {
- p, _ := typecheck("p.go", "package p; type T int", nil)
- q, _ := typecheck("q.go", "package q", nil)
+ p := mustTypecheck("p.go", "package p; type T int", nil)
+ q := mustTypecheck("q.go", "package q", nil)
pT := p.Scope().Lookup("T").Type()
for _, test := range []struct {