@@ -71,6 +71,8 @@ inductive StyleError where
71
71
| fileTooLong (numberLines : ℕ) (newSizeLimit : ℕ) (previousLimit : Option ℕ) : StyleError
72
72
/-- A line ends with windows line endings (\r\n) instead of unix ones (\n). -/
73
73
| windowsLineEnding
74
+ /-- A line contains trailing whitespace -/
75
+ | trailingWhitespace
74
76
deriving BEq
75
77
76
78
/-- How to format style errors -/
@@ -111,6 +113,7 @@ def StyleError.errorMessage (err : StyleError) (style : ErrorFormat) : String :=
111
113
| ErrorFormat.humanReadable => s! "file contains { currentSize} lines, try to split it up"
112
114
| windowsLineEnding => "This line ends with a windows line ending (\r\n ): please use Unix line\
113
115
endings (\n ) instead"
116
+ | trailingWhitespace => "This line ends with some whitespace: please remove this"
114
117
115
118
/-- The error code for a given style error. Keep this in sync with `parse?_errorContext` below! -/
116
119
-- FUTURE: we're matching the old codes in `lint-style.py` for compatibility;
@@ -122,6 +125,7 @@ def StyleError.errorCode (err : StyleError) : String := match err with
122
125
| StyleError.broadImport _ => "ERR_IMP"
123
126
| StyleError.fileTooLong _ _ _ => "ERR_NUM_LIN"
124
127
| StyleError.windowsLineEnding => "ERR_WIN"
128
+ | StyleError.trailingWhitespace => "ERR_TWS"
125
129
126
130
/-- Context for a style error: the actual error, the line number in the file we're reading
127
131
and the path to the file. -/
@@ -216,6 +220,7 @@ def parse?_errorContext (line : String) : Option ErrorContext := Id.run do
216
220
| "ERR_COP" => some (StyleError.copyright none)
217
221
| "ERR_AUT" => some (StyleError.authors)
218
222
| "ERR_ADN" => some (StyleError.adaptationNote)
223
+ | "ERR_TWS" => some (StyleError.trailingWhitespace)
219
224
| "ERR_WIN" => some (StyleError.windowsLineEnding)
220
225
| "ERR_IMP" =>
221
226
-- XXX tweak exceptions messages to ease parsing?
@@ -363,6 +368,21 @@ def windowsLineEndingLinter : TextbasedLinter := fun lines ↦ Id.run do
363
368
lineNumber := lineNumber + 1
364
369
return (errors, fixedLines)
365
370
371
+
372
+ /-- Lint a collection of input strings if one of them contains trailing whitespace. -/
373
+ def trailingWhitespaceLinter : TextbasedLinter := fun lines ↦ Id.run do
374
+ let mut errors := Array.mkEmpty 0
375
+ let mut fixedLines := lines
376
+ -- invariant: this equals the current index of 'line' in 'lines',
377
+ -- hence starts at 0 and is incremented *at the end* of the loop
378
+ let mut lineNumber := 0
379
+ for line in lines do
380
+ if line.back == ' ' then
381
+ errors := errors.push (StyleError.trailingWhitespace, lineNumber)
382
+ fixedLines := fixedLines.set! 0 (line.dropRightWhile (· == ' ' ))
383
+ lineNumber := lineNumber + 1
384
+ return (errors, fixedLines)
385
+
366
386
/-- Whether a collection of lines consists *only* of imports, blank lines and single-line comments.
367
387
In practice, this means it's an imports-only file and exempt from almost all linting. -/
368
388
def isImportsOnlyFile (lines : Array String) : Bool :=
395
415
396
416
/-- All text-based linters registered in this file. -/
397
417
def allLinters : Array TextbasedLinter := #[
398
- copyrightHeaderLinter, adaptationNoteLinter, broadImportsLinter, windowsLineEndingLinter
418
+ copyrightHeaderLinter, adaptationNoteLinter, broadImportsLinter,
419
+ windowsLineEndingLinter, trailingWhitespaceLinter
399
420
]
400
421
401
422
/-- Controls what kind of output this programme produces. -/
0 commit comments