aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--editors/code/src/commands/cargo_watch.ts110
-rw-r--r--editors/code/src/commands/watch_status.ts12
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';
3const spinnerFrames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']; 3const spinnerFrames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
4 4
5export class StatusDisplay { 5export 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();