1
1
package printers
2
2
3
3
import (
4
- "bytes"
5
4
"context"
6
5
"fmt"
7
- "io/ioutil"
8
- "time"
9
6
10
7
"github.com/fatih/color"
11
8
"github.com/golangci/golangci-lint/pkg/logutils"
12
9
"github.com/golangci/golangci-lint/pkg/result"
13
10
)
14
11
15
- type linesCache [][]byte
16
- type filesCache map [string ]linesCache
17
-
18
12
type Text struct {
19
13
printIssuedLine bool
20
14
useColors bool
21
15
printLinterName bool
22
16
23
- cache filesCache
24
- log logutils.Log
17
+ log logutils.Log
25
18
}
26
19
27
20
func NewText (printIssuedLine , useColors , printLinterName bool , log logutils.Log ) * Text {
28
21
return & Text {
29
22
printIssuedLine : printIssuedLine ,
30
23
useColors : useColors ,
31
24
printLinterName : printLinterName ,
32
- cache : filesCache {},
33
25
log : log ,
34
26
}
35
27
}
@@ -43,56 +35,19 @@ func (p Text) SprintfColored(ca color.Attribute, format string, args ...interfac
43
35
return c .Sprintf (format , args ... )
44
36
}
45
37
46
- func (p * Text ) getFileLinesForIssue (i * result.Issue ) (linesCache , error ) {
47
- fc := p .cache [i .FilePath ()]
48
- if fc != nil {
49
- return fc , nil
50
- }
51
-
52
- // TODO: make more optimal algorithm: don't load all files into memory
53
- fileBytes , err := ioutil .ReadFile (i .FilePath ())
54
- if err != nil {
55
- return nil , fmt .Errorf ("can't read file %s for printing issued line: %s" , i .FilePath (), err )
56
- }
57
- lines := bytes .Split (fileBytes , []byte ("\n " )) // TODO: what about \r\n?
58
- fc = lines
59
- p .cache [i .FilePath ()] = fc
60
- return fc , nil
61
- }
62
-
63
- func (p * Text ) Print (ctx context.Context , issues <- chan result.Issue ) (bool , error ) {
64
- var issuedLineExtractingDuration time.Duration
65
- defer func () {
66
- p .log .Infof ("Extracting issued lines took %s" , issuedLineExtractingDuration )
67
- }()
68
-
69
- issuesN := 0
38
+ func (p * Text ) Print (ctx context.Context , issues <- chan result.Issue ) error {
70
39
for i := range issues {
71
- issuesN ++
72
40
p .printIssue (& i )
73
41
74
42
if ! p .printIssuedLine {
75
43
continue
76
44
}
77
45
78
- startedAt := time .Now ()
79
- lines , err := p .getFileLinesForIssue (& i )
80
- if err != nil {
81
- return false , err
82
- }
83
- issuedLineExtractingDuration += time .Since (startedAt )
84
-
85
- p .printIssuedLines (& i , lines )
86
- if i .Line ()- 1 < len (lines ) {
87
- p .printUnderLinePointer (& i , string (lines [i .Line ()- 1 ]))
88
- }
89
- }
90
-
91
- if issuesN != 0 {
92
- p .log .Infof ("Found %d issues" , issuesN )
46
+ p .printSourceCode (& i )
47
+ p .printUnderLinePointer (& i )
93
48
}
94
49
95
- return issuesN != 0 , nil
50
+ return nil
96
51
}
97
52
98
53
func (p Text ) printIssue (i * result.Issue ) {
@@ -107,32 +62,19 @@ func (p Text) printIssue(i *result.Issue) {
107
62
fmt .Fprintf (logutils .StdOut , "%s: %s\n " , pos , text )
108
63
}
109
64
110
- func (p Text ) printIssuedLines (i * result.Issue , lines linesCache ) {
111
- lineRange := i .GetLineRange ()
112
- var lineStr string
113
- for line := lineRange .From ; line <= lineRange .To ; line ++ {
114
- if line == 0 { // some linters, e.g. gas can do it: it really means first line
115
- line = 1
116
- }
117
-
118
- zeroIndexedLine := line - 1
119
- if zeroIndexedLine >= len (lines ) {
120
- p .log .Warnf ("No line %d in file %s" , line , i .FilePath ())
121
- break
122
- }
123
-
124
- lineStr = string (bytes .Trim (lines [zeroIndexedLine ], "\r " ))
125
- fmt .Fprintln (logutils .StdOut , lineStr )
65
+ func (p Text ) printSourceCode (i * result.Issue ) {
66
+ for _ , line := range i .SourceLines {
67
+ fmt .Fprintln (logutils .StdOut , line )
126
68
}
127
69
}
128
70
129
- func (p Text ) printUnderLinePointer (i * result.Issue , line string ) {
130
- lineRange := i .GetLineRange ()
131
- if lineRange .From != lineRange .To || i .Pos .Column == 0 {
71
+ func (p Text ) printUnderLinePointer (i * result.Issue ) {
72
+ if len (i .SourceLines ) != 1 || i .Pos .Column == 0 {
132
73
return
133
74
}
134
75
135
76
col0 := i .Pos .Column - 1
77
+ line := i .SourceLines [0 ]
136
78
prefixRunes := make ([]rune , 0 , len (line ))
137
79
for j := 0 ; j < len (line ) && j < col0 ; j ++ {
138
80
if line [j ] == '\t' {
0 commit comments