mirror of
				https://github.com/mgechev/revive.git
				synced 2025-10-30 23:37:49 +02:00 
			
		
		
		
	Fix #245 File header rule: index out of range [0] with length 0
This commit is contained in:
		
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,3 +1,4 @@ | ||||
| .idea | ||||
| golinter | ||||
| revive | ||||
| vendor | ||||
|   | ||||
							
								
								
									
										1
									
								
								fixtures/lint-file-header6.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								fixtures/lint-file-header6.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| package fixtures // MATCH /the file doesn't have an appropriate header/ | ||||
| @@ -51,25 +51,34 @@ type lintFileHeader struct { | ||||
| 	onFailure func(lint.Failure) | ||||
| } | ||||
|  | ||||
| var ( | ||||
| 	multiRegexp  = regexp.MustCompile("^/\\*") | ||||
| 	singleRegexp = regexp.MustCompile("^//") | ||||
| ) | ||||
|  | ||||
| func (w lintFileHeader) Visit(_ ast.Node) ast.Visitor { | ||||
| 	g := w.fileAst.Comments[0] | ||||
| 	failure := lint.Failure{ | ||||
| 		Node:       w.fileAst, | ||||
| 		Confidence: 1, | ||||
| 		Failure:    "the file doesn't have an appropriate header", | ||||
| 	} | ||||
|  | ||||
| 	if len(w.fileAst.Comments) == 0 { | ||||
| 		w.onFailure(failure) | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	g := w.fileAst.Comments[0] | ||||
| 	if g == nil { | ||||
| 		w.onFailure(failure) | ||||
| 		return nil | ||||
| 	} | ||||
| 	multi := regexp.MustCompile("^/\\*") | ||||
| 	single := regexp.MustCompile("^//") | ||||
| 	comment := "" | ||||
| 	for _, c := range g.List { | ||||
| 		text := c.Text | ||||
| 		if multi.Match([]byte(text)) { | ||||
| 		if multiRegexp.Match([]byte(text)) { | ||||
| 			text = text[2 : len(text)-2] | ||||
| 		} else if single.Match([]byte(text)) { | ||||
| 		} else if singleRegexp.Match([]byte(text)) { | ||||
| 			text = text[2:] | ||||
| 		} | ||||
| 		comment += text | ||||
|   | ||||
| @@ -27,4 +27,20 @@ func TestLintFileHeader(t *testing.T) { | ||||
| 	testRule(t, "lint-file-header5", &rule.FileHeaderRule{}, &lint.RuleConfig{ | ||||
| 		Arguments: []interface{}{"^\\sfoo.*bar$"}, | ||||
| 	}) | ||||
|  | ||||
| 	testRule(t, "lint-file-header6", &rule.FileHeaderRule{}, &lint.RuleConfig{ | ||||
| 		Arguments: []interface{}{"foobar"}, | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func BenchmarkLintFileHeader(b *testing.B) { | ||||
| 	benchRule(b, "lint-file-header1", &rule.FileHeaderRule{}, &lint.RuleConfig{ | ||||
| 		Arguments: []interface{}{"foobar"}, | ||||
| 	}) | ||||
| 	//var t *testing.T | ||||
| 	//for i := 0; i <= b.N; i++ { | ||||
| 	//	testRule(t, "lint-file-header1", &rule.FileHeaderRule{}, &lint.RuleConfig{ | ||||
| 	//		Arguments: []interface{}{"foobar"}, | ||||
| 	//	}) | ||||
| 	//} | ||||
| } | ||||
|   | ||||
| @@ -17,10 +17,7 @@ func TestImportsBlacklist(t *testing.T) { | ||||
|  | ||||
| func BenchmarkImportsBlacklist(b *testing.B) { | ||||
| 	args := []interface{}{"crypto/md5", "crypto/sha1"} | ||||
| 	var t *testing.T | ||||
| 	for i := 0; i <= b.N; i++ { | ||||
| 		testRule(t, "imports-blacklist", &rule.ImportsBlacklistRule{}, &lint.RuleConfig{ | ||||
| 			Arguments: args, | ||||
| 		}) | ||||
| 	} | ||||
| 	benchRule(b, "imports-blacklist", &rule.ImportsBlacklistRule{}, &lint.RuleConfig{ | ||||
| 		Arguments: args, | ||||
| 	}) | ||||
| } | ||||
|   | ||||
| @@ -11,8 +11,5 @@ func TestUnusedParam(t *testing.T) { | ||||
| } | ||||
|  | ||||
| func BenchmarkUnusedParam(b *testing.B) { | ||||
| 	var t *testing.T | ||||
| 	for i := 0; i <= b.N; i++ { | ||||
| 		testRule(t, "unused-param", &rule.UnusedParamRule{}) | ||||
| 	} | ||||
| 	benchRule(b, "unused-param", &rule.UnusedParamRule{}) | ||||
| } | ||||
|   | ||||
| @@ -6,7 +6,6 @@ import ( | ||||
| 	"fmt" | ||||
| 	"go/ast" | ||||
| 	"go/parser" | ||||
| 	"go/printer" | ||||
| 	"go/token" | ||||
| 	"go/types" | ||||
| 	"io/ioutil" | ||||
| @@ -19,14 +18,42 @@ import ( | ||||
| 	"github.com/pkg/errors" | ||||
| ) | ||||
|  | ||||
| const fixtureBasePath = "../fixtures/" | ||||
|  | ||||
| func benchRule(b *testing.B, filename string, rule lint.Rule, config ...*lint.RuleConfig) { | ||||
| 	fixturePath := fixtureBasePath + filename + ".go" | ||||
| 	stat, err := os.Stat(fixturePath) | ||||
| 	if err != nil { | ||||
| 		b.Fatalf("Cannot get file info for %s: %v", rule.Name(), err) | ||||
| 	} | ||||
| 	c := map[string]lint.RuleConfig{} | ||||
| 	if config != nil { | ||||
| 		c[rule.Name()] = *config[0] | ||||
| 	} | ||||
|  | ||||
| 	l := lint.New(func(file string) ([]byte, error) { | ||||
| 		return ioutil.ReadFile(fixtureBasePath + file) | ||||
| 	}) | ||||
|  | ||||
| 	for i := 0; i < b.N; i++ { | ||||
| 		ps, err := l.Lint([][]string{{stat.Name()}}, []lint.Rule{rule}, lint.Config{ | ||||
| 			Rules: c, | ||||
| 		}) | ||||
| 		if err != nil { | ||||
| 			b.Fatalf("Unexpected error: %s", err) | ||||
| 		} | ||||
| 		for range ps { | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func testRule(t *testing.T, filename string, rule lint.Rule, config ...*lint.RuleConfig) { | ||||
| 	baseDir := "../fixtures/" | ||||
| 	filename = filename + ".go" | ||||
| 	src, err := ioutil.ReadFile(baseDir + filename) | ||||
| 	fixturePath := fixtureBasePath + filename + ".go" | ||||
| 	src, err := ioutil.ReadFile(fixturePath) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("Bad filename path in test for %s: %v", rule.Name(), err) | ||||
| 	} | ||||
| 	stat, err := os.Stat(baseDir + filename) | ||||
| 	stat, err := os.Stat(fixturePath) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("Cannot get file info for %s: %v", rule.Name(), err) | ||||
| 	} | ||||
| @@ -35,10 +62,16 @@ func testRule(t *testing.T, filename string, rule lint.Rule, config ...*lint.Rul | ||||
| 		c[rule.Name()] = *config[0] | ||||
| 	} | ||||
| 	if parseInstructions(t, filename, src) == nil { | ||||
| 		assertSuccess(t, baseDir, stat, []lint.Rule{rule}, c) | ||||
| 		err := assertSuccess(t, fixtureBasePath, stat, []lint.Rule{rule}, c) | ||||
| 		if err != nil { | ||||
| 			t.Fatalf("Cannot invoke 'assertSuccess' for %s: %v", rule.Name(), err) | ||||
| 		} | ||||
| 		return | ||||
| 	} | ||||
| 	assertFailures(t, baseDir, stat, src, []lint.Rule{rule}, c) | ||||
| 	err = assertFailures(t, fixtureBasePath, stat, src, []lint.Rule{rule}, c) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("Cannot invoke 'assertFailures' for %s: %v", rule.Name(), err) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func assertSuccess(t *testing.T, baseDir string, fi os.FileInfo, rules []lint.Rule, config map[string]lint.RuleConfig) error { | ||||
| @@ -46,7 +79,7 @@ func assertSuccess(t *testing.T, baseDir string, fi os.FileInfo, rules []lint.Ru | ||||
| 		return ioutil.ReadFile(baseDir + file) | ||||
| 	}) | ||||
|  | ||||
| 	ps, err := l.Lint([][]string{[]string{fi.Name()}}, rules, lint.Config{ | ||||
| 	ps, err := l.Lint([][]string{{fi.Name()}}, rules, lint.Config{ | ||||
| 		Rules: config, | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| @@ -73,7 +106,7 @@ func assertFailures(t *testing.T, baseDir string, fi os.FileInfo, src []byte, ru | ||||
| 		return errors.Errorf("Test file %v does not have instructions", fi.Name()) | ||||
| 	} | ||||
|  | ||||
| 	ps, err := l.Lint([][]string{[]string{fi.Name()}}, rules, lint.Config{ | ||||
| 	ps, err := l.Lint([][]string{{fi.Name()}}, rules, lint.Config{ | ||||
| 		Rules: config, | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| @@ -200,14 +233,6 @@ func extractReplacement(line string) (string, bool) { | ||||
| 	return line[a+len(start) : b], true | ||||
| } | ||||
|  | ||||
| func render(fset *token.FileSet, x interface{}) string { | ||||
| 	var buf bytes.Buffer | ||||
| 	if err := printer.Fprint(&buf, fset, x); err != nil { | ||||
| 		panic(err) | ||||
| 	} | ||||
| 	return buf.String() | ||||
| } | ||||
|  | ||||
| func srcLine(src []byte, p token.Position) string { | ||||
| 	// Run to end of line in both directions if not at line start/end. | ||||
| 	lo, hi := p.Offset, p.Offset+1 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user