1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
|
package main
// When files are read in by pkglint, they are interpreted in terms of
// lines. For Makefiles, line continuations are handled properly, allowing
// multiple raw lines to end in a single logical line. For other files
// there is a 1:1 translation.
//
// A difference between the raw and the logical lines is that the
// raw lines include the line end sequence, whereas the logical lines
// do not.
//
// Some methods allow modification of the raw lines contained in the
// logical line, but leave the “text” field untouched. These methods are
// used in the --autofix mode.
import (
"fmt"
"io"
"strings"
)
type RawLine struct {
lineno int
textnl string
}
func (rline *RawLine) String() string {
return sprintf("%d:%s", rline.lineno, rline.textnl)
}
type Line struct {
fname string
lines string
text string
raw []*RawLine
changed bool
before []*RawLine
after []*RawLine
extra map[string]interface{}
}
func NewLine(fname, linenos, text string, rawLines []*RawLine) *Line {
return &Line{fname, linenos, text, rawLines, false, nil, nil, make(map[string]interface{})}
}
func (self *Line) rawLines() []*RawLine {
return append(self.before, append(self.raw, self.after...)...)
}
func (self *Line) printSource(out io.Writer) {
if G.opts.PrintSource {
io.WriteString(out, "\n")
for _, rawLine := range self.rawLines() {
fmt.Fprintf(out, "> %s", rawLine.textnl)
}
}
}
func (self *Line) fatalf(format string, args ...interface{}) bool {
self.printSource(G.logErr)
return fatalf(self.fname, self.lines, format, args...)
}
func (self *Line) errorf(format string, args ...interface{}) bool {
self.printSource(G.logOut)
return errorf(self.fname, self.lines, format, args...)
}
func (self *Line) warnf(format string, args ...interface{}) bool {
self.printSource(G.logOut)
return warnf(self.fname, self.lines, format, args...)
}
func (self *Line) notef(format string, args ...interface{}) bool {
self.printSource(G.logOut)
return notef(self.fname, self.lines, format, args...)
}
func (self *Line) debugf(format string, args ...interface{}) bool {
self.printSource(G.logOut)
return debugf(self.fname, self.lines, format, args...)
}
func (self *Line) explain(explanation ...string) {
if G.opts.Explain {
complete := strings.Join(explanation, "\n")
if G.explanationsGiven[complete] {
return
}
if G.explanationsGiven == nil {
G.explanationsGiven = make(map[string]bool)
G.explanationsGiven[complete] = true
}
io.WriteString(G.logOut, "\n")
for _, explanationLine := range explanation {
io.WriteString(G.logOut, "\t"+explanationLine+"\n")
}
io.WriteString(G.logOut, "\n")
}
G.explanationsAvailable = true
}
func (self *Line) String() string {
return self.fname + ":" + self.lines + ": " + self.text
}
func (self *Line) insertBefore(line string) {
self.before = append(self.before, &RawLine{0, line + "\n"})
self.changed = true
if G.opts.PrintAutofix {
self.notef("Autofix: inserting a line %q before this line.", line)
}
}
func (self *Line) insertAfter(line string) {
self.after = append(self.after, &RawLine{0, line + "\n"})
self.changed = true
if G.opts.PrintAutofix {
self.notef("Autofix: inserting a line %q after this line.", line)
}
}
func (self *Line) delete() {
self.raw = nil
self.changed = true
}
func (self *Line) replace(from, to string) {
for _, rawLine := range self.raw {
if rawLine.lineno != 0 {
if replaced := strings.Replace(rawLine.textnl, from, to, 1); replaced != rawLine.textnl {
rawLine.textnl = replaced
self.changed = true
if G.opts.PrintAutofix {
self.notef("Autofix: replacing %q with %q.", from, to)
}
G.autofixAvailable = true
}
}
}
}
func (self *Line) replaceRegex(from, to string) {
for _, rawLine := range self.raw {
if rawLine.lineno != 0 {
if replaced := regcomp(from).ReplaceAllString(rawLine.textnl, to); replaced != rawLine.textnl {
rawLine.textnl = replaced
self.changed = true
if G.opts.PrintAutofix {
self.notef("Autofix: replacing regular expression %q with %q.", from, to)
}
G.autofixAvailable = true
}
}
}
}
|