// TestVeryLongFile tests the position of an import object declared in // a very long input file. Line numbers greater than maxlines are // reported as line 1, not garbage or token.NoPos. func TestVeryLongFile(t *testing.T) { // parse and typecheck longFile := "package foo" + strings.Repeat("\n", 123456) + "var X int" fset1 := token.NewFileSet() f, err := parser.ParseFile(fset1, "foo.go", longFile, 0) if err != nil { t.Fatal(err) } var conf types.Config pkg, err := conf.Check("foo", fset1, []*ast.File{f}, nil) if err != nil { t.Fatal(err) } // export exportdata := gcimporter.BExportData(fset1, pkg) // import imports := make(map[string]*types.Package) fset2 := token.NewFileSet() _, pkg2, err := gcimporter.BImportData(fset2, imports, exportdata, pkg.Path()) if err != nil { t.Fatalf("BImportData(%s): %v", pkg.Path(), err) } // compare posn1 := fset1.Position(pkg.Scope().Lookup("X").Pos()) posn2 := fset2.Position(pkg2.Scope().Lookup("X").Pos()) if want := "foo.go:1:1"; posn2.String() != want { t.Errorf("X position = %s, want %s (orig was %s)", posn2, want, posn1) } }
func disabledTestInvalidAlias(t *testing.T) { // parse and typecheck const src = "package p; func InvalidAlias => foo.f" fset1 := token.NewFileSet() f, err := parser.ParseFile(fset1, "p.go", src, 0) if err != nil { t.Fatal(err) } var conf types.Config pkg, err := conf.Check("p", fset1, []*ast.File{f}, nil) if err == nil { t.Fatal("invalid source type-checked without error") } if pkg == nil { t.Fatal("nil package returned") } // export exportdata := gcimporter.BExportData(fset1, pkg) // import imports := make(map[string]*types.Package) fset2 := token.NewFileSet() _, pkg2, err := gcimporter.BImportData(fset2, imports, exportdata, pkg.Path()) if err != nil { t.Fatalf("BImportData(%s): %v", pkg.Path(), err) } // pkg2 must contain InvalidAlias as an invalid Alias obj := pkg2.Scope().Lookup("InvalidAlias") if obj == nil { t.Fatal("InvalidAlias not found") } alias, ok := obj.(*types.Alias) if !ok { t.Fatalf("got %v; want alias", alias) } if alias.Type() != types.Typ[types.Invalid] || alias.Orig() != nil { t.Fatalf("got %v (orig = %v); want invalid alias", alias, alias.Orig()) } }
func TestBExportData_stdlib(t *testing.T) { if runtime.GOOS == "android" { t.Skipf("incomplete std lib on %s", runtime.GOOS) } // Load, parse and type-check the program. ctxt := build.Default // copy ctxt.GOPATH = "" // disable GOPATH conf := loader.Config{ Build: &ctxt, AllowErrors: true, } for _, path := range buildutil.AllPackages(conf.Build) { conf.Import(path) } // Create a package containing type and value errors to ensure // they are properly encoded/decoded. f, err := conf.ParseFile("haserrors/haserrors.go", `package haserrors const UnknownValue = "" + 0 type UnknownType undefined `) if err != nil { t.Fatal(err) } conf.CreateFromFiles("haserrors", f) prog, err := conf.Load() if err != nil { t.Fatalf("Load failed: %v", err) } numPkgs := len(prog.AllPackages) if want := 248; numPkgs < want { t.Errorf("Loaded only %d packages, want at least %d", numPkgs, want) } for pkg, info := range prog.AllPackages { if info.Files == nil { continue // empty directory } exportdata := gcimporter.BExportData(conf.Fset, pkg) imports := make(map[string]*types.Package) fset2 := token.NewFileSet() n, pkg2, err := gcimporter.BImportData(fset2, imports, exportdata, pkg.Path()) if err != nil { t.Errorf("BImportData(%s): %v", pkg.Path(), err) continue } if n != len(exportdata) { t.Errorf("BImportData(%s) decoded %d bytes, want %d", pkg.Path(), n, len(exportdata)) } // Compare the packages' corresponding members. for _, name := range pkg.Scope().Names() { if !ast.IsExported(name) { continue } obj1 := pkg.Scope().Lookup(name) obj2 := pkg2.Scope().Lookup(name) if obj2 == nil { t.Errorf("%s.%s not found, want %s", pkg.Path(), name, obj1) continue } fl1 := fileLine(conf.Fset, obj1) fl2 := fileLine(fset2, obj2) if fl1 != fl2 { t.Errorf("%s.%s: got posn %s, want %s", pkg.Path(), name, fl2, fl1) } if err := equalObj(obj1, obj2); err != nil { t.Errorf("%s.%s: %s\ngot: %s\nwant: %s", pkg.Path(), name, err, obj2, obj1) } } } }
// Write writes encoded type information for the specified package to out. // The FileSet provides file position information for named objects. func Write(out io.Writer, fset *token.FileSet, pkg *types.Package) error { _, err := out.Write(gcimporter.BExportData(fset, pkg)) return err }