aboutsummaryrefslogtreecommitdiff
path: root/editors/code/src/commands
diff options
context:
space:
mode:
Diffstat (limited to 'editors/code/src/commands')
-rw-r--r--editors/code/src/commands/cargo_watch.ts78
-rw-r--r--editors/code/src/commands/line_buffer.ts16
2 files changed, 66 insertions, 28 deletions
diff --git a/editors/code/src/commands/cargo_watch.ts b/editors/code/src/commands/cargo_watch.ts
index 9864ce01a..fb8fcaeb3 100644
--- a/editors/code/src/commands/cargo_watch.ts
+++ b/editors/code/src/commands/cargo_watch.ts
@@ -3,9 +3,9 @@ import * as path from 'path';
3import * as vscode from 'vscode'; 3import * as vscode from 'vscode';
4import { Server } from '../server'; 4import { Server } from '../server';
5import { terminate } from '../utils/processes'; 5import { terminate } from '../utils/processes';
6import { LineBuffer } from './line_buffer';
6import { StatusDisplay } from './watch_status'; 7import { StatusDisplay } from './watch_status';
7 8
8
9export class CargoWatchProvider { 9export class CargoWatchProvider {
10 private diagnosticCollection?: vscode.DiagnosticCollection; 10 private diagnosticCollection?: vscode.DiagnosticCollection;
11 private cargoProcess?: child_process.ChildProcess; 11 private cargoProcess?: child_process.ChildProcess;
@@ -23,33 +23,44 @@ export class CargoWatchProvider {
23 this.outputChannel = vscode.window.createOutputChannel( 23 this.outputChannel = vscode.window.createOutputChannel(
24 'Cargo Watch Trace' 24 'Cargo Watch Trace'
25 ); 25 );
26 26
27 let args = '"check --message-format json';
28 if (Server.config.cargoWatchOptions.checkArguments.length > 0) {
29 // Excape the double quote string:
30 args += ' ' + Server.config.cargoWatchOptions.checkArguments;
31 }
32 args += '"';
33
27 // Start the cargo watch with json message 34 // Start the cargo watch with json message
28 this.cargoProcess = child_process.spawn( 35 this.cargoProcess = child_process.spawn(
29 'cargo', 36 'cargo',
30 ['watch', '-x', '\"check --message-format json\"'], 37 ['watch', '-x', args],
31 { 38 {
32 stdio: ['ignore', 'pipe', 'pipe'], 39 stdio: ['ignore', 'pipe', 'pipe'],
33 cwd: vscode.workspace.rootPath, 40 cwd: vscode.workspace.rootPath,
34 windowsVerbatimArguments: true, 41 windowsVerbatimArguments: true
35 } 42 }
36 ); 43 );
37 44
45 const stdoutData = new LineBuffer();
38 this.cargoProcess.stdout.on('data', (s: string) => { 46 this.cargoProcess.stdout.on('data', (s: string) => {
39 this.processOutput(s, (line) => { 47 stdoutData.processOutput(s, line => {
40 this.logInfo(line); 48 this.logInfo(line);
41 this.parseLine(line); 49 this.parseLine(line);
42 }); 50 });
43 }); 51 });
44 52
53 const stderrData = new LineBuffer();
45 this.cargoProcess.stderr.on('data', (s: string) => { 54 this.cargoProcess.stderr.on('data', (s: string) => {
46 this.processOutput(s, (line) => { 55 stderrData.processOutput(s, line => {
47 this.logError('Error on cargo-watch : {\n' + line + '}\n' ); 56 this.logError('Error on cargo-watch : {\n' + line + '}\n');
48 }); 57 });
49 }); 58 });
50 59
51 this.cargoProcess.on('error', (err: Error) => { 60 this.cargoProcess.on('error', (err: Error) => {
52 this.logError('Error on cargo-watch process : {\n' + err.message + '}\n'); 61 this.logError(
62 'Error on cargo-watch process : {\n' + err.message + '}\n'
63 );
53 }); 64 });
54 65
55 this.logInfo('cargo-watch started.'); 66 this.logInfo('cargo-watch started.');
@@ -66,7 +77,7 @@ export class CargoWatchProvider {
66 terminate(this.cargoProcess); 77 terminate(this.cargoProcess);
67 } 78 }
68 79
69 if(this.outputChannel) { 80 if (this.outputChannel) {
70 this.outputChannel.dispose(); 81 this.outputChannel.dispose();
71 } 82 }
72 } 83 }
@@ -74,13 +85,16 @@ export class CargoWatchProvider {
74 private logInfo(line: string) { 85 private logInfo(line: string) {
75 if (Server.config.cargoWatchOptions.trace === 'verbose') { 86 if (Server.config.cargoWatchOptions.trace === 'verbose') {
76 this.outputChannel!.append(line); 87 this.outputChannel!.append(line);
77 } 88 }
78 } 89 }
79 90
80 private logError(line: string) { 91 private logError(line: string) {
81 if (Server.config.cargoWatchOptions.trace === 'error' || Server.config.cargoWatchOptions.trace === 'verbose' ) { 92 if (
93 Server.config.cargoWatchOptions.trace === 'error' ||
94 Server.config.cargoWatchOptions.trace === 'verbose'
95 ) {
82 this.outputChannel!.append(line); 96 this.outputChannel!.append(line);
83 } 97 }
84 } 98 }
85 99
86 private parseLine(line: string) { 100 private parseLine(line: string) {
@@ -105,12 +119,32 @@ export class CargoWatchProvider {
105 return vscode.DiagnosticSeverity.Information; 119 return vscode.DiagnosticSeverity.Information;
106 } 120 }
107 121
122 interface ErrorSpan {
123 line_start: number;
124 line_end: number;
125 column_start: number;
126 column_end: number;
127 }
128
129 interface ErrorMessage {
130 reason: string;
131 message: {
132 spans: ErrorSpan[];
133 rendered: string;
134 level: string;
135 code?: {
136 code: string;
137 };
138 };
139 }
140
108 // cargo-watch itself output non json format 141 // cargo-watch itself output non json format
109 // Ignore these lines 142 // Ignore these lines
110 let data = null; 143 let data: ErrorMessage;
111 try { 144 try {
112 data = JSON.parse(line.trim()); 145 data = JSON.parse(line.trim());
113 } catch (error) { 146 } catch (error) {
147 this.logError(`Fail to pass to json : { ${error} }`);
114 return; 148 return;
115 } 149 }
116 150
@@ -137,7 +171,9 @@ export class CargoWatchProvider {
137 const diagnostic = new vscode.Diagnostic(range, rendered, level); 171 const diagnostic = new vscode.Diagnostic(range, rendered, level);
138 172
139 diagnostic.source = 'rustc'; 173 diagnostic.source = 'rustc';
140 diagnostic.code = data.message.code.code; 174 diagnostic.code = data.message.code
175 ? data.message.code.code
176 : undefined;
141 diagnostic.relatedInformation = []; 177 diagnostic.relatedInformation = [];
142 178
143 const fileUrl = vscode.Uri.file(fileName!); 179 const fileUrl = vscode.Uri.file(fileName!);
@@ -150,18 +186,4 @@ export class CargoWatchProvider {
150 this.diagnosticCollection!.set(fileUrl, diagnostics); 186 this.diagnosticCollection!.set(fileUrl, diagnostics);
151 } 187 }
152 } 188 }
153
154 private processOutput(chunk: string, cb: (line: string) => void ) {
155 // The stdout is not line based, convert it to line based for proceess.
156 this.outBuffer += chunk;
157 let eolIndex = this.outBuffer.indexOf('\n');
158 while (eolIndex >= 0) {
159 // line includes the EOL
160 const line = this.outBuffer.slice(0, eolIndex + 1);
161 cb(line);
162 this.outBuffer = this.outBuffer.slice(eolIndex + 1);
163
164 eolIndex = this.outBuffer.indexOf('\n');
165 }
166 }
167} 189}
diff --git a/editors/code/src/commands/line_buffer.ts b/editors/code/src/commands/line_buffer.ts
new file mode 100644
index 000000000..fb5b9f7f2
--- /dev/null
+++ b/editors/code/src/commands/line_buffer.ts
@@ -0,0 +1,16 @@
1export class LineBuffer {
2 private outBuffer: string = '';
3
4 public processOutput(chunk: string, cb: (line: string) => void) {
5 this.outBuffer += chunk;
6 let eolIndex = this.outBuffer.indexOf('\n');
7 while (eolIndex >= 0) {
8 // line includes the EOL
9 const line = this.outBuffer.slice(0, eolIndex + 1);
10 cb(line);
11 this.outBuffer = this.outBuffer.slice(eolIndex + 1);
12
13 eolIndex = this.outBuffer.indexOf('\n');
14 }
15 }
16}