1
0
mirror of https://github.com/mgechev/revive.git synced 2025-10-30 23:37:49 +02:00

fix: false positive in import-shadowing for method names (#876)

This commit is contained in:
Denis Voytyuk
2023-08-21 23:45:41 +02:00
committed by GitHub
parent e758901c9a
commit 4ee7542478
2 changed files with 17 additions and 2 deletions

View File

@@ -29,6 +29,7 @@ func (*ImportShadowingRule) Apply(file *lint.File, _ lint.Arguments) []lint.Fail
failures = append(failures, failure) failures = append(failures, failure)
}, },
alreadySeen: map[*ast.Object]struct{}{}, alreadySeen: map[*ast.Object]struct{}{},
skipIdents: map[*ast.Ident]struct{}{},
} }
ast.Walk(walker, fileAst) ast.Walk(walker, fileAst)
@@ -62,6 +63,7 @@ type importShadowing struct {
importNames map[string]struct{} importNames map[string]struct{}
onFailure func(lint.Failure) onFailure func(lint.Failure)
alreadySeen map[*ast.Object]struct{} alreadySeen map[*ast.Object]struct{}
skipIdents map[*ast.Ident]struct{}
} }
// Visit visits AST nodes and checks if id nodes (ast.Ident) shadow an import name // Visit visits AST nodes and checks if id nodes (ast.Ident) shadow an import name
@@ -80,6 +82,10 @@ func (w importShadowing) Visit(n ast.Node) ast.Visitor {
*ast.SelectorExpr, // skip analysis of selector expressions (anId.otherId): because if anId shadows an import name, it was already detected, and otherId does not shadows the import name *ast.SelectorExpr, // skip analysis of selector expressions (anId.otherId): because if anId shadows an import name, it was already detected, and otherId does not shadows the import name
*ast.StructType: // skip analysis of struct type because struct fields can not shadow an import name *ast.StructType: // skip analysis of struct type because struct fields can not shadow an import name
return nil return nil
case *ast.FuncDecl:
if n.Recv != nil {
w.skipIdents[n.Name] = struct{}{}
}
case *ast.Ident: case *ast.Ident:
if n == w.packageNameIdent { if n == w.packageNameIdent {
return nil // skip the ident corresponding to the package name of this file return nil // skip the ident corresponding to the package name of this file
@@ -92,11 +98,12 @@ func (w importShadowing) Visit(n ast.Node) ast.Visitor {
_, isImportName := w.importNames[id] _, isImportName := w.importNames[id]
_, alreadySeen := w.alreadySeen[n.Obj] _, alreadySeen := w.alreadySeen[n.Obj]
if isImportName && !alreadySeen { _, skipIdent := w.skipIdents[n]
if isImportName && !alreadySeen && !skipIdent {
w.onFailure(lint.Failure{ w.onFailure(lint.Failure{
Confidence: 1, Confidence: 1,
Node: n, Node: n,
Category: "namming", Category: "naming",
Failure: fmt.Sprintf("The name '%s' shadows an import name", id), Failure: fmt.Sprintf("The name '%s' shadows an import name", id),
}) })

View File

@@ -23,6 +23,14 @@ type fmt interface {} // MATCH /The name 'fmt' shadows an import name/
func (ast myAst) foo() {} // MATCH /The name 'ast' shadows an import name/ func (ast myAst) foo() {} // MATCH /The name 'ast' shadows an import name/
func (a myAst) fmt() { // this should be skipped (method, not a pkg func)
var fmt string // MATCH /The name 'fmt' shadows an import name/
}
func (a myAst) md5() { // this should be skipped (method, not a pkg func)
strings := map[string]string{} // MATCH /The name 'strings' shadows an import name/
}
func md5() {} // MATCH /The name 'md5' shadows an import name/ func md5() {} // MATCH /The name 'md5' shadows an import name/
func bar(_ string) {} func bar(_ string) {}