diff options
Diffstat (limited to 'editors/code')
-rw-r--r-- | editors/code/src/commands/cargo_watch.ts | 110 | ||||
-rw-r--r-- | editors/code/src/commands/watch_status.ts | 12 |
2 files changed, 78 insertions, 44 deletions
diff --git a/editors/code/src/commands/cargo_watch.ts b/editors/code/src/commands/cargo_watch.ts index 6d8e4d885..d45d0e7d1 100644 --- a/editors/code/src/commands/cargo_watch.ts +++ b/editors/code/src/commands/cargo_watch.ts | |||
@@ -68,7 +68,11 @@ export class CargoWatchProvider { | |||
68 | this.cargoProcess.stdout.on('data', (s: string) => { | 68 | this.cargoProcess.stdout.on('data', (s: string) => { |
69 | stdoutData.processOutput(s, line => { | 69 | stdoutData.processOutput(s, line => { |
70 | this.logInfo(line); | 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 | if (s === 'error') { | 137 | if (s === 'error') { |
134 | return vscode.DiagnosticSeverity.Error; | 138 | return vscode.DiagnosticSeverity.Error; |
135 | } | 139 | } |
136 | |||
137 | if (s.startsWith('warn')) { | 140 | if (s.startsWith('warn')) { |
138 | return vscode.DiagnosticSeverity.Warning; | 141 | return vscode.DiagnosticSeverity.Warning; |
139 | } | 142 | } |
140 | |||
141 | return vscode.DiagnosticSeverity.Information; | 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 | line_start: number; | 149 | line_start: number; |
146 | line_end: number; | 150 | line_end: number; |
147 | column_start: number; | 151 | column_start: number; |
148 | column_end: number; | 152 | column_end: number; |
153 | is_primary: boolean; | ||
154 | file_name: string; | ||
149 | } | 155 | } |
150 | 156 | ||
151 | interface ErrorMessage { | 157 | interface RustDiagnostic { |
152 | reason: string; | 158 | spans: RustDiagnosticSpan[]; |
153 | message: { | 159 | rendered: string; |
154 | spans: ErrorSpan[]; | 160 | level: string; |
155 | rendered: string; | 161 | code?: { |
156 | level: string; | 162 | code: string; |
157 | code?: { | ||
158 | code: string; | ||
159 | }; | ||
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 | // cargo-watch itself output non json format | 178 | // cargo-watch itself output non json format |
164 | // Ignore these lines | 179 | // Ignore these lines |
165 | let data: ErrorMessage; | 180 | let data: CargoMessage; |
166 | try { | 181 | try { |
167 | data = JSON.parse(line.trim()); | 182 | data = JSON.parse(line.trim()); |
168 | } catch (error) { | 183 | } catch (error) { |
169 | this.logError(`Fail to pass to json : { ${error} }`); | 184 | this.logError(`Fail to parse to json : { ${error} }`); |
170 | return; | 185 | return; |
171 | } | 186 | } |
172 | 187 | ||
173 | // Only handle compiler-message now | 188 | if (data.reason === 'compiler-artifact') { |
174 | if (data.reason !== 'compiler-message') { | 189 | const msg = data as CargoArtifact; |
175 | return; | ||
176 | } | ||
177 | 190 | ||
178 | let spans: any[] = data.message.spans; | 191 | // The format of the package_id is "{name} {version} ({source_id})", |
179 | spans = spans.filter(o => o.is_primary); | 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. | 197 | const spans = msg.spans.filter(o => o.is_primary); |
182 | if (spans.length > 0) { | ||
183 | const o = spans[0]; | ||
184 | 198 | ||
185 | const rendered = data.message.rendered; | 199 | // We only handle primary span right now. |
186 | const level = getLevel(data.message.level); | 200 | if (spans.length > 0) { |
187 | const range = new vscode.Range( | 201 | const o = spans[0]; |
188 | new vscode.Position(o.line_start - 1, o.column_start - 1), | 202 | |
189 | new vscode.Position(o.line_end - 1, o.column_end - 1) | 203 | const rendered = msg.rendered; |
190 | ); | 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); | 210 | const fileName = path.join( |
193 | const diagnostic = new vscode.Diagnostic(range, rendered, level); | 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'; | 220 | diagnostic.source = 'rustc'; |
196 | diagnostic.code = data.message.code | 221 | diagnostic.code = msg.code ? msg.code.code : undefined; |
197 | ? data.message.code.code | 222 | diagnostic.relatedInformation = []; |
198 | : undefined; | ||
199 | 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[] = [ | 226 | const diagnostics: vscode.Diagnostic[] = [ |
204 | ...(this.diagnosticCollection!.get(fileUrl) || []) | 227 | ...(this.diagnosticCollection!.get(fileUrl) || []) |
205 | ]; | 228 | ]; |
206 | diagnostics.push(diagnostic); | 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 | } |
diff --git a/editors/code/src/commands/watch_status.ts b/editors/code/src/commands/watch_status.ts index f027d7bbc..86ae821de 100644 --- a/editors/code/src/commands/watch_status.ts +++ b/editors/code/src/commands/watch_status.ts | |||
@@ -3,6 +3,8 @@ import * as vscode from 'vscode'; | |||
3 | const spinnerFrames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']; | 3 | const spinnerFrames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']; |
4 | 4 | ||
5 | export class StatusDisplay { | 5 | export class StatusDisplay { |
6 | public packageName?: string; | ||
7 | |||
6 | private i = 0; | 8 | private i = 0; |
7 | private statusBarItem: vscode.StatusBarItem; | 9 | private statusBarItem: vscode.StatusBarItem; |
8 | private timer?: NodeJS.Timeout; | 10 | private timer?: NodeJS.Timeout; |
@@ -17,10 +19,18 @@ export class StatusDisplay { | |||
17 | } | 19 | } |
18 | 20 | ||
19 | public show() { | 21 | public show() { |
22 | this.packageName = undefined; | ||
23 | |||
20 | this.timer = | 24 | this.timer = |
21 | this.timer || | 25 | this.timer || |
22 | setInterval(() => { | 26 | setInterval(() => { |
23 | this.statusBarItem!.text = 'cargo check ' + this.frame(); | 27 | if (this.packageName) { |
28 | this.statusBarItem!.text = `cargo check [${ | ||
29 | this.packageName | ||
30 | }] ${this.frame()}`; | ||
31 | } else { | ||
32 | this.statusBarItem!.text = `cargo check ${this.frame()}`; | ||
33 | } | ||
24 | }, 300); | 34 | }, 300); |
25 | 35 | ||
26 | this.statusBarItem!.show(); | 36 | this.statusBarItem!.show(); |