mirror of
				https://github.com/mgechev/revive.git
				synced 2025-10-30 23:37:49 +02:00 
			
		
		
		
	refactor: replace failure Category raw string with constant (#1196)
* refactor: replace Category raw strings with constants * Add type FailureCategory; add comments for constants
This commit is contained in:
		| @@ -5,6 +5,53 @@ import ( | ||||
| 	"go/token" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	// FailureCategoryArgOrder indicates argument order issues. | ||||
| 	FailureCategoryArgOrder FailureCategory = "arg-order" | ||||
| 	// FailureCategoryBadPractice indicates bad practice issues. | ||||
| 	FailureCategoryBadPractice FailureCategory = "bad practice" | ||||
| 	// FailureCategoryCodeStyle indicates code style issues. | ||||
| 	FailureCategoryCodeStyle FailureCategory = "code-style" | ||||
| 	// FailureCategoryComments indicates comment issues. | ||||
| 	FailureCategoryComments FailureCategory = "comments" | ||||
| 	// FailureCategoryComplexity indicates complexity issues. | ||||
| 	FailureCategoryComplexity FailureCategory = "complexity" | ||||
| 	// FailureCategoryContent indicates content issues. | ||||
| 	FailureCategoryContent FailureCategory = "content" | ||||
| 	// FailureCategoryErrors indicates error handling issues. | ||||
| 	FailureCategoryErrors FailureCategory = "errors" | ||||
| 	// FailureCategoryImports indicates import issues. | ||||
| 	FailureCategoryImports FailureCategory = "imports" | ||||
| 	// FailureCategoryLogic indicates logic issues. | ||||
| 	FailureCategoryLogic FailureCategory = "logic" | ||||
| 	// FailureCategoryMaintenance indicates maintenance issues. | ||||
| 	FailureCategoryMaintenance FailureCategory = "maintenance" | ||||
| 	// FailureCategoryNaming indicates naming issues. | ||||
| 	FailureCategoryNaming FailureCategory = "naming" | ||||
| 	// FailureCategoryOptimization indicates optimization issues. | ||||
| 	FailureCategoryOptimization FailureCategory = "optimization" | ||||
| 	// FailureCategoryStyle indicates style issues. | ||||
| 	FailureCategoryStyle FailureCategory = "style" | ||||
| 	// FailureCategoryTime indicates time-related issues. | ||||
| 	FailureCategoryTime FailureCategory = "time" | ||||
| 	// FailureCategoryTypeInference indicates type inference issues. | ||||
| 	FailureCategoryTypeInference FailureCategory = "type-inference" | ||||
| 	// FailureCategoryUnaryOp indicates unary operation issues. | ||||
| 	FailureCategoryUnaryOp FailureCategory = "unary-op" | ||||
| 	// FailureCategoryUnexportedTypeInAPI indicates unexported type in API issues. | ||||
| 	FailureCategoryUnexportedTypeInAPI FailureCategory = "unexported-type-in-api" | ||||
| 	// FailureCategoryZeroValue indicates zero value issues. | ||||
| 	FailureCategoryZeroValue FailureCategory = "zero-value" | ||||
|  | ||||
| 	// failureCategoryInternal indicates internal failures. | ||||
| 	failureCategoryInternal FailureCategory = "REVIVE_INTERNAL" | ||||
| 	// failureCategoryValidity indicates validity issues. | ||||
| 	failureCategoryValidity FailureCategory = "validity" | ||||
| ) | ||||
|  | ||||
| // FailureCategory is the type for the failure categories. | ||||
| type FailureCategory string | ||||
|  | ||||
| const ( | ||||
| 	// SeverityWarning declares failures of type warning | ||||
| 	SeverityWarning = "warning" | ||||
| @@ -25,7 +72,7 @@ type FailurePosition struct { | ||||
| type Failure struct { | ||||
| 	Failure    string | ||||
| 	RuleName   string | ||||
| 	Category   string | ||||
| 	Category   FailureCategory | ||||
| 	Position   FailurePosition | ||||
| 	Node       ast.Node `json:"-"` | ||||
| 	Confidence float64 | ||||
| @@ -38,17 +85,15 @@ func (f *Failure) GetFilename() string { | ||||
| 	return f.Position.Start.Filename | ||||
| } | ||||
|  | ||||
| const internalFailure = "REVIVE_INTERNAL" | ||||
|  | ||||
| // IsInternal returns true if this failure is internal, false otherwise. | ||||
| func (f *Failure) IsInternal() bool { | ||||
| 	return f.Category == internalFailure | ||||
| 	return f.Category == failureCategoryInternal | ||||
| } | ||||
|  | ||||
| // NewInternalFailure yields an internal failure with the given message as failure message. | ||||
| func NewInternalFailure(message string) Failure { | ||||
| 	return Failure{ | ||||
| 		Category: internalFailure, | ||||
| 		Category: failureCategoryInternal, | ||||
| 		Failure:  message, | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -223,7 +223,7 @@ func addInvalidFileFailure(filename, errStr string, failures chan Failure) { | ||||
| 	failures <- Failure{ | ||||
| 		Confidence: 1, | ||||
| 		Failure:    fmt.Sprintf("invalid file %s: %v", filename, errStr), | ||||
| 		Category:   "validity", | ||||
| 		Category:   failureCategoryValidity, | ||||
| 		Position:   position, | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -171,7 +171,7 @@ func (w *lintAddConstantRule) checkStrLit(n *ast.BasicLit) { | ||||
| 			w.onFailure(lint.Failure{ | ||||
| 				Confidence: 1, | ||||
| 				Node:       n, | ||||
| 				Category:   "style", | ||||
| 				Category:   lint.FailureCategoryStyle, | ||||
| 				Failure:    fmt.Sprintf("string literal %s appears, at least, %d times, create a named constant for it", n.Value, w.strLits[n.Value]), | ||||
| 			}) | ||||
| 			w.strLits[n.Value] = -1 // mark it to avoid failing again on the same literal | ||||
| @@ -187,7 +187,7 @@ func (w *lintAddConstantRule) checkNumLit(kind string, n *ast.BasicLit) { | ||||
| 	w.onFailure(lint.Failure{ | ||||
| 		Confidence: 1, | ||||
| 		Node:       n, | ||||
| 		Category:   "style", | ||||
| 		Category:   lint.FailureCategoryStyle, | ||||
| 		Failure:    fmt.Sprintf("avoid magic numbers like '%s', create a named constant for it", n.Value), | ||||
| 	}) | ||||
| } | ||||
|   | ||||
| @@ -23,7 +23,6 @@ func (r *BlankImportsRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failu | ||||
|  | ||||
| 	const ( | ||||
| 		message         = "a blank import should be only in a main or test package, or have a comment justifying it" | ||||
| 		category        = "imports" | ||||
| 		embedImportPath = `"embed"` | ||||
| 	) | ||||
|  | ||||
| @@ -55,7 +54,7 @@ func (r *BlankImportsRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failu | ||||
|  | ||||
| 		// This is the first blank import of a group. | ||||
| 		if imp.Doc == nil && imp.Comment == nil { | ||||
| 			failures = append(failures, lint.Failure{Failure: message, Category: category, Node: imp, Confidence: 1}) | ||||
| 			failures = append(failures, lint.Failure{Failure: message, Category: lint.FailureCategoryImports, Node: imp, Confidence: 1}) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -53,16 +53,16 @@ func (w *lintBoolLiteral) Visit(node ast.Node) ast.Visitor { | ||||
| 		isConstant := (n.Op == token.LAND && lexeme == "false") || (n.Op == token.LOR && lexeme == "true") | ||||
|  | ||||
| 		if isConstant { | ||||
| 			w.addFailure(n, "Boolean expression seems to always evaluate to "+lexeme, "logic") | ||||
| 			w.addFailure(n, "Boolean expression seems to always evaluate to "+lexeme, lint.FailureCategoryLogic) | ||||
| 		} else { | ||||
| 			w.addFailure(n, "omit Boolean literal in expression", "style") | ||||
| 			w.addFailure(n, "omit Boolean literal in expression", lint.FailureCategoryStyle) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return w | ||||
| } | ||||
|  | ||||
| func (w lintBoolLiteral) addFailure(node ast.Node, msg, cat string) { | ||||
| func (w lintBoolLiteral) addFailure(node ast.Node, msg string, cat lint.FailureCategory) { | ||||
| 	w.onFailure(lint.Failure{ | ||||
| 		Confidence: 1, | ||||
| 		Node:       node, | ||||
|   | ||||
| @@ -62,7 +62,7 @@ func (w lintCallToGC) Visit(node ast.Node) ast.Visitor { | ||||
| 	w.onFailure(lint.Failure{ | ||||
| 		Confidence: 1, | ||||
| 		Node:       node, | ||||
| 		Category:   "bad practice", | ||||
| 		Category:   lint.FailureCategoryBadPractice, | ||||
| 		Failure:    "explicit call to the garbage collector", | ||||
| 	}) | ||||
|  | ||||
|   | ||||
| @@ -73,7 +73,7 @@ func (w cognitiveComplexityLinter) lintCognitiveComplexity() { | ||||
| 			if c > w.maxComplexity { | ||||
| 				w.onFailure(lint.Failure{ | ||||
| 					Confidence: 1, | ||||
| 					Category:   "maintenance", | ||||
| 					Category:   lint.FailureCategoryMaintenance, | ||||
| 					Failure:    fmt.Sprintf("function %s has cognitive complexity %d (> max enabled %d)", funcName(fn), c, w.maxComplexity), | ||||
| 					Node:       fn, | ||||
| 				}) | ||||
|   | ||||
| @@ -57,7 +57,7 @@ func (r *CommentSpacingsRule) Apply(file *lint.File, _ lint.Arguments) []lint.Fa | ||||
| 			failures = append(failures, lint.Failure{ | ||||
| 				Node:       comment, | ||||
| 				Confidence: 1, | ||||
| 				Category:   "style", | ||||
| 				Category:   lint.FailureCategoryStyle, | ||||
| 				Failure:    "no space between comment delimiter and comment text", | ||||
| 			}) | ||||
| 		} | ||||
|   | ||||
| @@ -102,7 +102,7 @@ func checkMethodName(holder string, id *ast.Ident, w *lintConfusingNames) { | ||||
| 				Failure:    fmt.Sprintf("Method '%s' differs only by capitalization to %s '%s' in %s", id.Name, kind, refMethod.id.Name, fileName), | ||||
| 				Confidence: 1, | ||||
| 				Node:       id, | ||||
| 				Category:   "naming", | ||||
| 				Category:   lint.FailureCategoryNaming, | ||||
| 			}) | ||||
|  | ||||
| 			return | ||||
| @@ -176,7 +176,7 @@ func checkStructFields(fields *ast.FieldList, structName string, w *lintConfusin | ||||
| 					Failure:    fmt.Sprintf("Field '%s' differs only by capitalization to other field in the struct type %s", id.Name, structName), | ||||
| 					Confidence: 1, | ||||
| 					Node:       id, | ||||
| 					Category:   "naming", | ||||
| 					Category:   lint.FailureCategoryNaming, | ||||
| 				}) | ||||
| 			} else { | ||||
| 				bl[normName] = true | ||||
|   | ||||
| @@ -34,7 +34,7 @@ func (*ConfusingResultsRule) Apply(file *lint.File, _ lint.Arguments) []lint.Fai | ||||
| 				failures = append(failures, lint.Failure{ | ||||
| 					Node:       result, | ||||
| 					Confidence: 1, | ||||
| 					Category:   "naming", | ||||
| 					Category:   lint.FailureCategoryNaming, | ||||
| 					Failure:    "unnamed results of the same type may be confusing, consider using named results", | ||||
| 				}) | ||||
|  | ||||
|   | ||||
| @@ -95,7 +95,7 @@ func (w *lintConstantLogicalExpr) newFailure(node ast.Node, msg string) { | ||||
| 	w.onFailure(lint.Failure{ | ||||
| 		Confidence: 1, | ||||
| 		Node:       node, | ||||
| 		Category:   "logic", | ||||
| 		Category:   lint.FailureCategoryLogic, | ||||
| 		Failure:    msg, | ||||
| 	}) | ||||
| } | ||||
|   | ||||
| @@ -32,7 +32,7 @@ func (r *ContextAsArgumentRule) Apply(file *lint.File, _ lint.Arguments) []lint. | ||||
| 			if argIsCtx && !isCtxStillAllowed { | ||||
| 				failures = append(failures, lint.Failure{ | ||||
| 					Node:       arg, | ||||
| 					Category:   "arg-order", | ||||
| 					Category:   lint.FailureCategoryArgOrder, | ||||
| 					Failure:    "context.Context should be the first parameter of a function", | ||||
| 					Confidence: 0.9, | ||||
| 				}) | ||||
|   | ||||
| @@ -74,7 +74,7 @@ func checkContextKeyType(w lintContextKeyTypes, x *ast.CallExpr) { | ||||
| 		w.onFailure(lint.Failure{ | ||||
| 			Confidence: 1, | ||||
| 			Node:       x, | ||||
| 			Category:   "content", | ||||
| 			Category:   lint.FailureCategoryContent, | ||||
| 			Failure:    fmt.Sprintf("should not use basic type %s as key in context.WithValue", key.Type), | ||||
| 		}) | ||||
| 	} | ||||
|   | ||||
| @@ -47,7 +47,7 @@ func (r *CyclomaticRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure | ||||
| 		if c > r.maxComplexity { | ||||
| 			failures = append(failures, lint.Failure{ | ||||
| 				Confidence: 1, | ||||
| 				Category:   "maintenance", | ||||
| 				Category:   lint.FailureCategoryMaintenance, | ||||
| 				Failure: fmt.Sprintf("function %s has cyclomatic complexity %d (> max enabled %d)", | ||||
| 					funcName(fn), c, r.maxComplexity), | ||||
| 				Node: fn, | ||||
|   | ||||
| @@ -122,14 +122,14 @@ func (w lintFunctionForDataRaces) Visit(node ast.Node) ast.Visitor { | ||||
| 				w.onFailure(lint.Failure{ | ||||
| 					Confidence: 1, | ||||
| 					Node:       id, | ||||
| 					Category:   "logic", | ||||
| 					Category:   lint.FailureCategoryLogic, | ||||
| 					Failure:    fmt.Sprintf("datarace: range value %s is captured (by-reference) in goroutine", id.Name), | ||||
| 				}) | ||||
| 			case isReturnID: | ||||
| 				w.onFailure(lint.Failure{ | ||||
| 					Confidence: 0.8, | ||||
| 					Node:       id, | ||||
| 					Category:   "logic", | ||||
| 					Category:   lint.FailureCategoryLogic, | ||||
| 					Failure:    fmt.Sprintf("potential datarace: return value %s is captured (by-reference) in goroutine", id.Name), | ||||
| 				}) | ||||
| 			} | ||||
|   | ||||
| @@ -68,7 +68,7 @@ func (w *lintDeepExit) Visit(node ast.Node) ast.Visitor { | ||||
| 		w.onFailure(lint.Failure{ | ||||
| 			Confidence: 1, | ||||
| 			Node:       ce, | ||||
| 			Category:   "bad practice", | ||||
| 			Category:   lint.FailureCategoryBadPractice, | ||||
| 			Failure:    fmt.Sprintf("calls to %s.%s only in main() or init() functions", pkg, fn), | ||||
| 		}) | ||||
| 	} | ||||
|   | ||||
| @@ -94,7 +94,7 @@ func (w lintDeferRule) Visit(node ast.Node) ast.Visitor { | ||||
| 		return nil | ||||
| 	case *ast.ReturnStmt: | ||||
| 		if len(n.Results) != 0 && w.inADefer && w.inAFuncLit { | ||||
| 			w.newFailure("return in a defer function has no effect", n, 1.0, "logic", "return") | ||||
| 			w.newFailure("return in a defer function has no effect", n, 1.0, lint.FailureCategoryLogic, "return") | ||||
| 		} | ||||
| 	case *ast.CallExpr: | ||||
| 		isCallToRecover := isIdent(n.Fun, "recover") | ||||
| @@ -103,13 +103,13 @@ func (w lintDeferRule) Visit(node ast.Node) ast.Visitor { | ||||
| 			// func fn() { recover() } | ||||
| 			// | ||||
| 			// confidence is not 1 because recover can be in a function that is deferred elsewhere | ||||
| 			w.newFailure("recover must be called inside a deferred function", n, 0.8, "logic", "recover") | ||||
| 			w.newFailure("recover must be called inside a deferred function", n, 0.8, lint.FailureCategoryLogic, "recover") | ||||
| 		case w.inADefer && !w.inAFuncLit && isCallToRecover: | ||||
| 			// defer helper(recover()) | ||||
| 			// | ||||
| 			// confidence is not truly 1 because this could be in a correctly-deferred func, | ||||
| 			// but it is very likely to be a misunderstanding of defer's behavior around arguments. | ||||
| 			w.newFailure("recover must be called inside a deferred function, this is executing recover immediately", n, 1, "logic", "immediate-recover") | ||||
| 			w.newFailure("recover must be called inside a deferred function, this is executing recover immediately", n, 1, lint.FailureCategoryLogic, "immediate-recover") | ||||
| 		} | ||||
| 		return nil // no need to analyze the arguments of the function call | ||||
| 	case *ast.DeferStmt: | ||||
| @@ -118,7 +118,7 @@ func (w lintDeferRule) Visit(node ast.Node) ast.Visitor { | ||||
| 			// | ||||
| 			// confidence is not truly 1 because this could be in a correctly-deferred func, | ||||
| 			// but normally this doesn't suppress a panic, and even if it did it would silently discard the value. | ||||
| 			w.newFailure("recover must be called inside a deferred function, this is executing recover immediately", n, 1, "logic", "immediate-recover") | ||||
| 			w.newFailure("recover must be called inside a deferred function, this is executing recover immediately", n, 1, lint.FailureCategoryLogic, "immediate-recover") | ||||
| 		} | ||||
| 		w.visitSubtree(n.Call.Fun, true, false, false) | ||||
| 		for _, a := range n.Call.Args { | ||||
| @@ -131,17 +131,17 @@ func (w lintDeferRule) Visit(node ast.Node) ast.Visitor { | ||||
| 		} | ||||
|  | ||||
| 		if w.inALoop { | ||||
| 			w.newFailure("prefer not to defer inside loops", n, 1.0, "bad practice", "loop") | ||||
| 			w.newFailure("prefer not to defer inside loops", n, 1.0, lint.FailureCategoryBadPractice, "loop") | ||||
| 		} | ||||
|  | ||||
| 		switch fn := n.Call.Fun.(type) { | ||||
| 		case *ast.CallExpr: | ||||
| 			w.newFailure("prefer not to defer chains of function calls", fn, 1.0, "bad practice", "call-chain") | ||||
| 			w.newFailure("prefer not to defer chains of function calls", fn, 1.0, lint.FailureCategoryBadPractice, "call-chain") | ||||
| 		case *ast.SelectorExpr: | ||||
| 			if id, ok := fn.X.(*ast.Ident); ok { | ||||
| 				isMethodCall := id != nil && id.Obj != nil && id.Obj.Kind == ast.Typ | ||||
| 				if isMethodCall { | ||||
| 					w.newFailure("be careful when deferring calls to methods without pointer receiver", fn, 0.8, "bad practice", "method-call") | ||||
| 					w.newFailure("be careful when deferring calls to methods without pointer receiver", fn, 0.8, lint.FailureCategoryBadPractice, "method-call") | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| @@ -163,7 +163,7 @@ func (w lintDeferRule) visitSubtree(n ast.Node, inADefer, inALoop, inAFuncLit bo | ||||
| 	ast.Walk(nw, n) | ||||
| } | ||||
|  | ||||
| func (w lintDeferRule) newFailure(msg string, node ast.Node, confidence float64, cat, subcase string) { | ||||
| func (w lintDeferRule) newFailure(msg string, node ast.Node, confidence float64, cat lint.FailureCategory, subcase string) { | ||||
| 	if !w.allow[subcase] { | ||||
| 		return | ||||
| 	} | ||||
|   | ||||
| @@ -81,7 +81,7 @@ func (w lintImports) Visit(_ ast.Node) ast.Visitor { | ||||
| 				Confidence: 1, | ||||
| 				Failure:    "should not use dot imports", | ||||
| 				Node:       importSpec, | ||||
| 				Category:   "imports", | ||||
| 				Category:   lint.FailureCategoryImports, | ||||
| 			}) | ||||
| 		} | ||||
| 	} | ||||
|   | ||||
| @@ -22,7 +22,7 @@ func (*DuplicatedImportsRule) Apply(file *lint.File, _ lint.Arguments) []lint.Fa | ||||
| 				Confidence: 1, | ||||
| 				Failure:    fmt.Sprintf("Package %s already imported", path), | ||||
| 				Node:       imp, | ||||
| 				Category:   "imports", | ||||
| 				Category:   lint.FailureCategoryImports, | ||||
| 			}) | ||||
| 			continue | ||||
| 		} | ||||
|   | ||||
| @@ -55,7 +55,7 @@ func (w lintEmptyBlock) Visit(node ast.Node) ast.Visitor { | ||||
| 			w.onFailure(lint.Failure{ | ||||
| 				Confidence: 0.9, | ||||
| 				Node:       n, | ||||
| 				Category:   "logic", | ||||
| 				Category:   lint.FailureCategoryLogic, | ||||
| 				Failure:    "this block is empty, you can remove it", | ||||
| 			}) | ||||
| 			return nil // skip visiting the range subtree (it will produce a duplicated failure) | ||||
| @@ -65,7 +65,7 @@ func (w lintEmptyBlock) Visit(node ast.Node) ast.Visitor { | ||||
| 			w.onFailure(lint.Failure{ | ||||
| 				Confidence: 1, | ||||
| 				Node:       n, | ||||
| 				Category:   "logic", | ||||
| 				Category:   lint.FailureCategoryLogic, | ||||
| 				Failure:    "this block is empty, you can remove it", | ||||
| 			}) | ||||
| 		} | ||||
|   | ||||
| @@ -60,7 +60,7 @@ func (w lintEmptyLines) checkStart(block *ast.BlockStmt) { | ||||
| 	w.onFailure(lint.Failure{ | ||||
| 		Confidence: 1, | ||||
| 		Node:       block, | ||||
| 		Category:   "style", | ||||
| 		Category:   lint.FailureCategoryStyle, | ||||
| 		Failure:    "extra empty line at the start of a block", | ||||
| 	}) | ||||
| } | ||||
| @@ -79,7 +79,7 @@ func (w lintEmptyLines) checkEnd(block *ast.BlockStmt) { | ||||
| 	w.onFailure(lint.Failure{ | ||||
| 		Confidence: 1, | ||||
| 		Node:       block, | ||||
| 		Category:   "style", | ||||
| 		Category:   lint.FailureCategoryStyle, | ||||
| 		Failure:    "extra empty line at the end of a block", | ||||
| 	}) | ||||
| } | ||||
|   | ||||
| @@ -91,7 +91,7 @@ func (r *EnforceMapStyleRule) Apply(file *lint.File, _ lint.Arguments) []lint.Fa | ||||
| 			failures = append(failures, lint.Failure{ | ||||
| 				Confidence: 1, | ||||
| 				Node:       v, | ||||
| 				Category:   "style", | ||||
| 				Category:   lint.FailureCategoryStyle, | ||||
| 				Failure:    "use make(map[type]type) instead of map[type]type{}", | ||||
| 			}) | ||||
| 		case *ast.CallExpr: | ||||
| @@ -119,7 +119,7 @@ func (r *EnforceMapStyleRule) Apply(file *lint.File, _ lint.Arguments) []lint.Fa | ||||
| 			failures = append(failures, lint.Failure{ | ||||
| 				Confidence: 1, | ||||
| 				Node:       v.Args[0], | ||||
| 				Category:   "style", | ||||
| 				Category:   lint.FailureCategoryStyle, | ||||
| 				Failure:    "use map[type]type{} instead of make(map[type]type)", | ||||
| 			}) | ||||
| 		} | ||||
|   | ||||
| @@ -121,7 +121,7 @@ func (r *EnforceRepeatedArgTypeStyleRule) Apply(file *lint.File, _ lint.Argument | ||||
| 							failures = append(failures, lint.Failure{ | ||||
| 								Confidence: 1, | ||||
| 								Node:       field, | ||||
| 								Category:   "style", | ||||
| 								Category:   lint.FailureCategoryStyle, | ||||
| 								Failure:    "argument types should not be omitted", | ||||
| 							}) | ||||
| 						} | ||||
| @@ -137,7 +137,7 @@ func (r *EnforceRepeatedArgTypeStyleRule) Apply(file *lint.File, _ lint.Argument | ||||
| 							failures = append(failures, lint.Failure{ | ||||
| 								Confidence: 1, | ||||
| 								Node:       prevType, | ||||
| 								Category:   "style", | ||||
| 								Category:   lint.FailureCategoryStyle, | ||||
| 								Failure:    fmt.Sprintf("repeated argument type %q can be omitted", prevTypeStr), | ||||
| 							}) | ||||
| 						} | ||||
| @@ -154,7 +154,7 @@ func (r *EnforceRepeatedArgTypeStyleRule) Apply(file *lint.File, _ lint.Argument | ||||
| 							failures = append(failures, lint.Failure{ | ||||
| 								Confidence: 1, | ||||
| 								Node:       field, | ||||
| 								Category:   "style", | ||||
| 								Category:   lint.FailureCategoryStyle, | ||||
| 								Failure:    "return types should not be omitted", | ||||
| 							}) | ||||
| 						} | ||||
| @@ -170,7 +170,7 @@ func (r *EnforceRepeatedArgTypeStyleRule) Apply(file *lint.File, _ lint.Argument | ||||
| 							failures = append(failures, lint.Failure{ | ||||
| 								Confidence: 1, | ||||
| 								Node:       prevType, | ||||
| 								Category:   "style", | ||||
| 								Category:   lint.FailureCategoryStyle, | ||||
| 								Failure:    fmt.Sprintf("repeated return type %q can be omitted", prevTypeStr), | ||||
| 							}) | ||||
| 						} | ||||
|   | ||||
| @@ -105,7 +105,7 @@ func (r *EnforceSliceStyleRule) Apply(file *lint.File, _ lint.Arguments) []lint. | ||||
| 			failures = append(failures, lint.Failure{ | ||||
| 				Confidence: 1, | ||||
| 				Node:       v, | ||||
| 				Category:   "style", | ||||
| 				Category:   lint.FailureCategoryStyle, | ||||
| 				Failure:    failureMessage, | ||||
| 			}) | ||||
| 		case *ast.CallExpr: | ||||
| @@ -165,7 +165,7 @@ func (r *EnforceSliceStyleRule) Apply(file *lint.File, _ lint.Arguments) []lint. | ||||
| 			failures = append(failures, lint.Failure{ | ||||
| 				Confidence: 1, | ||||
| 				Node:       v.Args[0], | ||||
| 				Category:   "style", | ||||
| 				Category:   lint.FailureCategoryStyle, | ||||
| 				Failure:    failureMessage, | ||||
| 			}) | ||||
| 		} | ||||
|   | ||||
| @@ -69,7 +69,7 @@ func (w lintErrors) Visit(_ ast.Node) ast.Visitor { | ||||
| 				w.onFailure(lint.Failure{ | ||||
| 					Node:       id, | ||||
| 					Confidence: 0.9, | ||||
| 					Category:   "naming", | ||||
| 					Category:   lint.FailureCategoryNaming, | ||||
| 					Failure:    fmt.Sprintf("error var %s should have name of the form %sFoo", id.Name, prefix), | ||||
| 				}) | ||||
| 			} | ||||
|   | ||||
| @@ -31,7 +31,7 @@ func (*ErrorReturnRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure | ||||
| 		for _, r := range funcResults[:len(funcResults)-1] { | ||||
| 			if isIdent(r.Type, "error") { | ||||
| 				failures = append(failures, lint.Failure{ | ||||
| 					Category:   "style", | ||||
| 					Category:   lint.FailureCategoryStyle, | ||||
| 					Confidence: 0.9, | ||||
| 					Node:       funcDecl, | ||||
| 					Failure:    "error should be the last type when returning multiple items", | ||||
|   | ||||
| @@ -115,7 +115,7 @@ func (w lintErrorStrings) Visit(n ast.Node) ast.Visitor { | ||||
| 	w.onFailure(lint.Failure{ | ||||
| 		Node:       str, | ||||
| 		Confidence: conf, | ||||
| 		Category:   "errors", | ||||
| 		Category:   lint.FailureCategoryErrors, | ||||
| 		Failure:    "error strings should not be capitalized or end with punctuation or a newline", | ||||
| 	}) | ||||
| 	return w | ||||
|   | ||||
| @@ -69,7 +69,7 @@ func (w lintErrorf) Visit(n ast.Node) ast.Visitor { | ||||
| 	} | ||||
|  | ||||
| 	failure := lint.Failure{ | ||||
| 		Category:   "errors", | ||||
| 		Category:   lint.FailureCategoryErrors, | ||||
| 		Node:       n, | ||||
| 		Confidence: 1, | ||||
| 		Failure:    fmt.Sprintf("should replace %s(fmt.Sprintf(...)) with %s.Errorf(...)", w.file.Render(se), errorfPrefix), | ||||
|   | ||||
| @@ -186,7 +186,7 @@ func (w *lintExported) lintFuncDoc(fn *ast.FuncDecl) { | ||||
| 		w.onFailure(lint.Failure{ | ||||
| 			Node:       fn, | ||||
| 			Confidence: 1, | ||||
| 			Category:   "comments", | ||||
| 			Category:   lint.FailureCategoryComments, | ||||
| 			Failure:    fmt.Sprintf("exported %s %s should have comment or be unexported", kind, name), | ||||
| 		}) | ||||
| 		return | ||||
| @@ -198,7 +198,7 @@ func (w *lintExported) lintFuncDoc(fn *ast.FuncDecl) { | ||||
| 		w.onFailure(lint.Failure{ | ||||
| 			Node:       fn.Doc, | ||||
| 			Confidence: 0.8, | ||||
| 			Category:   "comments", | ||||
| 			Category:   lint.FailureCategoryComments, | ||||
| 			Failure:    fmt.Sprintf(`comment on exported %s %s should be of the form "%s..."`, kind, name, prefix), | ||||
| 		}) | ||||
| 	} | ||||
| @@ -232,7 +232,7 @@ func (w *lintExported) checkStutter(id *ast.Ident, thing string) { | ||||
| 		w.onFailure(lint.Failure{ | ||||
| 			Node:       id, | ||||
| 			Confidence: 0.8, | ||||
| 			Category:   "naming", | ||||
| 			Category:   lint.FailureCategoryNaming, | ||||
| 			Failure:    fmt.Sprintf("%s name will be used as %s.%s by other packages, and that %s; consider calling this %s", thing, pkg, name, w.stuttersMsg, rem), | ||||
| 		}) | ||||
| 	} | ||||
| @@ -251,7 +251,7 @@ func (w *lintExported) lintTypeDoc(t *ast.TypeSpec, doc *ast.CommentGroup) { | ||||
| 		w.onFailure(lint.Failure{ | ||||
| 			Node:       t, | ||||
| 			Confidence: 1, | ||||
| 			Category:   "comments", | ||||
| 			Category:   lint.FailureCategoryComments, | ||||
| 			Failure:    fmt.Sprintf("exported type %v should have comment or be unexported", t.Name), | ||||
| 		}) | ||||
| 		return | ||||
| @@ -278,7 +278,7 @@ func (w *lintExported) lintTypeDoc(t *ast.TypeSpec, doc *ast.CommentGroup) { | ||||
| 	w.onFailure(lint.Failure{ | ||||
| 		Node:       doc, | ||||
| 		Confidence: 1, | ||||
| 		Category:   "comments", | ||||
| 		Category:   lint.FailureCategoryComments, | ||||
| 		Failure:    fmt.Sprintf(`comment on exported type %v should be of the form "%s..." (with optional leading article)`, t.Name, expectedPrefix), | ||||
| 	}) | ||||
| } | ||||
| @@ -298,7 +298,7 @@ func (w *lintExported) lintValueSpecDoc(vs *ast.ValueSpec, gd *ast.GenDecl, genD | ||||
| 		for _, n := range vs.Names[1:] { | ||||
| 			if ast.IsExported(n.Name) { | ||||
| 				w.onFailure(lint.Failure{ | ||||
| 					Category:   "comments", | ||||
| 					Category:   lint.FailureCategoryComments, | ||||
| 					Confidence: 1, | ||||
| 					Failure:    fmt.Sprintf("exported %s %s should have its own declaration", kind, n.Name), | ||||
| 					Node:       vs, | ||||
| @@ -325,7 +325,7 @@ func (w *lintExported) lintValueSpecDoc(vs *ast.ValueSpec, gd *ast.GenDecl, genD | ||||
| 		w.onFailure(lint.Failure{ | ||||
| 			Confidence: 1, | ||||
| 			Node:       vs, | ||||
| 			Category:   "comments", | ||||
| 			Category:   lint.FailureCategoryComments, | ||||
| 			Failure:    fmt.Sprintf("exported %s %s should have comment%s or be unexported", kind, name, block), | ||||
| 		}) | ||||
| 		genDeclMissingComments[gd] = true | ||||
| @@ -353,7 +353,7 @@ func (w *lintExported) lintValueSpecDoc(vs *ast.ValueSpec, gd *ast.GenDecl, genD | ||||
| 		w.onFailure(lint.Failure{ | ||||
| 			Confidence: 1, | ||||
| 			Node:       doc, | ||||
| 			Category:   "comments", | ||||
| 			Category:   lint.FailureCategoryComments, | ||||
| 			Failure:    fmt.Sprintf(`comment on exported %s %s should be of the form "%s..."`, kind, name, prefix), | ||||
| 		}) | ||||
| 	} | ||||
| @@ -428,7 +428,7 @@ func (w *lintExported) lintInterfaceMethod(typeName string, m *ast.Field) { | ||||
| 		w.onFailure(lint.Failure{ | ||||
| 			Node:       m, | ||||
| 			Confidence: 1, | ||||
| 			Category:   "comments", | ||||
| 			Category:   lint.FailureCategoryComments, | ||||
| 			Failure:    fmt.Sprintf("public interface method %s.%s should be commented", typeName, name), | ||||
| 		}) | ||||
| 		return | ||||
| @@ -439,7 +439,7 @@ func (w *lintExported) lintInterfaceMethod(typeName string, m *ast.Field) { | ||||
| 		w.onFailure(lint.Failure{ | ||||
| 			Node:       m.Doc, | ||||
| 			Confidence: 0.8, | ||||
| 			Category:   "comments", | ||||
| 			Category:   lint.FailureCategoryComments, | ||||
| 			Failure:    fmt.Sprintf(`comment on exported interface method %s.%s should be of the form "%s..."`, typeName, name, expectedPrefix), | ||||
| 		}) | ||||
| 	} | ||||
|   | ||||
| @@ -57,7 +57,7 @@ func (r *FileLengthLimitRule) Apply(file *lint.File, _ lint.Arguments) []lint.Fa | ||||
|  | ||||
| 	return []lint.Failure{ | ||||
| 		{ | ||||
| 			Category:   "code-style", | ||||
| 			Category:   lint.FailureCategoryCodeStyle, | ||||
| 			Confidence: 1, | ||||
| 			Position: lint.FailurePosition{ | ||||
| 				Start: token.Position{ | ||||
|   | ||||
| @@ -81,7 +81,7 @@ func (w conditionVisitor) Visit(node ast.Node) ast.Visitor { | ||||
| 	w.onFailure(lint.Failure{ | ||||
| 		Confidence: 1, | ||||
| 		Node:       w.fd.Type.Params, | ||||
| 		Category:   "bad practice", | ||||
| 		Category:   lint.FailureCategoryBadPractice, | ||||
| 		Failure:    fmt.Sprintf("parameter '%s' seems to be a control flag, avoid control coupling", uses[0]), | ||||
| 	}) | ||||
|  | ||||
|   | ||||
| @@ -32,7 +32,7 @@ func (*GetReturnRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { | ||||
| 		failures = append(failures, lint.Failure{ | ||||
| 			Confidence: 0.8, | ||||
| 			Node:       fd, | ||||
| 			Category:   "logic", | ||||
| 			Category:   lint.FailureCategoryLogic, | ||||
| 			Failure:    fmt.Sprintf("function '%s' seems to be a getter but it does not return any result", fd.Name.Name), | ||||
| 		}) | ||||
| 	} | ||||
|   | ||||
| @@ -81,7 +81,7 @@ func (w *lintIdenticalBranches) newFailure(node ast.Node, msg string) { | ||||
| 	w.onFailure(lint.Failure{ | ||||
| 		Confidence: 1, | ||||
| 		Node:       node, | ||||
| 		Category:   "logic", | ||||
| 		Category:   lint.FailureCategoryLogic, | ||||
| 		Failure:    msg, | ||||
| 	}) | ||||
| } | ||||
|   | ||||
| @@ -80,7 +80,7 @@ func (r *ImportAliasNamingRule) Apply(file *lint.File, _ lint.Arguments) []lint. | ||||
| 				Confidence: 1, | ||||
| 				Failure:    fmt.Sprintf("import name (%s) must match the regular expression: %s", alias.Name, r.allowRegexp.String()), | ||||
| 				Node:       alias, | ||||
| 				Category:   "imports", | ||||
| 				Category:   lint.FailureCategoryImports, | ||||
| 			}) | ||||
| 		} | ||||
|  | ||||
| @@ -89,7 +89,7 @@ func (r *ImportAliasNamingRule) Apply(file *lint.File, _ lint.Arguments) []lint. | ||||
| 				Confidence: 1, | ||||
| 				Failure:    fmt.Sprintf("import name (%s) must NOT match the regular expression: %s", alias.Name, r.denyRegexp.String()), | ||||
| 				Node:       alias, | ||||
| 				Category:   "imports", | ||||
| 				Category:   lint.FailureCategoryImports, | ||||
| 			}) | ||||
| 		} | ||||
| 	} | ||||
|   | ||||
| @@ -103,7 +103,7 @@ func (w importShadowing) Visit(n ast.Node) ast.Visitor { | ||||
| 			w.onFailure(lint.Failure{ | ||||
| 				Confidence: 1, | ||||
| 				Node:       n, | ||||
| 				Category:   "naming", | ||||
| 				Category:   lint.FailureCategoryNaming, | ||||
| 				Failure:    fmt.Sprintf("The name '%s' shadows an import name", id), | ||||
| 			}) | ||||
|  | ||||
|   | ||||
| @@ -53,7 +53,7 @@ func (r *ImportsBlocklistRule) Apply(file *lint.File, _ lint.Arguments) []lint.F | ||||
| 				Confidence: 1, | ||||
| 				Failure:    "should not use the following blocklisted import: " + path.Value, | ||||
| 				Node:       is, | ||||
| 				Category:   "imports", | ||||
| 				Category:   lint.FailureCategoryImports, | ||||
| 			}) | ||||
| 		} | ||||
| 	} | ||||
|   | ||||
| @@ -61,7 +61,7 @@ func (w lintIncrementDecrement) Visit(n ast.Node) ast.Visitor { | ||||
| 	w.onFailure(lint.Failure{ | ||||
| 		Confidence: 0.8, | ||||
| 		Node:       as, | ||||
| 		Category:   "unary-op", | ||||
| 		Category:   lint.FailureCategoryUnaryOp, | ||||
| 		Failure:    fmt.Sprintf("should replace %s with %s%s", w.file.Render(as), w.file.Render(as.Lhs[0]), suffix), | ||||
| 	}) | ||||
| 	return w | ||||
|   | ||||
| @@ -76,7 +76,7 @@ func (r lintLineLengthNum) check() { | ||||
| 		c := utf8.RuneCountInString(t) | ||||
| 		if c > r.max { | ||||
| 			r.onFailure(lint.Failure{ | ||||
| 				Category: "code-style", | ||||
| 				Category: lint.FailureCategoryCodeStyle, | ||||
| 				Position: lint.FailurePosition{ | ||||
| 					// Offset not set; it is non-trivial, and doesn't appear to be needed. | ||||
| 					Start: token.Position{ | ||||
|   | ||||
| @@ -51,7 +51,7 @@ func (w *lintMaxControlNesting) Visit(n ast.Node) ast.Visitor { | ||||
| 			Failure:    fmt.Sprintf("control flow nesting exceeds %d", w.max), | ||||
| 			Confidence: 1, | ||||
| 			Node:       w.lastCtrlStmt, | ||||
| 			Category:   "complexity", | ||||
| 			Category:   lint.FailureCategoryComplexity, | ||||
| 		}) | ||||
| 		return nil // stop visiting deeper | ||||
| 	} | ||||
|   | ||||
| @@ -62,7 +62,7 @@ func (r *MaxPublicStructsRule) Apply(file *lint.File, _ lint.Arguments) []lint.F | ||||
| 			Failure:    fmt.Sprintf("you have exceeded the maximum number (%d) of public struct declarations", r.max), | ||||
| 			Confidence: 1, | ||||
| 			Node:       fileAst, | ||||
| 			Category:   "style", | ||||
| 			Category:   lint.FailureCategoryStyle, | ||||
| 		}) | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -73,7 +73,7 @@ func checkParam(id *ast.Ident, w *lintModifiesParamRule) { | ||||
| 		w.onFailure(lint.Failure{ | ||||
| 			Confidence: 0.5, // confidence is low because of shadow variables | ||||
| 			Node:       id, | ||||
| 			Category:   "bad practice", | ||||
| 			Category:   lint.FailureCategoryBadPractice, | ||||
| 			Failure:    fmt.Sprintf("parameter '%s' seems to be modified", id), | ||||
| 		}) | ||||
| 	} | ||||
|   | ||||
| @@ -68,7 +68,7 @@ func (l *lintStruct) Visit(n ast.Node) ast.Visitor { | ||||
| func (l *lintStruct) fail(n ast.Node) { | ||||
| 	l.onFailure(lint.Failure{ | ||||
| 		Failure:    "no nested structs are allowed", | ||||
| 		Category:   "style", | ||||
| 		Category:   lint.FailureCategoryStyle, | ||||
| 		Node:       n, | ||||
| 		Confidence: 1, | ||||
| 	}) | ||||
|   | ||||
| @@ -78,7 +78,7 @@ func (w lintOptimizeOperandsOrderlExpr) Visit(node ast.Node) ast.Visitor { | ||||
| 	w.onFailure(lint.Failure{ | ||||
| 		Failure:    fmt.Sprintf("for better performance '%v' might be rewritten as '%v'", gofmt(binExpr), gofmt(&newExpr)), | ||||
| 		Node:       node, | ||||
| 		Category:   "optimization", | ||||
| 		Category:   lint.FailureCategoryOptimization, | ||||
| 		Confidence: 0.3, | ||||
| 	}) | ||||
|  | ||||
|   | ||||
| @@ -88,7 +88,7 @@ func (l *lintPackageComments) checkPackageComment() []lint.Failure { | ||||
| 	if docFile != nil { | ||||
| 		pkgFile := l.file.Pkg.Files()[fileSource] | ||||
| 		return []lint.Failure{{ | ||||
| 			Category: "comments", | ||||
| 			Category: lint.FailureCategoryComments, | ||||
| 			Position: lint.FailurePosition{ | ||||
| 				Start: pkgFile.ToPosition(docFile.Pos()), | ||||
| 				End:   pkgFile.ToPosition(docFile.Name.End()), | ||||
| @@ -131,7 +131,7 @@ func (l *lintPackageComments) Visit(_ ast.Node) ast.Visitor { | ||||
| 				Column: 1, | ||||
| 			} | ||||
| 			l.onFailure(lint.Failure{ | ||||
| 				Category: "comments", | ||||
| 				Category: lint.FailureCategoryComments, | ||||
| 				Position: lint.FailurePosition{ | ||||
| 					Start: pos, | ||||
| 					End:   pos, | ||||
| @@ -154,7 +154,7 @@ func (l *lintPackageComments) Visit(_ ast.Node) ast.Visitor { | ||||
| 	// Only non-main packages need to keep to this form. | ||||
| 	if !l.file.Pkg.IsMain() && !strings.HasPrefix(s, prefix) && !isDirectiveComment(s) { | ||||
| 		l.onFailure(lint.Failure{ | ||||
| 			Category:   "comments", | ||||
| 			Category:   lint.FailureCategoryComments, | ||||
| 			Node:       l.fileAst.Doc, | ||||
| 			Confidence: 1, | ||||
| 			Failure:    fmt.Sprintf(`package comment should be of the form "%s..."`, prefix), | ||||
|   | ||||
| @@ -63,7 +63,7 @@ func (r *ReceiverNamingRule) Apply(file *lint.File, _ lint.Arguments) []lint.Fai | ||||
| 			failures = append(failures, lint.Failure{ | ||||
| 				Node:       decl, | ||||
| 				Confidence: 1, | ||||
| 				Category:   "naming", | ||||
| 				Category:   lint.FailureCategoryNaming, | ||||
| 				Failure:    "receiver name should not be an underscore, omit the name if it is unused", | ||||
| 			}) | ||||
| 			continue | ||||
| @@ -73,7 +73,7 @@ func (r *ReceiverNamingRule) Apply(file *lint.File, _ lint.Arguments) []lint.Fai | ||||
| 			failures = append(failures, lint.Failure{ | ||||
| 				Node:       decl, | ||||
| 				Confidence: 1, | ||||
| 				Category:   "naming", | ||||
| 				Category:   lint.FailureCategoryNaming, | ||||
| 				Failure:    `receiver name should be a reflection of its identity; don't use generic names such as "this" or "self"`, | ||||
| 			}) | ||||
| 			continue | ||||
| @@ -83,7 +83,7 @@ func (r *ReceiverNamingRule) Apply(file *lint.File, _ lint.Arguments) []lint.Fai | ||||
| 			failures = append(failures, lint.Failure{ | ||||
| 				Node:       decl, | ||||
| 				Confidence: 1, | ||||
| 				Category:   "naming", | ||||
| 				Category:   lint.FailureCategoryNaming, | ||||
| 				Failure:    fmt.Sprintf("receiver name %s is longer than %d characters", name, r.receiverNameMaxLength), | ||||
| 			}) | ||||
| 			continue | ||||
| @@ -94,7 +94,7 @@ func (r *ReceiverNamingRule) Apply(file *lint.File, _ lint.Arguments) []lint.Fai | ||||
| 			failures = append(failures, lint.Failure{ | ||||
| 				Node:       decl, | ||||
| 				Confidence: 1, | ||||
| 				Category:   "naming", | ||||
| 				Category:   lint.FailureCategoryNaming, | ||||
| 				Failure:    fmt.Sprintf("receiver name %s should be consistent with previous receiver name %s for %s", name, prev, recv), | ||||
| 			}) | ||||
| 			continue | ||||
|   | ||||
| @@ -202,7 +202,7 @@ func (w *lintRedefinesBuiltinID) addFailure(node ast.Node, msg string) { | ||||
| 	w.onFailure(lint.Failure{ | ||||
| 		Confidence: 1, | ||||
| 		Node:       node, | ||||
| 		Category:   "logic", | ||||
| 		Category:   lint.FailureCategoryLogic, | ||||
| 		Failure:    msg, | ||||
| 	}) | ||||
| } | ||||
|   | ||||
| @@ -23,7 +23,7 @@ func (*RedundantBuildTagRule) Apply(file *lint.File, _ lint.Arguments) []lint.Fa | ||||
|  | ||||
| 			if hasGoBuild && strings.HasPrefix(comment.Text, "// +build ") { | ||||
| 				return []lint.Failure{{ | ||||
| 					Category:   "style", | ||||
| 					Category:   lint.FailureCategoryStyle, | ||||
| 					Confidence: 1, | ||||
| 					Node:       comment, | ||||
| 					Failure:    `The build tag "// +build" is redundant since Go 1.17 and can be removed`, | ||||
|   | ||||
| @@ -25,7 +25,7 @@ func (*RedundantImportAlias) Apply(file *lint.File, _ lint.Arguments) []lint.Fai | ||||
| 				Confidence: 1, | ||||
| 				Failure:    fmt.Sprintf("Import alias \"%s\" is redundant", imp.Name.Name), | ||||
| 				Node:       imp, | ||||
| 				Category:   "imports", | ||||
| 				Category:   lint.FailureCategoryImports, | ||||
| 			}) | ||||
| 		} | ||||
| 	} | ||||
|   | ||||
| @@ -63,7 +63,7 @@ func (l *lintTimeEqual) Visit(node ast.Node) ast.Visitor { | ||||
| 	} | ||||
|  | ||||
| 	l.onFailure(lint.Failure{ | ||||
| 		Category:   "time", | ||||
| 		Category:   lint.FailureCategoryTime, | ||||
| 		Confidence: 1, | ||||
| 		Node:       node, | ||||
| 		Failure:    fmt.Sprintf("use %s%s.Equal(%s) instead of %q operator", negateStr, gofmt(expr.X), gofmt(expr.Y), expr.Op), | ||||
|   | ||||
| @@ -64,7 +64,7 @@ func (w *lintTimeNames) Visit(node ast.Node) ast.Visitor { | ||||
| 			continue | ||||
| 		} | ||||
| 		w.onFailure(lint.Failure{ | ||||
| 			Category:   "time", | ||||
| 			Category:   lint.FailureCategoryTime, | ||||
| 			Confidence: 0.9, | ||||
| 			Node:       v, | ||||
| 			Failure:    fmt.Sprintf("var %s is of type %v; don't use unit-specific suffix %q", name.Name, origTyp, suffix), | ||||
|   | ||||
| @@ -181,7 +181,7 @@ func (w *lintUncheckedTypeAssertion) Visit(node ast.Node) ast.Visitor { | ||||
| func (w *lintUncheckedTypeAssertion) addFailure(n *ast.TypeAssertExpr, why string) { | ||||
| 	s := fmt.Sprintf("type cast result is unchecked in %v - %s", gofmt(n), why) | ||||
| 	w.onFailure(lint.Failure{ | ||||
| 		Category:   "bad practice", | ||||
| 		Category:   lint.FailureCategoryBadPractice, | ||||
| 		Confidence: 1, | ||||
| 		Node:       n, | ||||
| 		Failure:    s, | ||||
|   | ||||
| @@ -100,7 +100,7 @@ func (w *lintUnconditionalRecursionRule) Visit(node ast.Node) ast.Visitor { | ||||
| 			!w.currentFunc.seenConditionalExit && // there is a conditional exit in the function | ||||
| 			w.currentFunc.funcDesc.equal(&funcDesc{selector, funcID}) { | ||||
| 			w.onFailure(lint.Failure{ | ||||
| 				Category:   "logic", | ||||
| 				Category:   lint.FailureCategoryLogic, | ||||
| 				Confidence: 0.8, | ||||
| 				Node:       n, | ||||
| 				Failure:    "unconditional recursive call", | ||||
|   | ||||
| @@ -107,7 +107,7 @@ func (unl unexportablenamingLinter) lintIDs(ids []*ast.Ident) { | ||||
| 			unl.onFailure(lint.Failure{ | ||||
| 				Node:       id, | ||||
| 				Confidence: 1, | ||||
| 				Category:   "naming", | ||||
| 				Category:   lint.FailureCategoryNaming, | ||||
| 				Failure:    fmt.Sprintf("the symbol %s is local, its name should start with a lowercase letter", id.String()), | ||||
| 			}) | ||||
| 		} | ||||
|   | ||||
| @@ -47,7 +47,7 @@ func (*UnexportedReturnRule) Apply(file *lint.File, _ lint.Arguments) []lint.Fai | ||||
| 			} | ||||
|  | ||||
| 			failures = append(failures, lint.Failure{ | ||||
| 				Category:   "unexported-type-in-api", | ||||
| 				Category:   lint.FailureCategoryUnexportedTypeInAPI, | ||||
| 				Node:       ret.Type, | ||||
| 				Confidence: 0.8, | ||||
| 				Failure: fmt.Sprintf("exported %s %s returns unexported type %s, which can be annoying to use", | ||||
|   | ||||
| @@ -113,7 +113,7 @@ func (w *lintUnhandledErrors) addFailure(n *ast.CallExpr) { | ||||
| 	} | ||||
|  | ||||
| 	w.onFailure(lint.Failure{ | ||||
| 		Category:   "bad practice", | ||||
| 		Category:   lint.FailureCategoryBadPractice, | ||||
| 		Confidence: 1, | ||||
| 		Node:       n, | ||||
| 		Failure:    fmt.Sprintf("Unhandled error in call to function %v", name), | ||||
|   | ||||
| @@ -101,7 +101,7 @@ func (w lintUnnecessaryStmtRule) newFailure(node ast.Node, msg string) { | ||||
| 	w.onFailure(lint.Failure{ | ||||
| 		Confidence: 1, | ||||
| 		Node:       node, | ||||
| 		Category:   "style", | ||||
| 		Category:   lint.FailureCategoryStyle, | ||||
| 		Failure:    msg, | ||||
| 	}) | ||||
| } | ||||
|   | ||||
| @@ -115,7 +115,7 @@ func newUnreachableCodeFailure(node ast.Node) lint.Failure { | ||||
| 	return lint.Failure{ | ||||
| 		Confidence: 1, | ||||
| 		Node:       node, | ||||
| 		Category:   "logic", | ||||
| 		Category:   lint.FailureCategoryLogic, | ||||
| 		Failure:    "unreachable code after this statement", | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -129,7 +129,7 @@ func (w lintUnusedParamRule) Visit(node ast.Node) ast.Visitor { | ||||
| 				w.onFailure(lint.Failure{ | ||||
| 					Confidence: 1, | ||||
| 					Node:       n, | ||||
| 					Category:   "bad practice", | ||||
| 					Category:   lint.FailureCategoryBadPractice, | ||||
| 					Failure:    fmt.Sprintf(w.failureMsg, n.Name), | ||||
| 				}) | ||||
| 			} | ||||
|   | ||||
| @@ -87,7 +87,7 @@ func (r *UnusedReceiverRule) Apply(file *lint.File, _ lint.Arguments) []lint.Fai | ||||
| 		failures = append(failures, lint.Failure{ | ||||
| 			Confidence: 1, | ||||
| 			Node:       recID, | ||||
| 			Category:   "bad practice", | ||||
| 			Category:   lint.FailureCategoryBadPractice, | ||||
| 			Failure:    fmt.Sprintf(r.failureMsg, recID.Name), | ||||
| 		}) | ||||
| 	} | ||||
|   | ||||
| @@ -46,7 +46,7 @@ func (w lintUseAny) Visit(n ast.Node) ast.Visitor { | ||||
| 	w.onFailure(lint.Failure{ | ||||
| 		Node:       n, | ||||
| 		Confidence: 1, | ||||
| 		Category:   "naming", | ||||
| 		Category:   lint.FailureCategoryNaming, | ||||
| 		Failure:    "since Go 1.18 'interface{}' can be replaced by 'any'", | ||||
| 	}) | ||||
|  | ||||
|   | ||||
| @@ -50,7 +50,7 @@ func (w lintFmtErrorf) Visit(n ast.Node) ast.Visitor { | ||||
|  | ||||
| 	// the call is of the form fmt.Errorf("...") | ||||
| 	w.onFailure(lint.Failure{ | ||||
| 		Category:   "errors", | ||||
| 		Category:   lint.FailureCategoryErrors, | ||||
| 		Node:       n, | ||||
| 		Confidence: 1, | ||||
| 		Failure:    "replace fmt.Errorf by errors.New", | ||||
|   | ||||
| @@ -93,7 +93,7 @@ func (w *lintVarDeclarations) Visit(node ast.Node) ast.Visitor { | ||||
| 			w.onFailure(lint.Failure{ | ||||
| 				Confidence: 0.9, | ||||
| 				Node:       rhs, | ||||
| 				Category:   "zero-value", | ||||
| 				Category:   lint.FailureCategoryZeroValue, | ||||
| 				Failure:    fmt.Sprintf("should drop = %s from declaration of var %s; it is the zero value", w.file.Render(rhs), v.Names[0]), | ||||
| 			}) | ||||
| 			return nil | ||||
| @@ -127,7 +127,7 @@ func (w *lintVarDeclarations) Visit(node ast.Node) ast.Visitor { | ||||
| 		} | ||||
|  | ||||
| 		w.onFailure(lint.Failure{ | ||||
| 			Category:   "type-inference", | ||||
| 			Category:   lint.FailureCategoryTypeInference, | ||||
| 			Confidence: 0.8, | ||||
| 			Node:       v.Type, | ||||
| 			Failure:    fmt.Sprintf("should omit type %s from declaration of var %s; it will be inferred from the right-hand side", w.file.Render(v.Type), v.Names[0]), | ||||
|   | ||||
| @@ -77,7 +77,7 @@ func (*VarNamingRule) applyPackageCheckRules(walker *lintNames) { | ||||
| 			Failure:    "don't use an underscore in package name", | ||||
| 			Confidence: 1, | ||||
| 			Node:       walker.fileAst.Name, | ||||
| 			Category:   "naming", | ||||
| 			Category:   lint.FailureCategoryNaming, | ||||
| 		}) | ||||
| 	} | ||||
| 	if anyCapsRE.MatchString(walker.fileAst.Name.Name) { | ||||
| @@ -85,7 +85,7 @@ func (*VarNamingRule) applyPackageCheckRules(walker *lintNames) { | ||||
| 			Failure:    fmt.Sprintf("don't use MixedCaps in package name; %s should be %s", walker.fileAst.Name.Name, strings.ToLower(walker.fileAst.Name.Name)), | ||||
| 			Confidence: 1, | ||||
| 			Node:       walker.fileAst.Name, | ||||
| 			Category:   "naming", | ||||
| 			Category:   lint.FailureCategoryNaming, | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| @@ -152,7 +152,7 @@ func (w *lintNames) check(id *ast.Ident, thing string) { | ||||
| 			Failure:    "don't use ALL_CAPS in Go names; use CamelCase", | ||||
| 			Confidence: 0.8, | ||||
| 			Node:       id, | ||||
| 			Category:   "naming", | ||||
| 			Category:   lint.FailureCategoryNaming, | ||||
| 		}) | ||||
| 		return | ||||
| 	} | ||||
| @@ -167,7 +167,7 @@ func (w *lintNames) check(id *ast.Ident, thing string) { | ||||
| 			Failure:    fmt.Sprintf("don't use underscores in Go names; %s %s should be %s", thing, id.Name, should), | ||||
| 			Confidence: 0.9, | ||||
| 			Node:       id, | ||||
| 			Category:   "naming", | ||||
| 			Category:   lint.FailureCategoryNaming, | ||||
| 		}) | ||||
| 		return | ||||
| 	} | ||||
| @@ -175,7 +175,7 @@ func (w *lintNames) check(id *ast.Ident, thing string) { | ||||
| 		Failure:    fmt.Sprintf("%s %s should be %s", thing, id.Name, should), | ||||
| 		Confidence: 0.8, | ||||
| 		Node:       id, | ||||
| 		Category:   "naming", | ||||
| 		Category:   lint.FailureCategoryNaming, | ||||
| 	}) | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user