func (p *Parser) Parse(path string, cursor SourceLocation, unsaved []UnsavedDocument, options Options) (*Parsed, error) { if len(options.GoPath) == 0 { options.GoPath = os.Getenv("GOPATH") } path, uns := p.canonicalPaths(path, unsaved) var info types.Info info.Types = make(map[ast.Expr]types.Type) info.Objects = make(map[*ast.Ident]types.Object) fs := token.NewFileSet() started := time.Now() dname := filepath.Dir(path) f, astf, tpkg, err := p.importSourcePackage(fs, path, dname, uns, options, &info) errors, _ := err.(scanner.ErrorList) return &Parsed{ Info: &info, Package: tpkg, FileSet: fs, Ast: astf, File: f, Errors: errors, Duration: time.Now().Sub(started), }, nil }
func (c *compiler) typecheck(pkgpath string, fset *token.FileSet, files []*ast.File) (*types.Package, error) { var errors string var imp = importer{compiler: c} config := &types.Config{ Error: func(err error) { if errors != "" { errors += "\n" } errors += err.Error() }, Import: imp.Import, Sizes: c.llvmtypes, } var info types.Info objectdata := make(map[types.Object]*ObjectData) info.Values = c.typeinfo.Values info.Types = c.typeinfo.Types info.Selections = c.typeinfo.Selections info.Implicits = make(map[ast.Node]types.Object) info.Objects = make(map[*ast.Ident]types.Object) pkg, err := config.Check(pkgpath, fset, files, &info) if err != nil { return nil, fmt.Errorf("%s", errors) } for id, obj := range info.Objects { if obj == nil { continue } c.typeinfo.Objects[id] = obj data := objectdata[obj] if data == nil { objectdata[obj] = &ObjectData{Ident: id} } else if data.Ident.Obj == nil { data.Ident = id } } for node, obj := range info.Implicits { id := ast.NewIdent(obj.Name()) c.typeinfo.Objects[id] = obj c.typeinfo.Implicits[node] = obj objectdata[obj] = &ObjectData{Ident: id} } for object, data := range objectdata { if object, ok := object.(*types.TypeName); ok { // Record exported types for generating runtime type information. // c.pkg is nil iff the package being checked is the package // being compiled. if c.pkg == nil && object.Pkg() == pkg && ast.IsExported(object.Name()) { c.exportedtypes = append(c.exportedtypes, object.Type()) } } c.objectdata[object] = data } return pkg, nil }
func (c *compiler) typecheck(pkgpath string, fset *token.FileSet, files []*ast.File) (*types.Package, error) { config := &types.Config{ Sizeof: c.llvmtypes.Sizeof, Alignof: c.llvmtypes.Alignof, Offsetsof: c.llvmtypes.Offsetsof, } var info types.Info objectdata := make(map[types.Object]*ObjectData) info.Values = c.typeinfo.Values info.Types = c.typeinfo.Types info.Implicits = make(map[ast.Node]types.Object) info.Objects = make(map[*ast.Ident]types.Object) pkg, err := config.Check(pkgpath, fset, files, &info) if err != nil { return nil, err } for id, obj := range info.Objects { if obj == nil { continue } c.typeinfo.Objects[id] = obj objectdata[obj] = &ObjectData{Ident: id, Package: pkg} } for node, obj := range info.Implicits { id := ast.NewIdent(obj.Name()) c.typeinfo.Objects[id] = obj c.typeinfo.Implicits[node] = obj objectdata[obj] = &ObjectData{Ident: id, Package: pkg} } for _, pkg := range pkg.Imports() { assocObjectPackages(pkg, objectdata) } for object, data := range objectdata { if object, ok := object.(*types.TypeName); ok { // Add TypeNames to the LLVMTypeMap's TypeStringer. c.llvmtypes.pkgmap[object] = data.Package // Record exported types for generating runtime type information. // c.pkg is nil iff the package being checked is the package // being compiled. if c.pkg == nil && object.Pkg() == pkg && ast.IsExported(object.Name()) { c.exportedtypes = append(c.exportedtypes, object.Type()) } } c.objectdata[object] = data } return pkg, nil }