Skip to content

Commit 024f937

Browse files
committed
VS Code: refactor DocumentLinter
Split DocumentLinter into two classes: DocumentLinter which handles the complex logic, and VSCodeDocumentLinter which interfaces between a VS Code Document+DocumentCollection and DocumentLinter. This split should make it easier to test DocumentLinter's logic. This commit should not change behavior.
1 parent ab19ed8 commit 024f937

File tree

1 file changed

+51
-15
lines changed

1 file changed

+51
-15
lines changed

plugin/vscode/extension.js

Lines changed: 51 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,14 @@ class DocumentLinterDisposed extends Error {}
4949
exports.DocumentLinterDisposed = DocumentLinterDisposed;
5050

5151
class DocumentLinter {
52-
constructor(document, diagnosticCollection) {
52+
// document has the following methods:
53+
//
54+
// getText(): string;
55+
// setDiagnostics(diagnostics: Object[]): void;
56+
// removeDiagnostics(): void;
57+
constructor(document, processFactoryPromise) {
5358
this._document = document;
54-
this._diagnosticCollection = diagnosticCollection;
59+
this._processFactoryPromise = processFactoryPromise;
5560
this._state = DocumentLinterState.NO_PARSER;
5661

5762
// Used only in states: CREATING_PARSER
@@ -71,7 +76,7 @@ class DocumentLinter {
7176
assert.strictEqual(this._state, DocumentLinterState.NO_PARSER);
7277
this._state = DocumentLinterState.CREATING_PARSER;
7378
this._parserPromise = (async () => {
74-
let factory = await processFactoryPromise;
79+
let factory = await this._processFactoryPromise;
7580
// TODO(strager): Reuse processes across documents.
7681
let process = await factory.createProcessAsync();
7782
let parser = await process.createDocumentForVSCodeAsync();
@@ -118,7 +123,7 @@ class DocumentLinter {
118123
default:
119124
throw new Error(`Unexpected linter state: ${this._state}`);
120125
}
121-
this._diagnosticCollection.delete(this._document.uri);
126+
this._document.removeDiagnostics();
122127
}
123128

124129
dispose() {
@@ -185,7 +190,7 @@ class DocumentLinter {
185190
// END CRITICAL SECTION (no awaiting above)
186191

187192
let diags = this._parser.lint();
188-
this._updateDocumentDiagnostics(diags);
193+
this._document.setDiagnostics(diags);
189194
} catch (e) {
190195
// END CRITICAL SECTION (no awaiting above)
191196
if (e instanceof ProcessCrashed) {
@@ -229,7 +234,7 @@ class DocumentLinter {
229234
// END CRITICAL SECTION (no awaiting above)
230235

231236
let diags = this._parser.lint();
232-
this._updateDocumentDiagnostics(diags);
237+
this._document.setDiagnostics(diags);
233238
} catch (e) {
234239
if (e instanceof ProcessCrashed) {
235240
await this._recoverFromCrashAsync(e);
@@ -250,7 +255,7 @@ class DocumentLinter {
250255
let diags;
251256
try {
252257
// TODO(strager): Reuse processes across documents.
253-
let factory = await processFactoryPromise;
258+
let factory = await this._processFactoryPromise;
254259
let process = await factory.createProcessAsync();
255260
let parser = await process.createDocumentForVSCodeAsync();
256261

@@ -279,20 +284,51 @@ class DocumentLinter {
279284
throw e;
280285
}
281286
}
282-
this._updateDocumentDiagnostics(diags);
287+
this._document.setDiagnostics(diags);
283288
})();
284289
// END CRITICAL SECTION (no awaiting above)
285290
await this._recoveryPromise;
286291
}
292+
}
287293

288-
_updateDocumentDiagnostics(qljsDiagnostics) {
289-
let diagnostics = qljsDiagnostics.map((diag) =>
290-
this._qljsDiagnosticToVSCodeDiagnostic(diag)
294+
class VSCodeDocumentLinter {
295+
constructor(document, diagnosticCollection) {
296+
this._documentLinter = new DocumentLinter(
297+
{
298+
getText() {
299+
return document.getText();
300+
},
301+
setDiagnostics(qljsDiagnostics) {
302+
let vscodeDiagnostics = qljsDiagnostics.map((diag) =>
303+
VSCodeDocumentLinter._qljsDiagnosticToVSCodeDiagnostic(diag)
304+
);
305+
diagnosticCollection.set(document.uri, vscodeDiagnostics);
306+
},
307+
removeDiagnostics() {
308+
diagnosticCollection.delete(document.uri);
309+
},
310+
},
311+
processFactoryPromise
291312
);
292-
this._diagnosticCollection.set(this._document.uri, diagnostics);
293313
}
294314

295-
_qljsDiagnosticToVSCodeDiagnostic(diag) {
315+
async disposeAsync() {
316+
await this._documentLinter.disposeAsync();
317+
}
318+
319+
dispose() {
320+
this._documentLinter.dispose();
321+
}
322+
323+
async editorChangedVisibilityAsync() {
324+
await this._documentLinter.editorChangedVisibilityAsync();
325+
}
326+
327+
async textChangedAsync(changes) {
328+
await this._documentLinter.textChangedAsync(changes);
329+
}
330+
331+
static _qljsDiagnosticToVSCodeDiagnostic(diag) {
296332
let vsCodeSeverity;
297333
switch (diag.severity) {
298334
case DiagnosticSeverity.ERROR:
@@ -326,15 +362,15 @@ class DocumentLinterCollection {
326362
constructor(diagnosticCollection) {
327363
this._diagnosticCollection = diagnosticCollection;
328364

329-
// Mapping from URI string to DocumentLinter.
365+
// Mapping from URI string to VSCodeDocumentLinter.
330366
this._linters = new Map();
331367
}
332368

333369
getLinter(document) {
334370
let documentURIString = document.uri.toString();
335371
let linter = this._linters.get(documentURIString);
336372
if (typeof linter === "undefined") {
337-
linter = new DocumentLinter(document, this._diagnosticCollection);
373+
linter = new VSCodeDocumentLinter(document, this._diagnosticCollection);
338374
this._linters.set(documentURIString, linter);
339375
}
340376
return linter;

0 commit comments

Comments
 (0)