Skip to content

Commit

Permalink
typesutil: DeleteObjects, CorrectTypesInfo
Browse files Browse the repository at this point in the history
  • Loading branch information
xushiwei committed Nov 11, 2023
1 parent be5b5e3 commit 04ab8c8
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 30 deletions.
2 changes: 2 additions & 0 deletions parser/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ const (
DeclarationErrors = Mode(goparser.DeclarationErrors)
// AllErrors - report all errors (not just the first 10 on different lines)
AllErrors = Mode(goparser.AllErrors)
// SkipObjectResolution - don't resolve identifiers to objects - see ParseFile
SkipObjectResolution = Mode(goparser.SkipObjectResolution)
// ParseGoAsGoPlus - parse Go files by gop/parser
ParseGoAsGoPlus Mode = 1 << 16
// ParserGoPlusClass - parse Go+ classfile by gop/parser
Expand Down
75 changes: 45 additions & 30 deletions x/typesutil/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,43 +167,58 @@ func (p *Checker) Files(goFiles []*goast.File, gopFiles []*ast.File) (err error)
}
if len(files) > 0 {
scope := pkgTypes.Scope()
objMap := make(map[types.Object]types.Object)
// remove all objects defined in Go files
for _, f := range files {
for _, decl := range f.Decls {
switch v := decl.(type) {
case *goast.GenDecl:
for _, spec := range v.Specs {
switch v := spec.(type) {
case *goast.ValueSpec:
for _, name := range v.Names {
scopeDelete(objMap, scope, name.Name)
}
case *goast.TypeSpec:
scopeDelete(objMap, scope, v.Name.Name)
objMap := DeleteObjects(scope, files)
checker := types.NewChecker(conf, fset, pkgTypes, p.goInfo)
err = checker.Files(files)
CorrectTypesInfo(scope, objMap, p.gopInfo.Uses)
}
return
}

type astIdent interface {
comparable
ast.Node
}

type objMapT = map[types.Object]types.Object

// CorrectTypesInfo corrects types info to avoid there are two instances for the same Go object.
func CorrectTypesInfo[Ident astIdent](scope *types.Scope, objMap objMapT, uses map[Ident]types.Object) {
for o := range objMap {
objMap[o] = scope.Lookup(o.Name())
}
for id, old := range uses {
if new := objMap[old]; new != nil {
uses[id] = new
}
}
}

// DeleteObjects deletes all objects defined in Go files and returns deleted objects.
func DeleteObjects(scope *types.Scope, files []*goast.File) objMapT {
objMap := make(objMapT)
for _, f := range files {
for _, decl := range f.Decls {
switch v := decl.(type) {
case *goast.GenDecl:
for _, spec := range v.Specs {
switch v := spec.(type) {
case *goast.ValueSpec:
for _, name := range v.Names {
scopeDelete(objMap, scope, name.Name)
}
}
case *goast.FuncDecl:
if v.Recv == nil {
case *goast.TypeSpec:
scopeDelete(objMap, scope, v.Name.Name)
}
}
}
}
checker := types.NewChecker(conf, fset, pkgTypes, p.goInfo)
err = checker.Files(files)
for o := range objMap {
objMap[o] = scope.Lookup(o.Name())
}
// correct Go+ types info to avoid there are two instances for same Go object:
uses := p.gopInfo.Uses
for id, old := range uses {
if new := objMap[old]; new != nil {
uses[id] = new
case *goast.FuncDecl:
if v.Recv == nil {
scopeDelete(objMap, scope, v.Name.Name)
}
}
}
}
return
return objMap
}

func convErr(fset *token.FileSet, e error) (ret types.Error, ok bool) {
Expand Down

0 comments on commit 04ab8c8

Please sign in to comment.