Exemple #1
0
func (tc *typechecker) checkPackage(pkg *ast.Package) {
	// setup package scope
	tc.topScope = Universe
	tc.openScope()
	defer tc.closeScope()

	// TODO(gri) there's no file scope at the moment since we ignore imports

	// phase 1: declare all global objects; also collect all function and method declarations
	var funcs []*ast.FuncDecl
	for _, file := range pkg.Files {
		for _, decl := range file.Decls {
			tc.declGlobal(decl)
			if f, isFunc := decl.(*ast.FuncDecl); isFunc {
				funcs = append(funcs, f)
			}
		}
	}

	// phase 2: bind methods to their receiver base types
	for _, m := range funcs {
		if m.Recv != nil {
			tc.bindMethod(m)
		}
	}

	// phase 3: resolve all global objects
	tc.cyclemap = make(map[*ast.Object]bool)
	for _, obj := range tc.globals {
		tc.resolve(obj)
	}
	assert(len(tc.cyclemap) == 0)

	// 4: sequentially typecheck function and method bodies
	for _, f := range funcs {
		ftype, _ := f.Name.Obj.Type.(*Type)
		tc.checkBlock(f.Body.List, ftype)
	}

	pkg.Scope = tc.topScope
}
Exemple #2
0
func ParseDir(dir string) ([]string, error) {
	var imports []string

	dirFile, err := os.Open(dir)
	if err != nil {
		return nil, err
	}
	defer dirFile.Close()
	info, err := dirFile.Stat()
	if err != nil {
		return nil, err
	}

	var pkgs map[string]*ast.Package

	if !info.IsDir() {
		var p *ast.File
		p, err = parser.ParseFile(token.NewFileSet(), dir, nil, 0)
		var pp ast.Package
		pkgs = make(map[string]*ast.Package)
		pp.Files = make(map[string]*ast.File)
		pp.Files[dir] = p
		pkgs[dir] = &pp
	} else {
		pkgs, err = parser.ParseDir(token.NewFileSet(), dir, FilterGo, 0)
		if err != nil {
			return nil, err
		}
	}

	for _, pkg := range pkgs {
		// var f *ast.File
		for _, f := range pkg.Files {
			for _, i := range f.Imports {
				d := strings.Trim(i.Path.Value, "\"")
				// from go/src/cmd/go/pkg.go
				//
				// p.Standard = p.Goroot && p.ImportPath != "" && !strings.Contains(p.ImportPath, ".")
				//
				// all Standard packages do not have "dot"
				if strings.Contains(d, ".") && !strings.HasPrefix(d, ".") {
					imports = append(imports, d)
				}
			}
		}
	}

	{
		dirs, err := dirFile.Readdir(-1)
		if err != nil {
			return nil, err
		}
		for _, info := range dirs {
			if info.IsDir() {
				t, e := ParseDir(path.Join(dir, info.Name()))
				if e != nil {
					return nil, e
				}
				imports = append(imports, t...)
			}
		}
	}

	return imports, nil
}