func TestExportedType(t *testing.T) { tests := []struct { typString string exp bool }{ {"int", true}, {"string", false}, // references the shadowed builtin "string" {"T", true}, {"t", false}, {"*T", true}, {"*t", false}, {"map[int]complex128", true}, } for _, test := range tests { src := `package foo; type T int; type t int; type string struct{}` fset := token.NewFileSet() file, err := parser.ParseFile(fset, "foo.go", src, 0) if err != nil { t.Fatalf("Parsing %q: %v", src, err) } // use the package name as package path pkg, err := types.Check(file.Name.Name, fset, []*ast.File{file}) if err != nil { t.Fatalf("Type checking %q: %v", src, err) } tv, err := types.Eval(fset, pkg, token.NoPos, test.typString) if err != nil { t.Errorf("types.Eval(%q): %v", test.typString, err) continue } if got := exportedType(tv.Type); got != test.exp { t.Errorf("exportedType(%v) = %t, want %t", tv.Type, got, test.exp) } } }
// isUntypedConst reports whether expr is an untyped constant, // and indicates what its default type is. // scope may be nil. func (f *file) isUntypedConst(expr ast.Expr) (defType string, ok bool) { // Re-evaluate expr outside of its context to see if it's untyped. // (An expr evaluated within, for example, an assignment context will get the type of the LHS.) exprStr := f.render(expr) tv, err := types.Eval(f.fset, f.pkg.typesPkg, expr.Pos(), exprStr) if err != nil { return "", false } if b, ok := tv.Type.(*types.Basic); ok { if dt, ok := basicTypeKinds[b.Kind()]; ok { return dt, true } } return "", false }