From a7c53b59a64e59d60bbd08f4d0bd086aaa90b32e Mon Sep 17 00:00:00 2001 From: "Hana (Hyang-Ah) Kim" Date: Wed, 13 Jul 2022 17:10:18 -0400 Subject: [PATCH] internal/analysisinternal: move FindBestMatch to internal/lsp/fuzzy This is used by internal/lsp/analysis/fillreturns and internal/lsp/analysis/fillstruct. This doesn't need to be in this analysisinternal package. This removes the dependency path go/analysis/internal/checker -> internal/analysisinternal -> internal/lsp/fuzzy Change-Id: I5db674ca30eb06ae6ce7021397cf5530a695af4e Reviewed-on: https://go-review.googlesource.com/c/tools/+/417418 gopls-CI: kokoro TryBot-Result: Gopher Robot Reviewed-by: Robert Findley Run-TryBot: Hyang-Ah Hana Kim --- internal/analysisinternal/analysis.go | 29 ------------------- .../lsp/analysis/fillreturns/fillreturns.go | 3 +- .../lsp/analysis/fillstruct/fillstruct.go | 3 +- internal/lsp/fuzzy/matcher.go | 28 ++++++++++++++++++ 4 files changed, 32 insertions(+), 31 deletions(-) diff --git a/internal/analysisinternal/analysis.go b/internal/analysisinternal/analysis.go index 3f1e573342..e32152ac22 100644 --- a/internal/analysisinternal/analysis.go +++ b/internal/analysisinternal/analysis.go @@ -12,8 +12,6 @@ import ( "go/token" "go/types" "strconv" - - "golang.org/x/tools/internal/lsp/fuzzy" ) // Flag to gate diagnostics for fuzz tests in 1.18. @@ -397,30 +395,3 @@ func equivalentTypes(want, got types.Type) bool { } return types.AssignableTo(want, got) } - -// FindBestMatch employs fuzzy matching to evaluate the similarity of each given identifier to the -// given pattern. We return the identifier whose name is most similar to the pattern. -func FindBestMatch(pattern string, idents []*ast.Ident) ast.Expr { - fuzz := fuzzy.NewMatcher(pattern) - var bestFuzz ast.Expr - highScore := float32(0) // minimum score is 0 (no match) - for _, ident := range idents { - // TODO: Improve scoring algorithm. - score := fuzz.Score(ident.Name) - if score > highScore { - highScore = score - bestFuzz = ident - } else if score == 0 { - // Order matters in the fuzzy matching algorithm. If we find no match - // when matching the target to the identifier, try matching the identifier - // to the target. - revFuzz := fuzzy.NewMatcher(ident.Name) - revScore := revFuzz.Score(pattern) - if revScore > highScore { - highScore = revScore - bestFuzz = ident - } - } - } - return bestFuzz -} diff --git a/internal/lsp/analysis/fillreturns/fillreturns.go b/internal/lsp/analysis/fillreturns/fillreturns.go index 72fe65d79c..4a30934c63 100644 --- a/internal/lsp/analysis/fillreturns/fillreturns.go +++ b/internal/lsp/analysis/fillreturns/fillreturns.go @@ -19,6 +19,7 @@ import ( "golang.org/x/tools/go/analysis" "golang.org/x/tools/go/ast/astutil" "golang.org/x/tools/internal/analysisinternal" + "golang.org/x/tools/internal/lsp/fuzzy" "golang.org/x/tools/internal/typeparams" ) @@ -191,7 +192,7 @@ outer: // Find the identifier whose name is most similar to the return type. // If we do not find any identifier that matches the pattern, // generate a zero value. - value := analysisinternal.FindBestMatch(retTyp.String(), idents) + value := fuzzy.FindBestMatch(retTyp.String(), idents) if value == nil { value = analysisinternal.ZeroValue(file, pass.Pkg, retTyp) } diff --git a/internal/lsp/analysis/fillstruct/fillstruct.go b/internal/lsp/analysis/fillstruct/fillstruct.go index f160d4422a..2103a55879 100644 --- a/internal/lsp/analysis/fillstruct/fillstruct.go +++ b/internal/lsp/analysis/fillstruct/fillstruct.go @@ -21,6 +21,7 @@ import ( "golang.org/x/tools/go/ast/astutil" "golang.org/x/tools/go/ast/inspector" "golang.org/x/tools/internal/analysisinternal" + "golang.org/x/tools/internal/lsp/fuzzy" "golang.org/x/tools/internal/span" "golang.org/x/tools/internal/typeparams" ) @@ -254,7 +255,7 @@ func SuggestedFix(fset *token.FileSet, rng span.Range, content []byte, file *ast // Find the identifier whose name is most similar to the name of the field's key. // If we do not find any identifier that matches the pattern, generate a new value. // NOTE: We currently match on the name of the field key rather than the field type. - value := analysisinternal.FindBestMatch(obj.Field(i).Name(), idents) + value := fuzzy.FindBestMatch(obj.Field(i).Name(), idents) if value == nil { value = populateValue(file, pkg, fieldTyp) } diff --git a/internal/lsp/fuzzy/matcher.go b/internal/lsp/fuzzy/matcher.go index 265cdcf160..92e1001fd1 100644 --- a/internal/lsp/fuzzy/matcher.go +++ b/internal/lsp/fuzzy/matcher.go @@ -8,6 +8,7 @@ package fuzzy import ( "bytes" "fmt" + "go/ast" ) const ( @@ -405,3 +406,30 @@ func (m *Matcher) poorMatch() bool { } return false } + +// FindBestMatch employs fuzzy matching to evaluate the similarity of each given identifier to the +// given pattern. We return the identifier whose name is most similar to the pattern. +func FindBestMatch(pattern string, idents []*ast.Ident) ast.Expr { + fuzz := NewMatcher(pattern) + var bestFuzz ast.Expr + highScore := float32(0) // minimum score is 0 (no match) + for _, ident := range idents { + // TODO: Improve scoring algorithm. + score := fuzz.Score(ident.Name) + if score > highScore { + highScore = score + bestFuzz = ident + } else if score == 0 { + // Order matters in the fuzzy matching algorithm. If we find no match + // when matching the target to the identifier, try matching the identifier + // to the target. + revFuzz := NewMatcher(ident.Name) + revScore := revFuzz.Score(pattern) + if revScore > highScore { + highScore = revScore + bestFuzz = ident + } + } + } + return bestFuzz +}