Skip to content

Commit f70eda2

Browse files
committed
Implement enums. Create base Scope element.
1 parent 5cabb06 commit f70eda2

File tree

6 files changed

+105
-29
lines changed

6 files changed

+105
-29
lines changed

server/src/project/document.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
import { CancellationToken, Diagnostic, LSPErrorCodes, PublishDiagnosticsParams, ResponseError, SemanticTokens, SymbolInformation, SymbolKind } from 'vscode-languageserver';
1+
import { CancellationToken, Diagnostic, PublishDiagnosticsParams, SymbolInformation, SymbolKind } from 'vscode-languageserver';
22
import { Workspace } from './workspace';
33
import { FoldableElement } from './elements/special';
44
import { BaseSyntaxElement, HasDiagnosticCapability, HasSemanticToken, HasSymbolInformation, ScopeElement } from './elements/base';
55
import { Range, TextDocument } from 'vscode-languageserver-textdocument';
66
import { SyntaxParser } from './parser/vbaSyntaxParser';
77
import { FoldingRange } from '../capabilities/folding';
88
import { SemanticTokensManager } from '../capabilities/semanticTokens';
9-
import { sleep } from '../utils/helpers';
109

1110

1211
export abstract class BaseProjectDocument {

server/src/project/elements/base.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ export interface FoldingRangeElement {
5454
}
5555

5656
export interface ScopeElement {
57-
declaredNames: Map<string, BaseSyntaxElement>;
57+
declaredNames: Map<string, IdentifiableSyntaxElement[]>;
5858
}
5959

6060
export abstract class BaseSyntaxElement implements ContextOptionalSyntaxElement {
@@ -107,3 +107,4 @@ export abstract class BaseContextSyntaxElement extends BaseSyntaxElement {
107107
super(ctx, doc);
108108
}
109109
}
110+

server/src/project/elements/memory.ts

Lines changed: 66 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import { AmbiguousIdentifierContext, FunctionDeclarationContext, ProcedureDeclarationContext, PropertyGetDeclarationContext, PropertySetDeclarationContext, SubroutineDeclarationContext } from '../../antlr/out/vbaParser';
1+
import { AmbiguousIdentifierContext, EnumDeclarationContext, EnumMemberContext, FunctionDeclarationContext, ProcedureDeclarationContext, PropertyGetDeclarationContext, PropertySetDeclarationContext, SubroutineDeclarationContext } from '../../antlr/out/vbaParser';
22

33
import { TextDocument } from 'vscode-languageserver-textdocument';
44

5-
import { BaseContextSyntaxElement, BaseSyntaxElement, HasSemanticToken, HasSymbolInformation, ScopeElement } from './base';
5+
import { BaseContextSyntaxElement, HasSemanticToken, HasSymbolInformation, IdentifiableSyntaxElement } from './base';
66
import { SemanticTokenModifiers, SemanticTokenTypes, SymbolInformation, SymbolKind } from 'vscode-languageserver';
7-
import { FoldableElement } from './special';
7+
import { ScopeElement } from './special';
88
import { SymbolInformationFactory } from '../../capabilities/symbolInformation';
99
import '../../extensions/parserExtensions';
1010
import { VbaClassDocument, VbaModuleDocument } from '../document';
@@ -16,9 +16,8 @@ export class IdentifierElement extends BaseContextSyntaxElement {
1616
}
1717
}
1818

