Exemple #1
0
func TestImportedTypes(t *testing.T) {
	// This package does not handle gccgo export data.
	if runtime.Compiler == "gccgo" {
		return
	}
	for _, test := range importedObjectTests {
		s := strings.Split(test.name, ".")
		if len(s) != 2 {
			t.Fatal("inconsistent test data")
		}
		importPath := s[0]
		objName := s[1]

		pkg, err := Import(imports, importPath)
		if err != nil {
			t.Error(err)
			continue
		}

		obj := pkg.Scope().Lookup(objName)
		if obj == nil {
			t.Errorf("%s: object not found", test.name)
			continue
		}

		got := types.ObjectString(pkg, obj)
		if got != test.want {
			t.Errorf("%s: got %q; want %q", test.name, got, test.want)
		}
	}
}
Exemple #2
0
// ObjectString prints object obj relative to the query position.
func (qpos *QueryPos) ObjectString(obj types.Object) string {
	return types.ObjectString(qpos.info.Pkg, obj)
}
Exemple #3
0
func TestStdlib(t *testing.T) {
	runtime.GC()
	t0 := time.Now()
	var memstats runtime.MemStats
	runtime.ReadMemStats(&memstats)
	alloc := memstats.Alloc

	// Load, parse and type-check the program.
	ctxt := build.Default // copy
	ctxt.GOPATH = ""      // disable GOPATH
	conf := loader.Config{Build: &ctxt}
	for _, path := range buildutil.AllPackages(conf.Build) {
		conf.ImportWithTests(path)
	}

	prog, err := conf.Load()
	if err != nil {
		t.Fatalf("Load failed: %v", err)
	}

	t1 := time.Now()
	runtime.GC()
	runtime.ReadMemStats(&memstats)

	numPkgs := len(prog.AllPackages)
	if want := 205; numPkgs < want {
		t.Errorf("Loaded only %d packages, want at least %d", numPkgs, want)
	}

	// Dump package members.
	if false {
		for pkg := range prog.AllPackages {
			fmt.Printf("Package %s:\n", pkg.Path())
			scope := pkg.Scope()
			for _, name := range scope.Names() {
				if ast.IsExported(name) {
					fmt.Printf("\t%s\n", types.ObjectString(pkg, scope.Lookup(name)))
				}
			}
			fmt.Println()
		}
	}

	// Check that Test functions for io/ioutil, regexp and
	// compress/bzip2 are all simultaneously present.
	// (The apparent cycle formed when augmenting all three of
	// these packages by their tests was the original motivation
	// for reporting b/7114.)
	//
	// compress/bzip2.TestBitReader in bzip2_test.go    imports io/ioutil
	// io/ioutil.TestTempFile       in tempfile_test.go imports regexp
	// regexp.TestRE2Search         in exec_test.go     imports compress/bzip2
	for _, test := range []struct{ pkg, fn string }{
		{"io/ioutil", "TestTempFile"},
		{"regexp", "TestRE2Search"},
		{"compress/bzip2", "TestBitReader"},
	} {
		info := prog.Imported[test.pkg]
		if info == nil {
			t.Errorf("failed to load package %q", test.pkg)
			continue
		}
		obj, _ := info.Pkg.Scope().Lookup(test.fn).(*types.Func)
		if obj == nil {
			t.Errorf("package %q has no func %q", test.pkg, test.fn)
			continue
		}
	}

	// Dump some statistics.

	// determine line count
	var lineCount int
	prog.Fset.Iterate(func(f *token.File) bool {
		lineCount += f.LineCount()
		return true
	})

	t.Log("GOMAXPROCS:           ", runtime.GOMAXPROCS(0))
	t.Log("#Source lines:        ", lineCount)
	t.Log("Load/parse/typecheck: ", t1.Sub(t0))
	t.Log("#MB:                  ", int64(memstats.Alloc-alloc)/1000000)
}
Exemple #4
0
func (a *analysis) doTypeInfo(info *loader.PackageInfo, implements map[*types.Named]implementsFacts) {
	// We must not assume the corresponding SSA packages were
	// created (i.e. were transitively error-free).

	// IMPORTS
	for _, f := range info.Files {
		// Package decl.
		fi, offset := a.fileAndOffset(f.Name.Pos())
		fi.addLink(aLink{
			start: offset,
			end:   offset + len(f.Name.Name),
			title: "Package docs for " + info.Pkg.Path(),
			// TODO(adonovan): fix: we're putting the untrusted Path()
			// into a trusted field.  What's the appropriate sanitizer?
			href: "/pkg/" + info.Pkg.Path(),
		})

		// Import specs.
		for _, imp := range f.Imports {
			// Remove quotes.
			L := int(imp.End()-imp.Path.Pos()) - len(`""`)
			path, _ := strconv.Unquote(imp.Path.Value)
			fi, offset := a.fileAndOffset(imp.Path.Pos())
			fi.addLink(aLink{
				start: offset + 1,
				end:   offset + 1 + L,
				title: "Package docs for " + path,
				// TODO(adonovan): fix: we're putting the untrusted path
				// into a trusted field.  What's the appropriate sanitizer?
				href: "/pkg/" + path,
			})
		}
	}

	// RESOLUTION
	for id, obj := range info.Uses {
		// Position of the object definition.
		pos := obj.Pos()
		Len := len(obj.Name())

		// Correct the position for non-renaming import specs.
		//  import "sync/atomic"
		//          ^^^^^^^^^^^
		if obj, ok := obj.(*types.PkgName); ok && id.Name == obj.Imported().Name() {
			// Assume this is a non-renaming import.
			// NB: not true for degenerate renamings: `import foo "foo"`.
			pos++
			Len = len(obj.Imported().Path())
		}

		if obj.Pkg() == nil {
			continue // don't mark up built-ins.
		}

		fi, offset := a.fileAndOffset(id.NamePos)
		fi.addLink(aLink{
			start: offset,
			end:   offset + len(id.Name),
			title: types.ObjectString(info.Pkg, obj),
			href:  a.posURL(pos, Len),
		})
	}

	// IMPLEMENTS & METHOD SETS
	for _, obj := range info.Defs {
		if obj, ok := obj.(*types.TypeName); ok {
			a.namedType(obj, implements)
		}
	}
}