brighterscript 1.0.0-alpha.26 → 1.0.0-alpha.28
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 +82 -5
- package/README.md +1 -1
- package/dist/AstValidationSegmenter.d.ts +1 -1
- package/dist/AstValidationSegmenter.js +4 -5
- package/dist/AstValidationSegmenter.js.map +1 -1
- package/dist/DiagnosticFilterer.d.ts +7 -4
- package/dist/DiagnosticFilterer.js +67 -37
- package/dist/DiagnosticFilterer.js.map +1 -1
- package/dist/DiagnosticMessages.d.ts +1 -3
- package/dist/DiagnosticMessages.js +5 -8
- package/dist/DiagnosticMessages.js.map +1 -1
- package/dist/PluginInterface.js +1 -1
- package/dist/PluginInterface.js.map +1 -1
- package/dist/Program.d.ts +1 -1
- package/dist/Program.js +34 -31
- package/dist/Program.js.map +1 -1
- package/dist/Scope.d.ts +7 -34
- package/dist/Scope.js +45 -305
- package/dist/Scope.js.map +1 -1
- package/dist/SymbolTable.d.ts +1 -8
- package/dist/SymbolTable.js +1 -10
- package/dist/SymbolTable.js.map +1 -1
- package/dist/SymbolTypeFlag.d.ts +8 -0
- package/dist/SymbolTypeFlag.js +13 -0
- package/dist/SymbolTypeFlag.js.map +1 -0
- package/dist/XmlScope.d.ts +0 -8
- package/dist/XmlScope.js +6 -84
- package/dist/XmlScope.js.map +1 -1
- package/dist/astUtils/CachedLookups.d.ts +1 -2
- package/dist/astUtils/CachedLookups.js +4 -19
- package/dist/astUtils/CachedLookups.js.map +1 -1
- package/dist/astUtils/creators.d.ts +1 -0
- package/dist/astUtils/creators.js +48 -8
- package/dist/astUtils/creators.js.map +1 -1
- package/dist/astUtils/creators.spec.js +0 -10
- package/dist/astUtils/creators.spec.js.map +1 -1
- package/dist/astUtils/reflection.d.ts +3 -2
- package/dist/astUtils/reflection.js +11 -7
- package/dist/astUtils/reflection.js.map +1 -1
- package/dist/astUtils/reflection.spec.js +11 -16
- package/dist/astUtils/reflection.spec.js.map +1 -1
- package/dist/astUtils/visitors.d.ts +1 -2
- package/dist/astUtils/visitors.js.map +1 -1
- package/dist/astUtils/visitors.spec.js +1 -5
- package/dist/astUtils/visitors.spec.js.map +1 -1
- package/dist/bscPlugin/BscPlugin.d.ts +2 -1
- package/dist/bscPlugin/BscPlugin.js +4 -0
- package/dist/bscPlugin/BscPlugin.js.map +1 -1
- package/dist/bscPlugin/SignatureHelpUtil.js +4 -3
- package/dist/bscPlugin/SignatureHelpUtil.js.map +1 -1
- package/dist/bscPlugin/completions/CompletionsProcessor.d.ts +1 -0
- package/dist/bscPlugin/completions/CompletionsProcessor.js +46 -29
- package/dist/bscPlugin/completions/CompletionsProcessor.js.map +1 -1
- package/dist/bscPlugin/completions/CompletionsProcessor.spec.js +39 -0
- package/dist/bscPlugin/completions/CompletionsProcessor.spec.js.map +1 -1
- package/dist/bscPlugin/hover/HoverProcessor.d.ts +1 -0
- package/dist/bscPlugin/hover/HoverProcessor.js +30 -10
- package/dist/bscPlugin/hover/HoverProcessor.js.map +1 -1
- package/dist/bscPlugin/hover/HoverProcessor.spec.js +125 -7
- package/dist/bscPlugin/hover/HoverProcessor.spec.js.map +1 -1
- package/dist/bscPlugin/references/ReferencesProvider.d.ts +12 -0
- package/dist/bscPlugin/references/ReferencesProvider.js +56 -0
- package/dist/bscPlugin/references/ReferencesProvider.js.map +1 -0
- package/dist/bscPlugin/references/ReferencesProvider.spec.d.ts +1 -0
- package/dist/bscPlugin/references/ReferencesProvider.spec.js +51 -0
- package/dist/bscPlugin/references/ReferencesProvider.spec.js.map +1 -0
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js +2 -3
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js.map +1 -1
- package/dist/bscPlugin/validation/BrsFileValidator.js +25 -31
- package/dist/bscPlugin/validation/BrsFileValidator.js.map +1 -1
- package/dist/bscPlugin/validation/ScopeValidator.d.ts +34 -1
- package/dist/bscPlugin/validation/ScopeValidator.js +435 -27
- package/dist/bscPlugin/validation/ScopeValidator.js.map +1 -1
- package/dist/bscPlugin/validation/ScopeValidator.spec.js +178 -10
- package/dist/bscPlugin/validation/ScopeValidator.spec.js.map +1 -1
- package/dist/diagnosticUtils.d.ts +1 -1
- package/dist/files/BrsFile.Class.spec.js +15 -7
- package/dist/files/BrsFile.Class.spec.js.map +1 -1
- package/dist/files/BrsFile.d.ts +14 -5
- package/dist/files/BrsFile.js +83 -150
- package/dist/files/BrsFile.js.map +1 -1
- package/dist/files/BrsFile.spec.js +429 -162
- package/dist/files/BrsFile.spec.js.map +1 -1
- package/dist/files/XmlFile.d.ts +2 -3
- package/dist/files/XmlFile.js +1 -3
- package/dist/files/XmlFile.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/interfaces.d.ts +117 -85
- package/dist/interfaces.js +9 -9
- package/dist/interfaces.js.map +1 -1
- package/dist/lexer/Lexer.d.ts +9 -3
- package/dist/lexer/Lexer.js +36 -15
- package/dist/lexer/Lexer.js.map +1 -1
- package/dist/lexer/Lexer.spec.js +76 -38
- package/dist/lexer/Lexer.spec.js.map +1 -1
- package/dist/lexer/Token.js +1 -1
- package/dist/lexer/Token.js.map +1 -1
- package/dist/lexer/TokenKind.d.ts +1 -0
- package/dist/lexer/TokenKind.js +4 -1
- package/dist/lexer/TokenKind.js.map +1 -1
- package/dist/parser/AstNode.d.ts +1 -2
- package/dist/parser/AstNode.js +0 -1
- package/dist/parser/AstNode.js.map +1 -1
- package/dist/parser/BrsTranspileState.d.ts +1 -1
- package/dist/parser/Expression.d.ts +153 -135
- package/dist/parser/Expression.js +204 -114
- package/dist/parser/Expression.js.map +1 -1
- package/dist/parser/Parser.Class.spec.js +15 -16
- package/dist/parser/Parser.Class.spec.js.map +1 -1
- package/dist/parser/Parser.d.ts +8 -4
- package/dist/parser/Parser.js +108 -149
- package/dist/parser/Parser.js.map +1 -1
- package/dist/parser/Parser.spec.js +48 -72
- package/dist/parser/Parser.spec.js.map +1 -1
- package/dist/parser/SGParser.js +49 -35
- package/dist/parser/SGParser.js.map +1 -1
- package/dist/parser/SGTypes.d.ts +36 -24
- package/dist/parser/SGTypes.js +31 -60
- package/dist/parser/SGTypes.js.map +1 -1
- package/dist/parser/Statement.d.ts +214 -207
- package/dist/parser/Statement.js +248 -169
- package/dist/parser/Statement.js.map +1 -1
- package/dist/parser/Statement.spec.js +0 -13
- package/dist/parser/Statement.spec.js.map +1 -1
- package/dist/parser/TranspileState.d.ts +17 -8
- package/dist/parser/TranspileState.js +64 -6
- package/dist/parser/TranspileState.js.map +1 -1
- package/dist/parser/tests/Parser.spec.d.ts +1 -1
- package/dist/parser/tests/Parser.spec.js +1 -2
- package/dist/parser/tests/Parser.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/If.spec.js +1 -1
- package/dist/parser/tests/controlFlow/If.spec.js.map +1 -1
- package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js +1 -3
- package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js.map +1 -1
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js +44 -0
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/TemplateStringExpression.spec.js +6 -6
- package/dist/parser/tests/expression/TernaryExpression.spec.js +47 -0
- package/dist/parser/tests/expression/TernaryExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/TypeExpression.spec.js +8 -9
- package/dist/parser/tests/expression/TypeExpression.spec.js.map +1 -1
- package/dist/parser/tests/statement/ConstStatement.spec.js +2 -2
- package/dist/parser/tests/statement/InterfaceStatement.spec.js +8 -1
- package/dist/parser/tests/statement/InterfaceStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/Misc.spec.js +25 -5
- package/dist/parser/tests/statement/Misc.spec.js.map +1 -1
- package/dist/parser/tests/statement/TryCatch.spec.js +9 -2
- package/dist/parser/tests/statement/TryCatch.spec.js.map +1 -1
- package/dist/preprocessor/Chunk.js +1 -2
- package/dist/preprocessor/Chunk.js.map +1 -1
- package/dist/preprocessor/PreprocessorParser.js +2 -1
- package/dist/preprocessor/PreprocessorParser.js.map +1 -1
- package/dist/roku-types/data.json +70 -52
- package/dist/roku-types/index.d.ts +43 -21
- package/dist/types/ArrayType.js +1 -2
- package/dist/types/ArrayType.js.map +1 -1
- package/dist/types/ArrayType.spec.js +7 -8
- package/dist/types/ArrayType.spec.js.map +1 -1
- package/dist/types/AssociativeArrayType.d.ts +3 -0
- package/dist/types/AssociativeArrayType.js +10 -2
- package/dist/types/AssociativeArrayType.js.map +1 -1
- package/dist/types/BscType.d.ts +1 -1
- package/dist/types/BscType.js +3 -3
- package/dist/types/BscType.js.map +1 -1
- package/dist/types/BuiltInInterfaceAdder.js +7 -8
- package/dist/types/BuiltInInterfaceAdder.js.map +1 -1
- package/dist/types/BuiltInInterfaceAdder.spec.js +31 -32
- package/dist/types/BuiltInInterfaceAdder.spec.js.map +1 -1
- package/dist/types/ClassType.spec.js +10 -11
- package/dist/types/ClassType.spec.js.map +1 -1
- package/dist/types/ComponentType.d.ts +2 -1
- package/dist/types/ComponentType.js.map +1 -1
- package/dist/types/EnumType.js +2 -3
- package/dist/types/EnumType.js.map +1 -1
- package/dist/types/InheritableType.js +3 -4
- package/dist/types/InheritableType.js.map +1 -1
- package/dist/types/InterfaceType.js +2 -3
- package/dist/types/InterfaceType.js.map +1 -1
- package/dist/types/InterfaceType.spec.js +3 -4
- package/dist/types/InterfaceType.spec.js.map +1 -1
- package/dist/types/ObjectType.js +1 -2
- package/dist/types/ObjectType.js.map +1 -1
- package/dist/types/ReferenceType.d.ts +1 -1
- package/dist/types/ReferenceType.spec.js +21 -22
- package/dist/types/ReferenceType.spec.js.map +1 -1
- package/dist/types/UnionType.js +3 -3
- package/dist/types/UnionType.js.map +1 -1
- package/dist/types/UnionType.spec.js +37 -38
- package/dist/types/UnionType.spec.js.map +1 -1
- package/dist/types/helper.spec.js +4 -5
- package/dist/types/helper.spec.js.map +1 -1
- package/dist/util.d.ts +21 -11
- package/dist/util.js +116 -37
- package/dist/util.js.map +1 -1
- package/dist/validators/ClassValidator.d.ts +0 -9
- package/dist/validators/ClassValidator.js +3 -46
- package/dist/validators/ClassValidator.js.map +1 -1
- package/package.json +6 -3
package/dist/parser/Parser.js
CHANGED
|
@@ -11,7 +11,6 @@ const Expression_1 = require("./Expression");
|
|
|
11
11
|
const Logger_1 = require("../Logger");
|
|
12
12
|
const reflection_1 = require("../astUtils/reflection");
|
|
13
13
|
const creators_1 = require("../astUtils/creators");
|
|
14
|
-
const SymbolTable_1 = require("../SymbolTable");
|
|
15
14
|
class Parser {
|
|
16
15
|
constructor() {
|
|
17
16
|
/**
|
|
@@ -28,6 +27,13 @@ class Parser {
|
|
|
28
27
|
*/
|
|
29
28
|
this.callExpressions = [];
|
|
30
29
|
}
|
|
30
|
+
get eofToken() {
|
|
31
|
+
var _a;
|
|
32
|
+
const lastToken = (_a = this.tokens) === null || _a === void 0 ? void 0 : _a[this.tokens.length - 1];
|
|
33
|
+
if ((lastToken === null || lastToken === void 0 ? void 0 : lastToken.kind) === TokenKind_1.TokenKind.Eof) {
|
|
34
|
+
return lastToken;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
31
37
|
get statements() {
|
|
32
38
|
return this.ast.statements;
|
|
33
39
|
}
|
|
@@ -57,16 +63,17 @@ class Parser {
|
|
|
57
63
|
*/
|
|
58
64
|
parse(toParse, options) {
|
|
59
65
|
var _a;
|
|
66
|
+
this.logger = (_a = options === null || options === void 0 ? void 0 : options.logger) !== null && _a !== void 0 ? _a : new Logger_1.Logger();
|
|
67
|
+
options = this.sanitizeParseOptions(options);
|
|
68
|
+
this.options = options;
|
|
60
69
|
let tokens;
|
|
61
70
|
if (typeof toParse === 'string') {
|
|
62
|
-
tokens = Lexer_1.Lexer.scan(toParse).tokens;
|
|
71
|
+
tokens = Lexer_1.Lexer.scan(toParse, { trackLocations: options.trackLocations }).tokens;
|
|
63
72
|
}
|
|
64
73
|
else {
|
|
65
74
|
tokens = toParse;
|
|
66
75
|
}
|
|
67
|
-
this.logger = (_a = options === null || options === void 0 ? void 0 : options.logger) !== null && _a !== void 0 ? _a : new Logger_1.Logger();
|
|
68
76
|
this.tokens = tokens;
|
|
69
|
-
this.options = this.sanitizeParseOptions(options);
|
|
70
77
|
this.allowedLocalIdentifiers = [
|
|
71
78
|
...TokenKind_1.AllowedLocalIdentifiers,
|
|
72
79
|
//when in plain brightscript mode, the BrighterScript source literals can be used as regular variables
|
|
@@ -115,7 +122,11 @@ class Parser {
|
|
|
115
122
|
return body;
|
|
116
123
|
}
|
|
117
124
|
sanitizeParseOptions(options) {
|
|
118
|
-
|
|
125
|
+
var _a, _b;
|
|
126
|
+
options !== null && options !== void 0 ? options : (options = {});
|
|
127
|
+
(_a = options.mode) !== null && _a !== void 0 ? _a : (options.mode = ParseMode.BrightScript);
|
|
128
|
+
(_b = options.trackLocations) !== null && _b !== void 0 ? _b : (options.trackLocations = true);
|
|
129
|
+
return options;
|
|
119
130
|
}
|
|
120
131
|
/**
|
|
121
132
|
* Determine if the parser is currently parsing tokens at the root level.
|
|
@@ -155,9 +166,6 @@ class Parser {
|
|
|
155
166
|
if (this.check(TokenKind_1.TokenKind.At) && this.checkNext(TokenKind_1.TokenKind.Identifier)) {
|
|
156
167
|
return this.annotationExpression();
|
|
157
168
|
}
|
|
158
|
-
if (this.check(TokenKind_1.TokenKind.Comment)) {
|
|
159
|
-
return this.commentStatement();
|
|
160
|
-
}
|
|
161
169
|
//catch certain global terminators to prevent unnecessary lookahead (i.e. like `end namespace`, no need to continue)
|
|
162
170
|
if (this.checkAny(...this.peekGlobalTerminators())) {
|
|
163
171
|
return;
|
|
@@ -190,13 +198,15 @@ class Parser {
|
|
|
190
198
|
return identifier;
|
|
191
199
|
}
|
|
192
200
|
enumMemberStatement() {
|
|
193
|
-
const
|
|
194
|
-
|
|
201
|
+
const name = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedClassFieldIdentifier(), TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedProperties);
|
|
202
|
+
let equalsToken;
|
|
203
|
+
let value;
|
|
195
204
|
//look for `= SOME_EXPRESSION`
|
|
196
205
|
if (this.check(TokenKind_1.TokenKind.Equal)) {
|
|
197
|
-
|
|
198
|
-
|
|
206
|
+
equalsToken = this.advance();
|
|
207
|
+
value = this.expression();
|
|
199
208
|
}
|
|
209
|
+
const statement = new Statement_1.EnumMemberStatement({ name: name, equals: equalsToken, value: value });
|
|
200
210
|
return statement;
|
|
201
211
|
}
|
|
202
212
|
/**
|
|
@@ -290,6 +300,10 @@ class Parser {
|
|
|
290
300
|
let body = [];
|
|
291
301
|
while (this.checkAny(TokenKind_1.TokenKind.Comment, TokenKind_1.TokenKind.Identifier, TokenKind_1.TokenKind.At, ...TokenKind_1.AllowedProperties)) {
|
|
292
302
|
try {
|
|
303
|
+
//break out of this loop if we encountered the `EndInterface` token not followed by `as`
|
|
304
|
+
if (this.check(TokenKind_1.TokenKind.EndInterface) && !this.checkNext(TokenKind_1.TokenKind.As)) {
|
|
305
|
+
break;
|
|
306
|
+
}
|
|
293
307
|
let decl;
|
|
294
308
|
//collect leading annotations
|
|
295
309
|
if (this.check(TokenKind_1.TokenKind.At)) {
|
|
@@ -309,10 +323,6 @@ class Parser {
|
|
|
309
323
|
}
|
|
310
324
|
else if (this.checkAny(TokenKind_1.TokenKind.Function, TokenKind_1.TokenKind.Sub) && this.checkAnyNext(TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedProperties)) {
|
|
311
325
|
decl = this.interfaceMethodStatement(optionalKeyword);
|
|
312
|
-
//comments
|
|
313
|
-
}
|
|
314
|
-
else if (this.check(TokenKind_1.TokenKind.Comment)) {
|
|
315
|
-
decl = this.commentStatement();
|
|
316
326
|
}
|
|
317
327
|
if (decl) {
|
|
318
328
|
this.consumePendingAnnotations(decl);
|
|
@@ -329,10 +339,6 @@ class Parser {
|
|
|
329
339
|
}
|
|
330
340
|
//ensure statement separator
|
|
331
341
|
this.consumeStatementSeparators();
|
|
332
|
-
//break out of this loop if we encountered the `EndInterface` token not followed by `as`
|
|
333
|
-
if (this.check(TokenKind_1.TokenKind.EndInterface) && !this.checkNext(TokenKind_1.TokenKind.As)) {
|
|
334
|
-
break;
|
|
335
|
-
}
|
|
336
342
|
}
|
|
337
343
|
//consume the final `end interface` token
|
|
338
344
|
const endInterfaceToken = this.consumeToken(TokenKind_1.TokenKind.EndInterface);
|
|
@@ -348,12 +354,12 @@ class Parser {
|
|
|
348
354
|
return statement;
|
|
349
355
|
}
|
|
350
356
|
enumDeclaration() {
|
|
351
|
-
const
|
|
357
|
+
const enumToken = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedKeyword(TokenKind_1.TokenKind.Enum), TokenKind_1.TokenKind.Enum);
|
|
358
|
+
const nameToken = this.tryIdentifier(...this.allowedLocalIdentifiers);
|
|
352
359
|
this.warnIfNotBrighterScriptMode('enum declarations');
|
|
353
360
|
const parentAnnotations = this.enterAnnotationBlock();
|
|
354
|
-
result.tokens.enum = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedKeyword(TokenKind_1.TokenKind.Enum), TokenKind_1.TokenKind.Enum);
|
|
355
|
-
result.tokens.name = this.tryIdentifier(...this.allowedLocalIdentifiers);
|
|
356
361
|
this.consumeStatementSeparators();
|
|
362
|
+
const body = [];
|
|
357
363
|
//gather up all members
|
|
358
364
|
while (this.checkAny(TokenKind_1.TokenKind.Comment, TokenKind_1.TokenKind.Identifier, TokenKind_1.TokenKind.At, ...TokenKind_1.AllowedProperties)) {
|
|
359
365
|
try {
|
|
@@ -365,14 +371,10 @@ class Parser {
|
|
|
365
371
|
//members
|
|
366
372
|
if (this.checkAny(TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedProperties)) {
|
|
367
373
|
decl = this.enumMemberStatement();
|
|
368
|
-
//comments
|
|
369
|
-
}
|
|
370
|
-
else if (this.check(TokenKind_1.TokenKind.Comment)) {
|
|
371
|
-
decl = this.commentStatement();
|
|
372
374
|
}
|
|
373
375
|
if (decl) {
|
|
374
376
|
this.consumePendingAnnotations(decl);
|
|
375
|
-
|
|
377
|
+
body.push(decl);
|
|
376
378
|
}
|
|
377
379
|
else {
|
|
378
380
|
//we didn't find a declaration...flag tokens until next line
|
|
@@ -391,7 +393,13 @@ class Parser {
|
|
|
391
393
|
}
|
|
392
394
|
}
|
|
393
395
|
//consume the final `end interface` token
|
|
394
|
-
|
|
396
|
+
const endEnumToken = this.consumeToken(TokenKind_1.TokenKind.EndEnum);
|
|
397
|
+
const result = new Statement_1.EnumStatement({
|
|
398
|
+
enum: enumToken,
|
|
399
|
+
name: nameToken,
|
|
400
|
+
body: body,
|
|
401
|
+
endEnum: endEnumToken
|
|
402
|
+
});
|
|
395
403
|
this.exitAnnotationBlock(parentAnnotations);
|
|
396
404
|
return result;
|
|
397
405
|
}
|
|
@@ -448,8 +456,6 @@ class Parser {
|
|
|
448
456
|
func: funcDeclaration.func,
|
|
449
457
|
override: overrideKeyword
|
|
450
458
|
});
|
|
451
|
-
//refer to this statement as parent of the expression
|
|
452
|
-
funcDeclaration.func.functionStatement = decl;
|
|
453
459
|
//fields
|
|
454
460
|
}
|
|
455
461
|
else if (this.checkAny(TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedProperties)) {
|
|
@@ -458,10 +464,6 @@ class Parser {
|
|
|
458
464
|
if (overrideKeyword) {
|
|
459
465
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.classFieldCannotBeOverridden()), { range: overrideKeyword.range }));
|
|
460
466
|
}
|
|
461
|
-
//comments
|
|
462
|
-
}
|
|
463
|
-
else if (this.check(TokenKind_1.TokenKind.Comment)) {
|
|
464
|
-
decl = this.commentStatement();
|
|
465
467
|
}
|
|
466
468
|
if (decl) {
|
|
467
469
|
this.consumePendingAnnotations(decl);
|
|
@@ -542,7 +544,6 @@ class Parser {
|
|
|
542
544
|
});
|
|
543
545
|
}
|
|
544
546
|
functionDeclaration(isAnonymous, checkIdentifier = true, onlyCallableAsMember = false) {
|
|
545
|
-
var _a;
|
|
546
547
|
let previousCallExpressions = this.callExpressions;
|
|
547
548
|
this.callExpressions = [];
|
|
548
549
|
try {
|
|
@@ -610,46 +611,38 @@ class Parser {
|
|
|
610
611
|
return haveFoundOptional || !!param.defaultValue;
|
|
611
612
|
}, false);
|
|
612
613
|
this.consumeStatementSeparators(true);
|
|
614
|
+
//support ending the function with `end sub` OR `end function`
|
|
615
|
+
let body = this.block();
|
|
616
|
+
//if the parser was unable to produce a block, make an empty one so the AST makes some sense...
|
|
617
|
+
// consume 'end sub' or 'end function'
|
|
618
|
+
const endFunctionType = this.advance();
|
|
619
|
+
let expectedEndKind = isSub ? TokenKind_1.TokenKind.EndSub : TokenKind_1.TokenKind.EndFunction;
|
|
620
|
+
//if `function` is ended with `end sub`, or `sub` is ended with `end function`, then
|
|
621
|
+
//add an error but don't hard-fail so the AST can continue more gracefully
|
|
622
|
+
if (endFunctionType.kind !== expectedEndKind) {
|
|
623
|
+
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.mismatchedEndCallableKeyword(functionTypeText, endFunctionType.text)), { range: endFunctionType.range }));
|
|
624
|
+
}
|
|
625
|
+
if (!body) {
|
|
626
|
+
body = new Statement_1.Block({
|
|
627
|
+
statements: [],
|
|
628
|
+
startingRange: util_1.util.createBoundingRange(functionType, name, leftParen, ...params, rightParen, asToken, typeExpression, endFunctionType)
|
|
629
|
+
});
|
|
630
|
+
}
|
|
613
631
|
let func = new Expression_1.FunctionExpression({
|
|
614
632
|
parameters: params,
|
|
615
|
-
body:
|
|
633
|
+
body: body,
|
|
616
634
|
functionType: functionType,
|
|
617
|
-
endFunctionType:
|
|
635
|
+
endFunctionType: endFunctionType,
|
|
618
636
|
leftParen: leftParen,
|
|
619
637
|
rightParen: rightParen,
|
|
620
638
|
as: asToken,
|
|
621
639
|
returnTypeExpression: typeExpression
|
|
622
640
|
});
|
|
623
|
-
//support ending the function with `end sub` OR `end function`
|
|
624
|
-
func.body = this.block();
|
|
625
|
-
//if the parser was unable to produce a block, make an empty one so the AST makes some sense...
|
|
626
|
-
if (!func.body) {
|
|
627
|
-
func.body = new Statement_1.Block({
|
|
628
|
-
statements: [],
|
|
629
|
-
startingRange: util_1.util.createRangeFromPositions(func.range.start, func.range.start)
|
|
630
|
-
});
|
|
631
|
-
}
|
|
632
|
-
func.body.symbolTable = new SymbolTable_1.SymbolTable(`Block: Function '${(_a = name === null || name === void 0 ? void 0 : name.text) !== null && _a !== void 0 ? _a : ''}'`, () => func.getSymbolTable());
|
|
633
|
-
if (!func.body) {
|
|
634
|
-
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.callableBlockMissingEndKeyword(functionTypeText)), { range: this.peek().range }));
|
|
635
|
-
throw this.lastDiagnosticAsError();
|
|
636
|
-
}
|
|
637
|
-
// consume 'end sub' or 'end function'
|
|
638
|
-
func.tokens.endFunctionType = this.advance();
|
|
639
|
-
let expectedEndKind = isSub ? TokenKind_1.TokenKind.EndSub : TokenKind_1.TokenKind.EndFunction;
|
|
640
|
-
//if `function` is ended with `end sub`, or `sub` is ended with `end function`, then
|
|
641
|
-
//add an error but don't hard-fail so the AST can continue more gracefully
|
|
642
|
-
if (func.tokens.endFunctionType.kind !== expectedEndKind) {
|
|
643
|
-
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.mismatchedEndCallableKeyword(functionTypeText, func.tokens.endFunctionType.text)), { range: func.tokens.endFunctionType.range }));
|
|
644
|
-
}
|
|
645
|
-
func.callExpressions = this.callExpressions;
|
|
646
641
|
if (isAnonymous) {
|
|
647
642
|
return func;
|
|
648
643
|
}
|
|
649
644
|
else {
|
|
650
645
|
let result = new Statement_1.FunctionStatement({ name: name, func: func });
|
|
651
|
-
func.symbolTable.name += `: '${name === null || name === void 0 ? void 0 : name.text}'`;
|
|
652
|
-
func.functionStatement = result;
|
|
653
646
|
return result;
|
|
654
647
|
}
|
|
655
648
|
}
|
|
@@ -926,6 +919,7 @@ class Parser {
|
|
|
926
919
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.expectedInAfterForEach(name.text)), { range: this.peek().range }));
|
|
927
920
|
throw this.lastDiagnosticAsError();
|
|
928
921
|
}
|
|
922
|
+
maybeIn.kind = TokenKind_1.TokenKind.In;
|
|
929
923
|
let target = this.expression();
|
|
930
924
|
if (!target) {
|
|
931
925
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.expectedExpressionAfterForEachIn()), { range: this.peek().range }));
|
|
@@ -951,29 +945,12 @@ class Parser {
|
|
|
951
945
|
let keyword = this.advance();
|
|
952
946
|
return new Statement_1.ExitForStatement({ exitFor: keyword });
|
|
953
947
|
}
|
|
954
|
-
commentStatement() {
|
|
955
|
-
//if this comment is on the same line as the previous statement,
|
|
956
|
-
//then this comment should be treated as a single-line comment
|
|
957
|
-
let prev = this.previous();
|
|
958
|
-
if ((prev === null || prev === void 0 ? void 0 : prev.range.end.line) === this.peek().range.start.line) {
|
|
959
|
-
return new Statement_1.CommentStatement({ comments: [this.advance()] });
|
|
960
|
-
}
|
|
961
|
-
else {
|
|
962
|
-
let comments = [this.advance()];
|
|
963
|
-
while (this.check(TokenKind_1.TokenKind.Newline) && this.checkNext(TokenKind_1.TokenKind.Comment)) {
|
|
964
|
-
this.advance();
|
|
965
|
-
comments.push(this.advance());
|
|
966
|
-
}
|
|
967
|
-
return new Statement_1.CommentStatement({ comments: comments });
|
|
968
|
-
}
|
|
969
|
-
}
|
|
970
948
|
namespaceStatement() {
|
|
971
949
|
this.warnIfNotBrighterScriptMode('namespace');
|
|
972
950
|
let keyword = this.advance();
|
|
973
951
|
this.namespaceAndFunctionDepth++;
|
|
974
952
|
let name = this.identifyingExpression();
|
|
975
953
|
//set the current namespace name
|
|
976
|
-
let result = new Statement_1.NamespaceStatement({ namespace: keyword, nameExpression: name, body: null });
|
|
977
954
|
this.globalTerminators.push([TokenKind_1.TokenKind.EndNamespace]);
|
|
978
955
|
let body = this.body();
|
|
979
956
|
this.globalTerminators.pop();
|
|
@@ -986,8 +963,12 @@ class Parser {
|
|
|
986
963
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.couldNotFindMatchingEndKeyword('namespace')), { range: keyword.range }));
|
|
987
964
|
}
|
|
988
965
|
this.namespaceAndFunctionDepth--;
|
|
989
|
-
result
|
|
990
|
-
|
|
966
|
+
let result = new Statement_1.NamespaceStatement({
|
|
967
|
+
namespace: keyword,
|
|
968
|
+
nameExpression: name,
|
|
969
|
+
body: body,
|
|
970
|
+
endNamespace: endKeyword
|
|
971
|
+
});
|
|
991
972
|
//cache the range property so that plugins can't affect it
|
|
992
973
|
result.cacheRange();
|
|
993
974
|
result.body.symbolTable.name += `: namespace '${result.name}'`;
|
|
@@ -1071,7 +1052,7 @@ class Parser {
|
|
|
1071
1052
|
let importStatement = new Statement_1.ImportStatement({
|
|
1072
1053
|
import: this.advance(),
|
|
1073
1054
|
//grab the next token only if it's a string
|
|
1074
|
-
|
|
1055
|
+
path: this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.expectedStringLiteralAfterKeyword('import'), TokenKind_1.TokenKind.StringLiteral)
|
|
1075
1056
|
});
|
|
1076
1057
|
return importStatement;
|
|
1077
1058
|
}
|
|
@@ -1217,36 +1198,43 @@ class Parser {
|
|
|
1217
1198
|
}
|
|
1218
1199
|
tryCatchStatement() {
|
|
1219
1200
|
const tryToken = this.advance();
|
|
1220
|
-
|
|
1201
|
+
let endTryToken;
|
|
1202
|
+
let catchStmt;
|
|
1221
1203
|
//ensure statement separator
|
|
1222
1204
|
this.consumeStatementSeparators();
|
|
1223
|
-
|
|
1205
|
+
let tryBranch = this.block(TokenKind_1.TokenKind.Catch, TokenKind_1.TokenKind.EndTry);
|
|
1224
1206
|
const peek = this.peek();
|
|
1225
1207
|
if (peek.kind !== TokenKind_1.TokenKind.Catch) {
|
|
1226
1208
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.expectedCatchBlockInTryCatch()), { range: this.peek().range }));
|
|
1227
|
-
//gracefully handle end-try
|
|
1228
|
-
if (peek.kind === TokenKind_1.TokenKind.EndTry) {
|
|
1229
|
-
statement.tokens.endTry = this.advance();
|
|
1230
|
-
}
|
|
1231
|
-
return statement;
|
|
1232
1209
|
}
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1210
|
+
else {
|
|
1211
|
+
const catchToken = this.advance();
|
|
1212
|
+
const exceptionVarToken = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.missingExceptionVarToFollowCatch(), TokenKind_1.TokenKind.Identifier, ...this.allowedLocalIdentifiers);
|
|
1213
|
+
if (exceptionVarToken) {
|
|
1214
|
+
// force it into an identifier so the AST makes some sense
|
|
1215
|
+
exceptionVarToken.kind = TokenKind_1.TokenKind.Identifier;
|
|
1216
|
+
}
|
|
1217
|
+
//ensure statement sepatator
|
|
1218
|
+
this.consumeStatementSeparators();
|
|
1219
|
+
const catchBranch = this.block(TokenKind_1.TokenKind.EndTry);
|
|
1220
|
+
catchStmt = new Statement_1.CatchStatement({
|
|
1221
|
+
catch: catchToken,
|
|
1222
|
+
exceptionVariable: exceptionVarToken,
|
|
1223
|
+
catchBranch: catchBranch
|
|
1224
|
+
});
|
|
1240
1225
|
}
|
|
1241
|
-
//ensure statement sepatator
|
|
1242
|
-
this.consumeStatementSeparators();
|
|
1243
|
-
catchStmt.catchBranch = this.block(TokenKind_1.TokenKind.EndTry);
|
|
1244
1226
|
if (this.peek().kind !== TokenKind_1.TokenKind.EndTry) {
|
|
1245
1227
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.expectedEndTryToTerminateTryCatch()), { range: this.peek().range }));
|
|
1246
1228
|
}
|
|
1247
1229
|
else {
|
|
1248
|
-
|
|
1230
|
+
endTryToken = this.advance();
|
|
1249
1231
|
}
|
|
1232
|
+
const statement = new Statement_1.TryCatchStatement({
|
|
1233
|
+
try: tryToken,
|
|
1234
|
+
tryBranch: tryBranch,
|
|
1235
|
+
catchStatement: catchStmt,
|
|
1236
|
+
endTry: endTryToken
|
|
1237
|
+
});
|
|
1250
1238
|
return statement;
|
|
1251
1239
|
}
|
|
1252
1240
|
throwStatement() {
|
|
@@ -2077,8 +2065,6 @@ class Parser {
|
|
|
2077
2065
|
return this.anonymousFunction();
|
|
2078
2066
|
case this.check(TokenKind_1.TokenKind.RegexLiteral):
|
|
2079
2067
|
return this.regexLiteralExpression();
|
|
2080
|
-
case this.check(TokenKind_1.TokenKind.Comment):
|
|
2081
|
-
return new Statement_1.CommentStatement({ comments: [this.advance()] });
|
|
2082
2068
|
default:
|
|
2083
2069
|
//if we found an expected terminator, don't throw a diagnostic...just return undefined
|
|
2084
2070
|
if (this.checkAny(...this.peekGlobalTerminators())) {
|
|
@@ -2094,10 +2080,6 @@ class Parser {
|
|
|
2094
2080
|
arrayLiteral() {
|
|
2095
2081
|
let elements = [];
|
|
2096
2082
|
let openingSquare = this.previous();
|
|
2097
|
-
//add any comment found right after the opening square
|
|
2098
|
-
if (this.check(TokenKind_1.TokenKind.Comment)) {
|
|
2099
|
-
elements.push(new Statement_1.CommentStatement({ comments: [this.advance()] }));
|
|
2100
|
-
}
|
|
2101
2083
|
while (this.match(TokenKind_1.TokenKind.Newline)) {
|
|
2102
2084
|
}
|
|
2103
2085
|
let closingSquare;
|
|
@@ -2105,10 +2087,6 @@ class Parser {
|
|
|
2105
2087
|
try {
|
|
2106
2088
|
elements.push(this.expression());
|
|
2107
2089
|
while (this.matchAny(TokenKind_1.TokenKind.Comma, TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Comment)) {
|
|
2108
|
-
if (this.checkPrevious(TokenKind_1.TokenKind.Comment) || this.check(TokenKind_1.TokenKind.Comment)) {
|
|
2109
|
-
let comment = this.check(TokenKind_1.TokenKind.Comment) ? this.advance() : this.previous();
|
|
2110
|
-
elements.push(new Statement_1.CommentStatement({ comments: [comment] }));
|
|
2111
|
-
}
|
|
2112
2090
|
while (this.match(TokenKind_1.TokenKind.Newline)) {
|
|
2113
2091
|
}
|
|
2114
2092
|
if (this.check(TokenKind_1.TokenKind.RightSquareBracket)) {
|
|
@@ -2156,11 +2134,23 @@ class Parser {
|
|
|
2156
2134
|
if (!this.match(TokenKind_1.TokenKind.RightCurlyBrace)) {
|
|
2157
2135
|
let lastAAMember;
|
|
2158
2136
|
try {
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2137
|
+
let k = key();
|
|
2138
|
+
let expr = this.expression();
|
|
2139
|
+
lastAAMember = new Expression_1.AAMemberExpression({
|
|
2140
|
+
key: k.keyToken,
|
|
2141
|
+
colon: k.colonToken,
|
|
2142
|
+
value: expr
|
|
2143
|
+
});
|
|
2144
|
+
members.push(lastAAMember);
|
|
2145
|
+
while (this.matchAny(TokenKind_1.TokenKind.Comma, TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Colon, TokenKind_1.TokenKind.Comment)) {
|
|
2146
|
+
// collect comma at end of expression
|
|
2147
|
+
if (lastAAMember && this.checkPrevious(TokenKind_1.TokenKind.Comma)) {
|
|
2148
|
+
lastAAMember.tokens.comma = this.previous();
|
|
2149
|
+
}
|
|
2150
|
+
this.consumeStatementSeparators(true);
|
|
2151
|
+
if (this.check(TokenKind_1.TokenKind.RightCurlyBrace)) {
|
|
2152
|
+
break;
|
|
2153
|
+
}
|
|
2164
2154
|
let k = key();
|
|
2165
2155
|
let expr = this.expression();
|
|
2166
2156
|
lastAAMember = new Expression_1.AAMemberExpression({
|
|
@@ -2170,38 +2160,6 @@ class Parser {
|
|
|
2170
2160
|
});
|
|
2171
2161
|
members.push(lastAAMember);
|
|
2172
2162
|
}
|
|
2173
|
-
while (this.matchAny(TokenKind_1.TokenKind.Comma, TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Colon, TokenKind_1.TokenKind.Comment)) {
|
|
2174
|
-
// collect comma at end of expression
|
|
2175
|
-
if (lastAAMember && this.checkPrevious(TokenKind_1.TokenKind.Comma)) {
|
|
2176
|
-
lastAAMember.tokens.comma = this.previous();
|
|
2177
|
-
}
|
|
2178
|
-
//check for comment at the end of the current line
|
|
2179
|
-
if (this.check(TokenKind_1.TokenKind.Comment) || this.checkPrevious(TokenKind_1.TokenKind.Comment)) {
|
|
2180
|
-
let token = this.checkPrevious(TokenKind_1.TokenKind.Comment) ? this.previous() : this.advance();
|
|
2181
|
-
members.push(new Statement_1.CommentStatement({ comments: [token] }));
|
|
2182
|
-
}
|
|
2183
|
-
else {
|
|
2184
|
-
this.consumeStatementSeparators(true);
|
|
2185
|
-
//check for a comment on its own line
|
|
2186
|
-
if (this.check(TokenKind_1.TokenKind.Comment) || this.checkPrevious(TokenKind_1.TokenKind.Comment)) {
|
|
2187
|
-
let token = this.checkPrevious(TokenKind_1.TokenKind.Comment) ? this.previous() : this.advance();
|
|
2188
|
-
lastAAMember = null;
|
|
2189
|
-
members.push(new Statement_1.CommentStatement({ comments: [token] }));
|
|
2190
|
-
continue;
|
|
2191
|
-
}
|
|
2192
|
-
if (this.check(TokenKind_1.TokenKind.RightCurlyBrace)) {
|
|
2193
|
-
break;
|
|
2194
|
-
}
|
|
2195
|
-
let k = key();
|
|
2196
|
-
let expr = this.expression();
|
|
2197
|
-
lastAAMember = new Expression_1.AAMemberExpression({
|
|
2198
|
-
key: k.keyToken,
|
|
2199
|
-
colon: k.colonToken,
|
|
2200
|
-
value: expr
|
|
2201
|
-
});
|
|
2202
|
-
members.push(lastAAMember);
|
|
2203
|
-
}
|
|
2204
|
-
}
|
|
2205
2163
|
}
|
|
2206
2164
|
catch (error) {
|
|
2207
2165
|
this.rethrowNonDiagnosticError(error);
|
|
@@ -2353,7 +2311,8 @@ class Parser {
|
|
|
2353
2311
|
return tokenKinds.includes(nextKind);
|
|
2354
2312
|
}
|
|
2355
2313
|
isAtEnd() {
|
|
2356
|
-
|
|
2314
|
+
const peekToken = this.peek();
|
|
2315
|
+
return !peekToken || peekToken.kind === TokenKind_1.TokenKind.Eof;
|
|
2357
2316
|
}
|
|
2358
2317
|
peekNext() {
|
|
2359
2318
|
if (this.isAtEnd()) {
|