19-
export abstract class DeclarationElement extends FoldableElement implements ScopeElement {
19+
export abstract class DeclarationElement extends ScopeElement {
2020
abstract identifier: IdentifierElement;
21-
abstract declaredNames: Map<string, BaseSyntaxElement>;
2221

2322
constructor(context: ProcedureDeclarationContext, document: TextDocument) {
2423
super(context, document);
@@ -40,11 +39,13 @@ export abstract class DeclarationElement extends FoldableElement implements Scop
4039
}
4140

4241
const propertyDeclaration = new PropertyDeclarationElement(context, document.textDocument);
43-
const predeclaredElement = document.currentScopeElement?.declaredNames.get(propertyDeclaration.identifier.text);
44-
if (predeclaredElement && isPropertyDeclarationElement(predeclaredElement)) {
45-
predeclaredElement.addPropertyDeclaration(context, document.textDocument);
46-
return predeclaredElement;
47-
}
42+
const predeclaredElements = document.currentScopeElement?.declaredNames.get(propertyDeclaration.identifier.text);
43+
predeclaredElements?.forEach(predeclaredElement => {
44+
if (predeclaredElement && isPropertyDeclarationElement(predeclaredElement)) {
45+
predeclaredElement.addPropertyDeclaration(context, document.textDocument);
46+
return predeclaredElement;
47+
}
48+
});
4849
return propertyDeclaration;
4950
}
5051

@@ -53,7 +54,6 @@ export abstract class DeclarationElement extends FoldableElement implements Scop
5354
export class SubDeclarationElement extends DeclarationElement implements HasSymbolInformation {
5455
identifier: IdentifierElement;
5556
symbolInformation: SymbolInformation;
56-
declaredNames: Map<string, BaseSyntaxElement> = new Map();
5757

5858
constructor(context: ProcedureDeclarationContext, document: TextDocument, methodContext: SubroutineDeclarationContext) {
5959
super(context, document);
@@ -72,7 +72,6 @@ export class SubDeclarationElement extends DeclarationElement implements HasSymb
7272
export class FunctionDeclarationElement extends DeclarationElement implements HasSymbolInformation {
7373
identifier: IdentifierElement;
7474
symbolInformation: SymbolInformation;
75-
declaredNames: Map<string, BaseSyntaxElement> = new Map();
7675

7776
constructor(context: ProcedureDeclarationContext, document: TextDocument, methodContext: FunctionDeclarationContext) {
7877
super(context, document);
@@ -93,7 +92,6 @@ export class PropertyDeclarationElement extends DeclarationElement implements Ha
9392
getDeclarations: PropertyGetDeclarationElement[] = [];
9493
letDeclarations: PropertyLetDeclarationElement[] = [];
9594
setDeclarations: PropertyLetDeclarationElement[] = [];
96-
declaredNames: Map<string, BaseSyntaxElement> = new Map();
9795

9896
constructor(context: ProcedureDeclarationContext, document: TextDocument) {
9997
super(context, document);
@@ -126,7 +124,6 @@ export class PropertyDeclarationElement extends DeclarationElement implements Ha
126124

127125
class PropertyGetDeclarationElement extends DeclarationElement {
128126
identifier: IdentifierElement;
129-
declaredNames: Map<string, BaseSyntaxElement> = new Map();
130127

131128
constructor(context: ProcedureDeclarationContext, document: TextDocument, getContext: PropertyGetDeclarationContext) {
132129
super(context, document);
@@ -136,7 +133,6 @@ class PropertyGetDeclarationElement extends DeclarationElement {
136133

137134
class PropertyLetDeclarationElement extends DeclarationElement {
138135
identifier: IdentifierElement;
139-
declaredNames: Map<string, BaseSyntaxElement> = new Map();
140136

141137
constructor(context: ProcedureDeclarationContext, document: TextDocument, setContext: PropertySetDeclarationContext) {
142138
super(context, document);
@@ -146,18 +142,71 @@ class PropertyLetDeclarationElement extends DeclarationElement {
146142

147143
class PropertySetDeclarationElement extends DeclarationElement {
148144
identifier: IdentifierElement;
149-
declaredNames: Map<string, BaseSyntaxElement> = new Map();
150145

151146
constructor(context: ProcedureDeclarationContext, document: TextDocument, setContext: PropertySetDeclarationContext) {
152147
super(context, document);
153148
this.identifier = new IdentifierElement(setContext.subroutineName()!.ambiguousIdentifier()!, document);
154149
}
155150
}
156151

157-
function isPropertyDeclarationElement(element: BaseSyntaxElement): element is PropertyDeclarationElement {
152+
function isPropertyDeclarationElement(element: IdentifiableSyntaxElement): element is PropertyDeclarationElement {
158153
return 'getDeclarations' in element;
159154
}
160155

156+
abstract class BaseEnumDeclarationElement extends ScopeElement implements HasSemanticToken, HasSymbolInformation {
157+
identifier: IdentifierElement;
158+
tokenModifiers: SemanticTokenModifiers[] = [];
159+
declaredNames: Map<string, EnumMemberDeclarationElement[]> = new Map();
160+
161+
abstract tokenType: SemanticTokenTypes;
162+
abstract symbolInformation: SymbolInformation;
163+
164+
get name(): string {
165+
return this.identifier.text;
166+
}
167+
168+
constructor(context: EnumDeclarationContext | EnumMemberContext, document: TextDocument) {
169+
super(context, document);
170+
this.identifier = new IdentifierElement(context.untypedName().ambiguousIdentifier()!, document);
171+
}
172+
173+
}
174+
175+
export class EnumDeclarationElement extends BaseEnumDeclarationElement implements ScopeElement {
176+
tokenType: SemanticTokenTypes;
177+
178+
constructor(context: EnumDeclarationContext, document: TextDocument) {
179+
super(context, document);
180+
this.tokenType = SemanticTokenTypes.enum;
181+
this.identifier = new IdentifierElement(context.untypedName().ambiguousIdentifier()!, document);
182+
context.enumMemberList().enumElement().forEach(enumElementContext =>
183+
this._pushDeclaredName(new EnumMemberDeclarationElement(enumElementContext.enumMember()!, document))
184+
);
185+
}
186+
187+
get symbolInformation(): SymbolInformation {
188+
return SymbolInformationFactory.create(
189+
this, SymbolKind.Enum
190+
);
191+
}
192+
}
193+
194+
class EnumMemberDeclarationElement extends BaseEnumDeclarationElement {
195+
tokenType: SemanticTokenTypes;
196+
197+
constructor(context: EnumMemberContext, document: TextDocument) {
198+
super(context, document);
199+
this.tokenType = SemanticTokenTypes.enumMember;
200+
this.identifier = new IdentifierElement(context.untypedName().ambiguousIdentifier()!, document);
201+
}
202+
203+
get symbolInformation(): SymbolInformation {
204+
return SymbolInformationFactory.create(
205+
this, SymbolKind.EnumMember
206+
);
207+
}
208+
}
209+
161210

162211
// abstract class BaseEnumElement extends FoldableElement implements HasSemanticToken, HasSymbolInformation {
163212
// identifier: IdentifierElement;

server/src/project/elements/module.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
import { TextDocument } from 'vscode-languageserver-textdocument';
22
import { Diagnostic, Range, SymbolInformation, SymbolKind } from 'vscode-languageserver';
33
import { ClassModuleContext, IgnoredAttrContext, ProceduralModuleContext } from '../../antlr/out/vbaParser';
4-
import { BaseContextSyntaxElement, BaseSyntaxElement, HasDiagnosticCapability, HasSymbolInformation, ScopeElement } from './base';
4+
import { BaseContextSyntaxElement, HasDiagnosticCapability, HasSymbolInformation } from './base';
55
import { SymbolInformationFactory } from '../../capabilities/symbolInformation';
66
import { IgnoredAttributeDiagnostic, MissingAttributeDiagnostic, MissingOptionExplicitDiagnostic } from '../../capabilities/diagnostics';
77
import '../../extensions/stringExtensions';
8+
import { ScopeElement } from './special';
89

910

10-
abstract class BaseModuleElement extends BaseContextSyntaxElement implements HasSymbolInformation, HasDiagnosticCapability {
11+
abstract class BaseModuleElement extends ScopeElement implements HasSymbolInformation, HasDiagnosticCapability {
1112
protected abstract _name: string;
1213
symbolKind: SymbolKind;
1314
diagnostics: Diagnostic[] = [];
14-
declaredNames: Map<string, BaseSyntaxElement> = new Map();
1515

1616
constructor(context: ProceduralModuleContext | ClassModuleContext, document: TextDocument, symbolKind: SymbolKind) {
1717
super(context, document);
@@ -31,7 +31,7 @@ abstract class BaseModuleElement extends BaseContextSyntaxElement implements Has
3131
abstract evaluateDiagnostics(): void;
3232
}
3333

34-
export class ModuleElement extends BaseModuleElement implements ScopeElement {
34+
export class ModuleElement extends BaseModuleElement {
3535
context: ProceduralModuleContext;
3636
protected _name: string;
3737

server/src/project/elements/special.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { ParserRuleContext } from 'antlr4ng';
22
import { FoldingRangeKind } from '../../capabilities/folding';
3-
import { BaseContextSyntaxElement, FoldingRangeElement } from './base';
3+
import { BaseContextSyntaxElement, FoldingRangeElement, IdentifiableSyntaxElement } from './base';
44
import { Range, TextDocument } from 'vscode-languageserver-textdocument';
55

66

@@ -13,3 +13,18 @@ export class FoldableElement extends BaseContextSyntaxElement implements Folding
1313
this.foldingRangeKind = foldingRangeKind;
1414
}
1515
}
16+
17+
export class ScopeElement extends FoldableElement implements ScopeElement {
18+
declaredNames: Map<string, IdentifiableSyntaxElement[]> = new Map();
19+
20+
constructor(ctx: ParserRuleContext, doc: TextDocument) {
21+
super(ctx, doc);
22+
}
23+
24+
protected _pushDeclaredName(element: IdentifiableSyntaxElement) {
25+
const name = element.identifier.text;
26+
const names: IdentifiableSyntaxElement[] = this.declaredNames.get(name) ?? [];
27+
names.push(element);
28+
this.declaredNames.set(name, names);
29+
}
30+
}

server/src/project/parser/vbaSyntaxParser.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
import { TextDocument } from 'vscode-languageserver-textdocument';
22

33
import { vbaLexer } from '../../antlr/out/vbaLexer';
4-
import { ClassModuleContext, IgnoredAttrContext, ModuleContext, ProceduralModuleBodyContext, ProceduralModuleContext, ProcedureDeclarationContext, vbaParser } from '../../antlr/out/vbaParser';
4+
import { ClassModuleContext, EnumDeclarationContext, IgnoredAttrContext, ProceduralModuleContext, ProcedureDeclarationContext, vbaParser } from '../../antlr/out/vbaParser';
55
import { vbaListener } from '../../antlr/out/vbaListener';
66

77
import { VbaClassDocument, VbaModuleDocument } from '../document';
8-
import { FoldableElement } from '../elements/special';
98
import { sleep } from '../../utils/helpers';
109
import { CancellationToken } from 'vscode-languageserver';
11-
import { CharStream, CommonTokenStream, ConsoleErrorListener, DefaultErrorStrategy, ParseTreeWalker, Parser, RecognitionException, Recognizer } from 'antlr4ng';
10+
import { CharStream, CommonTokenStream, DefaultErrorStrategy, ParseTreeWalker, Parser, RecognitionException } from 'antlr4ng';
1211
import { ClassElement, IgnoredAttributeElement, ModuleElement } from '../elements/module';
13-
import { DeclarationElement } from '../elements/memory';
12+
import { DeclarationElement, EnumDeclarationElement } from '../elements/memory';
1413

1514
export class SyntaxParser {
1615
private static _lockIdentifier = 0;
@@ -93,6 +92,19 @@ class VbaListener extends vbaListener {
9392
this.document = document;
9493
}
9594

95+
enterEnumDeclaration = (ctx: EnumDeclarationContext) => {
96+
const element = new EnumDeclarationElement(ctx, this.document.textDocument);
97+
this.document.registerFoldableElement(element)
98+
.registerScopedElement(element)
99+
.registerSemanticToken(element)
100+
.registerSymbolInformation(element);
101+
element.declaredNames.forEach(names =>
102+
names.forEach(name => this.document
103+
.registerSemanticToken(name)
104+
.registerSymbolInformation(name))
105+
);
106+
};
107+
96108
enterClassModule = (ctx: ClassModuleContext) => {
97109
const element = new ClassElement(ctx, this.document.textDocument);
98110
this.document.registerSymbolInformation(element)

0 commit comments

Comments
 (0)