mirror of
				https://github.com/mgechev/revive.git
				synced 2025-10-30 23:37:49 +02:00 
			
		
		
		
	Add rules
This commit is contained in:
		
							
								
								
									
										74
									
								
								defaultrule/blank-imports.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								defaultrule/blank-imports.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,74 @@ | ||||
| package defaultrule | ||||
|  | ||||
| import ( | ||||
| 	"go/ast" | ||||
|  | ||||
| 	"github.com/mgechev/revive/file" | ||||
| 	"github.com/mgechev/revive/rule" | ||||
| ) | ||||
|  | ||||
| // BlankImportsRule lints given else constructs. | ||||
| type BlankImportsRule struct{} | ||||
|  | ||||
| // Apply applies the rule to given file. | ||||
| func (r *BlankImportsRule) Apply(file *file.File, arguments rule.Arguments) []rule.Failure { | ||||
| 	var failures []rule.Failure | ||||
|  | ||||
| 	fileAst := file.GetAST() | ||||
| 	walker := lintBlankImports{ | ||||
| 		file:    file, | ||||
| 		fileAst: fileAst, | ||||
| 		onFailure: func(failure rule.Failure) { | ||||
| 			failures = append(failures, failure) | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	ast.Walk(walker, fileAst) | ||||
|  | ||||
| 	return failures | ||||
| } | ||||
|  | ||||
| // Name returns the rule name. | ||||
| func (r *BlankImportsRule) Name() string { | ||||
| 	return "argument-limit" | ||||
| } | ||||
|  | ||||
| type lintBlankImports struct { | ||||
| 	fileAst   *ast.File | ||||
| 	file      *file.File | ||||
| 	onFailure func(rule.Failure) | ||||
| } | ||||
|  | ||||
| func (w lintBlankImports) Visit(n ast.Node) ast.Visitor { | ||||
| 	// In package main and in tests, we don't complain about blank imports. | ||||
| 	if w.fileAst.Name.Name == "main" || isTest(w.file) { | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	// The first element of each contiguous group of blank imports should have | ||||
| 	// an explanatory comment of some kind. | ||||
| 	for i, imp := range w.fileAst.Imports { | ||||
| 		pos := w.file.ToPosition(imp.Pos()) | ||||
|  | ||||
| 		if !isBlank(imp.Name) { | ||||
| 			continue // Ignore non-blank imports. | ||||
| 		} | ||||
| 		if i > 0 { | ||||
| 			prev := w.fileAst.Imports[i-1] | ||||
| 			prevPos := w.file.ToPosition(prev.Pos()) | ||||
| 			if isBlank(prev.Name) && prevPos.Line+1 == pos.Line { | ||||
| 				continue // A subsequent blank in a group. | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		// This is the first blank import of a group. | ||||
| 		if imp.Doc == nil && imp.Comment == nil { | ||||
| 			w.onFailure(rule.Failure{ | ||||
| 				Node:       imp, | ||||
| 				Failure:    "a blank import should be only in a main or test package, or have a comment justifying it", | ||||
| 				Confidence: 1, | ||||
| 			}) | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										46
									
								
								defaultrule/blank-imports_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								defaultrule/blank-imports_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | ||||
| package defaultrule | ||||
|  | ||||
| import ( | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/mgechev/revive/rule" | ||||
| 	"github.com/mgechev/revive/testutil" | ||||
| ) | ||||
|  | ||||
| func TestBlankImports(t *testing.T) { | ||||
| 	t.Parallel() | ||||
|  | ||||
| 	program := ` | ||||
| 	package foo | ||||
| 	 | ||||
| 	import ( | ||||
| 		"fmt" | ||||
| 	 | ||||
| 		/* MATCH /blank import/ */ [@f1]_ "os"[/@f1] | ||||
| 	 | ||||
| 		/* MATCH /blank import/ */ [@f2]_ "net/http"[/@f2] | ||||
| 		_ "path" | ||||
| 	) | ||||
| 	      | ||||
| 	` | ||||
| 	testutil.AssertFailures(t, program, &BlankImportsRule{}, rule.Arguments{}) | ||||
| } | ||||
|  | ||||
| func TestBlankImports_ShouldSkipMain(t *testing.T) { | ||||
| 	t.Parallel() | ||||
|  | ||||
| 	program := ` | ||||
| 	package main | ||||
| 	 | ||||
| 	import ( | ||||
| 		"fmt" | ||||
| 	 | ||||
| 		/* MATCH /blank import/ */ _ "os" | ||||
| 	 | ||||
| 		/* MATCH /blank import/ */ _ "net/http" | ||||
| 		_ "path" | ||||
| 	) | ||||
| 	      | ||||
| 	` | ||||
| 	testutil.AssertSuccess(t, program, &BlankImportsRule{}, rule.Arguments{}) | ||||
| } | ||||
| @@ -1,13 +1,18 @@ | ||||
| package defaultrule | ||||
|  | ||||
| import ( | ||||
| 	"go/ast" | ||||
| 	"strings" | ||||
|  | ||||
| 	"github.com/mgechev/revive/file" | ||||
| ) | ||||
|  | ||||
| const styleGuideBase = "https://golang.org/wiki/CodeReviewComments" | ||||
|  | ||||
| // isBlank returns whether id is the blank identifier "_". | ||||
| // If id == nil, the answer is false. | ||||
| func isBlank(id *ast.Ident) bool { return id != nil && id.Name == "_" } | ||||
|  | ||||
| func isTest(f *file.File) bool { | ||||
| 	return strings.HasSuffix(f.Name, "_test.go") | ||||
| } | ||||
|  | ||||
| const styleGuideBase = "https://golang.org/wiki/CodeReviewComments" | ||||
|   | ||||
		Reference in New Issue
	
	Block a user