Ejemplo n.º 1
0
// DefaultGetPackage looks for the package; if it finds it,
// it parses and returns it. If no package was found, it returns nil.
func DefaultImporter(path string) *ast.Package {
	bpkg, err := build.Default.Import(path, "", 0)
	if err != nil {
		return nil
	}
	pkgs, err := parser.ParseDir(FileSet, bpkg.Dir, isGoFile, 0)
	if err != nil {
		if Debug {
			switch err := err.(type) {
			case scanner.ErrorList:
				for _, e := range err {
					debugp("\t%v: %s", e.Pos, e.Msg)
				}
			default:
				debugp("\terror parsing %s: %v", bpkg.Dir, err)
			}
		}
		return nil
	}
	if pkg := pkgs[bpkg.Name]; pkg != nil {
		return pkg
	}
	if Debug {
		debugp("package not found by ParseDir!")
	}
	return nil
}
Ejemplo n.º 2
0
// DefaultGetPackage looks for the package; if it finds it,
// it parses and returns it. If no package was found, it returns nil.
func DefaultImporter(path string) *ast.Package {
	debugp("getting package %s", path)
	for _, pd := range GoPath {
		dir := pd + "/" + path
		pkgs, err := parser.ParseDir(FileSet, dir, isGoFile, 0)
		if err != nil {
			if Debug {
				switch err := err.(type) {
				case scanner.ErrorList:
					for _, e := range err {
						debugp("\t%v: %s", e.Pos, e.Msg)
					}
				default:
					debugp("\terror parsing %s: %v", dir, err)
				}
			}
			continue
		}
		if pkg := pkgs[parser.ImportPathToName(path)]; pkg != nil {
			return pkg
		}
		delete(pkgs, "documentation")
		for name, pkg := range pkgs {
			if len(pkgs) == 1 || name != "main" {
				return pkg
			}
		}
	}
	return nil
}
Ejemplo n.º 3
0
func parseDir(dir string) *ast.Package {
	pkgs, _ := parser.ParseDir(FileSet, dir, isGoFile, 0)
	if len(pkgs) == 0 {
		return nil
	}
	delete(pkgs, "documentation")
	for name, pkg := range pkgs {
		if len(pkgs) == 1 || name != "main" {
			return pkg
		}
	}
	return nil
}
Ejemplo n.º 4
0
func (def Definition) findReferences(searchpath string, recursive bool) (chan Reference, chan error) {
	refs := make(chan Reference)
	errs := make(chan error, 1000)

	// returns true on error and reports it
	failed := func(err error) bool {
		if err != nil {
			select {
			case errs <- err:
			default:
			}
			return true
		}
		return false
	}

	scanAST := func(f ast.Node) {
		check := func(expr ast.Expr) {
			pos := getDefPosition(expr)
			if pos != nil && *pos == def.Position {
				refs <- Reference{fileset.Position(expr.Pos())}
			}
		}

		ast.Inspect(f, func(node ast.Node) bool {
			switch e := node.(type) {
			case *ast.SelectorExpr:
				if e.Sel.Name == def.Name {
					check(e)
				}
			case *ast.Ident:
				if e.Name == def.Name {
					check(e)
				}
			}
			return true
		})
	}

	scanFile := func(filepath string) {
		f, err := parser.ParseFile(fileset, filepath, nil, 0, getScope(filepath))
		if failed(err) {
			return
		}
		scanAST(f)
	}

	var scanFolder func(dirpath string)
	scanFolder = func(dirpath string) {
		filter := func(fi os.FileInfo) bool {
			return path.Ext(fi.Name()) == ".go"
		}
		result, err := parser.ParseDir(fileset, dirpath, filter, 0)
		if failed(err) {
			return
		}

		for _, pkg := range result {
			scanAST(pkg)
		}

		if !recursive {
			return
		}

		dir, err := os.Open(dirpath)
		if failed(err) {
			return
		}

		infos, err := dir.Readdir(0)
		if failed(err) {
			return
		}

		for _, fi := range infos {
			if fi.IsDir() && !strings.HasPrefix(fi.Name(), ".") {
				scanFolder(path.Join(dirpath, fi.Name()))
			}
		}
	}

	go func() {
		defer close(refs)
		defer close(errs)

		fi, err := os.Lstat(searchpath)
		if err != nil {
			return
		}
		if fi.IsDir() {
			scanFolder(searchpath)
		} else {
			scanFile(searchpath)
		}
	}()

	return refs, errs
}