brighterscript 1.0.0-alpha.11 → 1.0.0-alpha.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +253 -268
- package/README.md +2 -2
- package/dist/Cache.d.ts +3 -8
- package/dist/Cache.js +9 -14
- package/dist/Cache.js.map +1 -1
- package/dist/CommentFlagProcessor.js +5 -3
- package/dist/CommentFlagProcessor.js.map +1 -1
- package/dist/DiagnosticMessages.d.ts +21 -1
- package/dist/DiagnosticMessages.js +21 -1
- package/dist/DiagnosticMessages.js.map +1 -1
- package/dist/LanguageServer.d.ts +1 -6
- package/dist/LanguageServer.js +0 -9
- package/dist/LanguageServer.js.map +1 -1
- package/dist/PluginInterface.d.ts +3 -3
- package/dist/PluginInterface.js +3 -0
- package/dist/PluginInterface.js.map +1 -1
- package/dist/Program.d.ts +30 -16
- package/dist/Program.js +110 -45
- package/dist/Program.js.map +1 -1
- package/dist/ProgramBuilder.js +3 -3
- package/dist/ProgramBuilder.js.map +1 -1
- package/dist/Scope.d.ts +31 -17
- package/dist/Scope.js +86 -48
- package/dist/Scope.js.map +1 -1
- package/dist/SymbolTable.d.ts +1 -1
- package/dist/XmlScope.d.ts +3 -3
- package/dist/astUtils/AstEditor.d.ts +33 -0
- package/dist/astUtils/AstEditor.js +107 -0
- package/dist/astUtils/AstEditor.js.map +1 -0
- package/dist/{bscPlugin/semanticTokens/SemanticTokensProcessor.spec.d.ts → astUtils/AstEditor.spec.d.ts} +0 -0
- package/dist/astUtils/AstEditor.spec.js +170 -0
- package/dist/astUtils/AstEditor.spec.js.map +1 -0
- package/dist/astUtils/reflection.d.ts +3 -1
- package/dist/astUtils/reflection.js +10 -2
- package/dist/astUtils/reflection.js.map +1 -1
- package/dist/astUtils/reflection.spec.js +6 -6
- package/dist/astUtils/reflection.spec.js.map +1 -1
- package/dist/astUtils/visitors.d.ts +3 -1
- package/dist/astUtils/visitors.js.map +1 -1
- package/dist/astUtils/visitors.spec.js +8 -8
- package/dist/astUtils/visitors.spec.js.map +1 -1
- package/dist/astUtils/xml.d.ts +1 -0
- package/dist/astUtils/xml.js +6 -1
- package/dist/astUtils/xml.js.map +1 -1
- package/dist/bscPlugin/BscPlugin.d.ts +4 -1
- package/dist/bscPlugin/BscPlugin.js +21 -2
- package/dist/bscPlugin/BscPlugin.js.map +1 -1
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.js +3 -3
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.js.map +1 -1
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js.map +1 -1
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.d.ts +9 -0
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js +97 -0
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js.map +1 -0
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.d.ts +1 -0
- package/dist/bscPlugin/semanticTokens/{SemanticTokensProcessor.spec.js → BrsFileSemanticTokensProcessor.spec.js} +30 -2
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js.map +1 -0
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.d.ts +8 -0
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.js +36 -0
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.js.map +1 -0
- package/dist/bscPlugin/validation/BrsFileValidator.d.ts +9 -0
- package/dist/bscPlugin/validation/BrsFileValidator.js +66 -0
- package/dist/bscPlugin/validation/BrsFileValidator.js.map +1 -0
- package/dist/bscPlugin/validation/ScopeValidator.d.ts +11 -0
- package/dist/bscPlugin/validation/ScopeValidator.js +94 -0
- package/dist/bscPlugin/validation/ScopeValidator.js.map +1 -0
- package/dist/files/BrsFile.Class.spec.js +404 -230
- package/dist/files/BrsFile.Class.spec.js.map +1 -1
- package/dist/files/BrsFile.d.ts +26 -12
- package/dist/files/BrsFile.js +265 -127
- package/dist/files/BrsFile.js.map +1 -1
- package/dist/files/BrsFile.spec.js +586 -169
- package/dist/files/BrsFile.spec.js.map +1 -1
- package/dist/files/XmlFile.d.ts +11 -10
- package/dist/files/XmlFile.js +13 -8
- package/dist/files/XmlFile.js.map +1 -1
- package/dist/files/XmlFile.spec.js +106 -59
- package/dist/files/XmlFile.spec.js.map +1 -1
- package/dist/files/tests/imports.spec.js +8 -6
- package/dist/files/tests/imports.spec.js.map +1 -1
- package/dist/globalCallables.d.ts +3 -1
- package/dist/globalCallables.js +198 -99
- package/dist/globalCallables.js.map +1 -1
- package/dist/index.d.ts +12 -3
- package/dist/index.js +21 -4
- package/dist/index.js.map +1 -1
- package/dist/interfaces.d.ts +68 -15
- package/dist/lexer/Lexer.js +1 -2
- package/dist/lexer/Lexer.js.map +1 -1
- package/dist/lexer/Lexer.spec.js +470 -462
- package/dist/lexer/Lexer.spec.js.map +1 -1
- package/dist/lexer/TokenKind.d.ts +2 -0
- package/dist/lexer/TokenKind.js +5 -0
- package/dist/lexer/TokenKind.js.map +1 -1
- package/dist/parser/Expression.d.ts +1 -1
- package/dist/parser/Expression.js +10 -10
- package/dist/parser/Expression.js.map +1 -1
- package/dist/parser/Parser.Class.spec.js +33 -32
- package/dist/parser/Parser.Class.spec.js.map +1 -1
- package/dist/parser/Parser.d.ts +28 -7
- package/dist/parser/Parser.js +494 -290
- package/dist/parser/Parser.js.map +1 -1
- package/dist/parser/Parser.spec.js +157 -35
- package/dist/parser/Parser.spec.js.map +1 -1
- package/dist/parser/SGParser.js +1 -1
- package/dist/parser/SGParser.js.map +1 -1
- package/dist/parser/SGTypes.d.ts +3 -0
- package/dist/parser/SGTypes.js +8 -3
- package/dist/parser/SGTypes.js.map +1 -1
- package/dist/parser/SGTypes.spec.js +9 -9
- package/dist/parser/SGTypes.spec.js.map +1 -1
- package/dist/parser/Statement.d.ts +55 -3
- package/dist/parser/Statement.js +162 -9
- package/dist/parser/Statement.js.map +1 -1
- package/dist/parser/tests/Parser.spec.d.ts +3 -3
- package/dist/parser/tests/Parser.spec.js +4 -4
- package/dist/parser/tests/Parser.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/For.spec.js +40 -40
- package/dist/parser/tests/controlFlow/For.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/ForEach.spec.js +22 -21
- package/dist/parser/tests/controlFlow/ForEach.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/If.spec.js +100 -99
- package/dist/parser/tests/controlFlow/If.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/While.spec.js +25 -25
- package/dist/parser/tests/controlFlow/While.spec.js.map +1 -1
- package/dist/parser/tests/expression/Additive.spec.js +21 -21
- package/dist/parser/tests/expression/Additive.spec.js.map +1 -1
- package/dist/parser/tests/expression/ArrayLiterals.spec.js +91 -91
- package/dist/parser/tests/expression/ArrayLiterals.spec.js.map +1 -1
- package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js +102 -102
- package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js.map +1 -1
- package/dist/parser/tests/expression/Boolean.spec.js +15 -15
- package/dist/parser/tests/expression/Boolean.spec.js.map +1 -1
- package/dist/parser/tests/expression/Call.spec.js +22 -21
- package/dist/parser/tests/expression/Call.spec.js.map +1 -1
- package/dist/parser/tests/expression/Exponential.spec.js +11 -11
- package/dist/parser/tests/expression/Exponential.spec.js.map +1 -1
- package/dist/parser/tests/expression/Function.spec.js +171 -171
- package/dist/parser/tests/expression/Function.spec.js.map +1 -1
- package/dist/parser/tests/expression/Indexing.spec.js +50 -50
- package/dist/parser/tests/expression/Indexing.spec.js.map +1 -1
- package/dist/parser/tests/expression/Multiplicative.spec.js +25 -25
- package/dist/parser/tests/expression/Multiplicative.spec.js.map +1 -1
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js +30 -18
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/PrefixUnary.spec.js +26 -26
- package/dist/parser/tests/expression/PrefixUnary.spec.js.map +1 -1
- package/dist/parser/tests/expression/Primary.spec.js +27 -27
- package/dist/parser/tests/expression/Primary.spec.js.map +1 -1
- package/dist/parser/tests/expression/RegexLiteralExpression.spec.js +3 -2
- package/dist/parser/tests/expression/RegexLiteralExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/Relational.spec.js +25 -25
- package/dist/parser/tests/expression/Relational.spec.js.map +1 -1
- package/dist/parser/tests/expression/TemplateStringExpression.spec.js +7 -7
- package/dist/parser/tests/expression/TemplateStringExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/TernaryExpression.spec.js +6 -6
- package/dist/parser/tests/expression/TernaryExpression.spec.js.map +1 -1
- package/dist/parser/tests/statement/AssignmentOperators.spec.js +15 -15
- package/dist/parser/tests/statement/AssignmentOperators.spec.js.map +1 -1
- package/dist/parser/tests/statement/Declaration.spec.js +20 -20
- package/dist/parser/tests/statement/Declaration.spec.js.map +1 -1
- package/dist/parser/tests/statement/Enum.spec.d.ts +1 -0
- package/dist/parser/tests/statement/Enum.spec.js +774 -0
- package/dist/parser/tests/statement/Enum.spec.js.map +1 -0
- package/dist/parser/tests/statement/Function.spec.js +121 -120
- package/dist/parser/tests/statement/Function.spec.js.map +1 -1
- package/dist/parser/tests/statement/Goto.spec.js +9 -8
- package/dist/parser/tests/statement/Goto.spec.js.map +1 -1
- package/dist/parser/tests/statement/Increment.spec.js +22 -22
- package/dist/parser/tests/statement/Increment.spec.js.map +1 -1
- package/dist/parser/tests/statement/InterfaceStatement.spec.js +12 -0
- package/dist/parser/tests/statement/InterfaceStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/LibraryStatement.spec.js +7 -7
- package/dist/parser/tests/statement/LibraryStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/Misc.spec.js +71 -70
- package/dist/parser/tests/statement/Misc.spec.js.map +1 -1
- package/dist/parser/tests/statement/PrintStatement.spec.js +17 -17
- package/dist/parser/tests/statement/PrintStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/ReturnStatement.spec.js +33 -33
- package/dist/parser/tests/statement/ReturnStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/Set.spec.js +53 -53
- package/dist/parser/tests/statement/Set.spec.js.map +1 -1
- package/dist/parser/tests/statement/Stop.spec.js +7 -6
- package/dist/parser/tests/statement/Stop.spec.js.map +1 -1
- package/dist/preprocessor/Chunk.d.ts +1 -1
- package/dist/preprocessor/Preprocessor.d.ts +1 -1
- package/dist/preprocessor/Preprocessor.js +7 -7
- package/dist/preprocessor/Preprocessor.js.map +1 -1
- package/dist/types/ArrayType.d.ts +8 -5
- package/dist/types/ArrayType.js +45 -9
- package/dist/types/ArrayType.js.map +1 -1
- package/dist/types/ArrayType.spec.js +62 -3
- package/dist/types/ArrayType.spec.js.map +1 -1
- package/dist/types/BscType.d.ts +1 -1
- package/dist/types/CustomType.d.ts +1 -1
- package/dist/types/CustomType.js +4 -2
- package/dist/types/CustomType.js.map +1 -1
- package/dist/types/FunctionType.d.ts +5 -5
- package/dist/types/FunctionType.js +11 -11
- package/dist/types/FunctionType.js.map +1 -1
- package/dist/types/FunctionType.spec.js +1 -1
- package/dist/types/FunctionType.spec.js.map +1 -1
- package/dist/types/LazyType.d.ts +1 -2
- package/dist/types/LazyType.js +1 -5
- package/dist/types/LazyType.js.map +1 -1
- package/dist/types/helpers.js +1 -1
- package/dist/types/helpers.js.map +1 -1
- package/dist/util.d.ts +25 -9
- package/dist/util.js +139 -55
- package/dist/util.js.map +1 -1
- package/dist/validators/ClassValidator.js +27 -27
- package/dist/validators/ClassValidator.js.map +1 -1
- package/package.json +4 -3
- package/dist/astUtils/index.d.ts +0 -7
- package/dist/astUtils/index.js +0 -26
- package/dist/astUtils/index.js.map +0 -1
- package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.d.ts +0 -7
- package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.js +0 -63
- package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.js.map +0 -1
- package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.spec.js.map +0 -1
- package/dist/lexer/index.d.ts +0 -3
- package/dist/lexer/index.js +0 -18
- package/dist/lexer/index.js.map +0 -1
- package/dist/parser/index.d.ts +0 -3
- package/dist/parser/index.js +0 -16
- package/dist/parser/index.js.map +0 -1
- package/dist/preprocessor/index.d.ts +0 -3
- package/dist/preprocessor/index.js +0 -16
- package/dist/preprocessor/index.js.map +0 -1
package/dist/parser/Parser.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getBscTypeFromExpression = exports.TokenUsage = exports.References = exports.ParseMode = exports.Parser = void 0;
|
|
4
|
-
const
|
|
4
|
+
const Token_1 = require("../lexer/Token");
|
|
5
|
+
const Lexer_1 = require("../lexer/Lexer");
|
|
6
|
+
const TokenKind_1 = require("../lexer/TokenKind");
|
|
5
7
|
const Statement_1 = require("./Statement");
|
|
6
8
|
const DiagnosticMessages_1 = require("../DiagnosticMessages");
|
|
7
9
|
const util_1 = require("../util");
|
|
@@ -10,12 +12,12 @@ const Logger_1 = require("../Logger");
|
|
|
10
12
|
const reflection_1 = require("../astUtils/reflection");
|
|
11
13
|
const visitors_1 = require("../astUtils/visitors");
|
|
12
14
|
const creators_1 = require("../astUtils/creators");
|
|
15
|
+
const Cache_1 = require("../Cache");
|
|
13
16
|
const DynamicType_1 = require("../types/DynamicType");
|
|
14
|
-
const SymbolTable_1 = require("../SymbolTable");
|
|
15
|
-
const ObjectType_1 = require("../types/ObjectType");
|
|
16
17
|
const ArrayType_1 = require("../types/ArrayType");
|
|
17
18
|
const helpers_1 = require("../types/helpers");
|
|
18
|
-
const
|
|
19
|
+
const SymbolTable_1 = require("../SymbolTable");
|
|
20
|
+
const ObjectType_1 = require("../types/ObjectType");
|
|
19
21
|
class Parser {
|
|
20
22
|
constructor() {
|
|
21
23
|
/**
|
|
@@ -61,7 +63,7 @@ class Parser {
|
|
|
61
63
|
this._references = undefined;
|
|
62
64
|
}
|
|
63
65
|
addPropertyHints(item) {
|
|
64
|
-
if ((0,
|
|
66
|
+
if ((0, Token_1.isToken)(item)) {
|
|
65
67
|
const name = item.text;
|
|
66
68
|
this._references.propertyHints[name.toLowerCase()] = name;
|
|
67
69
|
}
|
|
@@ -93,7 +95,7 @@ class Parser {
|
|
|
93
95
|
static parse(toParse, options) {
|
|
94
96
|
let tokens;
|
|
95
97
|
if (typeof toParse === 'string') {
|
|
96
|
-
tokens =
|
|
98
|
+
tokens = Lexer_1.Lexer.scan(toParse).tokens;
|
|
97
99
|
}
|
|
98
100
|
else {
|
|
99
101
|
tokens = toParse;
|
|
@@ -111,9 +113,9 @@ class Parser {
|
|
|
111
113
|
this.tokens = tokens;
|
|
112
114
|
this.options = this.sanitizeParseOptions(options);
|
|
113
115
|
this.allowedLocalIdentifiers = [
|
|
114
|
-
...
|
|
116
|
+
...TokenKind_1.AllowedLocalIdentifiers,
|
|
115
117
|
//when in plain brightscript mode, the BrighterScript source literals can be used as regular variables
|
|
116
|
-
...(this.options.mode === ParseMode.BrightScript ?
|
|
118
|
+
...(this.options.mode === ParseMode.BrightScript ? TokenKind_1.BrighterScriptSourceLiterals : [])
|
|
117
119
|
];
|
|
118
120
|
this.current = 0;
|
|
119
121
|
this.diagnostics = [];
|
|
@@ -184,16 +186,16 @@ class Parser {
|
|
|
184
186
|
}
|
|
185
187
|
declaration() {
|
|
186
188
|
try {
|
|
187
|
-
if (this.checkAny(
|
|
189
|
+
if (this.checkAny(TokenKind_1.TokenKind.Sub, TokenKind_1.TokenKind.Function)) {
|
|
188
190
|
return this.functionDeclaration(false);
|
|
189
191
|
}
|
|
190
192
|
if (this.checkLibrary()) {
|
|
191
193
|
return this.libraryStatement();
|
|
192
194
|
}
|
|
193
|
-
if (this.check(
|
|
195
|
+
if (this.check(TokenKind_1.TokenKind.At) && this.checkNext(TokenKind_1.TokenKind.Identifier)) {
|
|
194
196
|
return this.annotationExpression();
|
|
195
197
|
}
|
|
196
|
-
if (this.check(
|
|
198
|
+
if (this.check(TokenKind_1.TokenKind.Comment)) {
|
|
197
199
|
return this.commentStatement();
|
|
198
200
|
}
|
|
199
201
|
//catch certain global terminators to prevent unnecessary lookahead (i.e. like `end namespace`, no need to continue)
|
|
@@ -210,18 +212,39 @@ class Parser {
|
|
|
210
212
|
this.synchronize();
|
|
211
213
|
}
|
|
212
214
|
}
|
|
215
|
+
/**
|
|
216
|
+
* Try to get an identifier. If not found, add diagnostic and return undefined
|
|
217
|
+
*/
|
|
218
|
+
tryIdentifier(...additionalTokenKinds) {
|
|
219
|
+
const identifier = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier(), TokenKind_1.TokenKind.Identifier, ...additionalTokenKinds);
|
|
220
|
+
if (identifier) {
|
|
221
|
+
// force the name into an identifier so the AST makes some sense
|
|
222
|
+
identifier.kind = TokenKind_1.TokenKind.Identifier;
|
|
223
|
+
return identifier;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
213
226
|
identifier(...additionalTokenKinds) {
|
|
214
|
-
const identifier = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier(),
|
|
227
|
+
const identifier = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier(), TokenKind_1.TokenKind.Identifier, ...additionalTokenKinds);
|
|
215
228
|
// force the name into an identifier so the AST makes some sense
|
|
216
|
-
identifier.kind =
|
|
229
|
+
identifier.kind = TokenKind_1.TokenKind.Identifier;
|
|
217
230
|
return identifier;
|
|
218
231
|
}
|
|
232
|
+
enumMemberStatement() {
|
|
233
|
+
const statement = new Statement_1.EnumMemberStatement({});
|
|
234
|
+
statement.tokens.name = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedClassFieldIdentifier(), TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedProperties);
|
|
235
|
+
//look for `= SOME_EXPRESSION`
|
|
236
|
+
if (this.check(TokenKind_1.TokenKind.Equal)) {
|
|
237
|
+
statement.tokens.equal = this.advance();
|
|
238
|
+
statement.value = this.expression();
|
|
239
|
+
}
|
|
240
|
+
return statement;
|
|
241
|
+
}
|
|
219
242
|
/**
|
|
220
243
|
* Create a new InterfaceMethodStatement. This should only be called from within `interfaceDeclaration`
|
|
221
244
|
*/
|
|
222
245
|
interfaceFieldStatement() {
|
|
223
|
-
const name = this.identifier(...
|
|
224
|
-
let asToken = this.consumeToken(
|
|
246
|
+
const name = this.identifier(...TokenKind_1.AllowedProperties);
|
|
247
|
+
let asToken = this.consumeToken(TokenKind_1.TokenKind.As);
|
|
225
248
|
let typeToken = this.typeToken();
|
|
226
249
|
const type = util_1.util.tokenToBscType(typeToken);
|
|
227
250
|
if (!type) {
|
|
@@ -235,13 +258,13 @@ class Parser {
|
|
|
235
258
|
*/
|
|
236
259
|
interfaceMethodStatement() {
|
|
237
260
|
const functionType = this.advance();
|
|
238
|
-
const name = this.identifier(...
|
|
239
|
-
const leftParen = this.consumeToken(
|
|
261
|
+
const name = this.identifier(...TokenKind_1.AllowedProperties);
|
|
262
|
+
const leftParen = this.consumeToken(TokenKind_1.TokenKind.LeftParen);
|
|
240
263
|
const params = [];
|
|
241
|
-
const rightParen = this.consumeToken(
|
|
264
|
+
const rightParen = this.consumeToken(TokenKind_1.TokenKind.RightParen);
|
|
242
265
|
let asToken = null;
|
|
243
266
|
let returnTypeToken = null;
|
|
244
|
-
if (this.check(
|
|
267
|
+
if (this.check(TokenKind_1.TokenKind.As)) {
|
|
245
268
|
asToken = this.advance();
|
|
246
269
|
returnTypeToken = this.typeToken();
|
|
247
270
|
const returnType = util_1.util.tokenToBscType(returnTypeToken);
|
|
@@ -255,7 +278,7 @@ class Parser {
|
|
|
255
278
|
interfaceDeclaration() {
|
|
256
279
|
this.warnIfNotBrighterScriptMode('interface declarations');
|
|
257
280
|
const parentAnnotations = this.enterAnnotationBlock();
|
|
258
|
-
const interfaceToken = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedKeyword(
|
|
281
|
+
const interfaceToken = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedKeyword(TokenKind_1.TokenKind.Interface), TokenKind_1.TokenKind.Interface);
|
|
259
282
|
const nameToken = this.identifier(...this.allowedLocalIdentifiers);
|
|
260
283
|
let extendsToken;
|
|
261
284
|
let parentInterfaceName;
|
|
@@ -266,23 +289,23 @@ class Parser {
|
|
|
266
289
|
this.consumeStatementSeparators();
|
|
267
290
|
//gather up all interface members (Fields, Methods)
|
|
268
291
|
let body = [];
|
|
269
|
-
while (this.checkAny(
|
|
292
|
+
while (this.checkAny(TokenKind_1.TokenKind.Comment, TokenKind_1.TokenKind.Identifier, TokenKind_1.TokenKind.At, ...TokenKind_1.AllowedProperties)) {
|
|
270
293
|
try {
|
|
271
294
|
let decl;
|
|
272
295
|
//collect leading annotations
|
|
273
|
-
if (this.check(
|
|
296
|
+
if (this.check(TokenKind_1.TokenKind.At)) {
|
|
274
297
|
this.annotationExpression();
|
|
275
298
|
}
|
|
276
299
|
//fields
|
|
277
|
-
if (this.checkAny(
|
|
300
|
+
if (this.checkAny(TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedProperties) && this.checkNext(TokenKind_1.TokenKind.As)) {
|
|
278
301
|
decl = this.interfaceFieldStatement();
|
|
279
302
|
//methods (function/sub keyword followed by opening paren)
|
|
280
303
|
}
|
|
281
|
-
else if (this.checkAny(
|
|
304
|
+
else if (this.checkAny(TokenKind_1.TokenKind.Function, TokenKind_1.TokenKind.Sub) && this.checkAny(TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedProperties)) {
|
|
282
305
|
decl = this.interfaceMethodStatement();
|
|
283
306
|
//comments
|
|
284
307
|
}
|
|
285
|
-
else if (this.check(
|
|
308
|
+
else if (this.check(TokenKind_1.TokenKind.Comment)) {
|
|
286
309
|
decl = this.commentStatement();
|
|
287
310
|
}
|
|
288
311
|
if (decl) {
|
|
@@ -291,39 +314,87 @@ class Parser {
|
|
|
291
314
|
}
|
|
292
315
|
else {
|
|
293
316
|
//we didn't find a declaration...flag tokens until next line
|
|
294
|
-
this.flagUntil(
|
|
317
|
+
this.flagUntil(TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Colon, TokenKind_1.TokenKind.Eof);
|
|
295
318
|
}
|
|
296
319
|
}
|
|
297
320
|
catch (e) {
|
|
298
321
|
//throw out any failed members and move on to the next line
|
|
299
|
-
this.flagUntil(
|
|
322
|
+
this.flagUntil(TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Colon, TokenKind_1.TokenKind.Eof);
|
|
300
323
|
}
|
|
301
324
|
//ensure statement separator
|
|
302
325
|
this.consumeStatementSeparators();
|
|
303
326
|
//break out of this loop if we encountered the `EndInterface` token not followed by `as`
|
|
304
|
-
if (this.check(
|
|
327
|
+
if (this.check(TokenKind_1.TokenKind.EndInterface) && !this.checkNext(TokenKind_1.TokenKind.As)) {
|
|
305
328
|
break;
|
|
306
329
|
}
|
|
307
330
|
}
|
|
308
331
|
//consume the final `end interface` token
|
|
309
|
-
const endInterfaceToken = this.consumeToken(
|
|
310
|
-
this.consumeStatementSeparators();
|
|
332
|
+
const endInterfaceToken = this.consumeToken(TokenKind_1.TokenKind.EndInterface);
|
|
311
333
|
const statement = new Statement_1.InterfaceStatement(interfaceToken, nameToken, extendsToken, parentInterfaceName, body, endInterfaceToken, this.currentNamespaceName);
|
|
312
334
|
this._references.interfaceStatements.push(statement);
|
|
313
335
|
this.exitAnnotationBlock(parentAnnotations);
|
|
314
336
|
return statement;
|
|
315
337
|
}
|
|
338
|
+
enumDeclaration() {
|
|
339
|
+
const result = new Statement_1.EnumStatement({}, [], this.currentNamespaceName);
|
|
340
|
+
this.warnIfNotBrighterScriptMode('enum declarations');
|
|
341
|
+
const parentAnnotations = this.enterAnnotationBlock();
|
|
342
|
+
result.tokens.enum = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedKeyword(TokenKind_1.TokenKind.Enum), TokenKind_1.TokenKind.Enum);
|
|
343
|
+
result.tokens.name = this.tryIdentifier();
|
|
344
|
+
this.consumeStatementSeparators();
|
|
345
|
+
//gather up all members
|
|
346
|
+
while (this.checkAny(TokenKind_1.TokenKind.Comment, TokenKind_1.TokenKind.Identifier, TokenKind_1.TokenKind.At, ...TokenKind_1.AllowedProperties)) {
|
|
347
|
+
try {
|
|
348
|
+
let decl;
|
|
349
|
+
//collect leading annotations
|
|
350
|
+
if (this.check(TokenKind_1.TokenKind.At)) {
|
|
351
|
+
this.annotationExpression();
|
|
352
|
+
}
|
|
353
|
+
//members
|
|
354
|
+
if (this.checkAny(TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedProperties)) {
|
|
355
|
+
decl = this.enumMemberStatement();
|
|
356
|
+
//comments
|
|
357
|
+
}
|
|
358
|
+
else if (this.check(TokenKind_1.TokenKind.Comment)) {
|
|
359
|
+
decl = this.commentStatement();
|
|
360
|
+
}
|
|
361
|
+
if (decl) {
|
|
362
|
+
this.consumePendingAnnotations(decl);
|
|
363
|
+
result.body.push(decl);
|
|
364
|
+
}
|
|
365
|
+
else {
|
|
366
|
+
//we didn't find a declaration...flag tokens until next line
|
|
367
|
+
this.flagUntil(TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Colon, TokenKind_1.TokenKind.Eof);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
catch (e) {
|
|
371
|
+
//throw out any failed members and move on to the next line
|
|
372
|
+
this.flagUntil(TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Colon, TokenKind_1.TokenKind.Eof);
|
|
373
|
+
}
|
|
374
|
+
//ensure statement separator
|
|
375
|
+
this.consumeStatementSeparators();
|
|
376
|
+
//break out of this loop if we encountered the `EndEnum` token
|
|
377
|
+
if (this.check(TokenKind_1.TokenKind.EndEnum)) {
|
|
378
|
+
break;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
//consume the final `end interface` token
|
|
382
|
+
result.tokens.endEnum = this.consumeToken(TokenKind_1.TokenKind.EndEnum);
|
|
383
|
+
this._references.enumStatements.push(result);
|
|
384
|
+
this.exitAnnotationBlock(parentAnnotations);
|
|
385
|
+
return result;
|
|
386
|
+
}
|
|
316
387
|
/**
|
|
317
388
|
* A BrighterScript class declaration
|
|
318
389
|
*/
|
|
319
390
|
classDeclaration() {
|
|
320
391
|
this.warnIfNotBrighterScriptMode('class declarations');
|
|
321
392
|
const parentAnnotations = this.enterAnnotationBlock();
|
|
322
|
-
let classKeyword = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedKeyword(
|
|
393
|
+
let classKeyword = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedKeyword(TokenKind_1.TokenKind.Class), TokenKind_1.TokenKind.Class);
|
|
323
394
|
let extendsKeyword;
|
|
324
395
|
let parentClassName;
|
|
325
396
|
//get the class name
|
|
326
|
-
let className = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifierAfterKeyword('class'),
|
|
397
|
+
let className = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifierAfterKeyword('class'), TokenKind_1.TokenKind.Identifier, ...this.allowedLocalIdentifiers);
|
|
327
398
|
//see if the class inherits from parent
|
|
328
399
|
if (this.peek().text.toLowerCase() === 'extends') {
|
|
329
400
|
extendsKeyword = this.advance();
|
|
@@ -333,14 +404,14 @@ class Parser {
|
|
|
333
404
|
this.consumeStatementSeparators();
|
|
334
405
|
//gather up all class members (Fields, Methods)
|
|
335
406
|
let body = [];
|
|
336
|
-
while (this.checkAny(
|
|
407
|
+
while (this.checkAny(TokenKind_1.TokenKind.Public, TokenKind_1.TokenKind.Protected, TokenKind_1.TokenKind.Private, TokenKind_1.TokenKind.Function, TokenKind_1.TokenKind.Sub, TokenKind_1.TokenKind.Comment, TokenKind_1.TokenKind.Identifier, TokenKind_1.TokenKind.At, ...TokenKind_1.AllowedProperties)) {
|
|
337
408
|
try {
|
|
338
409
|
let decl;
|
|
339
410
|
let accessModifier;
|
|
340
|
-
if (this.check(
|
|
411
|
+
if (this.check(TokenKind_1.TokenKind.At)) {
|
|
341
412
|
this.annotationExpression();
|
|
342
413
|
}
|
|
343
|
-
if (this.checkAny(
|
|
414
|
+
if (this.checkAny(TokenKind_1.TokenKind.Public, TokenKind_1.TokenKind.Protected, TokenKind_1.TokenKind.Private)) {
|
|
344
415
|
//use actual access modifier
|
|
345
416
|
accessModifier = this.advance();
|
|
346
417
|
}
|
|
@@ -349,7 +420,7 @@ class Parser {
|
|
|
349
420
|
overrideKeyword = this.advance();
|
|
350
421
|
}
|
|
351
422
|
//methods (function/sub keyword OR identifier followed by opening paren)
|
|
352
|
-
if (this.checkAny(
|
|
423
|
+
if (this.checkAny(TokenKind_1.TokenKind.Function, TokenKind_1.TokenKind.Sub) || (this.checkAny(TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedProperties) && this.checkNext(TokenKind_1.TokenKind.LeftParen))) {
|
|
353
424
|
const funcDeclaration = this.functionDeclaration(false, false, true);
|
|
354
425
|
//remove this function from the lists because it's not a callable
|
|
355
426
|
const functionStatement = this._references.functionStatements.pop();
|
|
@@ -362,7 +433,7 @@ class Parser {
|
|
|
362
433
|
functionStatement.func.functionStatement = decl;
|
|
363
434
|
//fields
|
|
364
435
|
}
|
|
365
|
-
else if (this.checkAny(
|
|
436
|
+
else if (this.checkAny(TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedProperties)) {
|
|
366
437
|
decl = this.classFieldDeclaration(accessModifier);
|
|
367
438
|
//class fields cannot be overridden
|
|
368
439
|
if (overrideKeyword) {
|
|
@@ -370,7 +441,7 @@ class Parser {
|
|
|
370
441
|
}
|
|
371
442
|
//comments
|
|
372
443
|
}
|
|
373
|
-
else if (this.check(
|
|
444
|
+
else if (this.check(TokenKind_1.TokenKind.Comment)) {
|
|
374
445
|
decl = this.commentStatement();
|
|
375
446
|
}
|
|
376
447
|
if (decl) {
|
|
@@ -380,13 +451,13 @@ class Parser {
|
|
|
380
451
|
}
|
|
381
452
|
catch (e) {
|
|
382
453
|
//throw out any failed members and move on to the next line
|
|
383
|
-
this.flagUntil(
|
|
454
|
+
this.flagUntil(TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Colon, TokenKind_1.TokenKind.Eof);
|
|
384
455
|
}
|
|
385
456
|
//ensure statement separator
|
|
386
457
|
this.consumeStatementSeparators();
|
|
387
458
|
}
|
|
388
459
|
let endingKeyword = this.advance();
|
|
389
|
-
if (endingKeyword.kind !==
|
|
460
|
+
if (endingKeyword.kind !== TokenKind_1.TokenKind.EndClass) {
|
|
390
461
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.couldNotFindMatchingEndKeyword('class')), { range: endingKeyword.range }));
|
|
391
462
|
}
|
|
392
463
|
const result = new Statement_1.ClassStatement(classKeyword, className, body, endingKeyword, extendsKeyword, parentClassName, this.currentNamespaceName, this.currentSymbolTable);
|
|
@@ -398,11 +469,11 @@ class Parser {
|
|
|
398
469
|
return result;
|
|
399
470
|
}
|
|
400
471
|
classFieldDeclaration(accessModifier) {
|
|
401
|
-
let name = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedClassFieldIdentifier(),
|
|
472
|
+
let name = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedClassFieldIdentifier(), TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedProperties);
|
|
402
473
|
let asToken;
|
|
403
474
|
let fieldType;
|
|
404
475
|
//look for `as SOME_TYPE`
|
|
405
|
-
if (this.check(
|
|
476
|
+
if (this.check(TokenKind_1.TokenKind.As)) {
|
|
406
477
|
asToken = this.advance();
|
|
407
478
|
fieldType = this.typeToken();
|
|
408
479
|
//no field type specified
|
|
@@ -413,7 +484,7 @@ class Parser {
|
|
|
413
484
|
let initialValue;
|
|
414
485
|
let equal;
|
|
415
486
|
//if there is a field initializer
|
|
416
|
-
if (this.check(
|
|
487
|
+
if (this.check(TokenKind_1.TokenKind.Equal)) {
|
|
417
488
|
equal = this.advance();
|
|
418
489
|
initialValue = this.expression();
|
|
419
490
|
}
|
|
@@ -427,14 +498,14 @@ class Parser {
|
|
|
427
498
|
//track depth to help certain statements need to know if they are contained within a function body
|
|
428
499
|
this.namespaceAndFunctionDepth++;
|
|
429
500
|
let functionType;
|
|
430
|
-
if (this.checkAny(
|
|
501
|
+
if (this.checkAny(TokenKind_1.TokenKind.Sub, TokenKind_1.TokenKind.Function)) {
|
|
431
502
|
functionType = this.advance();
|
|
432
503
|
}
|
|
433
504
|
else {
|
|
434
505
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.missingCallableKeyword()), { range: this.peek().range }));
|
|
435
506
|
functionType = {
|
|
436
507
|
isReserved: true,
|
|
437
|
-
kind:
|
|
508
|
+
kind: TokenKind_1.TokenKind.Function,
|
|
438
509
|
text: 'function',
|
|
439
510
|
//zero-length location means derived
|
|
440
511
|
range: {
|
|
@@ -444,16 +515,16 @@ class Parser {
|
|
|
444
515
|
leadingWhitespace: ''
|
|
445
516
|
};
|
|
446
517
|
}
|
|
447
|
-
let isSub = (functionType === null || functionType === void 0 ? void 0 : functionType.kind) ===
|
|
518
|
+
let isSub = (functionType === null || functionType === void 0 ? void 0 : functionType.kind) === TokenKind_1.TokenKind.Sub;
|
|
448
519
|
let functionTypeText = isSub ? 'sub' : 'function';
|
|
449
520
|
let name;
|
|
450
521
|
let leftParen;
|
|
451
522
|
if (isAnonymous) {
|
|
452
|
-
leftParen = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedLeftParenAfterCallable(functionTypeText),
|
|
523
|
+
leftParen = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedLeftParenAfterCallable(functionTypeText), TokenKind_1.TokenKind.LeftParen);
|
|
453
524
|
}
|
|
454
525
|
else {
|
|
455
|
-
name = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedNameAfterCallableKeyword(functionTypeText),
|
|
456
|
-
leftParen = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedLeftParenAfterCallableName(functionTypeText),
|
|
526
|
+
name = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedNameAfterCallableKeyword(functionTypeText), TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedProperties);
|
|
527
|
+
leftParen = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedLeftParenAfterCallableName(functionTypeText), TokenKind_1.TokenKind.LeftParen);
|
|
457
528
|
//prevent functions from ending with type designators
|
|
458
529
|
let lastChar = name.text[name.text.length - 1];
|
|
459
530
|
if (['$', '%', '!', '#', '&'].includes(lastChar)) {
|
|
@@ -461,23 +532,23 @@ class Parser {
|
|
|
461
532
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.functionNameCannotEndWithTypeDesignator(functionTypeText, name.text, lastChar)), { range: name.range }));
|
|
462
533
|
}
|
|
463
534
|
//flag functions with keywords for names (only for standard functions)
|
|
464
|
-
if (checkIdentifier &&
|
|
535
|
+
if (checkIdentifier && TokenKind_1.DisallowedFunctionIdentifiersText.has(name.text.toLowerCase())) {
|
|
465
536
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.cannotUseReservedWordAsIdentifier(name.text)), { range: name.range }));
|
|
466
537
|
}
|
|
467
538
|
}
|
|
468
539
|
let params = [];
|
|
469
540
|
let asToken;
|
|
470
541
|
let typeToken;
|
|
471
|
-
if (!this.check(
|
|
542
|
+
if (!this.check(TokenKind_1.TokenKind.RightParen)) {
|
|
472
543
|
do {
|
|
473
544
|
if (params.length >= Expression_1.CallExpression.MaximumArguments) {
|
|
474
545
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.tooManyCallableParameters(params.length, Expression_1.CallExpression.MaximumArguments)), { range: this.peek().range }));
|
|
475
546
|
}
|
|
476
547
|
params.push(this.functionParameter());
|
|
477
|
-
} while (this.match(
|
|
548
|
+
} while (this.match(TokenKind_1.TokenKind.Comma));
|
|
478
549
|
}
|
|
479
550
|
let rightParen = this.advance();
|
|
480
|
-
if (this.check(
|
|
551
|
+
if (this.check(TokenKind_1.TokenKind.As)) {
|
|
481
552
|
asToken = this.advance();
|
|
482
553
|
typeToken = this.typeToken();
|
|
483
554
|
if (!util_1.util.tokenToBscType(typeToken, this.options.mode === ParseMode.BrighterScript, this.currentNamespaceName)) {
|
|
@@ -529,7 +600,7 @@ class Parser {
|
|
|
529
600
|
}
|
|
530
601
|
// consume 'end sub' or 'end function'
|
|
531
602
|
func.end = this.advance();
|
|
532
|
-
let expectedEndKind = isSub ?
|
|
603
|
+
let expectedEndKind = isSub ? TokenKind_1.TokenKind.EndSub : TokenKind_1.TokenKind.EndFunction;
|
|
533
604
|
//if `function` is ended with `end sub`, or `sub` is ended with `end function`, then
|
|
534
605
|
//add an error but don't hard-fail so the AST can continue more gracefully
|
|
535
606
|
if (func.end.kind !== expectedEndKind) {
|
|
@@ -553,22 +624,22 @@ class Parser {
|
|
|
553
624
|
}
|
|
554
625
|
}
|
|
555
626
|
functionParameter() {
|
|
556
|
-
if (!this.checkAny(
|
|
627
|
+
if (!this.checkAny(TokenKind_1.TokenKind.Identifier, ...this.allowedLocalIdentifiers)) {
|
|
557
628
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.expectedParameterNameButFound(this.peek().text)), { range: this.peek().range }));
|
|
558
629
|
throw this.lastDiagnosticAsError();
|
|
559
630
|
}
|
|
560
|
-
const name = this.identifier(...
|
|
631
|
+
const name = this.identifier(...TokenKind_1.AllowedLocalIdentifiers);
|
|
561
632
|
let typeToken;
|
|
562
633
|
let defaultValue;
|
|
563
634
|
let equalsToken;
|
|
564
635
|
// parse argument default value
|
|
565
|
-
if (this.match(
|
|
636
|
+
if (this.match(TokenKind_1.TokenKind.Equal)) {
|
|
566
637
|
equalsToken = this.previous();
|
|
567
638
|
// it seems any expression is allowed here -- including ones that operate on other arguments!
|
|
568
639
|
defaultValue = this.expression();
|
|
569
640
|
}
|
|
570
641
|
let asToken = null;
|
|
571
|
-
if (this.check(
|
|
642
|
+
if (this.check(TokenKind_1.TokenKind.As)) {
|
|
572
643
|
asToken = this.advance();
|
|
573
644
|
typeToken = this.typeToken();
|
|
574
645
|
if (!util_1.util.tokenToBscType(typeToken, this.options.mode === ParseMode.BrighterScript, this.currentNamespaceName)) {
|
|
@@ -594,17 +665,20 @@ class Parser {
|
|
|
594
665
|
assignment() {
|
|
595
666
|
let name = this.identifier(...this.allowedLocalIdentifiers);
|
|
596
667
|
//add diagnostic if name is a reserved word that cannot be used as an identifier
|
|
597
|
-
if (
|
|
668
|
+
if (TokenKind_1.DisallowedLocalIdentifiersText.has(name.text.toLowerCase())) {
|
|
598
669
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.cannotUseReservedWordAsIdentifier(name.text)), { range: name.range }));
|
|
599
670
|
}
|
|
600
|
-
let operator = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedOperatorAfterIdentifier(
|
|
671
|
+
let operator = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedOperatorAfterIdentifier(TokenKind_1.AssignmentOperators, name.text), ...TokenKind_1.AssignmentOperators);
|
|
601
672
|
let value = this.expression();
|
|
602
673
|
let result;
|
|
603
|
-
if (operator.kind ===
|
|
674
|
+
if (operator.kind === TokenKind_1.TokenKind.Equal) {
|
|
604
675
|
result = new Statement_1.AssignmentStatement(name, operator, value, this.currentFunctionExpression);
|
|
605
676
|
}
|
|
606
677
|
else {
|
|
607
678
|
result = new Statement_1.AssignmentStatement(name, operator, new Expression_1.BinaryExpression(new Expression_1.VariableExpression(name, this.currentNamespaceName), operator, value), this.currentFunctionExpression);
|
|
679
|
+
//remove the right-hand-side expression from this assignment operator, and replace with the full assignment expression
|
|
680
|
+
this._references.expressions.delete(value);
|
|
681
|
+
this._references.expressions.add(result);
|
|
608
682
|
}
|
|
609
683
|
this._references.assignmentStatements.push(result);
|
|
610
684
|
const assignmentType = getBscTypeFromExpression(result.value, this.currentFunctionExpression);
|
|
@@ -612,14 +686,14 @@ class Parser {
|
|
|
612
686
|
return result;
|
|
613
687
|
}
|
|
614
688
|
checkLibrary() {
|
|
615
|
-
let isLibraryToken = this.check(
|
|
689
|
+
let isLibraryToken = this.check(TokenKind_1.TokenKind.Library);
|
|
616
690
|
//if we are at the top level, any line that starts with "library" should be considered a library statement
|
|
617
691
|
if (this.isAtRootLevel() && isLibraryToken) {
|
|
618
692
|
return true;
|
|
619
693
|
//not at root level, library statements are all invalid here, but try to detect if the tokens look
|
|
620
694
|
//like a library statement (and let the libraryStatement function handle emitting the diagnostics)
|
|
621
695
|
}
|
|
622
|
-
else if (isLibraryToken && this.checkNext(
|
|
696
|
+
else if (isLibraryToken && this.checkNext(TokenKind_1.TokenKind.StringLiteral)) {
|
|
623
697
|
return true;
|
|
624
698
|
//definitely not a library statement
|
|
625
699
|
}
|
|
@@ -631,54 +705,54 @@ class Parser {
|
|
|
631
705
|
if (this.checkLibrary()) {
|
|
632
706
|
return this.libraryStatement();
|
|
633
707
|
}
|
|
634
|
-
if (this.check(
|
|
708
|
+
if (this.check(TokenKind_1.TokenKind.Import)) {
|
|
635
709
|
return this.importStatement();
|
|
636
710
|
}
|
|
637
|
-
if (this.check(
|
|
711
|
+
if (this.check(TokenKind_1.TokenKind.Stop)) {
|
|
638
712
|
return this.stopStatement();
|
|
639
713
|
}
|
|
640
|
-
if (this.check(
|
|
714
|
+
if (this.check(TokenKind_1.TokenKind.If)) {
|
|
641
715
|
return this.ifStatement();
|
|
642
716
|
}
|
|
643
717
|
//`try` must be followed by a block, otherwise it could be a local variable
|
|
644
|
-
if (this.check(
|
|
718
|
+
if (this.check(TokenKind_1.TokenKind.Try) && this.checkAnyNext(TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Colon, TokenKind_1.TokenKind.Comment)) {
|
|
645
719
|
return this.tryCatchStatement();
|
|
646
720
|
}
|
|
647
|
-
if (this.check(
|
|
721
|
+
if (this.check(TokenKind_1.TokenKind.Throw)) {
|
|
648
722
|
return this.throwStatement();
|
|
649
723
|
}
|
|
650
|
-
if (this.checkAny(
|
|
724
|
+
if (this.checkAny(TokenKind_1.TokenKind.Print, TokenKind_1.TokenKind.Question)) {
|
|
651
725
|
return this.printStatement();
|
|
652
726
|
}
|
|
653
|
-
if (this.check(
|
|
727
|
+
if (this.check(TokenKind_1.TokenKind.Dim)) {
|
|
654
728
|
return this.dimStatement();
|
|
655
729
|
}
|
|
656
|
-
if (this.check(
|
|
730
|
+
if (this.check(TokenKind_1.TokenKind.While)) {
|
|
657
731
|
return this.whileStatement();
|
|
658
732
|
}
|
|
659
|
-
if (this.check(
|
|
733
|
+
if (this.check(TokenKind_1.TokenKind.ExitWhile)) {
|
|
660
734
|
return this.exitWhile();
|
|
661
735
|
}
|
|
662
|
-
if (this.check(
|
|
736
|
+
if (this.check(TokenKind_1.TokenKind.For)) {
|
|
663
737
|
return this.forStatement();
|
|
664
738
|
}
|
|
665
|
-
if (this.check(
|
|
739
|
+
if (this.check(TokenKind_1.TokenKind.ForEach)) {
|
|
666
740
|
return this.forEachStatement();
|
|
667
741
|
}
|
|
668
|
-
if (this.check(
|
|
742
|
+
if (this.check(TokenKind_1.TokenKind.ExitFor)) {
|
|
669
743
|
return this.exitFor();
|
|
670
744
|
}
|
|
671
|
-
if (this.check(
|
|
745
|
+
if (this.check(TokenKind_1.TokenKind.End)) {
|
|
672
746
|
return this.endStatement();
|
|
673
747
|
}
|
|
674
|
-
if (this.match(
|
|
748
|
+
if (this.match(TokenKind_1.TokenKind.Return)) {
|
|
675
749
|
return this.returnStatement();
|
|
676
750
|
}
|
|
677
|
-
if (this.check(
|
|
751
|
+
if (this.check(TokenKind_1.TokenKind.Goto)) {
|
|
678
752
|
return this.gotoStatement();
|
|
679
753
|
}
|
|
680
754
|
//does this line look like a label? (i.e. `someIdentifier:` )
|
|
681
|
-
if (this.check(
|
|
755
|
+
if (this.check(TokenKind_1.TokenKind.Identifier) && this.checkNext(TokenKind_1.TokenKind.Colon) && this.checkPrevious(TokenKind_1.TokenKind.Newline)) {
|
|
682
756
|
try {
|
|
683
757
|
return this.labelStatement();
|
|
684
758
|
}
|
|
@@ -692,20 +766,23 @@ class Parser {
|
|
|
692
766
|
// BrightScript is like python, in that variables can be declared without a `var`,
|
|
693
767
|
// `let`, (...) keyword. As such, we must check the token *after* an identifier to figure
|
|
694
768
|
// out what to do with it.
|
|
695
|
-
if (this.checkAny(
|
|
696
|
-
this.checkAnyNext(...
|
|
769
|
+
if (this.checkAny(TokenKind_1.TokenKind.Identifier, ...this.allowedLocalIdentifiers) &&
|
|
770
|
+
this.checkAnyNext(...TokenKind_1.AssignmentOperators)) {
|
|
697
771
|
return this.assignment();
|
|
698
772
|
}
|
|
699
773
|
//some BrighterScript keywords are allowed as a local identifiers, so we need to check for them AFTER the assignment check
|
|
700
|
-
if (this.check(
|
|
774
|
+
if (this.check(TokenKind_1.TokenKind.Interface)) {
|
|
701
775
|
return this.interfaceDeclaration();
|
|
702
776
|
}
|
|
703
|
-
if (this.check(
|
|
777
|
+
if (this.check(TokenKind_1.TokenKind.Class)) {
|
|
704
778
|
return this.classDeclaration();
|
|
705
779
|
}
|
|
706
|
-
if (this.check(
|
|
780
|
+
if (this.check(TokenKind_1.TokenKind.Namespace)) {
|
|
707
781
|
return this.namespaceStatement();
|
|
708
782
|
}
|
|
783
|
+
if (this.check(TokenKind_1.TokenKind.Enum)) {
|
|
784
|
+
return this.enumDeclaration();
|
|
785
|
+
}
|
|
709
786
|
// TODO: support multi-statements
|
|
710
787
|
return this.setStatement();
|
|
711
788
|
}
|
|
@@ -713,9 +790,9 @@ class Parser {
|
|
|
713
790
|
const whileKeyword = this.advance();
|
|
714
791
|
const condition = this.expression();
|
|
715
792
|
this.consumeStatementSeparators();
|
|
716
|
-
const whileBlock = this.block(
|
|
793
|
+
const whileBlock = this.block(TokenKind_1.TokenKind.EndWhile);
|
|
717
794
|
let endWhile;
|
|
718
|
-
if (!whileBlock || this.peek().kind !==
|
|
795
|
+
if (!whileBlock || this.peek().kind !== TokenKind_1.TokenKind.EndWhile) {
|
|
719
796
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.couldNotFindMatchingEndKeyword('while')), { range: this.peek().range }));
|
|
720
797
|
if (!whileBlock) {
|
|
721
798
|
throw this.lastDiagnosticAsError();
|
|
@@ -738,7 +815,7 @@ class Parser {
|
|
|
738
815
|
const finalValue = this.expression();
|
|
739
816
|
let incrementExpression;
|
|
740
817
|
let stepToken;
|
|
741
|
-
if (this.check(
|
|
818
|
+
if (this.check(TokenKind_1.TokenKind.Step)) {
|
|
742
819
|
stepToken = this.advance();
|
|
743
820
|
incrementExpression = this.expression();
|
|
744
821
|
}
|
|
@@ -746,9 +823,9 @@ class Parser {
|
|
|
746
823
|
// BrightScript for/to/step loops default to a step of 1 if no `step` is provided
|
|
747
824
|
}
|
|
748
825
|
this.consumeStatementSeparators();
|
|
749
|
-
let body = this.block(
|
|
826
|
+
let body = this.block(TokenKind_1.TokenKind.EndFor, TokenKind_1.TokenKind.Next);
|
|
750
827
|
let endForToken;
|
|
751
|
-
if (!body || !this.checkAny(
|
|
828
|
+
if (!body || !this.checkAny(TokenKind_1.TokenKind.EndFor, TokenKind_1.TokenKind.Next)) {
|
|
752
829
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.expectedEndForOrNextToTerminateForLoop()), { range: this.peek().range }));
|
|
753
830
|
if (!body) {
|
|
754
831
|
throw this.lastDiagnosticAsError();
|
|
@@ -765,7 +842,7 @@ class Parser {
|
|
|
765
842
|
let forEach = this.advance();
|
|
766
843
|
let name = this.identifier(...this.allowedLocalIdentifiers);
|
|
767
844
|
let maybeIn = this.peek();
|
|
768
|
-
if (this.check(
|
|
845
|
+
if (this.check(TokenKind_1.TokenKind.Identifier) && maybeIn.text.toLowerCase() === 'in') {
|
|
769
846
|
this.advance();
|
|
770
847
|
}
|
|
771
848
|
else {
|
|
@@ -778,14 +855,17 @@ class Parser {
|
|
|
778
855
|
throw this.lastDiagnosticAsError();
|
|
779
856
|
}
|
|
780
857
|
this.consumeStatementSeparators();
|
|
781
|
-
let body = this.block(
|
|
858
|
+
let body = this.block(TokenKind_1.TokenKind.EndFor, TokenKind_1.TokenKind.Next);
|
|
782
859
|
if (!body) {
|
|
783
860
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.expectedEndForOrNextToTerminateForLoop()), { range: this.peek().range }));
|
|
784
861
|
throw this.lastDiagnosticAsError();
|
|
785
862
|
}
|
|
786
863
|
let endFor = this.advance();
|
|
787
|
-
|
|
788
|
-
const
|
|
864
|
+
let itemType = new DynamicType_1.DynamicType();
|
|
865
|
+
const targetType = getBscTypeFromExpression(target, this.currentFunctionExpression);
|
|
866
|
+
if ((0, reflection_1.isArrayType)(targetType)) {
|
|
867
|
+
itemType = targetType.getDefaultType();
|
|
868
|
+
}
|
|
789
869
|
this.currentSymbolTable.addSymbol(name.text, name.range, itemType);
|
|
790
870
|
return new Statement_1.ForEachStatement(forEach, name, maybeIn, target, body, endFor);
|
|
791
871
|
}
|
|
@@ -802,7 +882,7 @@ class Parser {
|
|
|
802
882
|
}
|
|
803
883
|
else {
|
|
804
884
|
let comments = [this.advance()];
|
|
805
|
-
while (this.check(
|
|
885
|
+
while (this.check(TokenKind_1.TokenKind.Newline) && this.checkNext(TokenKind_1.TokenKind.Comment)) {
|
|
806
886
|
this.advance();
|
|
807
887
|
comments.push(this.advance());
|
|
808
888
|
}
|
|
@@ -820,13 +900,13 @@ class Parser {
|
|
|
820
900
|
//set the current namespace name
|
|
821
901
|
let result = new Statement_1.NamespaceStatement(keyword, name, null, null, this.currentSymbolTable);
|
|
822
902
|
this.currentNamespace = result;
|
|
823
|
-
this.globalTerminators.push([
|
|
903
|
+
this.globalTerminators.push([TokenKind_1.TokenKind.EndNamespace]);
|
|
824
904
|
let body = this.body();
|
|
825
905
|
this.globalTerminators.pop();
|
|
826
906
|
//unset the current namespace name
|
|
827
907
|
this.currentNamespace = undefined;
|
|
828
908
|
let endKeyword;
|
|
829
|
-
if (this.check(
|
|
909
|
+
if (this.check(TokenKind_1.TokenKind.EndNamespace)) {
|
|
830
910
|
endKeyword = this.advance();
|
|
831
911
|
}
|
|
832
912
|
else {
|
|
@@ -843,24 +923,25 @@ class Parser {
|
|
|
843
923
|
* Get an expression with identifiers separated by periods. Useful for namespaces and class extends
|
|
844
924
|
*/
|
|
845
925
|
getNamespacedVariableNameExpression() {
|
|
846
|
-
let firstIdentifier = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifierAfterKeyword(this.previous().text),
|
|
926
|
+
let firstIdentifier = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifierAfterKeyword(this.previous().text), TokenKind_1.TokenKind.Identifier, ...this.allowedLocalIdentifiers);
|
|
847
927
|
let expr;
|
|
848
928
|
if (firstIdentifier) {
|
|
849
929
|
// force it into an identifier so the AST makes some sense
|
|
850
|
-
firstIdentifier.kind =
|
|
851
|
-
|
|
930
|
+
firstIdentifier.kind = TokenKind_1.TokenKind.Identifier;
|
|
931
|
+
const varExpr = new Expression_1.VariableExpression(firstIdentifier, null);
|
|
932
|
+
expr = varExpr;
|
|
852
933
|
//consume multiple dot identifiers (i.e. `Name.Space.Can.Have.Many.Parts`)
|
|
853
|
-
while (this.check(
|
|
854
|
-
let dot = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.unexpectedToken(this.peek().text),
|
|
934
|
+
while (this.check(TokenKind_1.TokenKind.Dot)) {
|
|
935
|
+
let dot = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.unexpectedToken(this.peek().text), TokenKind_1.TokenKind.Dot);
|
|
855
936
|
if (!dot) {
|
|
856
937
|
break;
|
|
857
938
|
}
|
|
858
|
-
let identifier = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier(),
|
|
939
|
+
let identifier = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier(), TokenKind_1.TokenKind.Identifier, ...this.allowedLocalIdentifiers, ...TokenKind_1.AllowedProperties);
|
|
859
940
|
if (!identifier) {
|
|
860
941
|
break;
|
|
861
942
|
}
|
|
862
943
|
// force it into an identifier so the AST makes some sense
|
|
863
|
-
identifier.kind =
|
|
944
|
+
identifier.kind = TokenKind_1.TokenKind.Identifier;
|
|
864
945
|
expr = new Expression_1.DottedGetExpression(expr, identifier, dot);
|
|
865
946
|
}
|
|
866
947
|
}
|
|
@@ -892,7 +973,7 @@ class Parser {
|
|
|
892
973
|
let libStatement = new Statement_1.LibraryStatement({
|
|
893
974
|
library: this.advance(),
|
|
894
975
|
//grab the next token only if it's a string
|
|
895
|
-
filePath: this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.expectedStringLiteralAfterKeyword('library'),
|
|
976
|
+
filePath: this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.expectedStringLiteralAfterKeyword('library'), TokenKind_1.TokenKind.StringLiteral)
|
|
896
977
|
});
|
|
897
978
|
this._references.libraryStatements.push(libStatement);
|
|
898
979
|
return libStatement;
|
|
@@ -901,20 +982,20 @@ class Parser {
|
|
|
901
982
|
this.warnIfNotBrighterScriptMode('import statements');
|
|
902
983
|
let importStatement = new Statement_1.ImportStatement(this.advance(),
|
|
903
984
|
//grab the next token only if it's a string
|
|
904
|
-
this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.expectedStringLiteralAfterKeyword('import'),
|
|
985
|
+
this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.expectedStringLiteralAfterKeyword('import'), TokenKind_1.TokenKind.StringLiteral));
|
|
905
986
|
this._references.importStatements.push(importStatement);
|
|
906
987
|
return importStatement;
|
|
907
988
|
}
|
|
908
989
|
annotationExpression() {
|
|
909
990
|
const atToken = this.advance();
|
|
910
|
-
const identifier = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier(),
|
|
991
|
+
const identifier = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier(), TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedProperties);
|
|
911
992
|
if (identifier) {
|
|
912
|
-
identifier.kind =
|
|
993
|
+
identifier.kind = TokenKind_1.TokenKind.Identifier;
|
|
913
994
|
}
|
|
914
995
|
let annotation = new Expression_1.AnnotationExpression(atToken, identifier);
|
|
915
996
|
this.pendingAnnotations.push(annotation);
|
|
916
997
|
//optional arguments
|
|
917
|
-
if (this.check(
|
|
998
|
+
if (this.check(TokenKind_1.TokenKind.LeftParen)) {
|
|
918
999
|
let leftParen = this.advance();
|
|
919
1000
|
annotation.call = this.finishCall(leftParen, annotation, false);
|
|
920
1001
|
}
|
|
@@ -927,7 +1008,7 @@ class Parser {
|
|
|
927
1008
|
}
|
|
928
1009
|
const questionMarkToken = this.advance();
|
|
929
1010
|
//consume newlines or comments
|
|
930
|
-
while (this.checkAny(
|
|
1011
|
+
while (this.checkAny(TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Comment)) {
|
|
931
1012
|
this.advance();
|
|
932
1013
|
}
|
|
933
1014
|
let consequent;
|
|
@@ -936,12 +1017,12 @@ class Parser {
|
|
|
936
1017
|
}
|
|
937
1018
|
catch (_a) { }
|
|
938
1019
|
//consume newlines or comments
|
|
939
|
-
while (this.checkAny(
|
|
1020
|
+
while (this.checkAny(TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Comment)) {
|
|
940
1021
|
this.advance();
|
|
941
1022
|
}
|
|
942
|
-
const colonToken = this.tryConsumeToken(
|
|
1023
|
+
const colonToken = this.tryConsumeToken(TokenKind_1.TokenKind.Colon);
|
|
943
1024
|
//consume newlines
|
|
944
|
-
while (this.checkAny(
|
|
1025
|
+
while (this.checkAny(TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Comment)) {
|
|
945
1026
|
this.advance();
|
|
946
1027
|
}
|
|
947
1028
|
let alternate;
|
|
@@ -959,7 +1040,7 @@ class Parser {
|
|
|
959
1040
|
}
|
|
960
1041
|
regexLiteralExpression() {
|
|
961
1042
|
this.warnIfNotBrighterScriptMode('regular expression literal');
|
|
962
|
-
return new
|
|
1043
|
+
return new Expression_1.RegexLiteralExpression({
|
|
963
1044
|
regexLiteral: this.advance()
|
|
964
1045
|
});
|
|
965
1046
|
}
|
|
@@ -968,23 +1049,23 @@ class Parser {
|
|
|
968
1049
|
//get the tag name
|
|
969
1050
|
let tagName;
|
|
970
1051
|
if (isTagged) {
|
|
971
|
-
tagName = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier(),
|
|
1052
|
+
tagName = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier(), TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedProperties);
|
|
972
1053
|
// force it into an identifier so the AST makes some sense
|
|
973
|
-
tagName.kind =
|
|
1054
|
+
tagName.kind = TokenKind_1.TokenKind.Identifier;
|
|
974
1055
|
}
|
|
975
1056
|
let quasis = [];
|
|
976
1057
|
let expressions = [];
|
|
977
1058
|
let openingBacktick = this.peek();
|
|
978
1059
|
this.advance();
|
|
979
1060
|
let currentQuasiExpressionParts = [];
|
|
980
|
-
while (!this.isAtEnd() && !this.check(
|
|
1061
|
+
while (!this.isAtEnd() && !this.check(TokenKind_1.TokenKind.BackTick)) {
|
|
981
1062
|
let next = this.peek();
|
|
982
|
-
if (next.kind ===
|
|
1063
|
+
if (next.kind === TokenKind_1.TokenKind.TemplateStringQuasi) {
|
|
983
1064
|
//a quasi can actually be made up of multiple quasis when it includes char literals
|
|
984
1065
|
currentQuasiExpressionParts.push(new Expression_1.LiteralExpression(next));
|
|
985
1066
|
this.advance();
|
|
986
1067
|
}
|
|
987
|
-
else if (next.kind ===
|
|
1068
|
+
else if (next.kind === TokenKind_1.TokenKind.EscapedCharCodeLiteral) {
|
|
988
1069
|
currentQuasiExpressionParts.push(new Expression_1.EscapedCharCodeLiteralExpression(next));
|
|
989
1070
|
this.advance();
|
|
990
1071
|
}
|
|
@@ -992,12 +1073,12 @@ class Parser {
|
|
|
992
1073
|
//finish up the current quasi
|
|
993
1074
|
quasis.push(new Expression_1.TemplateStringQuasiExpression(currentQuasiExpressionParts));
|
|
994
1075
|
currentQuasiExpressionParts = [];
|
|
995
|
-
if (next.kind ===
|
|
1076
|
+
if (next.kind === TokenKind_1.TokenKind.TemplateStringExpressionBegin) {
|
|
996
1077
|
this.advance();
|
|
997
1078
|
}
|
|
998
1079
|
//now keep this expression
|
|
999
1080
|
expressions.push(this.expression());
|
|
1000
|
-
if (!this.isAtEnd() && this.check(
|
|
1081
|
+
if (!this.isAtEnd() && this.check(TokenKind_1.TokenKind.TemplateStringExpressionEnd)) {
|
|
1001
1082
|
//TODO is it an error if this is not present?
|
|
1002
1083
|
this.advance();
|
|
1003
1084
|
}
|
|
@@ -1029,12 +1110,12 @@ class Parser {
|
|
|
1029
1110
|
const statement = new Statement_1.TryCatchStatement(tryToken);
|
|
1030
1111
|
//ensure statement separator
|
|
1031
1112
|
this.consumeStatementSeparators();
|
|
1032
|
-
statement.tryBranch = this.block(
|
|
1113
|
+
statement.tryBranch = this.block(TokenKind_1.TokenKind.Catch, TokenKind_1.TokenKind.EndTry);
|
|
1033
1114
|
const peek = this.peek();
|
|
1034
|
-
if (peek.kind !==
|
|
1115
|
+
if (peek.kind !== TokenKind_1.TokenKind.Catch) {
|
|
1035
1116
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.expectedCatchBlockInTryCatch()), { range: this.peek().range }));
|
|
1036
1117
|
//gracefully handle end-try
|
|
1037
|
-
if (peek.kind ===
|
|
1118
|
+
if (peek.kind === TokenKind_1.TokenKind.EndTry) {
|
|
1038
1119
|
statement.endTryToken = this.advance();
|
|
1039
1120
|
}
|
|
1040
1121
|
return statement;
|
|
@@ -1042,16 +1123,16 @@ class Parser {
|
|
|
1042
1123
|
else {
|
|
1043
1124
|
statement.catchToken = this.advance();
|
|
1044
1125
|
}
|
|
1045
|
-
const exceptionVarToken = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.missingExceptionVarToFollowCatch(),
|
|
1126
|
+
const exceptionVarToken = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.missingExceptionVarToFollowCatch(), TokenKind_1.TokenKind.Identifier, ...this.allowedLocalIdentifiers);
|
|
1046
1127
|
if (exceptionVarToken) {
|
|
1047
1128
|
// force it into an identifier so the AST makes some sense
|
|
1048
|
-
exceptionVarToken.kind =
|
|
1129
|
+
exceptionVarToken.kind = TokenKind_1.TokenKind.Identifier;
|
|
1049
1130
|
statement.exceptionVariable = exceptionVarToken;
|
|
1050
1131
|
}
|
|
1051
1132
|
//ensure statement sepatator
|
|
1052
1133
|
this.consumeStatementSeparators();
|
|
1053
|
-
statement.catchBranch = this.block(
|
|
1054
|
-
if (this.peek().kind !==
|
|
1134
|
+
statement.catchBranch = this.block(TokenKind_1.TokenKind.EndTry);
|
|
1135
|
+
if (this.peek().kind !== TokenKind_1.TokenKind.EndTry) {
|
|
1055
1136
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.expectedEndTryToTerminateTryCatch()), { range: this.peek().range }));
|
|
1056
1137
|
}
|
|
1057
1138
|
else {
|
|
@@ -1062,7 +1143,7 @@ class Parser {
|
|
|
1062
1143
|
throwStatement() {
|
|
1063
1144
|
const throwToken = this.advance();
|
|
1064
1145
|
let expression;
|
|
1065
|
-
if (this.checkAny(
|
|
1146
|
+
if (this.checkAny(TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Colon)) {
|
|
1066
1147
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.missingExceptionExpressionAfterThrowKeyword()), { range: throwToken.range }));
|
|
1067
1148
|
}
|
|
1068
1149
|
else {
|
|
@@ -1072,19 +1153,19 @@ class Parser {
|
|
|
1072
1153
|
}
|
|
1073
1154
|
dimStatement() {
|
|
1074
1155
|
const dim = this.advance();
|
|
1075
|
-
let identifier = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifierAfterKeyword('dim'),
|
|
1156
|
+
let identifier = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifierAfterKeyword('dim'), TokenKind_1.TokenKind.Identifier, ...this.allowedLocalIdentifiers);
|
|
1076
1157
|
// force to an identifier so the AST makes some sense
|
|
1077
1158
|
if (identifier) {
|
|
1078
|
-
identifier.kind =
|
|
1159
|
+
identifier.kind = TokenKind_1.TokenKind.Identifier;
|
|
1079
1160
|
}
|
|
1080
|
-
let leftSquareBracket = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.missingLeftSquareBracketAfterDimIdentifier(),
|
|
1161
|
+
let leftSquareBracket = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.missingLeftSquareBracketAfterDimIdentifier(), TokenKind_1.TokenKind.LeftSquareBracket);
|
|
1081
1162
|
let expressions = [];
|
|
1082
1163
|
let expression;
|
|
1083
1164
|
do {
|
|
1084
1165
|
try {
|
|
1085
1166
|
expression = this.expression();
|
|
1086
1167
|
expressions.push(expression);
|
|
1087
|
-
if (this.check(
|
|
1168
|
+
if (this.check(TokenKind_1.TokenKind.Comma)) {
|
|
1088
1169
|
this.advance();
|
|
1089
1170
|
}
|
|
1090
1171
|
else {
|
|
@@ -1098,15 +1179,15 @@ class Parser {
|
|
|
1098
1179
|
if (expressions.length === 0) {
|
|
1099
1180
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.missingExpressionsInDimStatement()), { range: this.peek().range }));
|
|
1100
1181
|
}
|
|
1101
|
-
let rightSquareBracket = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.missingRightSquareBracketAfterDimIdentifier(),
|
|
1182
|
+
let rightSquareBracket = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.missingRightSquareBracketAfterDimIdentifier(), TokenKind_1.TokenKind.RightSquareBracket);
|
|
1102
1183
|
return new Statement_1.DimStatement(dim, identifier, leftSquareBracket, expressions, rightSquareBracket);
|
|
1103
1184
|
}
|
|
1104
1185
|
ifStatement() {
|
|
1105
1186
|
// colon before `if` is usually not allowed, unless it's after `then`
|
|
1106
1187
|
if (this.current > 0) {
|
|
1107
1188
|
const prev = this.previous();
|
|
1108
|
-
if (prev.kind ===
|
|
1109
|
-
if (this.current > 1 && this.tokens[this.current - 2].kind !==
|
|
1189
|
+
if (prev.kind === TokenKind_1.TokenKind.Colon) {
|
|
1190
|
+
if (this.current > 1 && this.tokens[this.current - 2].kind !== TokenKind_1.TokenKind.Then) {
|
|
1110
1191
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.unexpectedColonBeforeIfStatement()), { range: prev.range }));
|
|
1111
1192
|
}
|
|
1112
1193
|
}
|
|
@@ -1120,14 +1201,14 @@ class Parser {
|
|
|
1120
1201
|
let endIfToken;
|
|
1121
1202
|
let elseToken;
|
|
1122
1203
|
//optional `then`
|
|
1123
|
-
if (this.check(
|
|
1204
|
+
if (this.check(TokenKind_1.TokenKind.Then)) {
|
|
1124
1205
|
thenToken = this.advance();
|
|
1125
1206
|
}
|
|
1126
1207
|
//is it inline or multi-line if?
|
|
1127
|
-
const isInlineIfThen = !this.checkAny(
|
|
1208
|
+
const isInlineIfThen = !this.checkAny(TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Colon, TokenKind_1.TokenKind.Comment);
|
|
1128
1209
|
if (isInlineIfThen) {
|
|
1129
1210
|
/*** PARSE INLINE IF STATEMENT ***/
|
|
1130
|
-
thenBranch = this.inlineConditionalBranch(
|
|
1211
|
+
thenBranch = this.inlineConditionalBranch(TokenKind_1.TokenKind.Else, TokenKind_1.TokenKind.EndIf);
|
|
1131
1212
|
if (!thenBranch) {
|
|
1132
1213
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.expectedStatementToFollowConditionalCondition(ifToken.text)), { range: this.peek().range }));
|
|
1133
1214
|
throw this.lastDiagnosticAsError();
|
|
@@ -1136,9 +1217,9 @@ class Parser {
|
|
|
1136
1217
|
this.ensureInline(thenBranch.statements);
|
|
1137
1218
|
}
|
|
1138
1219
|
//else branch
|
|
1139
|
-
if (this.check(
|
|
1220
|
+
if (this.check(TokenKind_1.TokenKind.Else)) {
|
|
1140
1221
|
elseToken = this.advance();
|
|
1141
|
-
if (this.check(
|
|
1222
|
+
if (this.check(TokenKind_1.TokenKind.If)) {
|
|
1142
1223
|
// recurse-read `else if`
|
|
1143
1224
|
elseBranch = this.ifStatement();
|
|
1144
1225
|
//no multi-line if chained with an inline if
|
|
@@ -1146,13 +1227,13 @@ class Parser {
|
|
|
1146
1227
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.expectedInlineIfStatement()), { range: elseBranch.range }));
|
|
1147
1228
|
}
|
|
1148
1229
|
}
|
|
1149
|
-
else if (this.checkAny(
|
|
1230
|
+
else if (this.checkAny(TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Colon)) {
|
|
1150
1231
|
//expecting inline else branch
|
|
1151
1232
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.expectedInlineIfStatement()), { range: this.peek().range }));
|
|
1152
1233
|
throw this.lastDiagnosticAsError();
|
|
1153
1234
|
}
|
|
1154
1235
|
else {
|
|
1155
|
-
elseBranch = this.inlineConditionalBranch(
|
|
1236
|
+
elseBranch = this.inlineConditionalBranch(TokenKind_1.TokenKind.Else, TokenKind_1.TokenKind.EndIf);
|
|
1156
1237
|
if (elseBranch) {
|
|
1157
1238
|
this.ensureInline(elseBranch.statements);
|
|
1158
1239
|
}
|
|
@@ -1166,9 +1247,9 @@ class Parser {
|
|
|
1166
1247
|
if (!elseBranch || !(0, reflection_1.isIfStatement)(elseBranch)) {
|
|
1167
1248
|
//enforce newline at the end of the inline if statement
|
|
1168
1249
|
const peek = this.peek();
|
|
1169
|
-
if (peek.kind !==
|
|
1250
|
+
if (peek.kind !== TokenKind_1.TokenKind.Newline && peek.kind !== TokenKind_1.TokenKind.Comment && !this.isAtEnd()) {
|
|
1170
1251
|
//ignore last error if it was about a colon
|
|
1171
|
-
if (this.previous().kind ===
|
|
1252
|
+
if (this.previous().kind === TokenKind_1.TokenKind.Colon) {
|
|
1172
1253
|
this.diagnostics.pop();
|
|
1173
1254
|
this.current--;
|
|
1174
1255
|
}
|
|
@@ -1183,9 +1264,9 @@ class Parser {
|
|
|
1183
1264
|
//ensure newline/colon before next keyword
|
|
1184
1265
|
this.ensureNewLineOrColon();
|
|
1185
1266
|
//else branch
|
|
1186
|
-
if (this.check(
|
|
1267
|
+
if (this.check(TokenKind_1.TokenKind.Else)) {
|
|
1187
1268
|
elseToken = this.advance();
|
|
1188
|
-
if (this.check(
|
|
1269
|
+
if (this.check(TokenKind_1.TokenKind.If)) {
|
|
1189
1270
|
// recurse-read `else if`
|
|
1190
1271
|
elseBranch = this.ifStatement();
|
|
1191
1272
|
}
|
|
@@ -1196,7 +1277,7 @@ class Parser {
|
|
|
1196
1277
|
}
|
|
1197
1278
|
}
|
|
1198
1279
|
if (!(0, reflection_1.isIfStatement)(elseBranch)) {
|
|
1199
|
-
if (this.check(
|
|
1280
|
+
if (this.check(TokenKind_1.TokenKind.EndIf)) {
|
|
1200
1281
|
endIfToken = this.advance();
|
|
1201
1282
|
}
|
|
1202
1283
|
else {
|
|
@@ -1219,7 +1300,7 @@ class Parser {
|
|
|
1219
1300
|
let diagnosticsLengthBeforeBlock = this.diagnostics.length;
|
|
1220
1301
|
// we're parsing a multi-line ("block") form of the BrightScript if/then and must find
|
|
1221
1302
|
// a trailing "end if" or "else if"
|
|
1222
|
-
let branch = this.block(
|
|
1303
|
+
let branch = this.block(TokenKind_1.TokenKind.EndIf, TokenKind_1.TokenKind.Else);
|
|
1223
1304
|
if (!branch) {
|
|
1224
1305
|
//throw out any new diagnostics created as a result of a `then` block parse failure.
|
|
1225
1306
|
//the block() function will discard the current line, so any discarded diagnostics will
|
|
@@ -1233,7 +1314,7 @@ class Parser {
|
|
|
1233
1314
|
}
|
|
1234
1315
|
ensureNewLineOrColon(silent = false) {
|
|
1235
1316
|
const prev = this.previous().kind;
|
|
1236
|
-
if (prev !==
|
|
1317
|
+
if (prev !== TokenKind_1.TokenKind.Newline && prev !== TokenKind_1.TokenKind.Colon) {
|
|
1237
1318
|
if (!silent) {
|
|
1238
1319
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.expectedNewlineOrColon()), { range: this.peek().range }));
|
|
1239
1320
|
}
|
|
@@ -1262,12 +1343,12 @@ class Parser {
|
|
|
1262
1343
|
const startingRange = statement.range;
|
|
1263
1344
|
//look for colon statement separator
|
|
1264
1345
|
let foundColon = false;
|
|
1265
|
-
while (this.match(
|
|
1346
|
+
while (this.match(TokenKind_1.TokenKind.Colon)) {
|
|
1266
1347
|
foundColon = true;
|
|
1267
1348
|
}
|
|
1268
1349
|
//if a colon was found, add the next statement or err if unexpected
|
|
1269
1350
|
if (foundColon) {
|
|
1270
|
-
if (!this.checkAny(
|
|
1351
|
+
if (!this.checkAny(TokenKind_1.TokenKind.Newline, ...additionalTerminators)) {
|
|
1271
1352
|
//if not an ending keyword, add next statement
|
|
1272
1353
|
let extra = this.inlineConditionalBranch(...additionalTerminators);
|
|
1273
1354
|
if (!extra) {
|
|
@@ -1285,9 +1366,9 @@ class Parser {
|
|
|
1285
1366
|
}
|
|
1286
1367
|
expressionStatement(expr) {
|
|
1287
1368
|
let expressionStart = this.peek();
|
|
1288
|
-
if (this.checkAny(
|
|
1369
|
+
if (this.checkAny(TokenKind_1.TokenKind.PlusPlus, TokenKind_1.TokenKind.MinusMinus)) {
|
|
1289
1370
|
let operator = this.advance();
|
|
1290
|
-
if (this.checkAny(
|
|
1371
|
+
if (this.checkAny(TokenKind_1.TokenKind.PlusPlus, TokenKind_1.TokenKind.MinusMinus)) {
|
|
1291
1372
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.consecutiveIncrementDecrementOperatorsAreNotAllowed()), { range: this.peek().range }));
|
|
1292
1373
|
throw this.lastDiagnosticAsError();
|
|
1293
1374
|
}
|
|
@@ -1295,7 +1376,9 @@ class Parser {
|
|
|
1295
1376
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.incrementDecrementOperatorsAreNotAllowedAsResultOfFunctionCall()), { range: expressionStart.range }));
|
|
1296
1377
|
throw this.lastDiagnosticAsError();
|
|
1297
1378
|
}
|
|
1298
|
-
|
|
1379
|
+
const result = new Statement_1.IncrementStatement(expr, operator);
|
|
1380
|
+
this._references.expressions.add(result);
|
|
1381
|
+
return result;
|
|
1299
1382
|
}
|
|
1300
1383
|
if ((0, reflection_1.isCallExpression)(expr) || (0, reflection_1.isCallfuncExpression)(expr)) {
|
|
1301
1384
|
return new Statement_1.ExpressionStatement(expr);
|
|
@@ -1312,18 +1395,18 @@ class Parser {
|
|
|
1312
1395
|
* priority as standalone function calls though, so we can parse them in the same way.
|
|
1313
1396
|
*/
|
|
1314
1397
|
let expr = this.call();
|
|
1315
|
-
if (this.checkAny(...
|
|
1398
|
+
if (this.checkAny(...TokenKind_1.AssignmentOperators) && !((0, reflection_1.isCallExpression)(expr))) {
|
|
1316
1399
|
let left = expr;
|
|
1317
1400
|
let operator = this.advance();
|
|
1318
1401
|
let right = this.expression();
|
|
1319
1402
|
// Create a dotted or indexed "set" based on the left-hand side's type
|
|
1320
1403
|
if ((0, reflection_1.isIndexedGetExpression)(left)) {
|
|
1321
|
-
return new Statement_1.IndexedSetStatement(left.obj, left.index, operator.kind ===
|
|
1404
|
+
return new Statement_1.IndexedSetStatement(left.obj, left.index, operator.kind === TokenKind_1.TokenKind.Equal
|
|
1322
1405
|
? right
|
|
1323
1406
|
: new Expression_1.BinaryExpression(left, operator, right), left.openingSquare, left.closingSquare);
|
|
1324
1407
|
}
|
|
1325
1408
|
else if ((0, reflection_1.isDottedGetExpression)(left)) {
|
|
1326
|
-
const dottedSetStmt = new Statement_1.DottedSetStatement(left.obj, left.name, operator.kind ===
|
|
1409
|
+
const dottedSetStmt = new Statement_1.DottedSetStatement(left.obj, left.name, operator.kind === TokenKind_1.TokenKind.Equal
|
|
1327
1410
|
? right
|
|
1328
1411
|
: new Expression_1.BinaryExpression(left, operator, right));
|
|
1329
1412
|
this._references.dottedSetStatements.push(dottedSetStmt);
|
|
@@ -1336,13 +1419,13 @@ class Parser {
|
|
|
1336
1419
|
let printKeyword = this.advance();
|
|
1337
1420
|
let values = [];
|
|
1338
1421
|
while (!this.checkEndOfStatement()) {
|
|
1339
|
-
if (this.check(
|
|
1422
|
+
if (this.check(TokenKind_1.TokenKind.Semicolon)) {
|
|
1340
1423
|
values.push(this.advance());
|
|
1341
1424
|
}
|
|
1342
|
-
else if (this.check(
|
|
1425
|
+
else if (this.check(TokenKind_1.TokenKind.Comma)) {
|
|
1343
1426
|
values.push(this.advance());
|
|
1344
1427
|
}
|
|
1345
|
-
else if (this.check(
|
|
1428
|
+
else if (this.check(TokenKind_1.TokenKind.Else)) {
|
|
1346
1429
|
break; // inline branch
|
|
1347
1430
|
}
|
|
1348
1431
|
else {
|
|
@@ -1355,7 +1438,7 @@ class Parser {
|
|
|
1355
1438
|
values.push(emptyStringLiteral);
|
|
1356
1439
|
}
|
|
1357
1440
|
let last = values[values.length - 1];
|
|
1358
|
-
if ((0,
|
|
1441
|
+
if ((0, Token_1.isToken)(last)) {
|
|
1359
1442
|
// TODO: error, expected value
|
|
1360
1443
|
}
|
|
1361
1444
|
return new Statement_1.PrintStatement({ print: printKeyword }, values);
|
|
@@ -1369,7 +1452,7 @@ class Parser {
|
|
|
1369
1452
|
if (this.checkEndOfStatement()) {
|
|
1370
1453
|
return new Statement_1.ReturnStatement(tokens);
|
|
1371
1454
|
}
|
|
1372
|
-
let toReturn = this.check(
|
|
1455
|
+
let toReturn = this.check(TokenKind_1.TokenKind.Else) ? undefined : this.expression();
|
|
1373
1456
|
return new Statement_1.ReturnStatement(tokens, toReturn);
|
|
1374
1457
|
}
|
|
1375
1458
|
/**
|
|
@@ -1382,7 +1465,7 @@ class Parser {
|
|
|
1382
1465
|
colon: this.advance()
|
|
1383
1466
|
};
|
|
1384
1467
|
//label must be alone on its line, this is probably not a label
|
|
1385
|
-
if (!this.checkAny(
|
|
1468
|
+
if (!this.checkAny(TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Comment)) {
|
|
1386
1469
|
//rewind and cancel
|
|
1387
1470
|
this.current -= 2;
|
|
1388
1471
|
throw new CancelStatementError();
|
|
@@ -1398,7 +1481,7 @@ class Parser {
|
|
|
1398
1481
|
gotoStatement() {
|
|
1399
1482
|
let tokens = {
|
|
1400
1483
|
goto: this.advance(),
|
|
1401
|
-
label: this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedLabelIdentifierAfterGotoKeyword(),
|
|
1484
|
+
label: this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedLabelIdentifierAfterGotoKeyword(), TokenKind_1.TokenKind.Identifier)
|
|
1402
1485
|
};
|
|
1403
1486
|
return new Statement_1.GotoStatement(tokens);
|
|
1404
1487
|
}
|
|
@@ -1429,7 +1512,7 @@ class Parser {
|
|
|
1429
1512
|
this.consumeStatementSeparators(true);
|
|
1430
1513
|
let startingToken = this.peek();
|
|
1431
1514
|
const statements = [];
|
|
1432
|
-
while (!this.isAtEnd() && !this.checkAny(
|
|
1515
|
+
while (!this.isAtEnd() && !this.checkAny(TokenKind_1.TokenKind.EndSub, TokenKind_1.TokenKind.EndFunction, ...terminators)) {
|
|
1433
1516
|
//grab the location of the current token
|
|
1434
1517
|
let loopCurrent = this.current;
|
|
1435
1518
|
let dec = this.declaration();
|
|
@@ -1445,7 +1528,7 @@ class Parser {
|
|
|
1445
1528
|
//something went wrong. reset to the top of the loop
|
|
1446
1529
|
this.current = loopCurrent;
|
|
1447
1530
|
//scrap the entire line (hopefully whatever failed has added a diagnostic)
|
|
1448
|
-
this.consumeUntil(
|
|
1531
|
+
this.consumeUntil(TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Colon, TokenKind_1.TokenKind.Eof);
|
|
1449
1532
|
//trash the next token. this prevents an infinite loop. not exactly sure why we need this,
|
|
1450
1533
|
//but there's already an error in the file being parsed, so just leave this line here
|
|
1451
1534
|
this.advance();
|
|
@@ -1462,8 +1545,8 @@ class Parser {
|
|
|
1462
1545
|
//if so, we need to restore the statement separator
|
|
1463
1546
|
let prev = this.previous().kind;
|
|
1464
1547
|
let peek = this.peek().kind;
|
|
1465
|
-
if ((peek ===
|
|
1466
|
-
(prev ===
|
|
1548
|
+
if ((peek === TokenKind_1.TokenKind.EndSub || peek === TokenKind_1.TokenKind.EndFunction) &&
|
|
1549
|
+
(prev === TokenKind_1.TokenKind.Newline || prev === TokenKind_1.TokenKind.Colon)) {
|
|
1467
1550
|
this.current--;
|
|
1468
1551
|
}
|
|
1469
1552
|
}
|
|
@@ -1495,13 +1578,15 @@ class Parser {
|
|
|
1495
1578
|
this.pendingAnnotations = parentAnnotations;
|
|
1496
1579
|
}
|
|
1497
1580
|
expression() {
|
|
1498
|
-
|
|
1581
|
+
const expression = this.anonymousFunction();
|
|
1582
|
+
this._references.expressions.add(expression);
|
|
1583
|
+
return expression;
|
|
1499
1584
|
}
|
|
1500
1585
|
anonymousFunction() {
|
|
1501
|
-
if (this.checkAny(
|
|
1586
|
+
if (this.checkAny(TokenKind_1.TokenKind.Sub, TokenKind_1.TokenKind.Function)) {
|
|
1502
1587
|
const func = this.functionDeclaration(true);
|
|
1503
1588
|
//if there's an open paren after this, this is an IIFE
|
|
1504
|
-
if (this.check(
|
|
1589
|
+
if (this.check(TokenKind_1.TokenKind.LeftParen)) {
|
|
1505
1590
|
return this.finishCall(this.advance(), func);
|
|
1506
1591
|
}
|
|
1507
1592
|
else {
|
|
@@ -1509,10 +1594,10 @@ class Parser {
|
|
|
1509
1594
|
}
|
|
1510
1595
|
}
|
|
1511
1596
|
let expr = this.boolean();
|
|
1512
|
-
if (this.check(
|
|
1597
|
+
if (this.check(TokenKind_1.TokenKind.Question)) {
|
|
1513
1598
|
return this.ternaryExpression(expr);
|
|
1514
1599
|
}
|
|
1515
|
-
else if (this.check(
|
|
1600
|
+
else if (this.check(TokenKind_1.TokenKind.QuestionQuestion)) {
|
|
1516
1601
|
return this.nullCoalescingExpression(expr);
|
|
1517
1602
|
}
|
|
1518
1603
|
else {
|
|
@@ -1521,7 +1606,7 @@ class Parser {
|
|
|
1521
1606
|
}
|
|
1522
1607
|
boolean() {
|
|
1523
1608
|
let expr = this.relational();
|
|
1524
|
-
while (this.matchAny(
|
|
1609
|
+
while (this.matchAny(TokenKind_1.TokenKind.And, TokenKind_1.TokenKind.Or)) {
|
|
1525
1610
|
let operator = this.previous();
|
|
1526
1611
|
let right = this.relational();
|
|
1527
1612
|
expr = new Expression_1.BinaryExpression(expr, operator, right);
|
|
@@ -1530,7 +1615,7 @@ class Parser {
|
|
|
1530
1615
|
}
|
|
1531
1616
|
relational() {
|
|
1532
1617
|
let expr = this.additive();
|
|
1533
|
-
while (this.matchAny(
|
|
1618
|
+
while (this.matchAny(TokenKind_1.TokenKind.Equal, TokenKind_1.TokenKind.LessGreater, TokenKind_1.TokenKind.Greater, TokenKind_1.TokenKind.GreaterEqual, TokenKind_1.TokenKind.Less, TokenKind_1.TokenKind.LessEqual)) {
|
|
1534
1619
|
let operator = this.previous();
|
|
1535
1620
|
let right = this.additive();
|
|
1536
1621
|
expr = new Expression_1.BinaryExpression(expr, operator, right);
|
|
@@ -1540,7 +1625,7 @@ class Parser {
|
|
|
1540
1625
|
// TODO: bitshift
|
|
1541
1626
|
additive() {
|
|
1542
1627
|
let expr = this.multiplicative();
|
|
1543
|
-
while (this.matchAny(
|
|
1628
|
+
while (this.matchAny(TokenKind_1.TokenKind.Plus, TokenKind_1.TokenKind.Minus)) {
|
|
1544
1629
|
let operator = this.previous();
|
|
1545
1630
|
let right = this.multiplicative();
|
|
1546
1631
|
expr = new Expression_1.BinaryExpression(expr, operator, right);
|
|
@@ -1549,7 +1634,7 @@ class Parser {
|
|
|
1549
1634
|
}
|
|
1550
1635
|
multiplicative() {
|
|
1551
1636
|
let expr = this.exponential();
|
|
1552
|
-
while (this.matchAny(
|
|
1637
|
+
while (this.matchAny(TokenKind_1.TokenKind.Forwardslash, TokenKind_1.TokenKind.Backslash, TokenKind_1.TokenKind.Star, TokenKind_1.TokenKind.Mod, TokenKind_1.TokenKind.LeftShift, TokenKind_1.TokenKind.RightShift)) {
|
|
1553
1638
|
let operator = this.previous();
|
|
1554
1639
|
let right = this.exponential();
|
|
1555
1640
|
expr = new Expression_1.BinaryExpression(expr, operator, right);
|
|
@@ -1558,7 +1643,7 @@ class Parser {
|
|
|
1558
1643
|
}
|
|
1559
1644
|
exponential() {
|
|
1560
1645
|
let expr = this.prefixUnary();
|
|
1561
|
-
while (this.match(
|
|
1646
|
+
while (this.match(TokenKind_1.TokenKind.Caret)) {
|
|
1562
1647
|
let operator = this.previous();
|
|
1563
1648
|
let right = this.prefixUnary();
|
|
1564
1649
|
expr = new Expression_1.BinaryExpression(expr, operator, right);
|
|
@@ -1567,7 +1652,7 @@ class Parser {
|
|
|
1567
1652
|
}
|
|
1568
1653
|
prefixUnary() {
|
|
1569
1654
|
const nextKind = this.peek().kind;
|
|
1570
|
-
if (nextKind ===
|
|
1655
|
+
if (nextKind === TokenKind_1.TokenKind.Not || nextKind === TokenKind_1.TokenKind.Minus) {
|
|
1571
1656
|
this.current++; //advance
|
|
1572
1657
|
let operator = this.previous();
|
|
1573
1658
|
let right = this.prefixUnary();
|
|
@@ -1577,17 +1662,17 @@ class Parser {
|
|
|
1577
1662
|
}
|
|
1578
1663
|
indexedGet(expr) {
|
|
1579
1664
|
let openingSquare = this.previous();
|
|
1580
|
-
while (this.match(
|
|
1665
|
+
while (this.match(TokenKind_1.TokenKind.Newline)) { }
|
|
1581
1666
|
let index = this.expression();
|
|
1582
|
-
while (this.match(
|
|
1583
|
-
let closingSquare = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedRightSquareBraceAfterArrayOrObjectIndex(),
|
|
1667
|
+
while (this.match(TokenKind_1.TokenKind.Newline)) { }
|
|
1668
|
+
let closingSquare = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedRightSquareBraceAfterArrayOrObjectIndex(), TokenKind_1.TokenKind.RightSquareBracket);
|
|
1584
1669
|
return new Expression_1.IndexedGetExpression(expr, index, openingSquare, closingSquare);
|
|
1585
1670
|
}
|
|
1586
1671
|
newExpression() {
|
|
1587
1672
|
this.warnIfNotBrighterScriptMode(`using 'new' keyword to construct a class`);
|
|
1588
1673
|
let newToken = this.advance();
|
|
1589
1674
|
let nameExpr = this.getNamespacedVariableNameExpression();
|
|
1590
|
-
let leftParen = this.consume(DiagnosticMessages_1.DiagnosticMessages.unexpectedToken(this.peek().text),
|
|
1675
|
+
let leftParen = this.consume(DiagnosticMessages_1.DiagnosticMessages.unexpectedToken(this.peek().text), TokenKind_1.TokenKind.LeftParen);
|
|
1591
1676
|
let call = this.finishCall(leftParen, nameExpr);
|
|
1592
1677
|
//pop the call from the callExpressions list because this is technically something else
|
|
1593
1678
|
this.callExpressions.pop();
|
|
@@ -1601,46 +1686,52 @@ class Parser {
|
|
|
1601
1686
|
callfunc(callee) {
|
|
1602
1687
|
this.warnIfNotBrighterScriptMode('callfunc operator');
|
|
1603
1688
|
let operator = this.previous();
|
|
1604
|
-
let methodName = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier(),
|
|
1689
|
+
let methodName = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier(), TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedProperties);
|
|
1605
1690
|
// force it into an identifier so the AST makes some sense
|
|
1606
|
-
methodName.kind =
|
|
1607
|
-
let openParen = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedOpenParenToFollowCallfuncIdentifier(),
|
|
1691
|
+
methodName.kind = TokenKind_1.TokenKind.Identifier;
|
|
1692
|
+
let openParen = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedOpenParenToFollowCallfuncIdentifier(), TokenKind_1.TokenKind.LeftParen);
|
|
1608
1693
|
let call = this.finishCall(openParen, callee, false);
|
|
1609
1694
|
return new Expression_1.CallfuncExpression(callee, operator, methodName, openParen, call.args, call.closingParen);
|
|
1610
1695
|
}
|
|
1611
1696
|
call() {
|
|
1612
|
-
if (this.check(
|
|
1697
|
+
if (this.check(TokenKind_1.TokenKind.New) && this.checkAnyNext(TokenKind_1.TokenKind.Identifier, ...this.allowedLocalIdentifiers)) {
|
|
1613
1698
|
return this.newExpression();
|
|
1614
1699
|
}
|
|
1615
1700
|
let expr = this.primary();
|
|
1701
|
+
//an expression to keep for _references
|
|
1702
|
+
let referenceCallExpression;
|
|
1616
1703
|
while (true) {
|
|
1617
|
-
if (this.match(
|
|
1704
|
+
if (this.match(TokenKind_1.TokenKind.LeftParen)) {
|
|
1618
1705
|
expr = this.finishCall(this.previous(), expr);
|
|
1706
|
+
//store this call expression in references
|
|
1707
|
+
referenceCallExpression = expr;
|
|
1619
1708
|
}
|
|
1620
|
-
else if (this.match(
|
|
1709
|
+
else if (this.match(TokenKind_1.TokenKind.LeftSquareBracket)) {
|
|
1621
1710
|
expr = this.indexedGet(expr);
|
|
1622
1711
|
}
|
|
1623
|
-
else if (this.match(
|
|
1712
|
+
else if (this.match(TokenKind_1.TokenKind.Callfunc)) {
|
|
1624
1713
|
expr = this.callfunc(expr);
|
|
1714
|
+
//store this callfunc expression in references
|
|
1715
|
+
referenceCallExpression = expr;
|
|
1625
1716
|
}
|
|
1626
|
-
else if (this.match(
|
|
1627
|
-
if (this.match(
|
|
1717
|
+
else if (this.match(TokenKind_1.TokenKind.Dot)) {
|
|
1718
|
+
if (this.match(TokenKind_1.TokenKind.LeftSquareBracket)) {
|
|
1628
1719
|
expr = this.indexedGet(expr);
|
|
1629
1720
|
}
|
|
1630
1721
|
else {
|
|
1631
1722
|
let dot = this.previous();
|
|
1632
|
-
let name = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedPropertyNameAfterPeriod(),
|
|
1723
|
+
let name = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedPropertyNameAfterPeriod(), TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedProperties);
|
|
1633
1724
|
// force it into an identifier so the AST makes some sense
|
|
1634
|
-
name.kind =
|
|
1725
|
+
name.kind = TokenKind_1.TokenKind.Identifier;
|
|
1635
1726
|
expr = new Expression_1.DottedGetExpression(expr, name, dot);
|
|
1636
1727
|
this.addPropertyHints(name);
|
|
1637
1728
|
}
|
|
1638
1729
|
}
|
|
1639
|
-
else if (this.check(
|
|
1730
|
+
else if (this.check(TokenKind_1.TokenKind.At)) {
|
|
1640
1731
|
let dot = this.advance();
|
|
1641
|
-
let name = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedAttributeNameAfterAtSymbol(),
|
|
1732
|
+
let name = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedAttributeNameAfterAtSymbol(), TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedProperties);
|
|
1642
1733
|
// force it into an identifier so the AST makes some sense
|
|
1643
|
-
name.kind =
|
|
1734
|
+
name.kind = TokenKind_1.TokenKind.Identifier;
|
|
1644
1735
|
expr = new Expression_1.XmlAttributeGetExpression(expr, name, dot);
|
|
1645
1736
|
//only allow a single `@` expression
|
|
1646
1737
|
break;
|
|
@@ -1649,24 +1740,28 @@ class Parser {
|
|
|
1649
1740
|
break;
|
|
1650
1741
|
}
|
|
1651
1742
|
}
|
|
1743
|
+
//if we found a callExpression, add it to `expressions` in references
|
|
1744
|
+
if (referenceCallExpression) {
|
|
1745
|
+
this._references.expressions.add(referenceCallExpression);
|
|
1746
|
+
}
|
|
1652
1747
|
return expr;
|
|
1653
1748
|
}
|
|
1654
1749
|
finishCall(openingParen, callee, addToCallExpressionList = true) {
|
|
1655
1750
|
let args = [];
|
|
1656
|
-
while (this.match(
|
|
1751
|
+
while (this.match(TokenKind_1.TokenKind.Newline)) {
|
|
1657
1752
|
}
|
|
1658
|
-
if (!this.check(
|
|
1753
|
+
if (!this.check(TokenKind_1.TokenKind.RightParen)) {
|
|
1659
1754
|
do {
|
|
1660
|
-
while (this.match(
|
|
1755
|
+
while (this.match(TokenKind_1.TokenKind.Newline)) { }
|
|
1661
1756
|
if (args.length >= Expression_1.CallExpression.MaximumArguments) {
|
|
1662
1757
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.tooManyCallableArguments(args.length, Expression_1.CallExpression.MaximumArguments)), { range: this.peek().range }));
|
|
1663
1758
|
throw this.lastDiagnosticAsError();
|
|
1664
1759
|
}
|
|
1665
1760
|
args.push(this.expression());
|
|
1666
|
-
} while (this.match(
|
|
1761
|
+
} while (this.match(TokenKind_1.TokenKind.Comma));
|
|
1667
1762
|
}
|
|
1668
|
-
while (this.match(
|
|
1669
|
-
const closingParen = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedRightParenAfterFunctionCallArguments(),
|
|
1763
|
+
while (this.match(TokenKind_1.TokenKind.Newline)) { }
|
|
1764
|
+
const closingParen = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedRightParenAfterFunctionCallArguments(), TokenKind_1.TokenKind.RightParen);
|
|
1670
1765
|
if ((0, reflection_1.isVariableExpression)(callee)) {
|
|
1671
1766
|
callee.isCalled = true;
|
|
1672
1767
|
}
|
|
@@ -1683,15 +1778,15 @@ class Parser {
|
|
|
1683
1778
|
*/
|
|
1684
1779
|
typeToken() {
|
|
1685
1780
|
let typeToken;
|
|
1686
|
-
if (this.checkAny(...
|
|
1781
|
+
if (this.checkAny(...TokenKind_1.DeclarableTypes)) {
|
|
1687
1782
|
// Token is a built in type
|
|
1688
1783
|
typeToken = this.advance();
|
|
1689
1784
|
}
|
|
1690
1785
|
else if (this.options.mode === ParseMode.BrighterScript) {
|
|
1691
1786
|
try {
|
|
1692
|
-
// see if we can get a namespaced
|
|
1787
|
+
// see if we can get a namespaced identifier
|
|
1693
1788
|
const qualifiedType = this.getNamespacedVariableNameExpression();
|
|
1694
|
-
typeToken = (0, creators_1.createToken)(
|
|
1789
|
+
typeToken = (0, creators_1.createToken)(TokenKind_1.TokenKind.Identifier, qualifiedType.getName(this.options.mode), qualifiedType.range);
|
|
1695
1790
|
}
|
|
1696
1791
|
catch (_a) {
|
|
1697
1792
|
//could not get an identifier - just get whatever's next
|
|
@@ -1702,57 +1797,68 @@ class Parser {
|
|
|
1702
1797
|
// just get whatever's next
|
|
1703
1798
|
typeToken = this.advance();
|
|
1704
1799
|
}
|
|
1800
|
+
if (typeToken && this.options.mode === ParseMode.BrighterScript) {
|
|
1801
|
+
// Check if it is an array - that is, if it has `[]` after the type
|
|
1802
|
+
// eg. `string[]` or `SomeKlass[]`
|
|
1803
|
+
if (this.check(TokenKind_1.TokenKind.LeftSquareBracket)) {
|
|
1804
|
+
this.advance();
|
|
1805
|
+
if (this.check(TokenKind_1.TokenKind.RightSquareBracket)) {
|
|
1806
|
+
const rightBracket = this.advance();
|
|
1807
|
+
typeToken = (0, creators_1.createToken)(TokenKind_1.TokenKind.Identifier, typeToken.text + '[]', util_1.util.getRange(typeToken, rightBracket));
|
|
1808
|
+
}
|
|
1809
|
+
}
|
|
1810
|
+
}
|
|
1705
1811
|
return typeToken;
|
|
1706
1812
|
}
|
|
1707
1813
|
primary() {
|
|
1708
1814
|
switch (true) {
|
|
1709
|
-
case this.matchAny(
|
|
1815
|
+
case this.matchAny(TokenKind_1.TokenKind.False, TokenKind_1.TokenKind.True, TokenKind_1.TokenKind.Invalid, TokenKind_1.TokenKind.IntegerLiteral, TokenKind_1.TokenKind.LongIntegerLiteral, TokenKind_1.TokenKind.FloatLiteral, TokenKind_1.TokenKind.DoubleLiteral, TokenKind_1.TokenKind.StringLiteral):
|
|
1710
1816
|
return new Expression_1.LiteralExpression(this.previous());
|
|
1711
1817
|
//capture source literals (LINE_NUM if brightscript, or a bunch of them if brighterscript)
|
|
1712
|
-
case this.matchAny(
|
|
1818
|
+
case this.matchAny(TokenKind_1.TokenKind.LineNumLiteral, ...(this.options.mode === ParseMode.BrightScript ? [] : TokenKind_1.BrighterScriptSourceLiterals)):
|
|
1713
1819
|
return new Expression_1.SourceLiteralExpression(this.previous());
|
|
1714
1820
|
//template string
|
|
1715
|
-
case this.check(
|
|
1821
|
+
case this.check(TokenKind_1.TokenKind.BackTick):
|
|
1716
1822
|
return this.templateString(false);
|
|
1717
1823
|
//tagged template string (currently we do not support spaces between the identifier and the backtick)
|
|
1718
|
-
case this.checkAny(
|
|
1824
|
+
case this.checkAny(TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedLocalIdentifiers) && this.checkNext(TokenKind_1.TokenKind.BackTick):
|
|
1719
1825
|
return this.templateString(true);
|
|
1720
|
-
case this.matchAny(
|
|
1826
|
+
case this.matchAny(TokenKind_1.TokenKind.Identifier, ...this.allowedLocalIdentifiers):
|
|
1721
1827
|
return new Expression_1.VariableExpression(this.previous(), this.currentNamespaceName);
|
|
1722
|
-
case this.match(
|
|
1828
|
+
case this.match(TokenKind_1.TokenKind.LeftParen):
|
|
1723
1829
|
let left = this.previous();
|
|
1724
1830
|
let expr = this.expression();
|
|
1725
|
-
let right = this.consume(DiagnosticMessages_1.DiagnosticMessages.unmatchedLeftParenAfterExpression(),
|
|
1831
|
+
let right = this.consume(DiagnosticMessages_1.DiagnosticMessages.unmatchedLeftParenAfterExpression(), TokenKind_1.TokenKind.RightParen);
|
|
1726
1832
|
return new Expression_1.GroupingExpression({ left: left, right: right }, expr);
|
|
1727
|
-
case this.match(
|
|
1833
|
+
case this.match(TokenKind_1.TokenKind.LeftSquareBracket):
|
|
1728
1834
|
let elements = [];
|
|
1729
1835
|
let openingSquare = this.previous();
|
|
1730
1836
|
//add any comment found right after the opening square
|
|
1731
|
-
if (this.check(
|
|
1837
|
+
if (this.check(TokenKind_1.TokenKind.Comment)) {
|
|
1732
1838
|
elements.push(new Statement_1.CommentStatement([this.advance()]));
|
|
1733
1839
|
}
|
|
1734
|
-
while (this.match(
|
|
1840
|
+
while (this.match(TokenKind_1.TokenKind.Newline)) {
|
|
1735
1841
|
}
|
|
1736
|
-
if (!this.match(
|
|
1842
|
+
if (!this.match(TokenKind_1.TokenKind.RightSquareBracket)) {
|
|
1737
1843
|
elements.push(this.expression());
|
|
1738
|
-
while (this.matchAny(
|
|
1739
|
-
if (this.checkPrevious(
|
|
1740
|
-
let comment = this.check(
|
|
1844
|
+
while (this.matchAny(TokenKind_1.TokenKind.Comma, TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Comment)) {
|
|
1845
|
+
if (this.checkPrevious(TokenKind_1.TokenKind.Comment) || this.check(TokenKind_1.TokenKind.Comment)) {
|
|
1846
|
+
let comment = this.check(TokenKind_1.TokenKind.Comment) ? this.advance() : this.previous();
|
|
1741
1847
|
elements.push(new Statement_1.CommentStatement([comment]));
|
|
1742
1848
|
}
|
|
1743
|
-
while (this.match(
|
|
1849
|
+
while (this.match(TokenKind_1.TokenKind.Newline)) {
|
|
1744
1850
|
}
|
|
1745
|
-
if (this.check(
|
|
1851
|
+
if (this.check(TokenKind_1.TokenKind.RightSquareBracket)) {
|
|
1746
1852
|
break;
|
|
1747
1853
|
}
|
|
1748
1854
|
elements.push(this.expression());
|
|
1749
1855
|
}
|
|
1750
|
-
this.consume(DiagnosticMessages_1.DiagnosticMessages.unmatchedLeftSquareBraceAfterArrayLiteral(),
|
|
1856
|
+
this.consume(DiagnosticMessages_1.DiagnosticMessages.unmatchedLeftSquareBraceAfterArrayLiteral(), TokenKind_1.TokenKind.RightSquareBracket);
|
|
1751
1857
|
}
|
|
1752
1858
|
let closingSquare = this.previous();
|
|
1753
1859
|
//this.consume("Expected newline or ':' after array literal", TokenKind.Newline, TokenKind.Colon, TokenKind.Eof);
|
|
1754
1860
|
return new Expression_1.ArrayLiteralExpression(elements, openingSquare, closingSquare);
|
|
1755
|
-
case this.match(
|
|
1861
|
+
case this.match(TokenKind_1.TokenKind.LeftCurlyBrace):
|
|
1756
1862
|
let openingBrace = this.previous();
|
|
1757
1863
|
let members = [];
|
|
1758
1864
|
let key = () => {
|
|
@@ -1761,25 +1867,25 @@ class Parser {
|
|
|
1761
1867
|
keyToken: null,
|
|
1762
1868
|
range: null
|
|
1763
1869
|
};
|
|
1764
|
-
if (this.checkAny(
|
|
1870
|
+
if (this.checkAny(TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedProperties)) {
|
|
1765
1871
|
result.keyToken = this.advance();
|
|
1766
1872
|
}
|
|
1767
|
-
else if (this.check(
|
|
1873
|
+
else if (this.check(TokenKind_1.TokenKind.StringLiteral)) {
|
|
1768
1874
|
result.keyToken = this.advance();
|
|
1769
1875
|
}
|
|
1770
1876
|
else {
|
|
1771
1877
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.unexpectedAAKey()), { range: this.peek().range }));
|
|
1772
1878
|
throw this.lastDiagnosticAsError();
|
|
1773
1879
|
}
|
|
1774
|
-
result.colonToken = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedColonBetweenAAKeyAndvalue(),
|
|
1880
|
+
result.colonToken = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedColonBetweenAAKeyAndvalue(), TokenKind_1.TokenKind.Colon);
|
|
1775
1881
|
result.range = util_1.util.getRange(result.keyToken, result.colonToken);
|
|
1776
1882
|
return result;
|
|
1777
1883
|
};
|
|
1778
|
-
while (this.match(
|
|
1884
|
+
while (this.match(TokenKind_1.TokenKind.Newline)) {
|
|
1779
1885
|
}
|
|
1780
|
-
if (!this.match(
|
|
1886
|
+
if (!this.match(TokenKind_1.TokenKind.RightCurlyBrace)) {
|
|
1781
1887
|
let lastAAMember;
|
|
1782
|
-
if (this.check(
|
|
1888
|
+
if (this.check(TokenKind_1.TokenKind.Comment)) {
|
|
1783
1889
|
lastAAMember = null;
|
|
1784
1890
|
members.push(new Statement_1.CommentStatement([this.advance()]));
|
|
1785
1891
|
}
|
|
@@ -1789,26 +1895,26 @@ class Parser {
|
|
|
1789
1895
|
lastAAMember = new Expression_1.AAMemberExpression(k.keyToken, k.colonToken, expr, getBscTypeFromExpression(expr, this.currentFunctionExpression));
|
|
1790
1896
|
members.push(lastAAMember);
|
|
1791
1897
|
}
|
|
1792
|
-
while (this.matchAny(
|
|
1898
|
+
while (this.matchAny(TokenKind_1.TokenKind.Comma, TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Colon, TokenKind_1.TokenKind.Comment)) {
|
|
1793
1899
|
// collect comma at end of expression
|
|
1794
|
-
if (lastAAMember && this.checkPrevious(
|
|
1900
|
+
if (lastAAMember && this.checkPrevious(TokenKind_1.TokenKind.Comma)) {
|
|
1795
1901
|
lastAAMember.commaToken = this.previous();
|
|
1796
1902
|
}
|
|
1797
1903
|
//check for comment at the end of the current line
|
|
1798
|
-
if (this.check(
|
|
1799
|
-
let token = this.checkPrevious(
|
|
1904
|
+
if (this.check(TokenKind_1.TokenKind.Comment) || this.checkPrevious(TokenKind_1.TokenKind.Comment)) {
|
|
1905
|
+
let token = this.checkPrevious(TokenKind_1.TokenKind.Comment) ? this.previous() : this.advance();
|
|
1800
1906
|
members.push(new Statement_1.CommentStatement([token]));
|
|
1801
1907
|
}
|
|
1802
1908
|
else {
|
|
1803
1909
|
this.consumeStatementSeparators(true);
|
|
1804
1910
|
//check for a comment on its own line
|
|
1805
|
-
if (this.check(
|
|
1806
|
-
let token = this.checkPrevious(
|
|
1911
|
+
if (this.check(TokenKind_1.TokenKind.Comment) || this.checkPrevious(TokenKind_1.TokenKind.Comment)) {
|
|
1912
|
+
let token = this.checkPrevious(TokenKind_1.TokenKind.Comment) ? this.previous() : this.advance();
|
|
1807
1913
|
lastAAMember = null;
|
|
1808
1914
|
members.push(new Statement_1.CommentStatement([token]));
|
|
1809
1915
|
continue;
|
|
1810
1916
|
}
|
|
1811
|
-
if (this.check(
|
|
1917
|
+
if (this.check(TokenKind_1.TokenKind.RightCurlyBrace)) {
|
|
1812
1918
|
break;
|
|
1813
1919
|
}
|
|
1814
1920
|
let k = key();
|
|
@@ -1817,23 +1923,23 @@ class Parser {
|
|
|
1817
1923
|
members.push(lastAAMember);
|
|
1818
1924
|
}
|
|
1819
1925
|
}
|
|
1820
|
-
this.consume(DiagnosticMessages_1.DiagnosticMessages.unmatchedLeftCurlyAfterAALiteral(),
|
|
1926
|
+
this.consume(DiagnosticMessages_1.DiagnosticMessages.unmatchedLeftCurlyAfterAALiteral(), TokenKind_1.TokenKind.RightCurlyBrace);
|
|
1821
1927
|
}
|
|
1822
1928
|
let closingBrace = this.previous();
|
|
1823
1929
|
const aaExpr = new Expression_1.AALiteralExpression(members, openingBrace, closingBrace, this.currentFunctionExpression);
|
|
1824
1930
|
this._references.aaLiterals.push(aaExpr);
|
|
1825
1931
|
this.addPropertyHints(aaExpr);
|
|
1826
1932
|
return aaExpr;
|
|
1827
|
-
case this.matchAny(
|
|
1933
|
+
case this.matchAny(TokenKind_1.TokenKind.Pos, TokenKind_1.TokenKind.Tab):
|
|
1828
1934
|
let token = Object.assign(this.previous(), {
|
|
1829
|
-
kind:
|
|
1935
|
+
kind: TokenKind_1.TokenKind.Identifier
|
|
1830
1936
|
});
|
|
1831
1937
|
return new Expression_1.VariableExpression(token, this.currentNamespaceName);
|
|
1832
|
-
case this.checkAny(
|
|
1938
|
+
case this.checkAny(TokenKind_1.TokenKind.Function, TokenKind_1.TokenKind.Sub):
|
|
1833
1939
|
return this.anonymousFunction();
|
|
1834
|
-
case this.check(
|
|
1940
|
+
case this.check(TokenKind_1.TokenKind.RegexLiteral):
|
|
1835
1941
|
return this.regexLiteralExpression();
|
|
1836
|
-
case this.check(
|
|
1942
|
+
case this.check(TokenKind_1.TokenKind.Comment):
|
|
1837
1943
|
return new Statement_1.CommentStatement([this.advance()]);
|
|
1838
1944
|
default:
|
|
1839
1945
|
//if we found an expected terminator, don't throw a diagnostic...just return undefined
|
|
@@ -1903,12 +2009,12 @@ class Parser {
|
|
|
1903
2009
|
}
|
|
1904
2010
|
consumeStatementSeparators(optional = false) {
|
|
1905
2011
|
//a comment or EOF mark the end of the statement
|
|
1906
|
-
if (this.isAtEnd() || this.check(
|
|
2012
|
+
if (this.isAtEnd() || this.check(TokenKind_1.TokenKind.Comment)) {
|
|
1907
2013
|
return true;
|
|
1908
2014
|
}
|
|
1909
2015
|
let consumed = false;
|
|
1910
2016
|
//consume any newlines and colons
|
|
1911
|
-
while (this.matchAny(
|
|
2017
|
+
while (this.matchAny(TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Colon)) {
|
|
1912
2018
|
consumed = true;
|
|
1913
2019
|
}
|
|
1914
2020
|
if (!optional && !consumed) {
|
|
@@ -1924,7 +2030,7 @@ class Parser {
|
|
|
1924
2030
|
}
|
|
1925
2031
|
checkEndOfStatement() {
|
|
1926
2032
|
const nextKind = this.peek().kind;
|
|
1927
|
-
return [
|
|
2033
|
+
return [TokenKind_1.TokenKind.Colon, TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Comment, TokenKind_1.TokenKind.Eof].includes(nextKind);
|
|
1928
2034
|
}
|
|
1929
2035
|
checkPrevious(tokenKind) {
|
|
1930
2036
|
var _a;
|
|
@@ -1932,14 +2038,14 @@ class Parser {
|
|
|
1932
2038
|
}
|
|
1933
2039
|
check(tokenKind) {
|
|
1934
2040
|
const nextKind = this.peek().kind;
|
|
1935
|
-
if (nextKind ===
|
|
2041
|
+
if (nextKind === TokenKind_1.TokenKind.Eof) {
|
|
1936
2042
|
return false;
|
|
1937
2043
|
}
|
|
1938
2044
|
return nextKind === tokenKind;
|
|
1939
2045
|
}
|
|
1940
2046
|
checkAny(...tokenKinds) {
|
|
1941
2047
|
const nextKind = this.peek().kind;
|
|
1942
|
-
if (nextKind ===
|
|
2048
|
+
if (nextKind === TokenKind_1.TokenKind.Eof) {
|
|
1943
2049
|
return false;
|
|
1944
2050
|
}
|
|
1945
2051
|
return tokenKinds.includes(nextKind);
|
|
@@ -1958,7 +2064,7 @@ class Parser {
|
|
|
1958
2064
|
return tokenKinds.includes(nextKind);
|
|
1959
2065
|
}
|
|
1960
2066
|
isAtEnd() {
|
|
1961
|
-
return this.peek().kind ===
|
|
2067
|
+
return this.peek().kind === TokenKind_1.TokenKind.Eof;
|
|
1962
2068
|
}
|
|
1963
2069
|
peekNext() {
|
|
1964
2070
|
if (this.isAtEnd()) {
|
|
@@ -1980,16 +2086,16 @@ class Parser {
|
|
|
1980
2086
|
return;
|
|
1981
2087
|
}
|
|
1982
2088
|
switch (this.peek().kind) { //eslint-disable-line @typescript-eslint/switch-exhaustiveness-check
|
|
1983
|
-
case
|
|
1984
|
-
case
|
|
1985
|
-
case
|
|
1986
|
-
case
|
|
1987
|
-
case
|
|
1988
|
-
case
|
|
1989
|
-
case
|
|
1990
|
-
case
|
|
1991
|
-
case
|
|
1992
|
-
case
|
|
2089
|
+
case TokenKind_1.TokenKind.Namespace:
|
|
2090
|
+
case TokenKind_1.TokenKind.Class:
|
|
2091
|
+
case TokenKind_1.TokenKind.Function:
|
|
2092
|
+
case TokenKind_1.TokenKind.Sub:
|
|
2093
|
+
case TokenKind_1.TokenKind.If:
|
|
2094
|
+
case TokenKind_1.TokenKind.For:
|
|
2095
|
+
case TokenKind_1.TokenKind.ForEach:
|
|
2096
|
+
case TokenKind_1.TokenKind.While:
|
|
2097
|
+
case TokenKind_1.TokenKind.Print:
|
|
2098
|
+
case TokenKind_1.TokenKind.Return:
|
|
1993
2099
|
// start parsing again from the next block starter or obvious
|
|
1994
2100
|
// expression start
|
|
1995
2101
|
return;
|
|
@@ -2035,17 +2141,17 @@ class Parser {
|
|
|
2035
2141
|
const previousToken = this.getPreviousToken(closestToken);
|
|
2036
2142
|
const previousTokenKind = previousToken === null || previousToken === void 0 ? void 0 : previousToken.kind;
|
|
2037
2143
|
//next to matched token
|
|
2038
|
-
if (!closestToken || closestToken.kind ===
|
|
2144
|
+
if (!closestToken || closestToken.kind === TokenKind_1.TokenKind.Eof) {
|
|
2039
2145
|
return false;
|
|
2040
2146
|
}
|
|
2041
2147
|
else if (closestToken.kind === tokenKind) {
|
|
2042
2148
|
return true;
|
|
2043
2149
|
}
|
|
2044
|
-
else if (closestToken.kind ===
|
|
2150
|
+
else if (closestToken.kind === TokenKind_1.TokenKind.Newline || previousTokenKind === TokenKind_1.TokenKind.Newline) {
|
|
2045
2151
|
return false;
|
|
2046
2152
|
//next to an identifier, which is next to token kind
|
|
2047
2153
|
}
|
|
2048
|
-
else if (closestToken.kind ===
|
|
2154
|
+
else if (closestToken.kind === TokenKind_1.TokenKind.Identifier && previousTokenKind === tokenKind) {
|
|
2049
2155
|
return true;
|
|
2050
2156
|
}
|
|
2051
2157
|
else {
|
|
@@ -2056,7 +2162,7 @@ class Parser {
|
|
|
2056
2162
|
const index = this.tokens.indexOf(currentToken);
|
|
2057
2163
|
for (let i = index - 1; i >= 0; i--) {
|
|
2058
2164
|
currentToken = this.tokens[i];
|
|
2059
|
-
if (currentToken.kind ===
|
|
2165
|
+
if (currentToken.kind === TokenKind_1.TokenKind.Newline) {
|
|
2060
2166
|
break;
|
|
2061
2167
|
}
|
|
2062
2168
|
else if (currentToken.kind === tokenKind) {
|
|
@@ -2076,7 +2182,7 @@ class Parser {
|
|
|
2076
2182
|
let tokens = [];
|
|
2077
2183
|
for (let i = this.tokens.indexOf(currentToken); direction === -1 ? i >= 0 : i === this.tokens.length; i += direction) {
|
|
2078
2184
|
currentToken = this.tokens[i];
|
|
2079
|
-
if (currentToken.kind ===
|
|
2185
|
+
if (currentToken.kind === TokenKind_1.TokenKind.Newline || currentToken.kind === tokenKind) {
|
|
2080
2186
|
break;
|
|
2081
2187
|
}
|
|
2082
2188
|
tokens.push(currentToken);
|
|
@@ -2147,12 +2253,12 @@ class Parser {
|
|
|
2147
2253
|
currentToken = previousTokenResult === null || previousTokenResult === void 0 ? void 0 : previousTokenResult.token;
|
|
2148
2254
|
currentTokenIndex = previousTokenResult === null || previousTokenResult === void 0 ? void 0 : previousTokenResult.index;
|
|
2149
2255
|
}
|
|
2150
|
-
if ((currentToken === null || currentToken === void 0 ? void 0 : currentToken.kind) ===
|
|
2256
|
+
if ((currentToken === null || currentToken === void 0 ? void 0 : currentToken.kind) === TokenKind_1.TokenKind.Dot) {
|
|
2151
2257
|
previousTokenResult = this.getPreviousTokenFromIndex(currentTokenIndex);
|
|
2152
2258
|
currentToken = previousTokenResult.token;
|
|
2153
2259
|
currentTokenIndex = previousTokenResult.index;
|
|
2154
2260
|
}
|
|
2155
|
-
previousTokenResult = this.getPreviousTokenIgnoreNests(currentTokenIndex,
|
|
2261
|
+
previousTokenResult = this.getPreviousTokenIgnoreNests(currentTokenIndex, TokenKind_1.TokenKind.LeftParen, TokenKind_1.TokenKind.RightParen);
|
|
2156
2262
|
currentToken = previousTokenResult === null || previousTokenResult === void 0 ? void 0 : previousTokenResult.token;
|
|
2157
2263
|
currentTokenIndex = previousTokenResult === null || previousTokenResult === void 0 ? void 0 : previousTokenResult.index;
|
|
2158
2264
|
if (previousTokenResult.hasBrackets) {
|
|
@@ -2160,7 +2266,7 @@ class Parser {
|
|
|
2160
2266
|
}
|
|
2161
2267
|
let tokenTypeIsNotKnowable = previousTokenResult === null || previousTokenResult === void 0 ? void 0 : previousTokenResult.tokenTypeIsNotKnowable;
|
|
2162
2268
|
if (currentTokenIndex) {
|
|
2163
|
-
previousTokenResult = this.getPreviousTokenIgnoreNests(currentTokenIndex,
|
|
2269
|
+
previousTokenResult = this.getPreviousTokenIgnoreNests(currentTokenIndex, TokenKind_1.TokenKind.LeftSquareBracket, TokenKind_1.TokenKind.RightSquareBracket);
|
|
2164
2270
|
currentToken = previousTokenResult === null || previousTokenResult === void 0 ? void 0 : previousTokenResult.token;
|
|
2165
2271
|
currentTokenIndex = previousTokenResult === null || previousTokenResult === void 0 ? void 0 : previousTokenResult.index;
|
|
2166
2272
|
if (previousTokenResult.hasBrackets) {
|
|
@@ -2178,15 +2284,15 @@ class Parser {
|
|
|
2178
2284
|
if (!currentToken || lastTokenHasWhitespace) {
|
|
2179
2285
|
return false;
|
|
2180
2286
|
}
|
|
2181
|
-
if (currentToken.kind ===
|
|
2287
|
+
if (currentToken.kind === TokenKind_1.TokenKind.Identifier) {
|
|
2182
2288
|
return true;
|
|
2183
2289
|
}
|
|
2184
2290
|
if (currentToken.leadingWhitespace.length === 0) {
|
|
2185
2291
|
// start of the chain
|
|
2186
|
-
return
|
|
2292
|
+
return TokenKind_1.AllowedLocalIdentifiers.includes(currentToken.kind);
|
|
2187
2293
|
}
|
|
2188
2294
|
// not the start of the chain
|
|
2189
|
-
return
|
|
2295
|
+
return TokenKind_1.AllowedProperties.includes(currentToken.kind);
|
|
2190
2296
|
}
|
|
2191
2297
|
/**
|
|
2192
2298
|
* Builds up a chain of tokens, starting with the first in the chain, and ending with currentToken
|
|
@@ -2233,32 +2339,67 @@ class Parser {
|
|
|
2233
2339
|
*/
|
|
2234
2340
|
findReferences() {
|
|
2235
2341
|
this._references = new References();
|
|
2342
|
+
const excludedExpressions = new Set();
|
|
2343
|
+
const visitCallExpression = (e) => {
|
|
2344
|
+
for (const p of e.args) {
|
|
2345
|
+
this._references.expressions.add(p);
|
|
2346
|
+
}
|
|
2347
|
+
//add calls that were not excluded (from loop below)
|
|
2348
|
+
if (!excludedExpressions.has(e)) {
|
|
2349
|
+
this._references.expressions.add(e);
|
|
2350
|
+
}
|
|
2351
|
+
//if this call is part of a longer expression that includes a call higher up, find that higher one and remove it
|
|
2352
|
+
if (e.callee) {
|
|
2353
|
+
let node = e.callee;
|
|
2354
|
+
while (node) {
|
|
2355
|
+
//the primary goal for this loop. If we found a parent call expression, remove it from `references`
|
|
2356
|
+
if ((0, reflection_1.isCallExpression)(node)) {
|
|
2357
|
+
this.references.expressions.delete(node);
|
|
2358
|
+
excludedExpressions.add(node);
|
|
2359
|
+
//stop here. even if there are multiple calls in the chain, each child will find and remove its closest parent, so that reduces excess walking.
|
|
2360
|
+
break;
|
|
2361
|
+
//when we hit a variable expression, we're definitely at the leftmost expression so stop
|
|
2362
|
+
}
|
|
2363
|
+
else if ((0, reflection_1.isVariableExpression)(node)) {
|
|
2364
|
+
break;
|
|
2365
|
+
//if
|
|
2366
|
+
}
|
|
2367
|
+
else if ((0, reflection_1.isDottedGetExpression)(node) || (0, reflection_1.isIndexedGetExpression)(node)) {
|
|
2368
|
+
node = node.obj;
|
|
2369
|
+
}
|
|
2370
|
+
else {
|
|
2371
|
+
//some expression we don't understand. log it and quit the loop
|
|
2372
|
+
this.logger.info('Encountered unknown expression while calculating function expression chain', node);
|
|
2373
|
+
break;
|
|
2374
|
+
}
|
|
2375
|
+
}
|
|
2376
|
+
}
|
|
2377
|
+
};
|
|
2236
2378
|
//gather up all the top-level statements
|
|
2237
2379
|
this.ast.walk((0, visitors_1.createVisitor)({
|
|
2380
|
+
AssignmentStatement: s => {
|
|
2381
|
+
this._references.assignmentStatements.push(s);
|
|
2382
|
+
this.references.expressions.add(s.value);
|
|
2383
|
+
},
|
|
2238
2384
|
ClassStatement: s => {
|
|
2239
2385
|
this._references.classStatements.push(s);
|
|
2240
2386
|
},
|
|
2387
|
+
ClassFieldStatement: s => {
|
|
2388
|
+
if (s.initialValue) {
|
|
2389
|
+
this._references.expressions.add(s.initialValue);
|
|
2390
|
+
}
|
|
2391
|
+
},
|
|
2241
2392
|
NamespaceStatement: s => {
|
|
2242
2393
|
this._references.namespaceStatements.push(s);
|
|
2243
2394
|
},
|
|
2244
2395
|
FunctionStatement: s => {
|
|
2245
2396
|
this._references.functionStatements.push(s);
|
|
2246
|
-
//add the initial set of function expressions for function statements
|
|
2247
|
-
this._references.functionExpressions.push(s.func);
|
|
2248
2397
|
},
|
|
2249
2398
|
ImportStatement: s => {
|
|
2250
2399
|
this._references.importStatements.push(s);
|
|
2251
2400
|
},
|
|
2252
2401
|
LibraryStatement: s => {
|
|
2253
2402
|
this._references.libraryStatements.push(s);
|
|
2254
|
-
}
|
|
2255
|
-
}), {
|
|
2256
|
-
walkMode: visitors_1.WalkMode.visitStatements
|
|
2257
|
-
});
|
|
2258
|
-
let func;
|
|
2259
|
-
let visitor = (0, visitors_1.createVisitor)({
|
|
2260
|
-
AssignmentStatement: s => {
|
|
2261
|
-
this._references.assignmentStatements.push(s);
|
|
2262
2403
|
},
|
|
2263
2404
|
FunctionExpression: (expression, parent) => {
|
|
2264
2405
|
if (!(0, reflection_1.isClassMethodStatement)(parent)) {
|
|
@@ -2267,25 +2408,54 @@ class Parser {
|
|
|
2267
2408
|
},
|
|
2268
2409
|
NewExpression: e => {
|
|
2269
2410
|
this._references.newExpressions.push(e);
|
|
2411
|
+
for (const p of e.call.args) {
|
|
2412
|
+
this._references.expressions.add(p);
|
|
2413
|
+
}
|
|
2414
|
+
},
|
|
2415
|
+
ExpressionStatement: s => {
|
|
2416
|
+
this._references.expressions.add(s.expression);
|
|
2417
|
+
},
|
|
2418
|
+
CallfuncExpression: e => {
|
|
2419
|
+
visitCallExpression(e);
|
|
2420
|
+
},
|
|
2421
|
+
CallExpression: e => {
|
|
2422
|
+
visitCallExpression(e);
|
|
2270
2423
|
},
|
|
2271
2424
|
AALiteralExpression: e => {
|
|
2272
2425
|
this.addPropertyHints(e);
|
|
2426
|
+
this._references.expressions.add(e);
|
|
2427
|
+
for (const member of e.elements) {
|
|
2428
|
+
if ((0, reflection_1.isAAMemberExpression)(member)) {
|
|
2429
|
+
this._references.expressions.add(member.value);
|
|
2430
|
+
}
|
|
2431
|
+
}
|
|
2432
|
+
},
|
|
2433
|
+
ArrayLiteralExpression: e => {
|
|
2434
|
+
for (const element of e.elements) {
|
|
2435
|
+
//keep everything except comments
|
|
2436
|
+
if (!(0, reflection_1.isCommentStatement)(element)) {
|
|
2437
|
+
this._references.expressions.add(element);
|
|
2438
|
+
}
|
|
2439
|
+
}
|
|
2273
2440
|
},
|
|
2274
2441
|
DottedGetExpression: e => {
|
|
2275
2442
|
this.addPropertyHints(e.name);
|
|
2276
2443
|
},
|
|
2277
2444
|
DottedSetStatement: e => {
|
|
2278
2445
|
this.addPropertyHints(e.name);
|
|
2446
|
+
},
|
|
2447
|
+
EnumStatement: e => {
|
|
2448
|
+
this._references.enumStatements.push(e);
|
|
2449
|
+
},
|
|
2450
|
+
UnaryExpression: e => {
|
|
2451
|
+
this._references.expressions.add(e);
|
|
2452
|
+
},
|
|
2453
|
+
IncrementStatement: e => {
|
|
2454
|
+
this._references.expressions.add(e);
|
|
2279
2455
|
}
|
|
2456
|
+
}), {
|
|
2457
|
+
walkMode: visitors_1.WalkMode.visitAllRecursive
|
|
2280
2458
|
});
|
|
2281
|
-
//walk all function expressions (we'll add new ones as we move along too)
|
|
2282
|
-
for (let i = 0; i < this._references.functionExpressions.length; i++) {
|
|
2283
|
-
func = this._references.functionExpressions[i];
|
|
2284
|
-
//walk this function expression
|
|
2285
|
-
func.body.walk(visitor, {
|
|
2286
|
-
walkMode: visitors_1.WalkMode.visitAll
|
|
2287
|
-
});
|
|
2288
|
-
}
|
|
2289
2459
|
}
|
|
2290
2460
|
getContainingClass(currentToken) {
|
|
2291
2461
|
return this.references.classStatements.find((cs) => util_1.util.rangeContains(cs.range, currentToken.range.start));
|
|
@@ -2297,7 +2467,10 @@ class Parser {
|
|
|
2297
2467
|
return this.references.namespaceStatements.find((cs) => util_1.util.rangeContains(cs.range, currentToken.range.start));
|
|
2298
2468
|
}
|
|
2299
2469
|
getContainingFunctionExpression(currentToken) {
|
|
2300
|
-
return this.
|
|
2470
|
+
return this.getContainingFunctionExpressionByPosition(currentToken.range.start);
|
|
2471
|
+
}
|
|
2472
|
+
getContainingFunctionExpressionByPosition(position) {
|
|
2473
|
+
return this.references.functionExpressions.find((fe) => util_1.util.rangeContains(fe.range, position));
|
|
2301
2474
|
}
|
|
2302
2475
|
dispose() {
|
|
2303
2476
|
}
|
|
@@ -2310,6 +2483,7 @@ var ParseMode;
|
|
|
2310
2483
|
})(ParseMode = exports.ParseMode || (exports.ParseMode = {}));
|
|
2311
2484
|
class References {
|
|
2312
2485
|
constructor() {
|
|
2486
|
+
this.cache = new Cache_1.Cache();
|
|
2313
2487
|
this.assignmentStatements = [];
|
|
2314
2488
|
this.classStatements = [];
|
|
2315
2489
|
this.dottedSetStatements = [];
|
|
@@ -2317,6 +2491,18 @@ class References {
|
|
|
2317
2491
|
this.functionExpressions = [];
|
|
2318
2492
|
this.functionStatements = [];
|
|
2319
2493
|
this.interfaceStatements = [];
|
|
2494
|
+
this.enumStatements = [];
|
|
2495
|
+
/**
|
|
2496
|
+
* A collection of full expressions. This excludes intermediary expressions.
|
|
2497
|
+
*
|
|
2498
|
+
* Example 1:
|
|
2499
|
+
* `a.b.c` is composed of `a` (variableExpression) `.b` (DottedGetExpression) `.c` (DottedGetExpression)
|
|
2500
|
+
* This will only contain the final `.c` DottedGetExpression because `.b` and `a` can both be derived by walking back from the `.c` DottedGetExpression.
|
|
2501
|
+
*
|
|
2502
|
+
* Example 2:
|
|
2503
|
+
* `name.space.doSomething(a.b.c)` will result in 2 entries in this list. the `CallExpression` for `doSomething`, and the `.c` DottedGetExpression.
|
|
2504
|
+
*/
|
|
2505
|
+
this.expressions = new Set();
|
|
2320
2506
|
this.importStatements = [];
|
|
2321
2507
|
this.libraryStatements = [];
|
|
2322
2508
|
this.namespaceStatements = [];
|
|
@@ -2353,6 +2539,15 @@ class References {
|
|
|
2353
2539
|
}
|
|
2354
2540
|
return this._interfaceStatementLookup;
|
|
2355
2541
|
}
|
|
2542
|
+
get enumStatementLookup() {
|
|
2543
|
+
return this.cache.getOrAdd('enums', () => {
|
|
2544
|
+
const result = new Map();
|
|
2545
|
+
for (const stmt of this.enumStatements) {
|
|
2546
|
+
result.set(stmt.fullName.toLowerCase(), stmt);
|
|
2547
|
+
}
|
|
2548
|
+
return result;
|
|
2549
|
+
});
|
|
2550
|
+
}
|
|
2356
2551
|
}
|
|
2357
2552
|
exports.References = References;
|
|
2358
2553
|
var TokenUsage;
|
|
@@ -2388,7 +2583,10 @@ function getBscTypeFromExpression(expression, functionExpression) {
|
|
|
2388
2583
|
//Array literal
|
|
2389
2584
|
}
|
|
2390
2585
|
else if ((0, reflection_1.isArrayLiteralExpression)(expression)) {
|
|
2391
|
-
|
|
2586
|
+
const innerTypes = expression.elements.filter((element) => !(0, reflection_1.isCommentStatement)(element)).map((element) => {
|
|
2587
|
+
return getBscTypeFromExpression(element, functionExpression);
|
|
2588
|
+
});
|
|
2589
|
+
return new ArrayType_1.ArrayType(...innerTypes);
|
|
2392
2590
|
//function call
|
|
2393
2591
|
}
|
|
2394
2592
|
else if ((0, reflection_1.isNewExpression)(expression)) {
|
|
@@ -2404,6 +2602,12 @@ function getBscTypeFromExpression(expression, functionExpression) {
|
|
|
2404
2602
|
else if ((0, reflection_1.isDottedGetExpression)(expression)) {
|
|
2405
2603
|
return (0, helpers_1.getTypeFromDottedGetExpression)(expression, functionExpression);
|
|
2406
2604
|
}
|
|
2605
|
+
else if ((0, reflection_1.isIndexedGetExpression)(expression)) {
|
|
2606
|
+
const source = getBscTypeFromExpression(expression.obj, functionExpression);
|
|
2607
|
+
if ((0, reflection_1.isArrayType)(source)) {
|
|
2608
|
+
return source.getDefaultType();
|
|
2609
|
+
}
|
|
2610
|
+
}
|
|
2407
2611
|
}
|
|
2408
2612
|
catch (e) {
|
|
2409
2613
|
//do nothing. Just return dynamic
|