Beispiel #1
0
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
}
Beispiel #2
0
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
}
Beispiel #3
0
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
}