update revive lint to latest commit (#12921)

* update revive lint to latest commit

* make fmt

* change import
This commit is contained in:
techknowlogick 2020-09-22 13:02:16 -04:00 committed by GitHub
parent 63e8bdaf73
commit 1c3278c2fa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
154 changed files with 5965 additions and 8502 deletions

View file

@ -194,6 +194,7 @@ type Boundary struct {
Start bool // Is this the start of a block?
Count int // Event count from the cover profile.
Norm float64 // Count normalized to [0..1].
Index int // Order in input file.
}
// Boundaries returns a Profile as a set of Boundary objects within the provided src.
@ -209,8 +210,10 @@ func (p *Profile) Boundaries(src []byte) (boundaries []Boundary) {
divisor := math.Log(float64(max))
// boundary returns a Boundary, populating the Norm field with a normalized Count.
index := 0
boundary := func(offset int, start bool, count int) Boundary {
b := Boundary{Offset: offset, Start: start, Count: count}
b := Boundary{Offset: offset, Start: start, Count: count, Index: index}
index++
if !start || count == 0 {
return b
}
@ -250,7 +253,9 @@ func (b boundariesByPos) Len() int { return len(b) }
func (b boundariesByPos) Swap(i, j int) { b[i], b[j] = b[j], b[i] }
func (b boundariesByPos) Less(i, j int) bool {
if b[i].Offset == b[j].Offset {
return !b[i].Start && b[j].Start
// Boundaries at the same offset should be ordered according to
// their original position.
return b[i].Index < b[j].Index
}
return b[i].Offset < b[j].Offset
}

View file

@ -3,6 +3,7 @@ package analysis
import (
"fmt"
"reflect"
"strings"
"unicode"
)
@ -58,14 +59,28 @@ func Validate(analyzers []*Analyzer) error {
}
// recursion
for i, req := range a.Requires {
for _, req := range a.Requires {
if err := visit(req); err != nil {
return fmt.Errorf("%s.Requires[%d]: %v", a.Name, i, err)
return err
}
}
color[a] = black
}
if color[a] == grey {
stack := []*Analyzer{a}
inCycle := map[string]bool{}
for len(stack) > 0 {
current := stack[len(stack)-1]
stack = stack[:len(stack)-1]
if color[current] == grey && !inCycle[current.Name] {
inCycle[current.Name] = true
stack = append(stack, current.Requires...)
}
}
return &CycleInRequiresGraphError{AnalyzerNames: inCycle}
}
return nil
}
for _, a := range analyzers {
@ -95,3 +110,17 @@ func validIdent(name string) bool {
}
return name != ""
}
type CycleInRequiresGraphError struct {
AnalyzerNames map[string]bool
}
func (e *CycleInRequiresGraphError) Error() string {
var b strings.Builder
b.WriteString("cycle detected involving the following analyzers:")
for n := range e.AnalyzerNames {
b.WriteByte(' ')
b.WriteString(n)
}
return b.String()
}

View file

@ -491,7 +491,7 @@ func (p *parser) parseMapType(parent *types.Package) types.Type {
//
// For unqualified and anonymous names, the returned package is the parent
// package unless parent == nil, in which case the returned package is the
// package being imported. (The parent package is not nil if the the name
// package being imported. (The parent package is not nil if the name
// is an unqualified struct field or interface method name belonging to a
// type declared in another package.)
//

View file

@ -246,6 +246,21 @@ extractQueries:
}
}
}
// Add root for any package that matches a pattern. This applies only to
// packages that are modified by overlays, since they are not added as
// roots automatically.
for _, pattern := range restPatterns {
match := matchPattern(pattern)
for _, pkgID := range modifiedPkgs {
pkg, ok := response.seenPackages[pkgID]
if !ok {
continue
}
if match(pkg.PkgPath) {
response.addRoot(pkg.ID)
}
}
}
sizeswg.Wait()
if sizeserr != nil {
@ -753,7 +768,8 @@ func (state *golistState) getGoVersion() (string, error) {
return state.goVersion, state.goVersionError
}
// getPkgPath finds the package path of a directory if it's relative to a root directory.
// getPkgPath finds the package path of a directory if it's relative to a root
// directory.
func (state *golistState) getPkgPath(dir string) (string, bool, error) {
absDir, err := filepath.Abs(dir)
if err != nil {

View file

@ -8,9 +8,12 @@ import (
"log"
"os"
"path/filepath"
"regexp"
"sort"
"strconv"
"strings"
"golang.org/x/tools/internal/gocommand"
)
// processGolistOverlay provides rudimentary support for adding
@ -89,9 +92,19 @@ func (state *golistState) processGolistOverlay(response *responseDeduper) (modif
// because the file is generated in another directory.
testVariantOf = p
continue nextPackage
} else if !isTestFile && hasTestFiles(p) {
// We're examining a test variant, but the overlaid file is
// a non-test file. Because the overlay implementation
// (currently) only adds a file to one package, skip this
// package, so that we can add the file to the production
// variant of the package. (https://golang.org/issue/36857
// tracks handling overlays on both the production and test
// variant of a package).
continue nextPackage
}
// We must have already seen the package of which this is a test variant.
if pkg != nil && p != pkg && pkg.PkgPath == p.PkgPath {
// We have already seen the production version of the
// for which p is a test variant.
if hasTestFiles(p) {
testVariantOf = pkg
}
@ -240,7 +253,7 @@ func (state *golistState) processGolistOverlay(response *responseDeduper) (modif
return modifiedPkgs, needPkgs, err
}
// resolveImport finds the the ID of a package given its import path.
// resolveImport finds the ID of a package given its import path.
// In particular, it will find the right vendored copy when in GOPATH mode.
func (state *golistState) resolveImport(sourceDir, importPath string) (string, error) {
env, err := state.getEnv()
@ -315,24 +328,25 @@ func (state *golistState) determineRootDirs() (map[string]string, error) {
}
func (state *golistState) determineRootDirsModules() (map[string]string, error) {
// This will only return the root directory for the main module.
// For now we only support overlays in main modules.
// List all of the modules--the first will be the directory for the main
// module. Any replaced modules will also need to be treated as roots.
// Editing files in the module cache isn't a great idea, so we don't
// plan to ever support that, but editing files in replaced modules
// is something we may want to support. To do that, we'll want to
// do a go list -m to determine the replaced module's module path and
// directory, and then a go list -m {{with .Replace}}{{.Dir}}{{end}} <replaced module's path>
// from the main module to determine if that module is actually a replacement.
// See bcmills's comment here: https://github.com/golang/go/issues/37629#issuecomment-594179751
// for more information.
out, err := state.invokeGo("list", "-m", "-json")
// plan to ever support that.
out, err := state.invokeGo("list", "-m", "-json", "all")
if err != nil {
return nil, err
// 'go list all' will fail if we're outside of a module and
// GO111MODULE=on. Try falling back without 'all'.
var innerErr error
out, innerErr = state.invokeGo("list", "-m", "-json")
if innerErr != nil {
return nil, err
}
}
m := map[string]string{}
type jsonMod struct{ Path, Dir string }
roots := map[string]string{}
modules := map[string]string{}
var i int
for dec := json.NewDecoder(out); dec.More(); {
mod := new(jsonMod)
mod := new(gocommand.ModuleJSON)
if err := dec.Decode(mod); err != nil {
return nil, err
}
@ -342,10 +356,15 @@ func (state *golistState) determineRootDirsModules() (map[string]string, error)
if err != nil {
return nil, err
}
m[absDir] = mod.Path
modules[absDir] = mod.Path
// The first result is the main module.
if i == 0 || mod.Replace != nil && mod.Replace.Path != "" {
roots[absDir] = mod.Path
}
}
i++
}
return m, nil
return roots, nil
}
func (state *golistState) determineRootDirsGOPATH() (map[string]string, error) {
@ -471,3 +490,79 @@ func maybeFixPackageName(newName string, isTestFile bool, pkgsOfDir []*Package)
p.Name = newName
}
}
// This function is copy-pasted from
// https://github.com/golang/go/blob/9706f510a5e2754595d716bd64be8375997311fb/src/cmd/go/internal/search/search.go#L360.
// It should be deleted when we remove support for overlays from go/packages.
//
// NOTE: This does not handle any ./... or ./ style queries, as this function
// doesn't know the working directory.
//
// matchPattern(pattern)(name) reports whether
// name matches pattern. Pattern is a limited glob
// pattern in which '...' means 'any string' and there
// is no other special syntax.
// Unfortunately, there are two special cases. Quoting "go help packages":
//
// First, /... at the end of the pattern can match an empty string,
// so that net/... matches both net and packages in its subdirectories, like net/http.
// Second, any slash-separated pattern element containing a wildcard never
// participates in a match of the "vendor" element in the path of a vendored
// package, so that ./... does not match packages in subdirectories of
// ./vendor or ./mycode/vendor, but ./vendor/... and ./mycode/vendor/... do.
// Note, however, that a directory named vendor that itself contains code
// is not a vendored package: cmd/vendor would be a command named vendor,
// and the pattern cmd/... matches it.
func matchPattern(pattern string) func(name string) bool {
// Convert pattern to regular expression.
// The strategy for the trailing /... is to nest it in an explicit ? expression.
// The strategy for the vendor exclusion is to change the unmatchable
// vendor strings to a disallowed code point (vendorChar) and to use
// "(anything but that codepoint)*" as the implementation of the ... wildcard.
// This is a bit complicated but the obvious alternative,
// namely a hand-written search like in most shell glob matchers,
// is too easy to make accidentally exponential.
// Using package regexp guarantees linear-time matching.
const vendorChar = "\x00"
if strings.Contains(pattern, vendorChar) {
return func(name string) bool { return false }
}
re := regexp.QuoteMeta(pattern)
re = replaceVendor(re, vendorChar)
switch {
case strings.HasSuffix(re, `/`+vendorChar+`/\.\.\.`):
re = strings.TrimSuffix(re, `/`+vendorChar+`/\.\.\.`) + `(/vendor|/` + vendorChar + `/\.\.\.)`
case re == vendorChar+`/\.\.\.`:
re = `(/vendor|/` + vendorChar + `/\.\.\.)`
case strings.HasSuffix(re, `/\.\.\.`):
re = strings.TrimSuffix(re, `/\.\.\.`) + `(/\.\.\.)?`
}
re = strings.ReplaceAll(re, `\.\.\.`, `[^`+vendorChar+`]*`)
reg := regexp.MustCompile(`^` + re + `$`)
return func(name string) bool {
if strings.Contains(name, vendorChar) {
return false
}
return reg.MatchString(replaceVendor(name, vendorChar))
}
}
// replaceVendor returns the result of replacing
// non-trailing vendor path elements in x with repl.
func replaceVendor(x, repl string) string {
if !strings.Contains(x, "vendor") {
return x
}
elem := strings.Split(x, "/")
for i := 0; i < len(elem)-1; i++ {
if elem[i] == "vendor" {
elem[i] = repl
}
}
return strings.Join(elem, "/")
}

View file

@ -402,14 +402,14 @@ func equivalentTypes(want, got types.Type) bool {
func FindBestMatch(pattern string, idents []*ast.Ident) ast.Expr {
fuzz := fuzzy.NewMatcher(pattern)
var bestFuzz ast.Expr
highScore := float32(-1) // minimum score is -1 (no match)
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 == -1 {
} 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.

View file

@ -615,7 +615,7 @@ func getCandidatePkgs(ctx context.Context, wrappedCallback *scanCallback, filena
packageName: path.Base(importPath),
relevance: MaxRelevance,
}
if notSelf(p) && wrappedCallback.packageNameLoaded(p) {
if notSelf(p) && wrappedCallback.dirFound(p) && wrappedCallback.packageNameLoaded(p) {
wrappedCallback.exportsLoaded(p, exports)
}
}
@ -827,7 +827,11 @@ func (e *ProcessEnv) goEnv() (map[string]string, error) {
}
func (e *ProcessEnv) matchFile(dir, name string) (bool, error) {
return build.Default.MatchFile(dir, name)
bctx, err := e.buildContext()
if err != nil {
return false, err
}
return bctx.MatchFile(dir, name)
}
// CopyConfig copies the env's configuration into a new env.
@ -920,15 +924,21 @@ func (e *ProcessEnv) buildContext() (*build.Context, error) {
// Populate it only if present.
rc := reflect.ValueOf(&ctx).Elem()
dir := rc.FieldByName("Dir")
if !dir.IsValid() {
// Working drafts of Go 1.14 named the field "WorkingDir" instead.
// TODO(bcmills): Remove this case after the Go 1.14 beta has been released.
dir = rc.FieldByName("WorkingDir")
}
if dir.IsValid() && dir.Kind() == reflect.String {
dir.SetString(e.WorkingDir)
}
// Since Go 1.11, go/build.Context.Import may invoke 'go list' depending on
// the value in GO111MODULE in the process's environment. We always want to
// run in GOPATH mode when calling Import, so we need to prevent this from
// happening. In Go 1.16, GO111MODULE defaults to "on", so this problem comes
// up more frequently.
//
// HACK: setting any of the Context I/O hooks prevents Import from invoking
// 'go list', regardless of GO111MODULE. This is undocumented, but it's
// unlikely to change before GOPATH support is removed.
ctx.ReadDir = ioutil.ReadDir
return &ctx, nil
}

View file

@ -135,7 +135,7 @@ func (m *Matcher) Score(candidate string) float32 {
}
m.lastCandidateMatched = false
return -1
return 0
}
const minScore = -10000