1
1
XRegExp = require ' xregexp'
2
- sb_exec = require ' sb-exec'
3
2
path = require ' path'
3
+ atom_linter = require ' atom-linter'
4
+ CachedResult = require ' ./cached_result'
4
5
5
6
pattern = XRegExp (' (?<file>[^\n\r ]+):(?<from_line>\\ d+):(?<from_col>\\ d+):\\ s*\
6
7
(?<to_line>\\ d+):(?<to_col>\\ d+)\\ s+\
7
8
((?<error>error|fatal error)|(?<warning>warning)|(?<info>note|help)):\\ s+\
8
9
(?<message>.+?)[\n\r ]+($|(?=[^\n\r ]+:\\ d+))' , ' s' )
9
10
10
- parseOldMessages = (output , disabledWarnings ) ->
11
+ parseOldMessages = (output , { disabledWarnings, textEditor} ) ->
11
12
elements = []
12
13
XRegExp .forEach output, pattern, (match ) ->
13
- if match .from_col == match .to_col
14
- match .to_col = parseInt (match .to_col ) + 1
15
- range = [
16
- [match .from_line - 1 , match .from_col - 1 ],
17
- [match .to_line - 1 , match .to_col - 1 ]
18
- ]
14
+ range = if match .from_col == match .to_col and match .from_line == match .to_line
15
+ atom_linter .rangeFromLineNumber (textEditor, Number .parseInt (match .from_line , 10 ) - 1 , Number .parseInt (match .from_col , 10 ) - 1 )
16
+ else
17
+ [
18
+ [match .from_line - 1 , match .from_col - 1 ],
19
+ [match .to_line - 1 , match .to_col - 1 ]
20
+ ]
19
21
level = if match .error then ' error'
20
22
else if match .warning then ' warning'
21
23
else if match .info then ' info'
@@ -29,7 +31,7 @@ parseOldMessages = (output, disabledWarnings) ->
29
31
elements .push element
30
32
buildMessages elements, disabledWarnings
31
33
32
- parseJsonMessages = (messages , disabledWarnings ) ->
34
+ parseJsonMessages = (messages , { disabledWarnings} ) ->
33
35
elements = []
34
36
for input in messages
35
37
continue unless input and input .spans
@@ -39,7 +41,7 @@ parseJsonMessages = (messages, disabledWarnings) ->
39
41
[primary_span .line_start - 1 , primary_span .column_start - 1 ],
40
42
[primary_span .line_end - 1 , primary_span .column_end - 1 ]
41
43
]
42
- input .level = ' error' if input == ' fatal error'
44
+ input .level = ' error' if input . level == ' fatal error'
43
45
element =
44
46
type : input .level
45
47
message : input .message
@@ -57,13 +59,17 @@ parseJsonMessages = (messages, disabledWarnings) ->
57
59
elements .push element
58
60
buildMessages elements, disabledWarnings
59
61
60
- parseJsonOutput = (output , disabledWarnings ) ->
62
+ parseJsonOutput = (output , { disabledWarnings, additionalFilter} ) ->
61
63
results = output .split (' \n ' ).map (message) ->
62
64
message = message .trim ()
63
65
if message .startsWith ' {'
64
- JSON .parse message
66
+ json = JSON .parse message
67
+ if additionalFilter?
68
+ additionalFilter (json)
69
+ else
70
+ json
65
71
.filter (m) -> m?
66
- parseJsonMessages results, disabledWarnings
72
+ parseJsonMessages results, { disabledWarnings}
67
73
68
74
buildMessages = (elements , disabledWarnings ) ->
69
75
messages = []
@@ -134,7 +140,36 @@ buildRustcArguments = (linter, paths) ->
134
140
cmd = cmd .concat [editingFile]
135
141
[editingFile, cmd]
136
142
143
+ cachedUsingMultitoolForClippy = null
144
+
137
145
buildCargoArguments = (linter , cargoManifestPath ) ->
146
+ buildCargoPath = (cargoPath , cargoCommand ) ->
147
+ # the result is cached to avoid delays
148
+ if cachedUsingMultitoolForClippy? and do cachedUsingMultitoolForClippy .valid
149
+ Promise .resolve ().then () =>
150
+ do cachedUsingMultitoolForClippy .getResult
151
+ else
152
+ # Decide if should use older multirust or newer rustup
153
+ usingMultitoolForClippy =
154
+ atom_linter .exec ' rustup' , [' --version' ], {ignoreExitCode : true }
155
+ .then ->
156
+ result : true , tool : ' rustup'
157
+ .catch ->
158
+ # Try to use older multirust at least
159
+ atom_linter .exec ' multirust' , [' --version' ], {ignoreExitCode : true }
160
+ .then ->
161
+ result : true , tool : ' multirust'
162
+ .catch ->
163
+ result : false
164
+ usingMultitoolForClippy .then (canUseMultirust) ->
165
+ if cargoCommand == ' clippy' and canUseMultirust .result
166
+ [canUseMultirust .tool , ' run' , ' nightly' , ' cargo' ]
167
+ else
168
+ [cargoPath]
169
+ .then (cached) =>
170
+ cachedUsingMultitoolForClippy = new CachedResult (cached, 20 )
171
+ cached
172
+
138
173
cargoArgs = switch linter .cargoCommand
139
174
when ' check' then [' check' ]
140
175
when ' test' then [' test' , ' --no-run' ]
@@ -143,42 +178,22 @@ buildCargoArguments = (linter, cargoManifestPath) ->
143
178
else [' build' ]
144
179
145
180
compilationFeatures = linter .compilationFeatures (true )
146
- buildCargoPath (linter .cargoPath ).then (cmd) ->
181
+ buildCargoPath (linter .cargoPath , linter . cargoCommand ).then (cmd) ->
147
182
cmd = cmd
148
183
.concat cargoArgs
149
184
.concat [' -j' , linter .jobsNumber ]
150
185
cmd = cmd .concat compilationFeatures if compilationFeatures
151
186
cmd = cmd .concat [' --manifest-path' , cargoManifestPath]
152
187
[cargoManifestPath, cmd]
153
188
154
- buildCargoPath = (cargoPath , cargoCommand ) ->
155
- usingMultitoolForClippy ().then (canUseMultirust) ->
156
- if cargoCommand == ' clippy' and canUseMultirust .result
157
- [canUseMultirust .tool , ' run' , ' nightly' , ' cargo' ]
158
- else
159
- [cargoPath]
160
-
161
- usingMultitoolForClippy = () ->
162
- # Try to use rustup
163
- sb_exec .exec ' rustup' , [' --version' ], {ignoreExitCode : true }
164
- .then ->
165
- result : true , tool : ' rustup'
166
- .catch ->
167
- # Try to use odler multirust at least
168
- sb_exec .exec ' multirust' , [' --version' ], {ignoreExitCode : true }
169
- .then ->
170
- result : true , tool : ' multirust'
171
- .catch ->
172
- result : false
173
-
174
189
# These define the behabiour of each error mode linter-rust has
175
190
errorModes =
176
191
JSON_RUSTC :
177
192
neededOutput : (stdout , stderr ) ->
178
193
stderr
179
194
180
- parse : (output , disabledWarnings ) =>
181
- parseJsonOutput output, disabledWarnings
195
+ parse : (output , options ) =>
196
+ parseJsonOutput output, options
182
197
183
198
buildArguments : (linter , file ) ->
184
199
buildRustcArguments (linter, file).then (cmd_res) ->
@@ -190,16 +205,11 @@ errorModes =
190
205
neededOutput : (stdout , stderr ) ->
191
206
stdout
192
207
193
- parse : (output , disabledWarnings ) ->
194
- checkCompilerMessage = (message ) ->
195
- message = message .trim ()
196
- if message .startsWith ' {'
197
- input = JSON .parse message
198
- input .message if input? and input .reason == " compiler-message"
199
-
200
- results = output .split ' \n '
201
- results = results .map (checkCompilerMessage).filter ((i ) -> i? )
202
- parseJsonMessages results, disabledWarnings
208
+ parse : (output , options ) ->
209
+ options .additionalFilter = (json ) ->
210
+ if input? and input .reason == " compiler-message"
211
+ input .message
212
+ parseJsonOutput output, options
203
213
204
214
buildArguments : (linter , file ) ->
205
215
buildCargoArguments (linter, file).then (cmd_res) ->
0 commit comments