Skip to content

Commit b5003d5

Browse files
committed
Support for diagnostics
1 parent 827702c commit b5003d5

File tree

2 files changed

+43
-13
lines changed

2 files changed

+43
-13
lines changed

server/src/docInfo.ts

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { CompletionItem, Diagnostic, DiagnosticRelatedInformation, DiagnosticSeverity, DidChangeConfigurationParams, DidChangeWatchedFilesParams, DocumentSymbol, FoldingRange, Hover, HoverParams, Location, NotificationHandler, Position, Range, SemanticTokenModifiers, SemanticTokens, SemanticTokensParams, SemanticTokensRangeParams, SemanticTokensRequest, SymbolInformation, SymbolKind, TextDocumentPositionParams, TextDocuments, uinteger, _Connection } from 'vscode-languageserver';
1+
import { CompletionItem, Diagnostic, DiagnosticRelatedInformation, DiagnosticSeverity, DidChangeConfigurationParams, DidChangeWatchedFilesParams, DocumentSymbol, FoldingRange, Hover, HoverParams, Location, NotificationHandler, Position, PublishDiagnosticsParams, Range, SemanticTokenModifiers, SemanticTokens, SemanticTokensParams, SemanticTokensRangeParams, SemanticTokensRequest, SymbolInformation, SymbolKind, TextDocumentPositionParams, TextDocuments, uinteger, _Connection } from 'vscode-languageserver';
22
import { TextDocument } from 'vscode-languageserver-textdocument';
33
import { LiteralContext } from './antlr/out/vbaParser';
44
import { SemanticToken, sortSemanticTokens } from './capabilities/vbaSemanticTokens';
@@ -105,7 +105,8 @@ export class ProjectInformation {
105105
return this.docInfos.get(uri)?.getSemanticTokens(range) ?? null;
106106
}
107107

108-
108+
sendDiagnostics = (docInfo: DocumentInformation) =>
109+
this.conn.sendDiagnostics(docInfo.getDiagnostics());
109110

