@@ -68,7 +68,11 @@ export class CargoWatchProvider {
68
68
this . cargoProcess . stdout . on ( 'data' , ( s : string ) => {
69
69
stdoutData . processOutput ( s , line => {
70
70
this . logInfo ( line ) ;
71
- this . parseLine ( line ) ;
71
+ try {
72
+ this . parseLine ( line ) ;
73
+ } catch ( err ) {
74
+ this . logError ( `Failed to parse: ${ err } , content : ${ line } ` ) ;
75
+ }
72
76
} ) ;
73
77
} ) ;
74
78
@@ -133,79 +137,99 @@ export class CargoWatchProvider {
133
137
if ( s === 'error' ) {
134
138
return vscode . DiagnosticSeverity . Error ;
135
139
}
136
-
137
140
if ( s . startsWith ( 'warn' ) ) {
138
141
return vscode . DiagnosticSeverity . Warning ;
139
142
}
140
-
141
143
return vscode . DiagnosticSeverity . Information ;
142
144
}
143
145
144
- interface ErrorSpan {
146
+ // Reference:
147
+ // https://github.com/rust-lang/rust/blob/master/src/libsyntax/json.rs
148
+ interface RustDiagnosticSpan {
145
149
line_start : number ;
146
150
line_end : number ;
147
151
column_start : number ;
148
152
column_end : number ;
153
+ is_primary : boolean ;
154
+ file_name : string ;
149
155
}
150
156
151
- interface ErrorMessage {
152
- reason : string ;
153
- message : {
154
- spans : ErrorSpan [ ] ;
155
- rendered : string ;
156
- level : string ;
157
- code ?: {
158
- code : string ;
159
- } ;
157
+ interface RustDiagnostic {
158
+ spans : RustDiagnosticSpan [ ] ;
159
+ rendered : string ;
160
+ level : string ;
161
+ code ?: {
162
+ code : string ;
160
163
} ;
161
164
}
162
165
166
+ interface CargoArtifact {
167
+ reason : string ;
168
+ package_id : string ;
169
+ }
170
+
171
+ // https://github.com/rust-lang/cargo/blob/master/src/cargo/util/machine_message.rs
172
+ interface CargoMessage {
173
+ reason : string ;
174
+ package_id : string ;
175
+ message : RustDiagnostic ;
176
+ }
177
+
163
178
// cargo-watch itself output non json format
164
179
// Ignore these lines
165
- let data : ErrorMessage ;
180
+ let data : CargoMessage ;
166
181
try {
167
182
data = JSON . parse ( line . trim ( ) ) ;
168
183
} catch ( error ) {
169
- this . logError ( `Fail to pass to json : { ${ error } }` ) ;
184
+ this . logError ( `Fail to parse to json : { ${ error } }` ) ;
170
185
return ;
171
186
}
172
187
173
- // Only handle compiler-message now
174
- if ( data . reason !== 'compiler-message' ) {
175
- return ;
176
- }
188
+ if ( data . reason === 'compiler-artifact' ) {
189
+ const msg = data as CargoArtifact ;
177
190
178
- let spans : any [ ] = data . message . spans ;
179
- spans = spans . filter ( o => o . is_primary ) ;
191
+ // The format of the package_id is "{name} {version} ({source_id})",
192
+ // https://github.com/rust-lang/cargo/blob/37ad03f86e895bb80b474c1c088322634f4725f5/src/cargo/core/package_id.rs#L53
193
+ this . statusDisplay ! . packageName = msg . package_id . split ( ' ' ) [ 0 ] ;
194
+ } else if ( data . reason === 'compiler-message' ) {
195
+ const msg = data . message as RustDiagnostic ;
180
196
181
- // We only handle primary span right now.
182
- if ( spans . length > 0 ) {
183
- const o = spans [ 0 ] ;
197
+ const spans = msg . spans . filter ( o => o . is_primary ) ;
184
198
185
- const rendered = data . message . rendered ;
186
- const level = getLevel ( data . message . level ) ;
187
- const range = new vscode . Range (
188
- new vscode . Position ( o . line_start - 1 , o . column_start - 1 ) ,
189
- new vscode . Position ( o . line_end - 1 , o . column_end - 1 )
190
- ) ;
199
+ // We only handle primary span right now.
200
+ if ( spans . length > 0 ) {
201
+ const o = spans [ 0 ] ;
202
+
203
+ const rendered = msg . rendered ;
204
+ const level = getLevel ( msg . level ) ;
205
+ const range = new vscode . Range (
206
+ new vscode . Position ( o . line_start - 1 , o . column_start - 1 ) ,
207
+ new vscode . Position ( o . line_end - 1 , o . column_end - 1 )
208
+ ) ;
191
209
192
- const fileName = path . join ( vscode . workspace . rootPath ! , o . file_name ) ;
193
- const diagnostic = new vscode . Diagnostic ( range , rendered , level ) ;
210
+ const fileName = path . join (
211
+ vscode . workspace . rootPath ! ,
212
+ o . file_name
213
+ ) ;
214
+ const diagnostic = new vscode . Diagnostic (
215
+ range ,
216
+ rendered ,
217
+ level
218
+ ) ;
194
219
195
- diagnostic . source = 'rustc' ;
196
- diagnostic . code = data . message . code
197
- ? data . message . code . code
198
- : undefined ;
199
- diagnostic . relatedInformation = [ ] ;
220
+ diagnostic . source = 'rustc' ;
221
+ diagnostic . code = msg . code ? msg . code . code : undefined ;
222
+ diagnostic . relatedInformation = [ ] ;
200
223
201
- const fileUrl = vscode . Uri . file ( fileName ! ) ;
224
+ const fileUrl = vscode . Uri . file ( fileName ! ) ;
202
225
203
- const diagnostics : vscode . Diagnostic [ ] = [
204
- ...( this . diagnosticCollection ! . get ( fileUrl ) || [ ] )
205
- ] ;
206
- diagnostics . push ( diagnostic ) ;
226
+ const diagnostics : vscode . Diagnostic [ ] = [
227
+ ...( this . diagnosticCollection ! . get ( fileUrl ) || [ ] )
228
+ ] ;
229
+ diagnostics . push ( diagnostic ) ;
207
230
208
- this . diagnosticCollection ! . set ( fileUrl , diagnostics ) ;
231
+ this . diagnosticCollection ! . set ( fileUrl , diagnostics ) ;
232
+ }
209
233
}
210
234
}
211
235
}
0 commit comments