func LocalImporter(path string) (pkg *ast.Package) { path = filepath.Clean(path) //fmt.Printf("Importing %s\n", path) var ok bool var pkgtop *ast.Package if pkgtop, ok = PackageTops[path]; !ok { pkg = types.DefaultImporter(path) return } if pkg, ok = Packages[path]; ok { return } var sourcefiles []string for srcfile := range pkgtop.Files { sourcefiles = append(sourcefiles, srcfile) } //fmt.Printf("Parsing %v\n", sourcefiles) dirpkgs, err := parser.ParseFiles(AllSources, sourcefiles, parser.ParseComments) if err != nil { fmt.Println(err) return } pkg = dirpkgs[pkgtop.Name] Packages[path] = pkg //fmt.Printf("nil: %v name: %s\n", pkg == nil, pkgtop.Name) return }
func (ctxt *Context) importerFunc() types.Importer { return func(path string) *ast.Package { ctxt.pkgMutex.Lock() defer ctxt.pkgMutex.Unlock() if pkg := ctxt.pkgCache[path]; pkg != nil { return pkg } cwd, _ := os.Getwd() // TODO put this into Context? bpkg, err := build.Import(path, cwd, 0) if err != nil { ctxt.logf(token.NoPos, "cannot find %q: %v", path, err) return nil } // Relative paths can have several names if pkg := ctxt.pkgCache[bpkg.ImportPath]; pkg != nil { ctxt.pkgCache[path] = pkg return pkg } var files []string files = append(files, bpkg.GoFiles...) files = append(files, bpkg.CgoFiles...) files = append(files, bpkg.TestGoFiles...) for i, f := range files { files[i] = filepath.Join(bpkg.Dir, f) } pkgs, err := parser.ParseFiles(ctxt.FileSet, files, parser.ParseComments) if len(pkgs) == 0 { ctxt.logf(token.NoPos, "cannot parse package %q: %v", path, err) return nil } delete(pkgs, "documentation") for _, pkg := range pkgs { if ctxt.pkgCache[path] == nil { ctxt.pkgCache[path] = pkg if path != bpkg.ImportPath { ctxt.pkgCache[bpkg.ImportPath] = pkg } } else { ctxt.logf(token.NoPos, "unexpected extra package %q in %q", pkg.Name, path) } } return ctxt.pkgCache[path] } }
//Look at the imports, and build up ImportedBy func ScanForImports(path string) (err error) { sourcefiles, _ := filepath.Glob(filepath.Join(path, "*.go")) dirpkgs, err := parser.ParseFiles(AllSourceTops, sourcefiles, parser.ImportsOnly) if err != nil { fmt.Println(err) } //take the first non-main. otherwise, main is ok. var prime *ast.Package for name, pkg := range dirpkgs { prime = pkg if name != "main" { break } } if prime == nil { return } PackageTops[path] = prime is := make(ImportScanner) ast.Walk(is, prime) if v, ok := is["."]; !v && ok { return MakeErr("gorf can not deal with unnamed import in '%s'", path) } for path, _ := range is { if strings.HasPrefix(path, ".") { return MakeErr("gorf can not deal with relative import in '%s'", path) } } for imp := range is { ImportedBy[imp] = append(ImportedBy[imp], path) } return }