brighterscript 0.41.5 → 0.43.1
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 +39 -0
- package/dist/LanguageServer.js +0 -9
- package/dist/LanguageServer.js.map +1 -1
- package/dist/Program.d.ts +1 -1
- package/dist/Program.js +45 -10
- 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 +3 -2
- package/dist/Scope.js +14 -14
- package/dist/Scope.js.map +1 -1
- package/dist/astUtils/AstEditor.d.ts +27 -0
- package/dist/astUtils/AstEditor.js +97 -0
- package/dist/astUtils/AstEditor.js.map +1 -0
- package/dist/astUtils/AstEditor.spec.d.ts +1 -0
- package/dist/astUtils/AstEditor.spec.js +133 -0
- package/dist/astUtils/AstEditor.spec.js.map +1 -0
- package/dist/astUtils/reflection.d.ts +2 -1
- package/dist/astUtils/reflection.js +6 -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.spec.js +13 -16
- package/dist/astUtils/visitors.spec.js.map +1 -1
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.js +3 -3
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.js.map +1 -1
- package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.js +4 -4
- package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.js.map +1 -1
- package/dist/files/BrsFile.Class.spec.js +182 -78
- package/dist/files/BrsFile.Class.spec.js.map +1 -1
- package/dist/files/BrsFile.d.ts +11 -5
- package/dist/files/BrsFile.js +107 -67
- package/dist/files/BrsFile.js.map +1 -1
- package/dist/files/BrsFile.spec.js +175 -101
- package/dist/files/BrsFile.spec.js.map +1 -1
- package/dist/files/XmlFile.d.ts +1 -0
- package/dist/files/XmlFile.js +9 -8
- package/dist/files/XmlFile.js.map +1 -1
- package/dist/files/XmlFile.spec.js +41 -39
- package/dist/files/XmlFile.spec.js.map +1 -1
- package/dist/files/tests/imports.spec.js +6 -4
- package/dist/files/tests/imports.spec.js.map +1 -1
- package/dist/globalCallables.d.ts +3 -1
- package/dist/globalCallables.js +200 -100
- 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 +49 -4
- package/dist/lexer/Lexer.js +1 -2
- package/dist/lexer/Lexer.js.map +1 -1
- package/dist/lexer/Lexer.spec.js +462 -462
- package/dist/lexer/Lexer.spec.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 +32 -31
- package/dist/parser/Parser.Class.spec.js.map +1 -1
- package/dist/parser/Parser.d.ts +13 -1
- package/dist/parser/Parser.js +355 -253
- package/dist/parser/Parser.js.map +1 -1
- package/dist/parser/Parser.spec.js +86 -24
- package/dist/parser/Parser.spec.js.map +1 -1
- package/dist/parser/Statement.d.ts +2 -2
- package/dist/parser/Statement.js +8 -8
- package/dist/parser/Statement.js.map +1 -1
- package/dist/parser/Statement.spec.js +4 -4
- package/dist/parser/Statement.spec.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/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/util.d.ts +5 -1
- package/dist/util.js +43 -33
- package/dist/util.js.map +1 -1
- package/dist/validators/ClassValidator.js +20 -27
- package/dist/validators/ClassValidator.js.map +1 -1
- package/package.json +2 -1
- 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/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.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,7 +12,6 @@ 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");
|
|
13
|
-
const _1 = require(".");
|
|
14
15
|
class Parser {
|
|
15
16
|
constructor() {
|
|
16
17
|
/**
|
|
@@ -51,7 +52,7 @@ class Parser {
|
|
|
51
52
|
this._references = undefined;
|
|
52
53
|
}
|
|
53
54
|
addPropertyHints(item) {
|
|
54
|
-
if ((0,
|
|
55
|
+
if ((0, Token_1.isToken)(item)) {
|
|
55
56
|
const name = item.text;
|
|
56
57
|
this._references.propertyHints[name.toLowerCase()] = name;
|
|
57
58
|
}
|
|
@@ -79,7 +80,7 @@ class Parser {
|
|
|
79
80
|
static parse(toParse, options) {
|
|
80
81
|
let tokens;
|
|
81
82
|
if (typeof toParse === 'string') {
|
|
82
|
-
tokens =
|
|
83
|
+
tokens = Lexer_1.Lexer.scan(toParse).tokens;
|
|
83
84
|
}
|
|
84
85
|
else {
|
|
85
86
|
tokens = toParse;
|
|
@@ -97,9 +98,9 @@ class Parser {
|
|
|
97
98
|
this.tokens = tokens;
|
|
98
99
|
this.options = this.sanitizeParseOptions(options);
|
|
99
100
|
this.allowedLocalIdentifiers = [
|
|
100
|
-
...
|
|
101
|
+
...TokenKind_1.AllowedLocalIdentifiers,
|
|
101
102
|
//when in plain brightscript mode, the BrighterScript source literals can be used as regular variables
|
|
102
|
-
...(this.options.mode === ParseMode.BrightScript ?
|
|
103
|
+
...(this.options.mode === ParseMode.BrightScript ? TokenKind_1.BrighterScriptSourceLiterals : [])
|
|
103
104
|
];
|
|
104
105
|
this.current = 0;
|
|
105
106
|
this.diagnostics = [];
|
|
@@ -170,16 +171,16 @@ class Parser {
|
|
|
170
171
|
}
|
|
171
172
|
declaration() {
|
|
172
173
|
try {
|
|
173
|
-
if (this.checkAny(
|
|
174
|
+
if (this.checkAny(TokenKind_1.TokenKind.Sub, TokenKind_1.TokenKind.Function)) {
|
|
174
175
|
return this.functionDeclaration(false);
|
|
175
176
|
}
|
|
176
177
|
if (this.checkLibrary()) {
|
|
177
178
|
return this.libraryStatement();
|
|
178
179
|
}
|
|
179
|
-
if (this.check(
|
|
180
|
+
if (this.check(TokenKind_1.TokenKind.At) && this.checkNext(TokenKind_1.TokenKind.Identifier)) {
|
|
180
181
|
return this.annotationExpression();
|
|
181
182
|
}
|
|
182
|
-
if (this.check(
|
|
183
|
+
if (this.check(TokenKind_1.TokenKind.Comment)) {
|
|
183
184
|
return this.commentStatement();
|
|
184
185
|
}
|
|
185
186
|
//catch certain global terminators to prevent unnecessary lookahead (i.e. like `end namespace`, no need to continue)
|
|
@@ -197,17 +198,17 @@ class Parser {
|
|
|
197
198
|
}
|
|
198
199
|
}
|
|
199
200
|
identifier(...additionalTokenKinds) {
|
|
200
|
-
const identifier = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier(),
|
|
201
|
+
const identifier = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier(), TokenKind_1.TokenKind.Identifier, ...additionalTokenKinds);
|
|
201
202
|
// force the name into an identifier so the AST makes some sense
|
|
202
|
-
identifier.kind =
|
|
203
|
+
identifier.kind = TokenKind_1.TokenKind.Identifier;
|
|
203
204
|
return identifier;
|
|
204
205
|
}
|
|
205
206
|
/**
|
|
206
207
|
* Create a new InterfaceMethodStatement. This should only be called from within `interfaceDeclaration`
|
|
207
208
|
*/
|
|
208
209
|
interfaceFieldStatement() {
|
|
209
|
-
const name = this.identifier(...
|
|
210
|
-
let asToken = this.consumeToken(
|
|
210
|
+
const name = this.identifier(...TokenKind_1.AllowedProperties);
|
|
211
|
+
let asToken = this.consumeToken(TokenKind_1.TokenKind.As);
|
|
211
212
|
let typeToken = this.typeToken();
|
|
212
213
|
const type = util_1.util.tokenToBscType(typeToken);
|
|
213
214
|
if (!type) {
|
|
@@ -221,13 +222,13 @@ class Parser {
|
|
|
221
222
|
*/
|
|
222
223
|
interfaceMethodStatement() {
|
|
223
224
|
const functionType = this.advance();
|
|
224
|
-
const name = this.identifier(...
|
|
225
|
-
const leftParen = this.consumeToken(
|
|
225
|
+
const name = this.identifier(...TokenKind_1.AllowedProperties);
|
|
226
|
+
const leftParen = this.consumeToken(TokenKind_1.TokenKind.LeftParen);
|
|
226
227
|
const params = [];
|
|
227
|
-
const rightParen = this.consumeToken(
|
|
228
|
+
const rightParen = this.consumeToken(TokenKind_1.TokenKind.RightParen);
|
|
228
229
|
let asToken = null;
|
|
229
230
|
let returnTypeToken = null;
|
|
230
|
-
if (this.check(
|
|
231
|
+
if (this.check(TokenKind_1.TokenKind.As)) {
|
|
231
232
|
asToken = this.advance();
|
|
232
233
|
returnTypeToken = this.typeToken();
|
|
233
234
|
const returnType = util_1.util.tokenToBscType(returnTypeToken);
|
|
@@ -241,7 +242,7 @@ class Parser {
|
|
|
241
242
|
interfaceDeclaration() {
|
|
242
243
|
this.warnIfNotBrighterScriptMode('interface declarations');
|
|
243
244
|
const parentAnnotations = this.enterAnnotationBlock();
|
|
244
|
-
const interfaceToken = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedKeyword(
|
|
245
|
+
const interfaceToken = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedKeyword(TokenKind_1.TokenKind.Interface), TokenKind_1.TokenKind.Interface);
|
|
245
246
|
const nameToken = this.identifier();
|
|
246
247
|
let extendsToken;
|
|
247
248
|
let parentInterfaceName;
|
|
@@ -252,23 +253,23 @@ class Parser {
|
|
|
252
253
|
this.consumeStatementSeparators();
|
|
253
254
|
//gather up all interface members (Fields, Methods)
|
|
254
255
|
let body = [];
|
|
255
|
-
while (this.checkAny(
|
|
256
|
+
while (this.checkAny(TokenKind_1.TokenKind.Comment, TokenKind_1.TokenKind.Identifier, TokenKind_1.TokenKind.At, ...TokenKind_1.AllowedProperties)) {
|
|
256
257
|
try {
|
|
257
258
|
let decl;
|
|
258
259
|
//collect leading annotations
|
|
259
|
-
if (this.check(
|
|
260
|
+
if (this.check(TokenKind_1.TokenKind.At)) {
|
|
260
261
|
this.annotationExpression();
|
|
261
262
|
}
|
|
262
263
|
//fields
|
|
263
|
-
if (this.checkAny(
|
|
264
|
+
if (this.checkAny(TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedProperties) && this.checkNext(TokenKind_1.TokenKind.As)) {
|
|
264
265
|
decl = this.interfaceFieldStatement();
|
|
265
266
|
//methods (function/sub keyword followed by opening paren)
|
|
266
267
|
}
|
|
267
|
-
else if (this.checkAny(
|
|
268
|
+
else if (this.checkAny(TokenKind_1.TokenKind.Function, TokenKind_1.TokenKind.Sub) && this.checkAny(TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedProperties)) {
|
|
268
269
|
decl = this.interfaceMethodStatement();
|
|
269
270
|
//comments
|
|
270
271
|
}
|
|
271
|
-
else if (this.check(
|
|
272
|
+
else if (this.check(TokenKind_1.TokenKind.Comment)) {
|
|
272
273
|
decl = this.commentStatement();
|
|
273
274
|
}
|
|
274
275
|
if (decl) {
|
|
@@ -277,23 +278,22 @@ class Parser {
|
|
|
277
278
|
}
|
|
278
279
|
else {
|
|
279
280
|
//we didn't find a declaration...flag tokens until next line
|
|
280
|
-
this.flagUntil(
|
|
281
|
+
this.flagUntil(TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Colon, TokenKind_1.TokenKind.Eof);
|
|
281
282
|
}
|
|
282
283
|
}
|
|
283
284
|
catch (e) {
|
|
284
285
|
//throw out any failed members and move on to the next line
|
|
285
|
-
this.flagUntil(
|
|
286
|
+
this.flagUntil(TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Colon, TokenKind_1.TokenKind.Eof);
|
|
286
287
|
}
|
|
287
288
|
//ensure statement separator
|
|
288
289
|
this.consumeStatementSeparators();
|
|
289
290
|
//break out of this loop if we encountered the `EndInterface` token not followed by `as`
|
|
290
|
-
if (this.check(
|
|
291
|
+
if (this.check(TokenKind_1.TokenKind.EndInterface) && !this.checkNext(TokenKind_1.TokenKind.As)) {
|
|
291
292
|
break;
|
|
292
293
|
}
|
|
293
294
|
}
|
|
294
295
|
//consume the final `end interface` token
|
|
295
|
-
const endInterfaceToken = this.consumeToken(
|
|
296
|
-
this.consumeStatementSeparators();
|
|
296
|
+
const endInterfaceToken = this.consumeToken(TokenKind_1.TokenKind.EndInterface);
|
|
297
297
|
const statement = new Statement_1.InterfaceStatement(interfaceToken, nameToken, extendsToken, parentInterfaceName, body, endInterfaceToken, this.currentNamespaceName);
|
|
298
298
|
this._references.interfaceStatements.push(statement);
|
|
299
299
|
this.exitAnnotationBlock(parentAnnotations);
|
|
@@ -305,11 +305,11 @@ class Parser {
|
|
|
305
305
|
classDeclaration() {
|
|
306
306
|
this.warnIfNotBrighterScriptMode('class declarations');
|
|
307
307
|
const parentAnnotations = this.enterAnnotationBlock();
|
|
308
|
-
let classKeyword = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedKeyword(
|
|
308
|
+
let classKeyword = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedKeyword(TokenKind_1.TokenKind.Class), TokenKind_1.TokenKind.Class);
|
|
309
309
|
let extendsKeyword;
|
|
310
310
|
let parentClassName;
|
|
311
311
|
//get the class name
|
|
312
|
-
let className = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifierAfterKeyword('class'),
|
|
312
|
+
let className = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifierAfterKeyword('class'), TokenKind_1.TokenKind.Identifier, ...this.allowedLocalIdentifiers);
|
|
313
313
|
//see if the class inherits from parent
|
|
314
314
|
if (this.peek().text.toLowerCase() === 'extends') {
|
|
315
315
|
extendsKeyword = this.advance();
|
|
@@ -319,14 +319,14 @@ class Parser {
|
|
|
319
319
|
this.consumeStatementSeparators();
|
|
320
320
|
//gather up all class members (Fields, Methods)
|
|
321
321
|
let body = [];
|
|
322
|
-
while (this.checkAny(
|
|
322
|
+
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)) {
|
|
323
323
|
try {
|
|
324
324
|
let decl;
|
|
325
325
|
let accessModifier;
|
|
326
|
-
if (this.check(
|
|
326
|
+
if (this.check(TokenKind_1.TokenKind.At)) {
|
|
327
327
|
this.annotationExpression();
|
|
328
328
|
}
|
|
329
|
-
if (this.checkAny(
|
|
329
|
+
if (this.checkAny(TokenKind_1.TokenKind.Public, TokenKind_1.TokenKind.Protected, TokenKind_1.TokenKind.Private)) {
|
|
330
330
|
//use actual access modifier
|
|
331
331
|
accessModifier = this.advance();
|
|
332
332
|
}
|
|
@@ -335,7 +335,7 @@ class Parser {
|
|
|
335
335
|
overrideKeyword = this.advance();
|
|
336
336
|
}
|
|
337
337
|
//methods (function/sub keyword OR identifier followed by opening paren)
|
|
338
|
-
if (this.checkAny(
|
|
338
|
+
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))) {
|
|
339
339
|
const funcDeclaration = this.functionDeclaration(false, false);
|
|
340
340
|
//remove this function from the lists because it's not a callable
|
|
341
341
|
const functionStatement = this._references.functionStatements.pop();
|
|
@@ -348,7 +348,7 @@ class Parser {
|
|
|
348
348
|
functionStatement.func.functionStatement = decl;
|
|
349
349
|
//fields
|
|
350
350
|
}
|
|
351
|
-
else if (this.checkAny(
|
|
351
|
+
else if (this.checkAny(TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedProperties)) {
|
|
352
352
|
decl = this.classFieldDeclaration(accessModifier);
|
|
353
353
|
//class fields cannot be overridden
|
|
354
354
|
if (overrideKeyword) {
|
|
@@ -356,7 +356,7 @@ class Parser {
|
|
|
356
356
|
}
|
|
357
357
|
//comments
|
|
358
358
|
}
|
|
359
|
-
else if (this.check(
|
|
359
|
+
else if (this.check(TokenKind_1.TokenKind.Comment)) {
|
|
360
360
|
decl = this.commentStatement();
|
|
361
361
|
}
|
|
362
362
|
if (decl) {
|
|
@@ -366,13 +366,13 @@ class Parser {
|
|
|
366
366
|
}
|
|
367
367
|
catch (e) {
|
|
368
368
|
//throw out any failed members and move on to the next line
|
|
369
|
-
this.flagUntil(
|
|
369
|
+
this.flagUntil(TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Colon, TokenKind_1.TokenKind.Eof);
|
|
370
370
|
}
|
|
371
371
|
//ensure statement separator
|
|
372
372
|
this.consumeStatementSeparators();
|
|
373
373
|
}
|
|
374
374
|
let endingKeyword = this.advance();
|
|
375
|
-
if (endingKeyword.kind !==
|
|
375
|
+
if (endingKeyword.kind !== TokenKind_1.TokenKind.EndClass) {
|
|
376
376
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.couldNotFindMatchingEndKeyword('class')), { range: endingKeyword.range }));
|
|
377
377
|
}
|
|
378
378
|
const result = new Statement_1.ClassStatement(classKeyword, className, body, endingKeyword, extendsKeyword, parentClassName, this.currentNamespaceName);
|
|
@@ -381,11 +381,11 @@ class Parser {
|
|
|
381
381
|
return result;
|
|
382
382
|
}
|
|
383
383
|
classFieldDeclaration(accessModifier) {
|
|
384
|
-
let name = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedClassFieldIdentifier(),
|
|
384
|
+
let name = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedClassFieldIdentifier(), TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedProperties);
|
|
385
385
|
let asToken;
|
|
386
386
|
let fieldType;
|
|
387
387
|
//look for `as SOME_TYPE`
|
|
388
|
-
if (this.check(
|
|
388
|
+
if (this.check(TokenKind_1.TokenKind.As)) {
|
|
389
389
|
asToken = this.advance();
|
|
390
390
|
fieldType = this.typeToken();
|
|
391
391
|
//no field type specified
|
|
@@ -396,7 +396,7 @@ class Parser {
|
|
|
396
396
|
let initialValue;
|
|
397
397
|
let equal;
|
|
398
398
|
//if there is a field initializer
|
|
399
|
-
if (this.check(
|
|
399
|
+
if (this.check(TokenKind_1.TokenKind.Equal)) {
|
|
400
400
|
equal = this.advance();
|
|
401
401
|
initialValue = this.expression();
|
|
402
402
|
}
|
|
@@ -410,14 +410,14 @@ class Parser {
|
|
|
410
410
|
//track depth to help certain statements need to know if they are contained within a function body
|
|
411
411
|
this.namespaceAndFunctionDepth++;
|
|
412
412
|
let functionType;
|
|
413
|
-
if (this.checkAny(
|
|
413
|
+
if (this.checkAny(TokenKind_1.TokenKind.Sub, TokenKind_1.TokenKind.Function)) {
|
|
414
414
|
functionType = this.advance();
|
|
415
415
|
}
|
|
416
416
|
else {
|
|
417
417
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.missingCallableKeyword()), { range: this.peek().range }));
|
|
418
418
|
functionType = {
|
|
419
419
|
isReserved: true,
|
|
420
|
-
kind:
|
|
420
|
+
kind: TokenKind_1.TokenKind.Function,
|
|
421
421
|
text: 'function',
|
|
422
422
|
//zero-length location means derived
|
|
423
423
|
range: {
|
|
@@ -427,16 +427,16 @@ class Parser {
|
|
|
427
427
|
leadingWhitespace: ''
|
|
428
428
|
};
|
|
429
429
|
}
|
|
430
|
-
let isSub = (functionType === null || functionType === void 0 ? void 0 : functionType.kind) ===
|
|
430
|
+
let isSub = (functionType === null || functionType === void 0 ? void 0 : functionType.kind) === TokenKind_1.TokenKind.Sub;
|
|
431
431
|
let functionTypeText = isSub ? 'sub' : 'function';
|
|
432
432
|
let name;
|
|
433
433
|
let leftParen;
|
|
434
434
|
if (isAnonymous) {
|
|
435
|
-
leftParen = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedLeftParenAfterCallable(functionTypeText),
|
|
435
|
+
leftParen = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedLeftParenAfterCallable(functionTypeText), TokenKind_1.TokenKind.LeftParen);
|
|
436
436
|
}
|
|
437
437
|
else {
|
|
438
|
-
name = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedNameAfterCallableKeyword(functionTypeText),
|
|
439
|
-
leftParen = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedLeftParenAfterCallableName(functionTypeText),
|
|
438
|
+
name = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedNameAfterCallableKeyword(functionTypeText), TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedProperties);
|
|
439
|
+
leftParen = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedLeftParenAfterCallableName(functionTypeText), TokenKind_1.TokenKind.LeftParen);
|
|
440
440
|
//prevent functions from ending with type designators
|
|
441
441
|
let lastChar = name.text[name.text.length - 1];
|
|
442
442
|
if (['$', '%', '!', '#', '&'].includes(lastChar)) {
|
|
@@ -444,23 +444,23 @@ class Parser {
|
|
|
444
444
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.functionNameCannotEndWithTypeDesignator(functionTypeText, name.text, lastChar)), { range: name.range }));
|
|
445
445
|
}
|
|
446
446
|
//flag functions with keywords for names (only for standard functions)
|
|
447
|
-
if (checkIdentifier &&
|
|
447
|
+
if (checkIdentifier && TokenKind_1.DisallowedFunctionIdentifiersText.has(name.text.toLowerCase())) {
|
|
448
448
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.cannotUseReservedWordAsIdentifier(name.text)), { range: name.range }));
|
|
449
449
|
}
|
|
450
450
|
}
|
|
451
451
|
let params = [];
|
|
452
452
|
let asToken;
|
|
453
453
|
let typeToken;
|
|
454
|
-
if (!this.check(
|
|
454
|
+
if (!this.check(TokenKind_1.TokenKind.RightParen)) {
|
|
455
455
|
do {
|
|
456
456
|
if (params.length >= Expression_1.CallExpression.MaximumArguments) {
|
|
457
457
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.tooManyCallableParameters(params.length, Expression_1.CallExpression.MaximumArguments)), { range: this.peek().range }));
|
|
458
458
|
}
|
|
459
459
|
params.push(this.functionParameter());
|
|
460
|
-
} while (this.match(
|
|
460
|
+
} while (this.match(TokenKind_1.TokenKind.Comma));
|
|
461
461
|
}
|
|
462
462
|
let rightParen = this.advance();
|
|
463
|
-
if (this.check(
|
|
463
|
+
if (this.check(TokenKind_1.TokenKind.As)) {
|
|
464
464
|
asToken = this.advance();
|
|
465
465
|
typeToken = this.typeToken();
|
|
466
466
|
if (!util_1.util.tokenToBscType(typeToken, this.options.mode === ParseMode.BrighterScript)) {
|
|
@@ -498,7 +498,7 @@ class Parser {
|
|
|
498
498
|
}
|
|
499
499
|
// consume 'end sub' or 'end function'
|
|
500
500
|
func.end = this.advance();
|
|
501
|
-
let expectedEndKind = isSub ?
|
|
501
|
+
let expectedEndKind = isSub ? TokenKind_1.TokenKind.EndSub : TokenKind_1.TokenKind.EndFunction;
|
|
502
502
|
//if `function` is ended with `end sub`, or `sub` is ended with `end function`, then
|
|
503
503
|
//add an error but don't hard-fail so the AST can continue more gracefully
|
|
504
504
|
if (func.end.kind !== expectedEndKind) {
|
|
@@ -522,22 +522,22 @@ class Parser {
|
|
|
522
522
|
}
|
|
523
523
|
}
|
|
524
524
|
functionParameter() {
|
|
525
|
-
if (!this.checkAny(
|
|
525
|
+
if (!this.checkAny(TokenKind_1.TokenKind.Identifier, ...this.allowedLocalIdentifiers)) {
|
|
526
526
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.expectedParameterNameButFound(this.peek().text)), { range: this.peek().range }));
|
|
527
527
|
throw this.lastDiagnosticAsError();
|
|
528
528
|
}
|
|
529
529
|
let name = this.advance();
|
|
530
530
|
// force the name into an identifier so the AST makes some sense
|
|
531
|
-
name.kind =
|
|
531
|
+
name.kind = TokenKind_1.TokenKind.Identifier;
|
|
532
532
|
let typeToken;
|
|
533
533
|
let defaultValue;
|
|
534
534
|
// parse argument default value
|
|
535
|
-
if (this.match(
|
|
535
|
+
if (this.match(TokenKind_1.TokenKind.Equal)) {
|
|
536
536
|
// it seems any expression is allowed here -- including ones that operate on other arguments!
|
|
537
537
|
defaultValue = this.expression();
|
|
538
538
|
}
|
|
539
539
|
let asToken = null;
|
|
540
|
-
if (this.check(
|
|
540
|
+
if (this.check(TokenKind_1.TokenKind.As)) {
|
|
541
541
|
asToken = this.advance();
|
|
542
542
|
typeToken = this.typeToken();
|
|
543
543
|
if (!util_1.util.tokenToBscType(typeToken, this.options.mode === ParseMode.BrighterScript)) {
|
|
@@ -550,30 +550,33 @@ class Parser {
|
|
|
550
550
|
assignment() {
|
|
551
551
|
let name = this.advance();
|
|
552
552
|
//add diagnostic if name is a reserved word that cannot be used as an identifier
|
|
553
|
-
if (
|
|
553
|
+
if (TokenKind_1.DisallowedLocalIdentifiersText.has(name.text.toLowerCase())) {
|
|
554
554
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.cannotUseReservedWordAsIdentifier(name.text)), { range: name.range }));
|
|
555
555
|
}
|
|
556
|
-
let operator = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedOperatorAfterIdentifier(
|
|
556
|
+
let operator = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedOperatorAfterIdentifier(TokenKind_1.AssignmentOperators, name.text), ...TokenKind_1.AssignmentOperators);
|
|
557
557
|
let value = this.expression();
|
|
558
558
|
let result;
|
|
559
|
-
if (operator.kind ===
|
|
559
|
+
if (operator.kind === TokenKind_1.TokenKind.Equal) {
|
|
560
560
|
result = new Statement_1.AssignmentStatement(operator, name, value, this.currentFunctionExpression);
|
|
561
561
|
}
|
|
562
562
|
else {
|
|
563
563
|
result = new Statement_1.AssignmentStatement(operator, name, new Expression_1.BinaryExpression(new Expression_1.VariableExpression(name, this.currentNamespaceName), operator, value), this.currentFunctionExpression);
|
|
564
|
+
//remove the right-hand-side expression from this assignment operator, and replace with the full assignment expression
|
|
565
|
+
this._references.expressions.delete(value);
|
|
566
|
+
this._references.expressions.add(result);
|
|
564
567
|
}
|
|
565
568
|
this._references.assignmentStatements.push(result);
|
|
566
569
|
return result;
|
|
567
570
|
}
|
|
568
571
|
checkLibrary() {
|
|
569
|
-
let isLibraryToken = this.check(
|
|
572
|
+
let isLibraryToken = this.check(TokenKind_1.TokenKind.Library);
|
|
570
573
|
//if we are at the top level, any line that starts with "library" should be considered a library statement
|
|
571
574
|
if (this.isAtRootLevel() && isLibraryToken) {
|
|
572
575
|
return true;
|
|
573
576
|
//not at root level, library statements are all invalid here, but try to detect if the tokens look
|
|
574
577
|
//like a library statement (and let the libraryStatement function handle emitting the diagnostics)
|
|
575
578
|
}
|
|
576
|
-
else if (isLibraryToken && this.checkNext(
|
|
579
|
+
else if (isLibraryToken && this.checkNext(TokenKind_1.TokenKind.StringLiteral)) {
|
|
577
580
|
return true;
|
|
578
581
|
//definitely not a library statement
|
|
579
582
|
}
|
|
@@ -585,54 +588,54 @@ class Parser {
|
|
|
585
588
|
if (this.checkLibrary()) {
|
|
586
589
|
return this.libraryStatement();
|
|
587
590
|
}
|
|
588
|
-
if (this.check(
|
|
591
|
+
if (this.check(TokenKind_1.TokenKind.Import)) {
|
|
589
592
|
return this.importStatement();
|
|
590
593
|
}
|
|
591
|
-
if (this.check(
|
|
594
|
+
if (this.check(TokenKind_1.TokenKind.Stop)) {
|
|
592
595
|
return this.stopStatement();
|
|
593
596
|
}
|
|
594
|
-
if (this.check(
|
|
597
|
+
if (this.check(TokenKind_1.TokenKind.If)) {
|
|
595
598
|
return this.ifStatement();
|
|
596
599
|
}
|
|
597
600
|
//`try` must be followed by a block, otherwise it could be a local variable
|
|
598
|
-
if (this.check(
|
|
601
|
+
if (this.check(TokenKind_1.TokenKind.Try) && this.checkAnyNext(TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Colon, TokenKind_1.TokenKind.Comment)) {
|
|
599
602
|
return this.tryCatchStatement();
|
|
600
603
|
}
|
|
601
|
-
if (this.check(
|
|
604
|
+
if (this.check(TokenKind_1.TokenKind.Throw)) {
|
|
602
605
|
return this.throwStatement();
|
|
603
606
|
}
|
|
604
|
-
if (this.checkAny(
|
|
607
|
+
if (this.checkAny(TokenKind_1.TokenKind.Print, TokenKind_1.TokenKind.Question)) {
|
|
605
608
|
return this.printStatement();
|
|
606
609
|
}
|
|
607
|
-
if (this.check(
|
|
610
|
+
if (this.check(TokenKind_1.TokenKind.Dim)) {
|
|
608
611
|
return this.dimStatement();
|
|
609
612
|
}
|
|
610
|
-
if (this.check(
|
|
613
|
+
if (this.check(TokenKind_1.TokenKind.While)) {
|
|
611
614
|
return this.whileStatement();
|
|
612
615
|
}
|
|
613
|
-
if (this.check(
|
|
616
|
+
if (this.check(TokenKind_1.TokenKind.ExitWhile)) {
|
|
614
617
|
return this.exitWhile();
|
|
615
618
|
}
|
|
616
|
-
if (this.check(
|
|
619
|
+
if (this.check(TokenKind_1.TokenKind.For)) {
|
|
617
620
|
return this.forStatement();
|
|
618
621
|
}
|
|
619
|
-
if (this.check(
|
|
622
|
+
if (this.check(TokenKind_1.TokenKind.ForEach)) {
|
|
620
623
|
return this.forEachStatement();
|
|
621
624
|
}
|
|
622
|
-
if (this.check(
|
|
625
|
+
if (this.check(TokenKind_1.TokenKind.ExitFor)) {
|
|
623
626
|
return this.exitFor();
|
|
624
627
|
}
|
|
625
|
-
if (this.check(
|
|
628
|
+
if (this.check(TokenKind_1.TokenKind.End)) {
|
|
626
629
|
return this.endStatement();
|
|
627
630
|
}
|
|
628
|
-
if (this.match(
|
|
631
|
+
if (this.match(TokenKind_1.TokenKind.Return)) {
|
|
629
632
|
return this.returnStatement();
|
|
630
633
|
}
|
|
631
|
-
if (this.check(
|
|
634
|
+
if (this.check(TokenKind_1.TokenKind.Goto)) {
|
|
632
635
|
return this.gotoStatement();
|
|
633
636
|
}
|
|
634
637
|
//does this line look like a label? (i.e. `someIdentifier:` )
|
|
635
|
-
if (this.check(
|
|
638
|
+
if (this.check(TokenKind_1.TokenKind.Identifier) && this.checkNext(TokenKind_1.TokenKind.Colon) && this.checkPrevious(TokenKind_1.TokenKind.Newline)) {
|
|
636
639
|
try {
|
|
637
640
|
return this.labelStatement();
|
|
638
641
|
}
|
|
@@ -646,18 +649,18 @@ class Parser {
|
|
|
646
649
|
// BrightScript is like python, in that variables can be declared without a `var`,
|
|
647
650
|
// `let`, (...) keyword. As such, we must check the token *after* an identifier to figure
|
|
648
651
|
// out what to do with it.
|
|
649
|
-
if (this.checkAny(
|
|
650
|
-
this.checkAnyNext(...
|
|
652
|
+
if (this.checkAny(TokenKind_1.TokenKind.Identifier, ...this.allowedLocalIdentifiers) &&
|
|
653
|
+
this.checkAnyNext(...TokenKind_1.AssignmentOperators)) {
|
|
651
654
|
return this.assignment();
|
|
652
655
|
}
|
|
653
656
|
//some BrighterScript keywords are allowed as a local identifiers, so we need to check for them AFTER the assignment check
|
|
654
|
-
if (this.check(
|
|
657
|
+
if (this.check(TokenKind_1.TokenKind.Interface)) {
|
|
655
658
|
return this.interfaceDeclaration();
|
|
656
659
|
}
|
|
657
|
-
if (this.check(
|
|
660
|
+
if (this.check(TokenKind_1.TokenKind.Class)) {
|
|
658
661
|
return this.classDeclaration();
|
|
659
662
|
}
|
|
660
|
-
if (this.check(
|
|
663
|
+
if (this.check(TokenKind_1.TokenKind.Namespace)) {
|
|
661
664
|
return this.namespaceStatement();
|
|
662
665
|
}
|
|
663
666
|
// TODO: support multi-statements
|
|
@@ -667,9 +670,9 @@ class Parser {
|
|
|
667
670
|
const whileKeyword = this.advance();
|
|
668
671
|
const condition = this.expression();
|
|
669
672
|
this.consumeStatementSeparators();
|
|
670
|
-
const whileBlock = this.block(
|
|
673
|
+
const whileBlock = this.block(TokenKind_1.TokenKind.EndWhile);
|
|
671
674
|
let endWhile;
|
|
672
|
-
if (!whileBlock || this.peek().kind !==
|
|
675
|
+
if (!whileBlock || this.peek().kind !== TokenKind_1.TokenKind.EndWhile) {
|
|
673
676
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.couldNotFindMatchingEndKeyword('while')), { range: this.peek().range }));
|
|
674
677
|
if (!whileBlock) {
|
|
675
678
|
throw this.lastDiagnosticAsError();
|
|
@@ -692,7 +695,7 @@ class Parser {
|
|
|
692
695
|
const finalValue = this.expression();
|
|
693
696
|
let incrementExpression;
|
|
694
697
|
let stepToken;
|
|
695
|
-
if (this.check(
|
|
698
|
+
if (this.check(TokenKind_1.TokenKind.Step)) {
|
|
696
699
|
stepToken = this.advance();
|
|
697
700
|
incrementExpression = this.expression();
|
|
698
701
|
}
|
|
@@ -700,9 +703,9 @@ class Parser {
|
|
|
700
703
|
// BrightScript for/to/step loops default to a step of 1 if no `step` is provided
|
|
701
704
|
}
|
|
702
705
|
this.consumeStatementSeparators();
|
|
703
|
-
let body = this.block(
|
|
706
|
+
let body = this.block(TokenKind_1.TokenKind.EndFor, TokenKind_1.TokenKind.Next);
|
|
704
707
|
let endForToken;
|
|
705
|
-
if (!body || !this.checkAny(
|
|
708
|
+
if (!body || !this.checkAny(TokenKind_1.TokenKind.EndFor, TokenKind_1.TokenKind.Next)) {
|
|
706
709
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.expectedEndForOrNextToTerminateForLoop()), { range: this.peek().range }));
|
|
707
710
|
if (!body) {
|
|
708
711
|
throw this.lastDiagnosticAsError();
|
|
@@ -719,7 +722,7 @@ class Parser {
|
|
|
719
722
|
let forEach = this.advance();
|
|
720
723
|
let name = this.advance();
|
|
721
724
|
let maybeIn = this.peek();
|
|
722
|
-
if (this.check(
|
|
725
|
+
if (this.check(TokenKind_1.TokenKind.Identifier) && maybeIn.text.toLowerCase() === 'in') {
|
|
723
726
|
this.advance();
|
|
724
727
|
}
|
|
725
728
|
else {
|
|
@@ -732,7 +735,7 @@ class Parser {
|
|
|
732
735
|
throw this.lastDiagnosticAsError();
|
|
733
736
|
}
|
|
734
737
|
this.consumeStatementSeparators();
|
|
735
|
-
let body = this.block(
|
|
738
|
+
let body = this.block(TokenKind_1.TokenKind.EndFor, TokenKind_1.TokenKind.Next);
|
|
736
739
|
if (!body) {
|
|
737
740
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.expectedEndForOrNextToTerminateForLoop()), { range: this.peek().range }));
|
|
738
741
|
throw this.lastDiagnosticAsError();
|
|
@@ -757,7 +760,7 @@ class Parser {
|
|
|
757
760
|
}
|
|
758
761
|
else {
|
|
759
762
|
let comments = [this.advance()];
|
|
760
|
-
while (this.check(
|
|
763
|
+
while (this.check(TokenKind_1.TokenKind.Newline) && this.checkNext(TokenKind_1.TokenKind.Comment)) {
|
|
761
764
|
this.advance();
|
|
762
765
|
comments.push(this.advance());
|
|
763
766
|
}
|
|
@@ -774,13 +777,13 @@ class Parser {
|
|
|
774
777
|
let name = this.getNamespacedVariableNameExpression();
|
|
775
778
|
//set the current namespace name
|
|
776
779
|
this.currentNamespaceName = name;
|
|
777
|
-
this.globalTerminators.push([
|
|
780
|
+
this.globalTerminators.push([TokenKind_1.TokenKind.EndNamespace]);
|
|
778
781
|
let body = this.body();
|
|
779
782
|
this.globalTerminators.pop();
|
|
780
783
|
//unset the current namespace name
|
|
781
784
|
this.currentNamespaceName = undefined;
|
|
782
785
|
let endKeyword;
|
|
783
|
-
if (this.check(
|
|
786
|
+
if (this.check(TokenKind_1.TokenKind.EndNamespace)) {
|
|
784
787
|
endKeyword = this.advance();
|
|
785
788
|
}
|
|
786
789
|
else {
|
|
@@ -796,24 +799,24 @@ class Parser {
|
|
|
796
799
|
* Get an expression with identifiers separated by periods. Useful for namespaces and class extends
|
|
797
800
|
*/
|
|
798
801
|
getNamespacedVariableNameExpression() {
|
|
799
|
-
let firstIdentifier = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifierAfterKeyword(this.previous().text),
|
|
802
|
+
let firstIdentifier = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifierAfterKeyword(this.previous().text), TokenKind_1.TokenKind.Identifier, ...this.allowedLocalIdentifiers);
|
|
800
803
|
let expr;
|
|
801
804
|
if (firstIdentifier) {
|
|
802
805
|
// force it into an identifier so the AST makes some sense
|
|
803
|
-
firstIdentifier.kind =
|
|
806
|
+
firstIdentifier.kind = TokenKind_1.TokenKind.Identifier;
|
|
804
807
|
expr = new Expression_1.VariableExpression(firstIdentifier, null);
|
|
805
808
|
//consume multiple dot identifiers (i.e. `Name.Space.Can.Have.Many.Parts`)
|
|
806
|
-
while (this.check(
|
|
807
|
-
let dot = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.unexpectedToken(this.peek().text),
|
|
809
|
+
while (this.check(TokenKind_1.TokenKind.Dot)) {
|
|
810
|
+
let dot = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.unexpectedToken(this.peek().text), TokenKind_1.TokenKind.Dot);
|
|
808
811
|
if (!dot) {
|
|
809
812
|
break;
|
|
810
813
|
}
|
|
811
|
-
let identifier = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier(),
|
|
814
|
+
let identifier = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier(), TokenKind_1.TokenKind.Identifier, ...this.allowedLocalIdentifiers, ...TokenKind_1.AllowedProperties);
|
|
812
815
|
if (!identifier) {
|
|
813
816
|
break;
|
|
814
817
|
}
|
|
815
818
|
// force it into an identifier so the AST makes some sense
|
|
816
|
-
identifier.kind =
|
|
819
|
+
identifier.kind = TokenKind_1.TokenKind.Identifier;
|
|
817
820
|
expr = new Expression_1.DottedGetExpression(expr, identifier, dot);
|
|
818
821
|
}
|
|
819
822
|
}
|
|
@@ -845,7 +848,7 @@ class Parser {
|
|
|
845
848
|
let libStatement = new Statement_1.LibraryStatement({
|
|
846
849
|
library: this.advance(),
|
|
847
850
|
//grab the next token only if it's a string
|
|
848
|
-
filePath: this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.expectedStringLiteralAfterKeyword('library'),
|
|
851
|
+
filePath: this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.expectedStringLiteralAfterKeyword('library'), TokenKind_1.TokenKind.StringLiteral)
|
|
849
852
|
});
|
|
850
853
|
this._references.libraryStatements.push(libStatement);
|
|
851
854
|
return libStatement;
|
|
@@ -854,20 +857,20 @@ class Parser {
|
|
|
854
857
|
this.warnIfNotBrighterScriptMode('import statements');
|
|
855
858
|
let importStatement = new Statement_1.ImportStatement(this.advance(),
|
|
856
859
|
//grab the next token only if it's a string
|
|
857
|
-
this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.expectedStringLiteralAfterKeyword('import'),
|
|
860
|
+
this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.expectedStringLiteralAfterKeyword('import'), TokenKind_1.TokenKind.StringLiteral));
|
|
858
861
|
this._references.importStatements.push(importStatement);
|
|
859
862
|
return importStatement;
|
|
860
863
|
}
|
|
861
864
|
annotationExpression() {
|
|
862
865
|
const atToken = this.advance();
|
|
863
|
-
const identifier = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier(),
|
|
866
|
+
const identifier = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier(), TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedProperties);
|
|
864
867
|
if (identifier) {
|
|
865
|
-
identifier.kind =
|
|
868
|
+
identifier.kind = TokenKind_1.TokenKind.Identifier;
|
|
866
869
|
}
|
|
867
870
|
let annotation = new Expression_1.AnnotationExpression(atToken, identifier);
|
|
868
871
|
this.pendingAnnotations.push(annotation);
|
|
869
872
|
//optional arguments
|
|
870
|
-
if (this.check(
|
|
873
|
+
if (this.check(TokenKind_1.TokenKind.LeftParen)) {
|
|
871
874
|
let leftParen = this.advance();
|
|
872
875
|
annotation.call = this.finishCall(leftParen, annotation, false);
|
|
873
876
|
}
|
|
@@ -880,7 +883,7 @@ class Parser {
|
|
|
880
883
|
}
|
|
881
884
|
const questionMarkToken = this.advance();
|
|
882
885
|
//consume newlines or comments
|
|
883
|
-
while (this.checkAny(
|
|
886
|
+
while (this.checkAny(TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Comment)) {
|
|
884
887
|
this.advance();
|
|
885
888
|
}
|
|
886
889
|
let consequent;
|
|
@@ -889,12 +892,12 @@ class Parser {
|
|
|
889
892
|
}
|
|
890
893
|
catch (_a) { }
|
|
891
894
|
//consume newlines or comments
|
|
892
|
-
while (this.checkAny(
|
|
895
|
+
while (this.checkAny(TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Comment)) {
|
|
893
896
|
this.advance();
|
|
894
897
|
}
|
|
895
|
-
const colonToken = this.tryConsumeToken(
|
|
898
|
+
const colonToken = this.tryConsumeToken(TokenKind_1.TokenKind.Colon);
|
|
896
899
|
//consume newlines
|
|
897
|
-
while (this.checkAny(
|
|
900
|
+
while (this.checkAny(TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Comment)) {
|
|
898
901
|
this.advance();
|
|
899
902
|
}
|
|
900
903
|
let alternate;
|
|
@@ -912,7 +915,7 @@ class Parser {
|
|
|
912
915
|
}
|
|
913
916
|
regexLiteralExpression() {
|
|
914
917
|
this.warnIfNotBrighterScriptMode('regular expression literal');
|
|
915
|
-
return new
|
|
918
|
+
return new Expression_1.RegexLiteralExpression({
|
|
916
919
|
regexLiteral: this.advance()
|
|
917
920
|
});
|
|
918
921
|
}
|
|
@@ -921,23 +924,23 @@ class Parser {
|
|
|
921
924
|
//get the tag name
|
|
922
925
|
let tagName;
|
|
923
926
|
if (isTagged) {
|
|
924
|
-
tagName = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier(),
|
|
927
|
+
tagName = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier(), TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedProperties);
|
|
925
928
|
// force it into an identifier so the AST makes some sense
|
|
926
|
-
tagName.kind =
|
|
929
|
+
tagName.kind = TokenKind_1.TokenKind.Identifier;
|
|
927
930
|
}
|
|
928
931
|
let quasis = [];
|
|
929
932
|
let expressions = [];
|
|
930
933
|
let openingBacktick = this.peek();
|
|
931
934
|
this.advance();
|
|
932
935
|
let currentQuasiExpressionParts = [];
|
|
933
|
-
while (!this.isAtEnd() && !this.check(
|
|
936
|
+
while (!this.isAtEnd() && !this.check(TokenKind_1.TokenKind.BackTick)) {
|
|
934
937
|
let next = this.peek();
|
|
935
|
-
if (next.kind ===
|
|
938
|
+
if (next.kind === TokenKind_1.TokenKind.TemplateStringQuasi) {
|
|
936
939
|
//a quasi can actually be made up of multiple quasis when it includes char literals
|
|
937
940
|
currentQuasiExpressionParts.push(new Expression_1.LiteralExpression(next));
|
|
938
941
|
this.advance();
|
|
939
942
|
}
|
|
940
|
-
else if (next.kind ===
|
|
943
|
+
else if (next.kind === TokenKind_1.TokenKind.EscapedCharCodeLiteral) {
|
|
941
944
|
currentQuasiExpressionParts.push(new Expression_1.EscapedCharCodeLiteralExpression(next));
|
|
942
945
|
this.advance();
|
|
943
946
|
}
|
|
@@ -945,12 +948,12 @@ class Parser {
|
|
|
945
948
|
//finish up the current quasi
|
|
946
949
|
quasis.push(new Expression_1.TemplateStringQuasiExpression(currentQuasiExpressionParts));
|
|
947
950
|
currentQuasiExpressionParts = [];
|
|
948
|
-
if (next.kind ===
|
|
951
|
+
if (next.kind === TokenKind_1.TokenKind.TemplateStringExpressionBegin) {
|
|
949
952
|
this.advance();
|
|
950
953
|
}
|
|
951
954
|
//now keep this expression
|
|
952
955
|
expressions.push(this.expression());
|
|
953
|
-
if (!this.isAtEnd() && this.check(
|
|
956
|
+
if (!this.isAtEnd() && this.check(TokenKind_1.TokenKind.TemplateStringExpressionEnd)) {
|
|
954
957
|
//TODO is it an error if this is not present?
|
|
955
958
|
this.advance();
|
|
956
959
|
}
|
|
@@ -982,12 +985,12 @@ class Parser {
|
|
|
982
985
|
const statement = new Statement_1.TryCatchStatement(tryToken);
|
|
983
986
|
//ensure statement separator
|
|
984
987
|
this.consumeStatementSeparators();
|
|
985
|
-
statement.tryBranch = this.block(
|
|
988
|
+
statement.tryBranch = this.block(TokenKind_1.TokenKind.Catch, TokenKind_1.TokenKind.EndTry);
|
|
986
989
|
const peek = this.peek();
|
|
987
|
-
if (peek.kind !==
|
|
990
|
+
if (peek.kind !== TokenKind_1.TokenKind.Catch) {
|
|
988
991
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.expectedCatchBlockInTryCatch()), { range: this.peek().range }));
|
|
989
992
|
//gracefully handle end-try
|
|
990
|
-
if (peek.kind ===
|
|
993
|
+
if (peek.kind === TokenKind_1.TokenKind.EndTry) {
|
|
991
994
|
statement.endTryToken = this.advance();
|
|
992
995
|
}
|
|
993
996
|
return statement;
|
|
@@ -995,16 +998,16 @@ class Parser {
|
|
|
995
998
|
else {
|
|
996
999
|
statement.catchToken = this.advance();
|
|
997
1000
|
}
|
|
998
|
-
const exceptionVarToken = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.missingExceptionVarToFollowCatch(),
|
|
1001
|
+
const exceptionVarToken = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.missingExceptionVarToFollowCatch(), TokenKind_1.TokenKind.Identifier, ...this.allowedLocalIdentifiers);
|
|
999
1002
|
if (exceptionVarToken) {
|
|
1000
1003
|
// force it into an identifier so the AST makes some sense
|
|
1001
|
-
exceptionVarToken.kind =
|
|
1004
|
+
exceptionVarToken.kind = TokenKind_1.TokenKind.Identifier;
|
|
1002
1005
|
statement.exceptionVariable = exceptionVarToken;
|
|
1003
1006
|
}
|
|
1004
1007
|
//ensure statement sepatator
|
|
1005
1008
|
this.consumeStatementSeparators();
|
|
1006
|
-
statement.catchBranch = this.block(
|
|
1007
|
-
if (this.peek().kind !==
|
|
1009
|
+
statement.catchBranch = this.block(TokenKind_1.TokenKind.EndTry);
|
|
1010
|
+
if (this.peek().kind !== TokenKind_1.TokenKind.EndTry) {
|
|
1008
1011
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.expectedEndTryToTerminateTryCatch()), { range: this.peek().range }));
|
|
1009
1012
|
}
|
|
1010
1013
|
else {
|
|
@@ -1015,7 +1018,7 @@ class Parser {
|
|
|
1015
1018
|
throwStatement() {
|
|
1016
1019
|
const throwToken = this.advance();
|
|
1017
1020
|
let expression;
|
|
1018
|
-
if (this.checkAny(
|
|
1021
|
+
if (this.checkAny(TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Colon)) {
|
|
1019
1022
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.missingExceptionExpressionAfterThrowKeyword()), { range: throwToken.range }));
|
|
1020
1023
|
}
|
|
1021
1024
|
else {
|
|
@@ -1025,19 +1028,19 @@ class Parser {
|
|
|
1025
1028
|
}
|
|
1026
1029
|
dimStatement() {
|
|
1027
1030
|
const dim = this.advance();
|
|
1028
|
-
let identifier = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifierAfterKeyword('dim'),
|
|
1031
|
+
let identifier = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifierAfterKeyword('dim'), TokenKind_1.TokenKind.Identifier, ...this.allowedLocalIdentifiers);
|
|
1029
1032
|
// force to an identifier so the AST makes some sense
|
|
1030
1033
|
if (identifier) {
|
|
1031
|
-
identifier.kind =
|
|
1034
|
+
identifier.kind = TokenKind_1.TokenKind.Identifier;
|
|
1032
1035
|
}
|
|
1033
|
-
let leftSquareBracket = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.missingLeftSquareBracketAfterDimIdentifier(),
|
|
1036
|
+
let leftSquareBracket = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.missingLeftSquareBracketAfterDimIdentifier(), TokenKind_1.TokenKind.LeftSquareBracket);
|
|
1034
1037
|
let expressions = [];
|
|
1035
1038
|
let expression;
|
|
1036
1039
|
do {
|
|
1037
1040
|
try {
|
|
1038
1041
|
expression = this.expression();
|
|
1039
1042
|
expressions.push(expression);
|
|
1040
|
-
if (this.check(
|
|
1043
|
+
if (this.check(TokenKind_1.TokenKind.Comma)) {
|
|
1041
1044
|
this.advance();
|
|
1042
1045
|
}
|
|
1043
1046
|
else {
|
|
@@ -1051,15 +1054,15 @@ class Parser {
|
|
|
1051
1054
|
if (expressions.length === 0) {
|
|
1052
1055
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.missingExpressionsInDimStatement()), { range: this.peek().range }));
|
|
1053
1056
|
}
|
|
1054
|
-
let rightSquareBracket = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.missingRightSquareBracketAfterDimIdentifier(),
|
|
1057
|
+
let rightSquareBracket = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.missingRightSquareBracketAfterDimIdentifier(), TokenKind_1.TokenKind.RightSquareBracket);
|
|
1055
1058
|
return new Statement_1.DimStatement(dim, identifier, leftSquareBracket, expressions, rightSquareBracket);
|
|
1056
1059
|
}
|
|
1057
1060
|
ifStatement() {
|
|
1058
1061
|
// colon before `if` is usually not allowed, unless it's after `then`
|
|
1059
1062
|
if (this.current > 0) {
|
|
1060
1063
|
const prev = this.previous();
|
|
1061
|
-
if (prev.kind ===
|
|
1062
|
-
if (this.current > 1 && this.tokens[this.current - 2].kind !==
|
|
1064
|
+
if (prev.kind === TokenKind_1.TokenKind.Colon) {
|
|
1065
|
+
if (this.current > 1 && this.tokens[this.current - 2].kind !== TokenKind_1.TokenKind.Then) {
|
|
1063
1066
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.unexpectedColonBeforeIfStatement()), { range: prev.range }));
|
|
1064
1067
|
}
|
|
1065
1068
|
}
|
|
@@ -1073,14 +1076,14 @@ class Parser {
|
|
|
1073
1076
|
let endIfToken;
|
|
1074
1077
|
let elseToken;
|
|
1075
1078
|
//optional `then`
|
|
1076
|
-
if (this.check(
|
|
1079
|
+
if (this.check(TokenKind_1.TokenKind.Then)) {
|
|
1077
1080
|
thenToken = this.advance();
|
|
1078
1081
|
}
|
|
1079
1082
|
//is it inline or multi-line if?
|
|
1080
|
-
const isInlineIfThen = !this.checkAny(
|
|
1083
|
+
const isInlineIfThen = !this.checkAny(TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Colon, TokenKind_1.TokenKind.Comment);
|
|
1081
1084
|
if (isInlineIfThen) {
|
|
1082
1085
|
/*** PARSE INLINE IF STATEMENT ***/
|
|
1083
|
-
thenBranch = this.inlineConditionalBranch(
|
|
1086
|
+
thenBranch = this.inlineConditionalBranch(TokenKind_1.TokenKind.Else, TokenKind_1.TokenKind.EndIf);
|
|
1084
1087
|
if (!thenBranch) {
|
|
1085
1088
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.expectedStatementToFollowConditionalCondition(ifToken.text)), { range: this.peek().range }));
|
|
1086
1089
|
throw this.lastDiagnosticAsError();
|
|
@@ -1089,9 +1092,9 @@ class Parser {
|
|
|
1089
1092
|
this.ensureInline(thenBranch.statements);
|
|
1090
1093
|
}
|
|
1091
1094
|
//else branch
|
|
1092
|
-
if (this.check(
|
|
1095
|
+
if (this.check(TokenKind_1.TokenKind.Else)) {
|
|
1093
1096
|
elseToken = this.advance();
|
|
1094
|
-
if (this.check(
|
|
1097
|
+
if (this.check(TokenKind_1.TokenKind.If)) {
|
|
1095
1098
|
// recurse-read `else if`
|
|
1096
1099
|
elseBranch = this.ifStatement();
|
|
1097
1100
|
//no multi-line if chained with an inline if
|
|
@@ -1099,13 +1102,13 @@ class Parser {
|
|
|
1099
1102
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.expectedInlineIfStatement()), { range: elseBranch.range }));
|
|
1100
1103
|
}
|
|
1101
1104
|
}
|
|
1102
|
-
else if (this.checkAny(
|
|
1105
|
+
else if (this.checkAny(TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Colon)) {
|
|
1103
1106
|
//expecting inline else branch
|
|
1104
1107
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.expectedInlineIfStatement()), { range: this.peek().range }));
|
|
1105
1108
|
throw this.lastDiagnosticAsError();
|
|
1106
1109
|
}
|
|
1107
1110
|
else {
|
|
1108
|
-
elseBranch = this.inlineConditionalBranch(
|
|
1111
|
+
elseBranch = this.inlineConditionalBranch(TokenKind_1.TokenKind.Else, TokenKind_1.TokenKind.EndIf);
|
|
1109
1112
|
if (elseBranch) {
|
|
1110
1113
|
this.ensureInline(elseBranch.statements);
|
|
1111
1114
|
}
|
|
@@ -1119,9 +1122,9 @@ class Parser {
|
|
|
1119
1122
|
if (!elseBranch || !(0, reflection_1.isIfStatement)(elseBranch)) {
|
|
1120
1123
|
//enforce newline at the end of the inline if statement
|
|
1121
1124
|
const peek = this.peek();
|
|
1122
|
-
if (peek.kind !==
|
|
1125
|
+
if (peek.kind !== TokenKind_1.TokenKind.Newline && peek.kind !== TokenKind_1.TokenKind.Comment && !this.isAtEnd()) {
|
|
1123
1126
|
//ignore last error if it was about a colon
|
|
1124
|
-
if (this.previous().kind ===
|
|
1127
|
+
if (this.previous().kind === TokenKind_1.TokenKind.Colon) {
|
|
1125
1128
|
this.diagnostics.pop();
|
|
1126
1129
|
this.current--;
|
|
1127
1130
|
}
|
|
@@ -1136,9 +1139,9 @@ class Parser {
|
|
|
1136
1139
|
//ensure newline/colon before next keyword
|
|
1137
1140
|
this.ensureNewLineOrColon();
|
|
1138
1141
|
//else branch
|
|
1139
|
-
if (this.check(
|
|
1142
|
+
if (this.check(TokenKind_1.TokenKind.Else)) {
|
|
1140
1143
|
elseToken = this.advance();
|
|
1141
|
-
if (this.check(
|
|
1144
|
+
if (this.check(TokenKind_1.TokenKind.If)) {
|
|
1142
1145
|
// recurse-read `else if`
|
|
1143
1146
|
elseBranch = this.ifStatement();
|
|
1144
1147
|
}
|
|
@@ -1149,7 +1152,7 @@ class Parser {
|
|
|
1149
1152
|
}
|
|
1150
1153
|
}
|
|
1151
1154
|
if (!(0, reflection_1.isIfStatement)(elseBranch)) {
|
|
1152
|
-
if (this.check(
|
|
1155
|
+
if (this.check(TokenKind_1.TokenKind.EndIf)) {
|
|
1153
1156
|
endIfToken = this.advance();
|
|
1154
1157
|
}
|
|
1155
1158
|
else {
|
|
@@ -1172,7 +1175,7 @@ class Parser {
|
|
|
1172
1175
|
let diagnosticsLengthBeforeBlock = this.diagnostics.length;
|
|
1173
1176
|
// we're parsing a multi-line ("block") form of the BrightScript if/then and must find
|
|
1174
1177
|
// a trailing "end if" or "else if"
|
|
1175
|
-
let branch = this.block(
|
|
1178
|
+
let branch = this.block(TokenKind_1.TokenKind.EndIf, TokenKind_1.TokenKind.Else);
|
|
1176
1179
|
if (!branch) {
|
|
1177
1180
|
//throw out any new diagnostics created as a result of a `then` block parse failure.
|
|
1178
1181
|
//the block() function will discard the current line, so any discarded diagnostics will
|
|
@@ -1186,7 +1189,7 @@ class Parser {
|
|
|
1186
1189
|
}
|
|
1187
1190
|
ensureNewLineOrColon(silent = false) {
|
|
1188
1191
|
const prev = this.previous().kind;
|
|
1189
|
-
if (prev !==
|
|
1192
|
+
if (prev !== TokenKind_1.TokenKind.Newline && prev !== TokenKind_1.TokenKind.Colon) {
|
|
1190
1193
|
if (!silent) {
|
|
1191
1194
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.expectedNewlineOrColon()), { range: this.peek().range }));
|
|
1192
1195
|
}
|
|
@@ -1215,12 +1218,12 @@ class Parser {
|
|
|
1215
1218
|
const startingRange = statement.range;
|
|
1216
1219
|
//look for colon statement separator
|
|
1217
1220
|
let foundColon = false;
|
|
1218
|
-
while (this.match(
|
|
1221
|
+
while (this.match(TokenKind_1.TokenKind.Colon)) {
|
|
1219
1222
|
foundColon = true;
|
|
1220
1223
|
}
|
|
1221
1224
|
//if a colon was found, add the next statement or err if unexpected
|
|
1222
1225
|
if (foundColon) {
|
|
1223
|
-
if (!this.checkAny(
|
|
1226
|
+
if (!this.checkAny(TokenKind_1.TokenKind.Newline, ...additionalTerminators)) {
|
|
1224
1227
|
//if not an ending keyword, add next statement
|
|
1225
1228
|
let extra = this.inlineConditionalBranch(...additionalTerminators);
|
|
1226
1229
|
if (!extra) {
|
|
@@ -1238,9 +1241,9 @@ class Parser {
|
|
|
1238
1241
|
}
|
|
1239
1242
|
expressionStatement(expr) {
|
|
1240
1243
|
let expressionStart = this.peek();
|
|
1241
|
-
if (this.checkAny(
|
|
1244
|
+
if (this.checkAny(TokenKind_1.TokenKind.PlusPlus, TokenKind_1.TokenKind.MinusMinus)) {
|
|
1242
1245
|
let operator = this.advance();
|
|
1243
|
-
if (this.checkAny(
|
|
1246
|
+
if (this.checkAny(TokenKind_1.TokenKind.PlusPlus, TokenKind_1.TokenKind.MinusMinus)) {
|
|
1244
1247
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.consecutiveIncrementDecrementOperatorsAreNotAllowed()), { range: this.peek().range }));
|
|
1245
1248
|
throw this.lastDiagnosticAsError();
|
|
1246
1249
|
}
|
|
@@ -1248,7 +1251,9 @@ class Parser {
|
|
|
1248
1251
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.incrementDecrementOperatorsAreNotAllowedAsResultOfFunctionCall()), { range: expressionStart.range }));
|
|
1249
1252
|
throw this.lastDiagnosticAsError();
|
|
1250
1253
|
}
|
|
1251
|
-
|
|
1254
|
+
const result = new Statement_1.IncrementStatement(expr, operator);
|
|
1255
|
+
this._references.expressions.add(result);
|
|
1256
|
+
return result;
|
|
1252
1257
|
}
|
|
1253
1258
|
if ((0, reflection_1.isCallExpression)(expr) || (0, reflection_1.isCallfuncExpression)(expr)) {
|
|
1254
1259
|
return new Statement_1.ExpressionStatement(expr);
|
|
@@ -1265,18 +1270,18 @@ class Parser {
|
|
|
1265
1270
|
* priority as standalone function calls though, so we can parse them in the same way.
|
|
1266
1271
|
*/
|
|
1267
1272
|
let expr = this.call();
|
|
1268
|
-
if (this.checkAny(...
|
|
1273
|
+
if (this.checkAny(...TokenKind_1.AssignmentOperators) && !((0, reflection_1.isCallExpression)(expr))) {
|
|
1269
1274
|
let left = expr;
|
|
1270
1275
|
let operator = this.advance();
|
|
1271
1276
|
let right = this.expression();
|
|
1272
1277
|
// Create a dotted or indexed "set" based on the left-hand side's type
|
|
1273
1278
|
if ((0, reflection_1.isIndexedGetExpression)(left)) {
|
|
1274
|
-
return new Statement_1.IndexedSetStatement(left.obj, left.index, operator.kind ===
|
|
1279
|
+
return new Statement_1.IndexedSetStatement(left.obj, left.index, operator.kind === TokenKind_1.TokenKind.Equal
|
|
1275
1280
|
? right
|
|
1276
1281
|
: new Expression_1.BinaryExpression(left, operator, right), left.openingSquare, left.closingSquare);
|
|
1277
1282
|
}
|
|
1278
1283
|
else if ((0, reflection_1.isDottedGetExpression)(left)) {
|
|
1279
|
-
return new Statement_1.DottedSetStatement(left.obj, left.name, operator.kind ===
|
|
1284
|
+
return new Statement_1.DottedSetStatement(left.obj, left.name, operator.kind === TokenKind_1.TokenKind.Equal
|
|
1280
1285
|
? right
|
|
1281
1286
|
: new Expression_1.BinaryExpression(left, operator, right));
|
|
1282
1287
|
}
|
|
@@ -1287,13 +1292,13 @@ class Parser {
|
|
|
1287
1292
|
let printKeyword = this.advance();
|
|
1288
1293
|
let values = [];
|
|
1289
1294
|
while (!this.checkEndOfStatement()) {
|
|
1290
|
-
if (this.check(
|
|
1295
|
+
if (this.check(TokenKind_1.TokenKind.Semicolon)) {
|
|
1291
1296
|
values.push(this.advance());
|
|
1292
1297
|
}
|
|
1293
|
-
else if (this.check(
|
|
1298
|
+
else if (this.check(TokenKind_1.TokenKind.Comma)) {
|
|
1294
1299
|
values.push(this.advance());
|
|
1295
1300
|
}
|
|
1296
|
-
else if (this.check(
|
|
1301
|
+
else if (this.check(TokenKind_1.TokenKind.Else)) {
|
|
1297
1302
|
break; // inline branch
|
|
1298
1303
|
}
|
|
1299
1304
|
else {
|
|
@@ -1306,7 +1311,7 @@ class Parser {
|
|
|
1306
1311
|
values.push(emptyStringLiteral);
|
|
1307
1312
|
}
|
|
1308
1313
|
let last = values[values.length - 1];
|
|
1309
|
-
if ((0,
|
|
1314
|
+
if ((0, Token_1.isToken)(last)) {
|
|
1310
1315
|
// TODO: error, expected value
|
|
1311
1316
|
}
|
|
1312
1317
|
return new Statement_1.PrintStatement({ print: printKeyword }, values);
|
|
@@ -1320,7 +1325,7 @@ class Parser {
|
|
|
1320
1325
|
if (this.checkEndOfStatement()) {
|
|
1321
1326
|
return new Statement_1.ReturnStatement(tokens);
|
|
1322
1327
|
}
|
|
1323
|
-
let toReturn = this.check(
|
|
1328
|
+
let toReturn = this.check(TokenKind_1.TokenKind.Else) ? undefined : this.expression();
|
|
1324
1329
|
return new Statement_1.ReturnStatement(tokens, toReturn);
|
|
1325
1330
|
}
|
|
1326
1331
|
/**
|
|
@@ -1333,7 +1338,7 @@ class Parser {
|
|
|
1333
1338
|
colon: this.advance()
|
|
1334
1339
|
};
|
|
1335
1340
|
//label must be alone on its line, this is probably not a label
|
|
1336
|
-
if (!this.checkAny(
|
|
1341
|
+
if (!this.checkAny(TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Comment)) {
|
|
1337
1342
|
//rewind and cancel
|
|
1338
1343
|
this.current -= 2;
|
|
1339
1344
|
throw new CancelStatementError();
|
|
@@ -1347,7 +1352,7 @@ class Parser {
|
|
|
1347
1352
|
gotoStatement() {
|
|
1348
1353
|
let tokens = {
|
|
1349
1354
|
goto: this.advance(),
|
|
1350
|
-
label: this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedLabelIdentifierAfterGotoKeyword(),
|
|
1355
|
+
label: this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedLabelIdentifierAfterGotoKeyword(), TokenKind_1.TokenKind.Identifier)
|
|
1351
1356
|
};
|
|
1352
1357
|
return new Statement_1.GotoStatement(tokens);
|
|
1353
1358
|
}
|
|
@@ -1378,7 +1383,7 @@ class Parser {
|
|
|
1378
1383
|
this.consumeStatementSeparators(true);
|
|
1379
1384
|
let startingToken = this.peek();
|
|
1380
1385
|
const statements = [];
|
|
1381
|
-
while (!this.isAtEnd() && !this.checkAny(
|
|
1386
|
+
while (!this.isAtEnd() && !this.checkAny(TokenKind_1.TokenKind.EndSub, TokenKind_1.TokenKind.EndFunction, ...terminators)) {
|
|
1382
1387
|
//grab the location of the current token
|
|
1383
1388
|
let loopCurrent = this.current;
|
|
1384
1389
|
let dec = this.declaration();
|
|
@@ -1394,7 +1399,7 @@ class Parser {
|
|
|
1394
1399
|
//something went wrong. reset to the top of the loop
|
|
1395
1400
|
this.current = loopCurrent;
|
|
1396
1401
|
//scrap the entire line (hopefully whatever failed has added a diagnostic)
|
|
1397
|
-
this.consumeUntil(
|
|
1402
|
+
this.consumeUntil(TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Colon, TokenKind_1.TokenKind.Eof);
|
|
1398
1403
|
//trash the next token. this prevents an infinite loop. not exactly sure why we need this,
|
|
1399
1404
|
//but there's already an error in the file being parsed, so just leave this line here
|
|
1400
1405
|
this.advance();
|
|
@@ -1411,8 +1416,8 @@ class Parser {
|
|
|
1411
1416
|
//if so, we need to restore the statement separator
|
|
1412
1417
|
let prev = this.previous().kind;
|
|
1413
1418
|
let peek = this.peek().kind;
|
|
1414
|
-
if ((peek ===
|
|
1415
|
-
(prev ===
|
|
1419
|
+
if ((peek === TokenKind_1.TokenKind.EndSub || peek === TokenKind_1.TokenKind.EndFunction) &&
|
|
1420
|
+
(prev === TokenKind_1.TokenKind.Newline || prev === TokenKind_1.TokenKind.Colon)) {
|
|
1416
1421
|
this.current--;
|
|
1417
1422
|
}
|
|
1418
1423
|
}
|
|
@@ -1444,13 +1449,15 @@ class Parser {
|
|
|
1444
1449
|
this.pendingAnnotations = parentAnnotations;
|
|
1445
1450
|
}
|
|
1446
1451
|
expression() {
|
|
1447
|
-
|
|
1452
|
+
const expression = this.anonymousFunction();
|
|
1453
|
+
this._references.expressions.add(expression);
|
|
1454
|
+
return expression;
|
|
1448
1455
|
}
|
|
1449
1456
|
anonymousFunction() {
|
|
1450
|
-
if (this.checkAny(
|
|
1457
|
+
if (this.checkAny(TokenKind_1.TokenKind.Sub, TokenKind_1.TokenKind.Function)) {
|
|
1451
1458
|
const func = this.functionDeclaration(true);
|
|
1452
1459
|
//if there's an open paren after this, this is an IIFE
|
|
1453
|
-
if (this.check(
|
|
1460
|
+
if (this.check(TokenKind_1.TokenKind.LeftParen)) {
|
|
1454
1461
|
return this.finishCall(this.advance(), func);
|
|
1455
1462
|
}
|
|
1456
1463
|
else {
|
|
@@ -1458,10 +1465,10 @@ class Parser {
|
|
|
1458
1465
|
}
|
|
1459
1466
|
}
|
|
1460
1467
|
let expr = this.boolean();
|
|
1461
|
-
if (this.check(
|
|
1468
|
+
if (this.check(TokenKind_1.TokenKind.Question)) {
|
|
1462
1469
|
return this.ternaryExpression(expr);
|
|
1463
1470
|
}
|
|
1464
|
-
else if (this.check(
|
|
1471
|
+
else if (this.check(TokenKind_1.TokenKind.QuestionQuestion)) {
|
|
1465
1472
|
return this.nullCoalescingExpression(expr);
|
|
1466
1473
|
}
|
|
1467
1474
|
else {
|
|
@@ -1470,7 +1477,7 @@ class Parser {
|
|
|
1470
1477
|
}
|
|
1471
1478
|
boolean() {
|
|
1472
1479
|
let expr = this.relational();
|
|
1473
|
-
while (this.matchAny(
|
|
1480
|
+
while (this.matchAny(TokenKind_1.TokenKind.And, TokenKind_1.TokenKind.Or)) {
|
|
1474
1481
|
let operator = this.previous();
|
|
1475
1482
|
let right = this.relational();
|
|
1476
1483
|
expr = new Expression_1.BinaryExpression(expr, operator, right);
|
|
@@ -1479,7 +1486,7 @@ class Parser {
|
|
|
1479
1486
|
}
|
|
1480
1487
|
relational() {
|
|
1481
1488
|
let expr = this.additive();
|
|
1482
|
-
while (this.matchAny(
|
|
1489
|
+
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)) {
|
|
1483
1490
|
let operator = this.previous();
|
|
1484
1491
|
let right = this.additive();
|
|
1485
1492
|
expr = new Expression_1.BinaryExpression(expr, operator, right);
|
|
@@ -1489,7 +1496,7 @@ class Parser {
|
|
|
1489
1496
|
// TODO: bitshift
|
|
1490
1497
|
additive() {
|
|
1491
1498
|
let expr = this.multiplicative();
|
|
1492
|
-
while (this.matchAny(
|
|
1499
|
+
while (this.matchAny(TokenKind_1.TokenKind.Plus, TokenKind_1.TokenKind.Minus)) {
|
|
1493
1500
|
let operator = this.previous();
|
|
1494
1501
|
let right = this.multiplicative();
|
|
1495
1502
|
expr = new Expression_1.BinaryExpression(expr, operator, right);
|
|
@@ -1498,7 +1505,7 @@ class Parser {
|
|
|
1498
1505
|
}
|
|
1499
1506
|
multiplicative() {
|
|
1500
1507
|
let expr = this.exponential();
|
|
1501
|
-
while (this.matchAny(
|
|
1508
|
+
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)) {
|
|
1502
1509
|
let operator = this.previous();
|
|
1503
1510
|
let right = this.exponential();
|
|
1504
1511
|
expr = new Expression_1.BinaryExpression(expr, operator, right);
|
|
@@ -1507,7 +1514,7 @@ class Parser {
|
|
|
1507
1514
|
}
|
|
1508
1515
|
exponential() {
|
|
1509
1516
|
let expr = this.prefixUnary();
|
|
1510
|
-
while (this.match(
|
|
1517
|
+
while (this.match(TokenKind_1.TokenKind.Caret)) {
|
|
1511
1518
|
let operator = this.previous();
|
|
1512
1519
|
let right = this.prefixUnary();
|
|
1513
1520
|
expr = new Expression_1.BinaryExpression(expr, operator, right);
|
|
@@ -1516,7 +1523,7 @@ class Parser {
|
|
|
1516
1523
|
}
|
|
1517
1524
|
prefixUnary() {
|
|
1518
1525
|
const nextKind = this.peek().kind;
|
|
1519
|
-
if (nextKind ===
|
|
1526
|
+
if (nextKind === TokenKind_1.TokenKind.Not || nextKind === TokenKind_1.TokenKind.Minus) {
|
|
1520
1527
|
this.current++; //advance
|
|
1521
1528
|
let operator = this.previous();
|
|
1522
1529
|
let right = this.prefixUnary();
|
|
@@ -1526,17 +1533,17 @@ class Parser {
|
|
|
1526
1533
|
}
|
|
1527
1534
|
indexedGet(expr) {
|
|
1528
1535
|
let openingSquare = this.previous();
|
|
1529
|
-
while (this.match(
|
|
1536
|
+
while (this.match(TokenKind_1.TokenKind.Newline)) { }
|
|
1530
1537
|
let index = this.expression();
|
|
1531
|
-
while (this.match(
|
|
1532
|
-
let closingSquare = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedRightSquareBraceAfterArrayOrObjectIndex(),
|
|
1538
|
+
while (this.match(TokenKind_1.TokenKind.Newline)) { }
|
|
1539
|
+
let closingSquare = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedRightSquareBraceAfterArrayOrObjectIndex(), TokenKind_1.TokenKind.RightSquareBracket);
|
|
1533
1540
|
return new Expression_1.IndexedGetExpression(expr, index, openingSquare, closingSquare);
|
|
1534
1541
|
}
|
|
1535
1542
|
newExpression() {
|
|
1536
1543
|
this.warnIfNotBrighterScriptMode(`using 'new' keyword to construct a class`);
|
|
1537
1544
|
let newToken = this.advance();
|
|
1538
1545
|
let nameExpr = this.getNamespacedVariableNameExpression();
|
|
1539
|
-
let leftParen = this.consume(DiagnosticMessages_1.DiagnosticMessages.unexpectedToken(this.peek().text),
|
|
1546
|
+
let leftParen = this.consume(DiagnosticMessages_1.DiagnosticMessages.unexpectedToken(this.peek().text), TokenKind_1.TokenKind.LeftParen);
|
|
1540
1547
|
let call = this.finishCall(leftParen, nameExpr);
|
|
1541
1548
|
//pop the call from the callExpressions list because this is technically something else
|
|
1542
1549
|
this.callExpressions.pop();
|
|
@@ -1550,46 +1557,52 @@ class Parser {
|
|
|
1550
1557
|
callfunc(callee) {
|
|
1551
1558
|
this.warnIfNotBrighterScriptMode('callfunc operator');
|
|
1552
1559
|
let operator = this.previous();
|
|
1553
|
-
let methodName = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier(),
|
|
1560
|
+
let methodName = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier(), TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedProperties);
|
|
1554
1561
|
// force it into an identifier so the AST makes some sense
|
|
1555
|
-
methodName.kind =
|
|
1556
|
-
let openParen = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedOpenParenToFollowCallfuncIdentifier(),
|
|
1562
|
+
methodName.kind = TokenKind_1.TokenKind.Identifier;
|
|
1563
|
+
let openParen = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedOpenParenToFollowCallfuncIdentifier(), TokenKind_1.TokenKind.LeftParen);
|
|
1557
1564
|
let call = this.finishCall(openParen, callee, false);
|
|
1558
1565
|
return new Expression_1.CallfuncExpression(callee, operator, methodName, openParen, call.args, call.closingParen);
|
|
1559
1566
|
}
|
|
1560
1567
|
call() {
|
|
1561
|
-
if (this.check(
|
|
1568
|
+
if (this.check(TokenKind_1.TokenKind.New) && this.checkAnyNext(TokenKind_1.TokenKind.Identifier, ...this.allowedLocalIdentifiers)) {
|
|
1562
1569
|
return this.newExpression();
|
|
1563
1570
|
}
|
|
1564
1571
|
let expr = this.primary();
|
|
1572
|
+
//an expression to keep for _references
|
|
1573
|
+
let referenceCallExpression;
|
|
1565
1574
|
while (true) {
|
|
1566
|
-
if (this.match(
|
|
1575
|
+
if (this.match(TokenKind_1.TokenKind.LeftParen)) {
|
|
1567
1576
|
expr = this.finishCall(this.previous(), expr);
|
|
1577
|
+
//store this call expression in references
|
|
1578
|
+
referenceCallExpression = expr;
|
|
1568
1579
|
}
|
|
1569
|
-
else if (this.match(
|
|
1580
|
+
else if (this.match(TokenKind_1.TokenKind.LeftSquareBracket)) {
|
|
1570
1581
|
expr = this.indexedGet(expr);
|
|
1571
1582
|
}
|
|
1572
|
-
else if (this.match(
|
|
1583
|
+
else if (this.match(TokenKind_1.TokenKind.Callfunc)) {
|
|
1573
1584
|
expr = this.callfunc(expr);
|
|
1585
|
+
//store this callfunc expression in references
|
|
1586
|
+
referenceCallExpression = expr;
|
|
1574
1587
|
}
|
|
1575
|
-
else if (this.match(
|
|
1576
|
-
if (this.match(
|
|
1588
|
+
else if (this.match(TokenKind_1.TokenKind.Dot)) {
|
|
1589
|
+
if (this.match(TokenKind_1.TokenKind.LeftSquareBracket)) {
|
|
1577
1590
|
expr = this.indexedGet(expr);
|
|
1578
1591
|
}
|
|
1579
1592
|
else {
|
|
1580
1593
|
let dot = this.previous();
|
|
1581
|
-
let name = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedPropertyNameAfterPeriod(),
|
|
1594
|
+
let name = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedPropertyNameAfterPeriod(), TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedProperties);
|
|
1582
1595
|
// force it into an identifier so the AST makes some sense
|
|
1583
|
-
name.kind =
|
|
1596
|
+
name.kind = TokenKind_1.TokenKind.Identifier;
|
|
1584
1597
|
expr = new Expression_1.DottedGetExpression(expr, name, dot);
|
|
1585
1598
|
this.addPropertyHints(name);
|
|
1586
1599
|
}
|
|
1587
1600
|
}
|
|
1588
|
-
else if (this.check(
|
|
1601
|
+
else if (this.check(TokenKind_1.TokenKind.At)) {
|
|
1589
1602
|
let dot = this.advance();
|
|
1590
|
-
let name = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedAttributeNameAfterAtSymbol(),
|
|
1603
|
+
let name = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedAttributeNameAfterAtSymbol(), TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedProperties);
|
|
1591
1604
|
// force it into an identifier so the AST makes some sense
|
|
1592
|
-
name.kind =
|
|
1605
|
+
name.kind = TokenKind_1.TokenKind.Identifier;
|
|
1593
1606
|
expr = new Expression_1.XmlAttributeGetExpression(expr, name, dot);
|
|
1594
1607
|
//only allow a single `@` expression
|
|
1595
1608
|
break;
|
|
@@ -1598,24 +1611,28 @@ class Parser {
|
|
|
1598
1611
|
break;
|
|
1599
1612
|
}
|
|
1600
1613
|
}
|
|
1614
|
+
//if we found a callExpression, add it to `expressions` in references
|
|
1615
|
+
if (referenceCallExpression) {
|
|
1616
|
+
this._references.expressions.add(referenceCallExpression);
|
|
1617
|
+
}
|
|
1601
1618
|
return expr;
|
|
1602
1619
|
}
|
|
1603
1620
|
finishCall(openingParen, callee, addToCallExpressionList = true) {
|
|
1604
1621
|
let args = [];
|
|
1605
|
-
while (this.match(
|
|
1622
|
+
while (this.match(TokenKind_1.TokenKind.Newline)) {
|
|
1606
1623
|
}
|
|
1607
|
-
if (!this.check(
|
|
1624
|
+
if (!this.check(TokenKind_1.TokenKind.RightParen)) {
|
|
1608
1625
|
do {
|
|
1609
|
-
while (this.match(
|
|
1626
|
+
while (this.match(TokenKind_1.TokenKind.Newline)) { }
|
|
1610
1627
|
if (args.length >= Expression_1.CallExpression.MaximumArguments) {
|
|
1611
1628
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.tooManyCallableArguments(args.length, Expression_1.CallExpression.MaximumArguments)), { range: this.peek().range }));
|
|
1612
1629
|
throw this.lastDiagnosticAsError();
|
|
1613
1630
|
}
|
|
1614
1631
|
args.push(this.expression());
|
|
1615
|
-
} while (this.match(
|
|
1632
|
+
} while (this.match(TokenKind_1.TokenKind.Comma));
|
|
1616
1633
|
}
|
|
1617
|
-
while (this.match(
|
|
1618
|
-
const closingParen = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedRightParenAfterFunctionCallArguments(),
|
|
1634
|
+
while (this.match(TokenKind_1.TokenKind.Newline)) { }
|
|
1635
|
+
const closingParen = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedRightParenAfterFunctionCallArguments(), TokenKind_1.TokenKind.RightParen);
|
|
1619
1636
|
if ((0, reflection_1.isVariableExpression)(callee)) {
|
|
1620
1637
|
callee.isCalled = true;
|
|
1621
1638
|
}
|
|
@@ -1632,7 +1649,7 @@ class Parser {
|
|
|
1632
1649
|
*/
|
|
1633
1650
|
typeToken() {
|
|
1634
1651
|
let typeToken;
|
|
1635
|
-
if (this.checkAny(...
|
|
1652
|
+
if (this.checkAny(...TokenKind_1.DeclarableTypes)) {
|
|
1636
1653
|
// Token is a built in type
|
|
1637
1654
|
typeToken = this.advance();
|
|
1638
1655
|
}
|
|
@@ -1640,7 +1657,7 @@ class Parser {
|
|
|
1640
1657
|
try {
|
|
1641
1658
|
// see if we can get a namespaced identifer
|
|
1642
1659
|
const qualifiedType = this.getNamespacedVariableNameExpression();
|
|
1643
|
-
typeToken = (0, creators_1.createToken)(
|
|
1660
|
+
typeToken = (0, creators_1.createToken)(TokenKind_1.TokenKind.Identifier, qualifiedType.getName(this.options.mode), qualifiedType.range);
|
|
1644
1661
|
}
|
|
1645
1662
|
catch (_a) {
|
|
1646
1663
|
//could not get an identifier - just get whatever's next
|
|
@@ -1655,53 +1672,53 @@ class Parser {
|
|
|
1655
1672
|
}
|
|
1656
1673
|
primary() {
|
|
1657
1674
|
switch (true) {
|
|
1658
|
-
case this.matchAny(
|
|
1675
|
+
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):
|
|
1659
1676
|
return new Expression_1.LiteralExpression(this.previous());
|
|
1660
1677
|
//capture source literals (LINE_NUM if brightscript, or a bunch of them if brighterscript)
|
|
1661
|
-
case this.matchAny(
|
|
1678
|
+
case this.matchAny(TokenKind_1.TokenKind.LineNumLiteral, ...(this.options.mode === ParseMode.BrightScript ? [] : TokenKind_1.BrighterScriptSourceLiterals)):
|
|
1662
1679
|
return new Expression_1.SourceLiteralExpression(this.previous());
|
|
1663
1680
|
//template string
|
|
1664
|
-
case this.check(
|
|
1681
|
+
case this.check(TokenKind_1.TokenKind.BackTick):
|
|
1665
1682
|
return this.templateString(false);
|
|
1666
1683
|
//tagged template string (currently we do not support spaces between the identifier and the backtick)
|
|
1667
|
-
case this.checkAny(
|
|
1684
|
+
case this.checkAny(TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedLocalIdentifiers) && this.checkNext(TokenKind_1.TokenKind.BackTick):
|
|
1668
1685
|
return this.templateString(true);
|
|
1669
|
-
case this.matchAny(
|
|
1686
|
+
case this.matchAny(TokenKind_1.TokenKind.Identifier, ...this.allowedLocalIdentifiers):
|
|
1670
1687
|
return new Expression_1.VariableExpression(this.previous(), this.currentNamespaceName);
|
|
1671
|
-
case this.match(
|
|
1688
|
+
case this.match(TokenKind_1.TokenKind.LeftParen):
|
|
1672
1689
|
let left = this.previous();
|
|
1673
1690
|
let expr = this.expression();
|
|
1674
|
-
let right = this.consume(DiagnosticMessages_1.DiagnosticMessages.unmatchedLeftParenAfterExpression(),
|
|
1691
|
+
let right = this.consume(DiagnosticMessages_1.DiagnosticMessages.unmatchedLeftParenAfterExpression(), TokenKind_1.TokenKind.RightParen);
|
|
1675
1692
|
return new Expression_1.GroupingExpression({ left: left, right: right }, expr);
|
|
1676
|
-
case this.match(
|
|
1693
|
+
case this.match(TokenKind_1.TokenKind.LeftSquareBracket):
|
|
1677
1694
|
let elements = [];
|
|
1678
1695
|
let openingSquare = this.previous();
|
|
1679
1696
|
//add any comment found right after the opening square
|
|
1680
|
-
if (this.check(
|
|
1697
|
+
if (this.check(TokenKind_1.TokenKind.Comment)) {
|
|
1681
1698
|
elements.push(new Statement_1.CommentStatement([this.advance()]));
|
|
1682
1699
|
}
|
|
1683
|
-
while (this.match(
|
|
1700
|
+
while (this.match(TokenKind_1.TokenKind.Newline)) {
|
|
1684
1701
|
}
|
|
1685
|
-
if (!this.match(
|
|
1702
|
+
if (!this.match(TokenKind_1.TokenKind.RightSquareBracket)) {
|
|
1686
1703
|
elements.push(this.expression());
|
|
1687
|
-
while (this.matchAny(
|
|
1688
|
-
if (this.checkPrevious(
|
|
1689
|
-
let comment = this.check(
|
|
1704
|
+
while (this.matchAny(TokenKind_1.TokenKind.Comma, TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Comment)) {
|
|
1705
|
+
if (this.checkPrevious(TokenKind_1.TokenKind.Comment) || this.check(TokenKind_1.TokenKind.Comment)) {
|
|
1706
|
+
let comment = this.check(TokenKind_1.TokenKind.Comment) ? this.advance() : this.previous();
|
|
1690
1707
|
elements.push(new Statement_1.CommentStatement([comment]));
|
|
1691
1708
|
}
|
|
1692
|
-
while (this.match(
|
|
1709
|
+
while (this.match(TokenKind_1.TokenKind.Newline)) {
|
|
1693
1710
|
}
|
|
1694
|
-
if (this.check(
|
|
1711
|
+
if (this.check(TokenKind_1.TokenKind.RightSquareBracket)) {
|
|
1695
1712
|
break;
|
|
1696
1713
|
}
|
|
1697
1714
|
elements.push(this.expression());
|
|
1698
1715
|
}
|
|
1699
|
-
this.consume(DiagnosticMessages_1.DiagnosticMessages.unmatchedLeftSquareBraceAfterArrayLiteral(),
|
|
1716
|
+
this.consume(DiagnosticMessages_1.DiagnosticMessages.unmatchedLeftSquareBraceAfterArrayLiteral(), TokenKind_1.TokenKind.RightSquareBracket);
|
|
1700
1717
|
}
|
|
1701
1718
|
let closingSquare = this.previous();
|
|
1702
1719
|
//this.consume("Expected newline or ':' after array literal", TokenKind.Newline, TokenKind.Colon, TokenKind.Eof);
|
|
1703
1720
|
return new Expression_1.ArrayLiteralExpression(elements, openingSquare, closingSquare);
|
|
1704
|
-
case this.match(
|
|
1721
|
+
case this.match(TokenKind_1.TokenKind.LeftCurlyBrace):
|
|
1705
1722
|
let openingBrace = this.previous();
|
|
1706
1723
|
let members = [];
|
|
1707
1724
|
let key = () => {
|
|
@@ -1710,25 +1727,25 @@ class Parser {
|
|
|
1710
1727
|
keyToken: null,
|
|
1711
1728
|
range: null
|
|
1712
1729
|
};
|
|
1713
|
-
if (this.checkAny(
|
|
1730
|
+
if (this.checkAny(TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedProperties)) {
|
|
1714
1731
|
result.keyToken = this.advance();
|
|
1715
1732
|
}
|
|
1716
|
-
else if (this.check(
|
|
1733
|
+
else if (this.check(TokenKind_1.TokenKind.StringLiteral)) {
|
|
1717
1734
|
result.keyToken = this.advance();
|
|
1718
1735
|
}
|
|
1719
1736
|
else {
|
|
1720
1737
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.unexpectedAAKey()), { range: this.peek().range }));
|
|
1721
1738
|
throw this.lastDiagnosticAsError();
|
|
1722
1739
|
}
|
|
1723
|
-
result.colonToken = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedColonBetweenAAKeyAndvalue(),
|
|
1740
|
+
result.colonToken = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedColonBetweenAAKeyAndvalue(), TokenKind_1.TokenKind.Colon);
|
|
1724
1741
|
result.range = util_1.util.getRange(result.keyToken, result.colonToken);
|
|
1725
1742
|
return result;
|
|
1726
1743
|
};
|
|
1727
|
-
while (this.match(
|
|
1744
|
+
while (this.match(TokenKind_1.TokenKind.Newline)) {
|
|
1728
1745
|
}
|
|
1729
|
-
if (!this.match(
|
|
1746
|
+
if (!this.match(TokenKind_1.TokenKind.RightCurlyBrace)) {
|
|
1730
1747
|
let lastAAMember;
|
|
1731
|
-
if (this.check(
|
|
1748
|
+
if (this.check(TokenKind_1.TokenKind.Comment)) {
|
|
1732
1749
|
lastAAMember = null;
|
|
1733
1750
|
members.push(new Statement_1.CommentStatement([this.advance()]));
|
|
1734
1751
|
}
|
|
@@ -1738,26 +1755,26 @@ class Parser {
|
|
|
1738
1755
|
lastAAMember = new Expression_1.AAMemberExpression(k.keyToken, k.colonToken, expr);
|
|
1739
1756
|
members.push(lastAAMember);
|
|
1740
1757
|
}
|
|
1741
|
-
while (this.matchAny(
|
|
1758
|
+
while (this.matchAny(TokenKind_1.TokenKind.Comma, TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Colon, TokenKind_1.TokenKind.Comment)) {
|
|
1742
1759
|
// collect comma at end of expression
|
|
1743
|
-
if (lastAAMember && this.checkPrevious(
|
|
1760
|
+
if (lastAAMember && this.checkPrevious(TokenKind_1.TokenKind.Comma)) {
|
|
1744
1761
|
lastAAMember.commaToken = this.previous();
|
|
1745
1762
|
}
|
|
1746
1763
|
//check for comment at the end of the current line
|
|
1747
|
-
if (this.check(
|
|
1748
|
-
let token = this.checkPrevious(
|
|
1764
|
+
if (this.check(TokenKind_1.TokenKind.Comment) || this.checkPrevious(TokenKind_1.TokenKind.Comment)) {
|
|
1765
|
+
let token = this.checkPrevious(TokenKind_1.TokenKind.Comment) ? this.previous() : this.advance();
|
|
1749
1766
|
members.push(new Statement_1.CommentStatement([token]));
|
|
1750
1767
|
}
|
|
1751
1768
|
else {
|
|
1752
1769
|
this.consumeStatementSeparators(true);
|
|
1753
1770
|
//check for a comment on its own line
|
|
1754
|
-
if (this.check(
|
|
1755
|
-
let token = this.checkPrevious(
|
|
1771
|
+
if (this.check(TokenKind_1.TokenKind.Comment) || this.checkPrevious(TokenKind_1.TokenKind.Comment)) {
|
|
1772
|
+
let token = this.checkPrevious(TokenKind_1.TokenKind.Comment) ? this.previous() : this.advance();
|
|
1756
1773
|
lastAAMember = null;
|
|
1757
1774
|
members.push(new Statement_1.CommentStatement([token]));
|
|
1758
1775
|
continue;
|
|
1759
1776
|
}
|
|
1760
|
-
if (this.check(
|
|
1777
|
+
if (this.check(TokenKind_1.TokenKind.RightCurlyBrace)) {
|
|
1761
1778
|
break;
|
|
1762
1779
|
}
|
|
1763
1780
|
let k = key();
|
|
@@ -1766,22 +1783,22 @@ class Parser {
|
|
|
1766
1783
|
members.push(lastAAMember);
|
|
1767
1784
|
}
|
|
1768
1785
|
}
|
|
1769
|
-
this.consume(DiagnosticMessages_1.DiagnosticMessages.unmatchedLeftCurlyAfterAALiteral(),
|
|
1786
|
+
this.consume(DiagnosticMessages_1.DiagnosticMessages.unmatchedLeftCurlyAfterAALiteral(), TokenKind_1.TokenKind.RightCurlyBrace);
|
|
1770
1787
|
}
|
|
1771
1788
|
let closingBrace = this.previous();
|
|
1772
1789
|
const aaExpr = new Expression_1.AALiteralExpression(members, openingBrace, closingBrace);
|
|
1773
1790
|
this.addPropertyHints(aaExpr);
|
|
1774
1791
|
return aaExpr;
|
|
1775
|
-
case this.matchAny(
|
|
1792
|
+
case this.matchAny(TokenKind_1.TokenKind.Pos, TokenKind_1.TokenKind.Tab):
|
|
1776
1793
|
let token = Object.assign(this.previous(), {
|
|
1777
|
-
kind:
|
|
1794
|
+
kind: TokenKind_1.TokenKind.Identifier
|
|
1778
1795
|
});
|
|
1779
1796
|
return new Expression_1.VariableExpression(token, this.currentNamespaceName);
|
|
1780
|
-
case this.checkAny(
|
|
1797
|
+
case this.checkAny(TokenKind_1.TokenKind.Function, TokenKind_1.TokenKind.Sub):
|
|
1781
1798
|
return this.anonymousFunction();
|
|
1782
|
-
case this.check(
|
|
1799
|
+
case this.check(TokenKind_1.TokenKind.RegexLiteral):
|
|
1783
1800
|
return this.regexLiteralExpression();
|
|
1784
|
-
case this.check(
|
|
1801
|
+
case this.check(TokenKind_1.TokenKind.Comment):
|
|
1785
1802
|
return new Statement_1.CommentStatement([this.advance()]);
|
|
1786
1803
|
default:
|
|
1787
1804
|
//if we found an expected terminator, don't throw a diagnostic...just return undefined
|
|
@@ -1851,12 +1868,12 @@ class Parser {
|
|
|
1851
1868
|
}
|
|
1852
1869
|
consumeStatementSeparators(optional = false) {
|
|
1853
1870
|
//a comment or EOF mark the end of the statement
|
|
1854
|
-
if (this.isAtEnd() || this.check(
|
|
1871
|
+
if (this.isAtEnd() || this.check(TokenKind_1.TokenKind.Comment)) {
|
|
1855
1872
|
return true;
|
|
1856
1873
|
}
|
|
1857
1874
|
let consumed = false;
|
|
1858
1875
|
//consume any newlines and colons
|
|
1859
|
-
while (this.matchAny(
|
|
1876
|
+
while (this.matchAny(TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Colon)) {
|
|
1860
1877
|
consumed = true;
|
|
1861
1878
|
}
|
|
1862
1879
|
if (!optional && !consumed) {
|
|
@@ -1872,7 +1889,7 @@ class Parser {
|
|
|
1872
1889
|
}
|
|
1873
1890
|
checkEndOfStatement() {
|
|
1874
1891
|
const nextKind = this.peek().kind;
|
|
1875
|
-
return [
|
|
1892
|
+
return [TokenKind_1.TokenKind.Colon, TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Comment, TokenKind_1.TokenKind.Eof].includes(nextKind);
|
|
1876
1893
|
}
|
|
1877
1894
|
checkPrevious(tokenKind) {
|
|
1878
1895
|
var _a;
|
|
@@ -1880,14 +1897,14 @@ class Parser {
|
|
|
1880
1897
|
}
|
|
1881
1898
|
check(tokenKind) {
|
|
1882
1899
|
const nextKind = this.peek().kind;
|
|
1883
|
-
if (nextKind ===
|
|
1900
|
+
if (nextKind === TokenKind_1.TokenKind.Eof) {
|
|
1884
1901
|
return false;
|
|
1885
1902
|
}
|
|
1886
1903
|
return nextKind === tokenKind;
|
|
1887
1904
|
}
|
|
1888
1905
|
checkAny(...tokenKinds) {
|
|
1889
1906
|
const nextKind = this.peek().kind;
|
|
1890
|
-
if (nextKind ===
|
|
1907
|
+
if (nextKind === TokenKind_1.TokenKind.Eof) {
|
|
1891
1908
|
return false;
|
|
1892
1909
|
}
|
|
1893
1910
|
return tokenKinds.includes(nextKind);
|
|
@@ -1906,7 +1923,7 @@ class Parser {
|
|
|
1906
1923
|
return tokenKinds.includes(nextKind);
|
|
1907
1924
|
}
|
|
1908
1925
|
isAtEnd() {
|
|
1909
|
-
return this.peek().kind ===
|
|
1926
|
+
return this.peek().kind === TokenKind_1.TokenKind.Eof;
|
|
1910
1927
|
}
|
|
1911
1928
|
peekNext() {
|
|
1912
1929
|
if (this.isAtEnd()) {
|
|
@@ -1928,16 +1945,16 @@ class Parser {
|
|
|
1928
1945
|
return;
|
|
1929
1946
|
}
|
|
1930
1947
|
switch (this.peek().kind) { //eslint-disable-line @typescript-eslint/switch-exhaustiveness-check
|
|
1931
|
-
case
|
|
1932
|
-
case
|
|
1933
|
-
case
|
|
1934
|
-
case
|
|
1935
|
-
case
|
|
1936
|
-
case
|
|
1937
|
-
case
|
|
1938
|
-
case
|
|
1939
|
-
case
|
|
1940
|
-
case
|
|
1948
|
+
case TokenKind_1.TokenKind.Namespace:
|
|
1949
|
+
case TokenKind_1.TokenKind.Class:
|
|
1950
|
+
case TokenKind_1.TokenKind.Function:
|
|
1951
|
+
case TokenKind_1.TokenKind.Sub:
|
|
1952
|
+
case TokenKind_1.TokenKind.If:
|
|
1953
|
+
case TokenKind_1.TokenKind.For:
|
|
1954
|
+
case TokenKind_1.TokenKind.ForEach:
|
|
1955
|
+
case TokenKind_1.TokenKind.While:
|
|
1956
|
+
case TokenKind_1.TokenKind.Print:
|
|
1957
|
+
case TokenKind_1.TokenKind.Return:
|
|
1941
1958
|
// start parsing again from the next block starter or obvious
|
|
1942
1959
|
// expression start
|
|
1943
1960
|
return;
|
|
@@ -1952,13 +1969,55 @@ class Parser {
|
|
|
1952
1969
|
*/
|
|
1953
1970
|
findReferences() {
|
|
1954
1971
|
this._references = new References();
|
|
1972
|
+
const excludedExpressions = new Set();
|
|
1973
|
+
const visitCallExpression = (e) => {
|
|
1974
|
+
for (const p of e.args) {
|
|
1975
|
+
this._references.expressions.add(p);
|
|
1976
|
+
}
|
|
1977
|
+
//add calls that were not excluded (from loop below)
|
|
1978
|
+
if (!excludedExpressions.has(e)) {
|
|
1979
|
+
this._references.expressions.add(e);
|
|
1980
|
+
}
|
|
1981
|
+
//if this call is part of a longer expression that includes a call higher up, find that higher one and remove it
|
|
1982
|
+
if (e.callee) {
|
|
1983
|
+
let node = e.callee;
|
|
1984
|
+
while (node) {
|
|
1985
|
+
//the primary goal for this loop. If we found a parent call expression, remove it from `references`
|
|
1986
|
+
if ((0, reflection_1.isCallExpression)(node)) {
|
|
1987
|
+
this.references.expressions.delete(node);
|
|
1988
|
+
excludedExpressions.add(node);
|
|
1989
|
+
//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.
|
|
1990
|
+
break;
|
|
1991
|
+
//when we hit a variable expression, we're definitely at the leftmost expression so stop
|
|
1992
|
+
}
|
|
1993
|
+
else if ((0, reflection_1.isVariableExpression)(node)) {
|
|
1994
|
+
break;
|
|
1995
|
+
//if
|
|
1996
|
+
}
|
|
1997
|
+
else if ((0, reflection_1.isDottedGetExpression)(node) || (0, reflection_1.isIndexedGetExpression)(node)) {
|
|
1998
|
+
node = node.obj;
|
|
1999
|
+
}
|
|
2000
|
+
else {
|
|
2001
|
+
//some expression we don't understand. log it and quit the loop
|
|
2002
|
+
this.logger.info('Encountered unknown expression while calculating function expression chain', node);
|
|
2003
|
+
break;
|
|
2004
|
+
}
|
|
2005
|
+
}
|
|
2006
|
+
}
|
|
2007
|
+
};
|
|
1955
2008
|
this.ast.walk((0, visitors_1.createVisitor)({
|
|
1956
2009
|
AssignmentStatement: s => {
|
|
1957
2010
|
this._references.assignmentStatements.push(s);
|
|
2011
|
+
this.references.expressions.add(s.value);
|
|
1958
2012
|
},
|
|
1959
2013
|
ClassStatement: s => {
|
|
1960
2014
|
this._references.classStatements.push(s);
|
|
1961
2015
|
},
|
|
2016
|
+
ClassFieldStatement: s => {
|
|
2017
|
+
if (s.initialValue) {
|
|
2018
|
+
this._references.expressions.add(s.initialValue);
|
|
2019
|
+
}
|
|
2020
|
+
},
|
|
1962
2021
|
NamespaceStatement: s => {
|
|
1963
2022
|
this._references.namespaceStatements.push(s);
|
|
1964
2023
|
},
|
|
@@ -1978,15 +2037,47 @@ class Parser {
|
|
|
1978
2037
|
},
|
|
1979
2038
|
NewExpression: e => {
|
|
1980
2039
|
this._references.newExpressions.push(e);
|
|
2040
|
+
for (const p of e.call.args) {
|
|
2041
|
+
this._references.expressions.add(p);
|
|
2042
|
+
}
|
|
2043
|
+
},
|
|
2044
|
+
ExpressionStatement: s => {
|
|
2045
|
+
this._references.expressions.add(s.expression);
|
|
2046
|
+
},
|
|
2047
|
+
CallfuncExpression: e => {
|
|
2048
|
+
visitCallExpression(e);
|
|
2049
|
+
},
|
|
2050
|
+
CallExpression: e => {
|
|
2051
|
+
visitCallExpression(e);
|
|
1981
2052
|
},
|
|
1982
2053
|
AALiteralExpression: e => {
|
|
1983
2054
|
this.addPropertyHints(e);
|
|
2055
|
+
this._references.expressions.add(e);
|
|
2056
|
+
for (const member of e.elements) {
|
|
2057
|
+
if ((0, reflection_1.isAAMemberExpression)(member)) {
|
|
2058
|
+
this._references.expressions.add(member.value);
|
|
2059
|
+
}
|
|
2060
|
+
}
|
|
2061
|
+
},
|
|
2062
|
+
ArrayLiteralExpression: e => {
|
|
2063
|
+
for (const element of e.elements) {
|
|
2064
|
+
//keep everything except comments
|
|
2065
|
+
if (!(0, reflection_1.isCommentStatement)(element)) {
|
|
2066
|
+
this._references.expressions.add(element);
|
|
2067
|
+
}
|
|
2068
|
+
}
|
|
1984
2069
|
},
|
|
1985
2070
|
DottedGetExpression: e => {
|
|
1986
2071
|
this.addPropertyHints(e.name);
|
|
1987
2072
|
},
|
|
1988
2073
|
DottedSetStatement: e => {
|
|
1989
2074
|
this.addPropertyHints(e.name);
|
|
2075
|
+
},
|
|
2076
|
+
UnaryExpression: e => {
|
|
2077
|
+
this._references.expressions.add(e);
|
|
2078
|
+
},
|
|
2079
|
+
IncrementStatement: e => {
|
|
2080
|
+
this._references.expressions.add(e);
|
|
1990
2081
|
}
|
|
1991
2082
|
}), {
|
|
1992
2083
|
walkMode: visitors_1.WalkMode.visitAllRecursive
|
|
@@ -2008,6 +2099,17 @@ class References {
|
|
|
2008
2099
|
this.functionExpressions = [];
|
|
2009
2100
|
this.functionStatements = [];
|
|
2010
2101
|
this.interfaceStatements = [];
|
|
2102
|
+
/**
|
|
2103
|
+
* A collection of full expressions. This excludes intermediary expressions.
|
|
2104
|
+
*
|
|
2105
|
+
* Example 1:
|
|
2106
|
+
* `a.b.c` is composed of `a` (variableExpression) `.b` (DottedGetExpression) `.c` (DottedGetExpression)
|
|
2107
|
+
* This will only contain the final `.c` DottedGetExpression because `.b` and `a` can both be derived by walking back from the `.c` DottedGetExpression.
|
|
2108
|
+
*
|
|
2109
|
+
* Example 2:
|
|
2110
|
+
* `name.space.doSomething(a.b.c)` will result in 2 entries in this list. the `CallExpression` for `doSomething`, and the `.c` DottedGetExpression.
|
|
2111
|
+
*/
|
|
2112
|
+
this.expressions = new Set();
|
|
2011
2113
|
this.importStatements = [];
|
|
2012
2114
|
this.libraryStatements = [];
|
|
2013
2115
|
this.namespaceStatements = [];
|