Skip to content

Commit

Permalink
Merge pull request #1503 from xushiwei/typesutil
Browse files Browse the repository at this point in the history
typesutil: avoid two instances for same Go object
  • Loading branch information
xushiwei authored Oct 31, 2023
2 parents d40c1e2 + 362ff94 commit 7625a67
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 6 deletions.
25 changes: 21 additions & 4 deletions x/typesutil/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,8 @@ func (p *Checker) Files(goFiles []*goast.File, gopFiles []*ast.File) (err error)
}
if len(files) > 0 {
scope := pkgTypes.Scope()
// remove all objects defined by files
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) {
Expand All @@ -164,21 +165,37 @@ func (p *Checker) Files(goFiles []*goast.File, gopFiles []*ast.File) (err error)
switch v := spec.(type) {
case *goast.ValueSpec:
for _, name := range v.Names {
typesutil.ScopeDelete(scope, name.Name)
scopeDelete(objMap, scope, name.Name)
}
case *goast.TypeSpec:
typesutil.ScopeDelete(scope, v.Name.Name)
scopeDelete(objMap, scope, v.Name.Name)
}
}
case *goast.FuncDecl:
if v.Recv == nil {
typesutil.ScopeDelete(scope, v.Name.Name)
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
}
}
}
return
}

func scopeDelete(objMap map[types.Object]types.Object, scope *types.Scope, name string) {
if o := typesutil.ScopeDelete(scope, name); o != nil {
objMap[o] = nil
}
}
9 changes: 7 additions & 2 deletions x/typesutil/internal/typesutil/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ type Scope struct {
}

// ScopeDelete deletes an object from specified scope by its name.
func ScopeDelete(s *types.Scope, name string) {
delete((*Scope)(unsafe.Pointer(s)).elems, name)
func ScopeDelete(s *types.Scope, name string) types.Object {
elems := (*Scope)(unsafe.Pointer(s)).elems
if o, ok := elems[name]; ok {
delete(elems, name)
return o
}
return nil
}

0 comments on commit 7625a67

Please sign in to comment.