110111
private getDocumentSettings(docUri: string): Thenable<ExampleSettings> {
111112
if (!this.hasConfigurationCapability) {
@@ -136,9 +137,11 @@ export class ProjectInformation {
136137
this.docs.onDidChangeContent(change => {
137138
const doc = change.document;
138139
const docInfo = new DocumentInformation(this.scopes, doc.uri);
140+
this.scopes.getScope(`undeclared|${doc.uri}`).clear();
139141
this.docInfos.set(doc.uri, docInfo);
140142
this.syntaxUtil.parse(doc, docInfo);
141143
docInfo.finalise();
144+
this.sendDiagnostics(docInfo);
142145
});
143146
}
144147
}
@@ -148,11 +151,11 @@ export class DocumentInformation implements ResultsContainer {
148151
elements: SyntaxElement[] = [];
149152
attrubutes: Map<string, string> = new Map();
150153
isBusy = true;
151-
154+
155+
private docUri: string;
152156
private ancestors: SyntaxElement[] = [];
153157
private localNames: Map<string, SyntaxElement> = new Map();
154158
private documentScope: Scope;
155-
private docUri: string;
156159

157160
constructor(scope: Scope, docUri: string) {
158161
scope.links.set(docUri, new Map());
@@ -219,12 +222,14 @@ export class DocumentInformation implements ResultsContainer {
219222
link.merge(undeclaredLink);
220223
undeclaredScope.delete(elId);
221224
}
225+
226+
this.addElement(emt);
222227
}
223228

224229
addScopeReference(emt: VariableAssignElement) {
225-
// this.addElement(emt);
226230
const link = this.getNameLink(emt.identifier!.text, emt.parent?.fqName ?? '', false, true);
227231
link.references.push(emt);
232+
this.addElement(emt);
228233
}
229234

230235
private getNameLink(identifier: string, fqName: string, isPrivate = false, searchScopes = false): NameLink {
@@ -257,7 +262,7 @@ export class DocumentInformation implements ResultsContainer {
257262
return scope;
258263
}
259264
}
260-
return this.documentScope.getScope(`undefined|${this.docUri}`);
265+
return this.documentScope.getScope(`undeclared|${this.docUri}`);
261266
}
262267

263268

@@ -341,6 +346,10 @@ export class DocumentInformation implements ResultsContainer {
341346
return results;
342347
}
343348

349+
getDiagnostics(): PublishDiagnosticsParams {
350+
return {uri: this.docUri, diagnostics: this.elements.map((e) => e.diagnostics).flat(1)};
351+
}
352+
344353
getSymbols = (uri: string): SymbolInformation[] =>
345354
this.elements
346355
.filter((x) => (!!x.identifier) && (x.identifier.text !== ''))
@@ -371,7 +380,10 @@ class Scope {
371380

372381
processLinks(key: string, optExplicit = false) {
373382
// TODO: check global for undeclareds
374-
this.getScope(key).forEach((x) => x.process(optExplicit));
383+
const undeclared = this.getScope(`undeclared|${key}`);
384+
const docScopes = this.getScope(key);
385+
undeclared.forEach((v, k) => docScopes.set(k, v));
386+
docScopes.forEach((x) => x.process(optExplicit));
375387
}
376388
}
377389

@@ -404,7 +416,9 @@ class NameLink {
404416
this.processDiagnosticRelatedInformation();
405417
this.validateDeclarationCount(optExplicit);
406418
this.validateMethodSignatures();
419+
407420
this.assignSemanticTokens();
421+
this.assignDiagnostics();
408422
}
409423

410424
private processDiagnosticRelatedInformation() {
@@ -417,7 +431,6 @@ class NameLink {
417431
}
418432

419433
private validateDeclarationCount(optExplicit: boolean) {
420-
// Base case.
421434
if (this.declarations.length === 1) {
422435
return;
423436
}
@@ -452,10 +465,18 @@ class NameLink {
452465
return;
453466
}
454467

455-
this.references.forEach(
456-
(x) => x.semanticToken = this.declarations[0]
457-
.semanticToken
458-
?.toNewRange(x.range));
468+
this.references.forEach((x) => x.semanticToken =
469+
this.declarations[0]
470+
.semanticToken
471+
?.toNewRange(x.range));
472+
}
473+
474+
private assignDiagnostics() {
475+
if (this.diagnostics.length === 0) {
476+
return;
477+
}
478+
const els = this.declarations.concat(this.references);
479+
els.forEach((x) => x.addDiagnostics(this.diagnostics));
459480
}
460481

461482
private validateMethodSignatures() {

server/src/utils/vbaSyntaxElements.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { ParserRuleContext } from 'antlr4ts';
2-
import { FoldingRange, Hover, Location, Range, SemanticTokenModifiers, SemanticTokenTypes, SymbolInformation, SymbolKind, uinteger } from 'vscode-languageserver';
2+
import { Diagnostic, FoldingRange, Hover, Location, Range, SemanticTokenModifiers, SemanticTokenTypes, SymbolInformation, SymbolKind, uinteger } from 'vscode-languageserver';
33
import { TextDocument } from 'vscode-languageserver-textdocument';
44
import { AmbiguousIdentifierContext, AttributeStmtContext, BaseTypeContext, ComplexTypeContext, ConstStmtContext, ConstSubStmtContext, EnumerationStmtContext, EnumerationStmt_ConstantContext, FunctionStmtContext, LetStmtContext, LiteralContext, ModuleContext, SetStmtContext, SubStmtContext, VariableStmtContext, VariableSubStmtContext } from '../antlr/out/vbaParser';
55
import { SemanticToken } from '../capabilities/vbaSemanticTokens';
@@ -16,6 +16,7 @@ interface SyntaxElement {
1616
context: ParserRuleContext;
1717
symbolKind: SymbolKind;
1818
semanticToken?: SemanticToken;
19+
diagnostics: Diagnostic[];
1920
hoverText: string;
2021
fqName?: string;
2122

@@ -28,6 +29,7 @@ interface SyntaxElement {
2829
symbolInformation(uri: string): SymbolInformation | undefined;
2930
foldingRange(): FoldingRange | undefined;
3031
location(): Location;
32+
addDiagnostics(diagnostics: Diagnostic[]): void;
3133
}
3234

3335
interface Identifiable {
@@ -43,11 +45,14 @@ abstract class BaseElement implements SyntaxElement {
4345
context: ParserRuleContext;
4446
symbolKind: SymbolKind;
4547
semanticToken?: SemanticToken;
48+
diagnostics: Diagnostic[] = [];
4649
hoverText: string;
4750
fqName?: string;
4851

4952
parent?: SyntaxElement;
53+
5054
children: SyntaxElement[] = [];
55+
private _countAncestors = 0;
5156

5257
constructor(ctx: ParserRuleContext, doc: TextDocument) {
5358
this.uri = doc.uri;
@@ -98,6 +103,10 @@ abstract class BaseElement implements SyntaxElement {
98103
this.range.end.character
99104
);
100105

106+
addDiagnostics(diagnostics: Diagnostic[]) {
107+
this.diagnostics = this.diagnostics.concat(diagnostics);
108+
}
109+
101110
private setIdentifierFromDoc(doc: TextDocument): void {
102111
if (this.isIdentifiable(this.context)) {
103112
const identCtx = this.context.ambiguousIdentifier(0);

0 commit comments

Comments
 (0)