@@ -56,6 +56,8 @@ inductive StyleError where
56
56
| adaptationNote
57
57
/-- A line ends with windows line endings (\r\n) instead of unix ones (\n). -/
58
58
| windowsLineEnding
59
+ /-- A line contains trailing whitespace. -/
60
+ | trailingWhitespace
59
61
deriving BEq
60
62
61
63
/-- How to format style errors -/
@@ -76,13 +78,15 @@ def StyleError.errorMessage (err : StyleError) : String := match err with
76
78
"Found the string \" Adaptation note:\" , please use the #adaptation_note command instead"
77
79
| windowsLineEnding => "This line ends with a windows line ending (\r\n ): please use Unix line\
78
80
endings (\n ) instead"
81
+ | trailingWhitespace => "This line ends with some whitespace: please remove this"
79
82
80
83
/-- The error code for a given style error. Keep this in sync with `parse?_errorContext` below! -/
81
84
-- FUTURE: we're matching the old codes in `lint-style.py` for compatibility;
82
85
-- in principle, we could also print something more readable.
83
86
def StyleError.errorCode (err : StyleError) : String := match err with
84
87
| StyleError.adaptationNote => "ERR_ADN"
85
88
| StyleError.windowsLineEnding => "ERR_WIN"
89
+ | StyleError.trailingWhitespace => "ERR_TWS"
86
90
87
91
/-- Context for a style error: the actual error, the line number in the file we're reading
88
92
and the path to the file. -/
@@ -160,6 +164,7 @@ def parse?_errorContext (line : String) : Option ErrorContext := Id.run do
160
164
-- Use default values for parameters which are ignored for comparing style exceptions.
161
165
-- NB: keep this in sync with `compare` above!
162
166
| "ERR_ADN" => some (StyleError.adaptationNote)
167
+ | "ERR_TWS" => some (StyleError.trailingWhitespace)
163
168
| "ERR_WIN" => some (StyleError.windowsLineEnding)
164
169
| _ => none
165
170
match String.toNat? lineNumber with
@@ -196,14 +201,24 @@ section
196
201
/-- Lint on any occurrences of the string "Adaptation note:" or variants thereof. -/
197
202
def adaptationNoteLinter : TextbasedLinter := fun lines ↦ Id.run do
198
203
let mut errors := Array.mkEmpty 0
199
- let mut lineNumber := 1
200
- for line in lines do
204
+ for (line, idx) in lines.zipWithIndex do
201
205
-- We make this shorter to catch "Adaptation note", "adaptation note" and a missing colon.
202
206
if line.containsSubstr "daptation note" then
203
- errors := errors.push (StyleError.adaptationNote, lineNumber)
204
- lineNumber := lineNumber + 1
207
+ errors := errors.push (StyleError.adaptationNote, idx + 1 )
205
208
return (errors, none)
206
209
210
+
211
+ /-- Lint a collection of input strings if one of them contains trailing whitespace. -/
212
+ def trailingWhitespaceLinter : TextbasedLinter := fun lines ↦ Id.run do
213
+ let mut errors := Array.mkEmpty 0
214
+ let mut fixedLines := lines
215
+ for (line, idx) in lines.zipWithIndex do
216
+ if line.back == ' ' then
217
+ errors := errors.push (StyleError.trailingWhitespace, idx + 1 )
218
+ fixedLines := fixedLines.set! idx line.trimRight
219
+ return (errors, if errors.size > 0 then some fixedLines else none)
220
+
221
+
207
222
/-- Whether a collection of lines consists *only* of imports, blank lines and single-line comments.
208
223
In practice, this means it's an imports-only file and exempt from almost all linting. -/
209
224
def isImportsOnlyFile (lines : Array String) : Bool :=
215
230
216
231
/-- All text-based linters registered in this file. -/
217
232
def allLinters : Array TextbasedLinter := #[
218
- adaptationNoteLinter
233
+ adaptationNoteLinter, trailingWhitespaceLinter
219
234
]
220
235
221
236
@@ -257,7 +272,6 @@ def lintFile (path : FilePath) (exceptions : Array ErrorContext) :
257
272
(allOutput.flatten.filter (fun e ↦ (e.find?_comparable exceptions).isNone))
258
273
return (errors, if changes_made then some changed else none)
259
274
260
-
261
275
/-- Lint a collection of modules for style violations.
262
276
Print formatted errors for all unexpected style violations to standard output;
263
277
correct automatically fixable style errors if configured so.
0 commit comments