brighterscript 1.0.0-alpha.15 → 1.0.0-alpha.18
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 +83 -0
- package/README.md +28 -9
- package/dist/DependencyGraph.js +5 -4
- package/dist/DependencyGraph.js.map +1 -1
- package/dist/DiagnosticMessages.d.ts +16 -1
- package/dist/DiagnosticMessages.js +15 -0
- package/dist/DiagnosticMessages.js.map +1 -1
- package/dist/Logger.js +5 -5
- package/dist/Logger.js.map +1 -1
- package/dist/Program.d.ts +2 -2
- package/dist/Program.js +5 -3
- package/dist/Program.js.map +1 -1
- package/dist/ProgramBuilder.js +1 -1
- package/dist/ProgramBuilder.js.map +1 -1
- package/dist/Scope.d.ts +58 -8
- package/dist/Scope.js +142 -23
- package/dist/Scope.js.map +1 -1
- package/dist/XmlScope.js +1 -1
- package/dist/XmlScope.js.map +1 -1
- package/dist/astUtils/creators.d.ts +10 -6
- package/dist/astUtils/creators.js +93 -12
- package/dist/astUtils/creators.js.map +1 -1
- package/dist/astUtils/creators.spec.js +10 -0
- package/dist/astUtils/creators.spec.js.map +1 -1
- package/dist/astUtils/reflection.d.ts +8 -3
- package/dist/astUtils/reflection.js +18 -2
- package/dist/astUtils/reflection.js.map +1 -1
- package/dist/astUtils/reflection.spec.js +15 -4
- package/dist/astUtils/reflection.spec.js.map +1 -1
- package/dist/astUtils/visitors.d.ts +4 -1
- package/dist/astUtils/visitors.js.map +1 -1
- package/dist/astUtils/visitors.spec.js +2 -0
- package/dist/astUtils/visitors.spec.js.map +1 -1
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js +2 -2
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js.map +1 -1
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.js +7 -3
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.js.map +1 -1
- package/dist/{types/FunctionType.spec.d.ts → bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.d.ts} +0 -0
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.js +32 -0
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.js.map +1 -0
- package/dist/diagnosticUtils.js +3 -3
- package/dist/diagnosticUtils.js.map +1 -1
- package/dist/examples/plugins/removePrint.js +12 -14
- package/dist/examples/plugins/removePrint.js.map +1 -1
- package/dist/files/BrsFile.Class.spec.js +3 -3
- package/dist/files/BrsFile.Class.spec.js.map +1 -1
- package/dist/files/BrsFile.d.ts +2 -2
- package/dist/files/BrsFile.js +99 -63
- package/dist/files/BrsFile.js.map +1 -1
- package/dist/files/BrsFile.spec.js +187 -67
- package/dist/files/BrsFile.spec.js.map +1 -1
- package/dist/files/XmlFile.js +3 -3
- package/dist/files/XmlFile.js.map +1 -1
- package/dist/globalCallables.js +79 -79
- package/dist/globalCallables.js.map +1 -1
- package/dist/interfaces.d.ts +43 -4
- package/dist/parser/Expression.d.ts +91 -22
- package/dist/parser/Expression.js +191 -57
- package/dist/parser/Expression.js.map +1 -1
- package/dist/parser/Parser.Class.spec.js +6 -6
- package/dist/parser/Parser.Class.spec.js.map +1 -1
- package/dist/parser/Parser.d.ts +3 -6
- package/dist/parser/Parser.js +166 -155
- package/dist/parser/Parser.js.map +1 -1
- package/dist/parser/Parser.spec.js +61 -6
- package/dist/parser/Parser.spec.js.map +1 -1
- package/dist/parser/SGTypes.d.ts +2 -2
- package/dist/parser/SGTypes.js +2 -2
- package/dist/parser/SGTypes.js.map +1 -1
- package/dist/parser/Statement.d.ts +85 -57
- package/dist/parser/Statement.js +228 -173
- package/dist/parser/Statement.js.map +1 -1
- package/dist/parser/tests/statement/For.spec.d.ts +1 -0
- package/dist/parser/tests/statement/For.spec.js +46 -0
- package/dist/parser/tests/statement/For.spec.js.map +1 -0
- package/dist/parser/tests/statement/ForEach.spec.d.ts +1 -0
- package/dist/parser/tests/statement/ForEach.spec.js +37 -0
- package/dist/parser/tests/statement/ForEach.spec.js.map +1 -0
- package/dist/parser/tests/statement/InterfaceStatement.spec.js +181 -0
- package/dist/parser/tests/statement/InterfaceStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/TryCatch.spec.js +7 -5
- package/dist/parser/tests/statement/TryCatch.spec.js.map +1 -1
- package/dist/types/ArrayType.js +4 -1
- package/dist/types/ArrayType.js.map +1 -1
- package/dist/types/ArrayType.spec.js +3 -1
- package/dist/types/ArrayType.spec.js.map +1 -1
- package/dist/types/BooleanType.d.ts +4 -2
- package/dist/types/BooleanType.js +7 -2
- package/dist/types/BooleanType.js.map +1 -1
- package/dist/types/BooleanType.spec.js +3 -1
- package/dist/types/BooleanType.spec.js.map +1 -1
- package/dist/types/BscType.d.ts +1 -0
- package/dist/types/BscType.js +16 -1
- package/dist/types/BscType.js.map +1 -1
- package/dist/types/CustomType.js +10 -0
- package/dist/types/CustomType.js.map +1 -1
- package/dist/types/DoubleType.d.ts +2 -0
- package/dist/types/DoubleType.js +7 -2
- package/dist/types/DoubleType.js.map +1 -1
- package/dist/types/DoubleType.spec.js +3 -1
- package/dist/types/DoubleType.spec.js.map +1 -1
- package/dist/types/DynamicType.d.ts +2 -0
- package/dist/types/DynamicType.js +5 -1
- package/dist/types/DynamicType.js.map +1 -1
- package/dist/types/FloatType.d.ts +3 -1
- package/dist/types/FloatType.js +7 -2
- package/dist/types/FloatType.js.map +1 -1
- package/dist/types/FloatType.spec.js +2 -0
- package/dist/types/FloatType.spec.js.map +1 -1
- package/dist/types/FunctionType.d.ts +3 -21
- package/dist/types/FunctionType.js +8 -65
- package/dist/types/FunctionType.js.map +1 -1
- package/dist/types/IntegerType.d.ts +3 -1
- package/dist/types/IntegerType.js +7 -2
- package/dist/types/IntegerType.js.map +1 -1
- package/dist/types/IntegerType.spec.js +3 -1
- package/dist/types/IntegerType.spec.js.map +1 -1
- package/dist/types/InterfaceType.d.ts +13 -10
- package/dist/types/InterfaceType.js +33 -29
- package/dist/types/InterfaceType.js.map +1 -1
- package/dist/types/InterfaceType.spec.js +36 -16
- package/dist/types/InterfaceType.spec.js.map +1 -1
- package/dist/types/InvalidType.d.ts +4 -2
- package/dist/types/InvalidType.js +7 -2
- package/dist/types/InvalidType.js.map +1 -1
- package/dist/types/InvalidType.spec.js +2 -0
- package/dist/types/InvalidType.spec.js.map +1 -1
- package/dist/types/LazyType.js +4 -0
- package/dist/types/LazyType.js.map +1 -1
- package/dist/types/LongIntegerType.d.ts +3 -1
- package/dist/types/LongIntegerType.js +7 -2
- package/dist/types/LongIntegerType.js.map +1 -1
- package/dist/types/LongIntegerType.spec.js +2 -0
- package/dist/types/LongIntegerType.spec.js.map +1 -1
- package/dist/types/ObjectType.d.ts +2 -1
- package/dist/types/ObjectType.js +4 -2
- package/dist/types/ObjectType.js.map +1 -1
- package/dist/types/StringType.d.ts +4 -2
- package/dist/types/StringType.js +7 -2
- package/dist/types/StringType.js.map +1 -1
- package/dist/types/StringType.spec.js +2 -0
- package/dist/types/StringType.spec.js.map +1 -1
- package/dist/types/TypedFunctionType.d.ts +28 -0
- package/dist/types/TypedFunctionType.js +88 -0
- package/dist/types/TypedFunctionType.js.map +1 -0
- package/dist/types/TypedFunctionType.spec.d.ts +1 -0
- package/dist/types/TypedFunctionType.spec.js +37 -0
- package/dist/types/TypedFunctionType.spec.js.map +1 -0
- package/dist/types/UninitializedType.js.map +1 -1
- package/dist/types/VoidType.d.ts +4 -2
- package/dist/types/VoidType.js +5 -1
- package/dist/types/VoidType.js.map +1 -1
- package/dist/types/helpers.js +7 -2
- package/dist/types/helpers.js.map +1 -1
- package/dist/util.d.ts +2 -2
- package/dist/util.js +39 -46
- package/dist/util.js.map +1 -1
- package/dist/validators/ClassValidator.d.ts +14 -1
- package/dist/validators/ClassValidator.js +129 -82
- package/dist/validators/ClassValidator.js.map +1 -1
- package/package.json +2 -3
- package/dist/types/FunctionType.spec.js +0 -29
- package/dist/types/FunctionType.spec.js.map +0 -1
package/dist/parser/Parser.js
CHANGED
|
@@ -187,7 +187,7 @@ class Parser {
|
|
|
187
187
|
declaration() {
|
|
188
188
|
try {
|
|
189
189
|
if (this.checkAny(TokenKind_1.TokenKind.Sub, TokenKind_1.TokenKind.Function)) {
|
|
190
|
-
return this.
|
|
190
|
+
return this.functionStatement({ hasName: true, hasBody: true, hasEnd: true });
|
|
191
191
|
}
|
|
192
192
|
if (this.checkLibrary()) {
|
|
193
193
|
return this.libraryStatement();
|
|
@@ -230,56 +230,40 @@ class Parser {
|
|
|
230
230
|
return identifier;
|
|
231
231
|
}
|
|
232
232
|
enumMemberStatement() {
|
|
233
|
-
const
|
|
234
|
-
|
|
233
|
+
const tokens = {};
|
|
234
|
+
let value;
|
|
235
|
+
tokens.name = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedClassFieldIdentifier(), TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedProperties);
|
|
235
236
|
//look for `= SOME_EXPRESSION`
|
|
236
237
|
if (this.check(TokenKind_1.TokenKind.Equal)) {
|
|
237
|
-
|
|
238
|
-
|
|
238
|
+
tokens.equal = this.advance();
|
|
239
|
+
value = this.expression();
|
|
239
240
|
}
|
|
240
|
-
return
|
|
241
|
+
return new Statement_1.EnumMemberStatement(tokens, value);
|
|
241
242
|
}
|
|
242
243
|
/**
|
|
243
|
-
* Create a new
|
|
244
|
+
* Create a new InterfaceFieldStatement. This should only be called from within `interfaceDeclaration`
|
|
244
245
|
*/
|
|
245
246
|
interfaceFieldStatement() {
|
|
246
247
|
const name = this.identifier(...TokenKind_1.AllowedProperties);
|
|
247
|
-
let asToken
|
|
248
|
-
let
|
|
249
|
-
|
|
250
|
-
if (!type) {
|
|
251
|
-
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.functionParameterTypeIsInvalid(name.text, typeToken.text)), { range: typeToken.range }));
|
|
252
|
-
throw this.lastDiagnosticAsError();
|
|
253
|
-
}
|
|
254
|
-
return new Statement_1.InterfaceFieldStatement(name, asToken, typeToken, type);
|
|
255
|
-
}
|
|
256
|
-
/**
|
|
257
|
-
* Create a new InterfaceMethodStatement. This should only be called from within `interfaceDeclaration()`
|
|
258
|
-
*/
|
|
259
|
-
interfaceMethodStatement() {
|
|
260
|
-
const functionType = this.advance();
|
|
261
|
-
const name = this.identifier(...TokenKind_1.AllowedProperties);
|
|
262
|
-
const leftParen = this.consumeToken(TokenKind_1.TokenKind.LeftParen);
|
|
263
|
-
const params = [];
|
|
264
|
-
const rightParen = this.consumeToken(TokenKind_1.TokenKind.RightParen);
|
|
265
|
-
let asToken = null;
|
|
266
|
-
let returnTypeToken = null;
|
|
248
|
+
let asToken;
|
|
249
|
+
let typeExpr;
|
|
250
|
+
//look for `as SOME_TYPE`
|
|
267
251
|
if (this.check(TokenKind_1.TokenKind.As)) {
|
|
268
|
-
asToken = this.
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
if (!
|
|
272
|
-
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.functionParameterTypeIsInvalid(name.text,
|
|
273
|
-
throw this.lastDiagnosticAsError();
|
|
252
|
+
asToken = this.consumeToken(TokenKind_1.TokenKind.As);
|
|
253
|
+
typeExpr = this.typeExpression();
|
|
254
|
+
//no field type specified
|
|
255
|
+
if (!typeExpr.isValidType()) {
|
|
256
|
+
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.functionParameterTypeIsInvalid(name.text, typeExpr.getText())), { range: typeExpr.range }));
|
|
274
257
|
}
|
|
275
258
|
}
|
|
276
|
-
return new Statement_1.
|
|
259
|
+
return new Statement_1.InterfaceFieldStatement(name, asToken, typeExpr, this.currentNamespaceName);
|
|
277
260
|
}
|
|
278
261
|
interfaceDeclaration() {
|
|
279
262
|
this.warnIfNotBrighterScriptMode('interface declarations');
|
|
280
263
|
const parentAnnotations = this.enterAnnotationBlock();
|
|
281
264
|
const interfaceToken = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedKeyword(TokenKind_1.TokenKind.Interface), TokenKind_1.TokenKind.Interface);
|
|
282
|
-
|
|
265
|
+
//get the interface name
|
|
266
|
+
let nameToken = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifierAfterKeyword('interface'), TokenKind_1.TokenKind.Identifier, ...this.allowedLocalIdentifiers);
|
|
283
267
|
let extendsToken;
|
|
284
268
|
let parentInterfaceName;
|
|
285
269
|
if (this.peek().text.toLowerCase() === 'extends') {
|
|
@@ -291,6 +275,10 @@ class Parser {
|
|
|
291
275
|
let body = [];
|
|
292
276
|
while (this.checkAny(TokenKind_1.TokenKind.Comment, TokenKind_1.TokenKind.Identifier, TokenKind_1.TokenKind.At, ...TokenKind_1.AllowedProperties)) {
|
|
293
277
|
try {
|
|
278
|
+
//break out of this loop if we encountered the `EndInterface` token not followed by `as`
|
|
279
|
+
if (this.check(TokenKind_1.TokenKind.EndInterface) && !this.checkNext(TokenKind_1.TokenKind.As)) {
|
|
280
|
+
break;
|
|
281
|
+
}
|
|
294
282
|
let decl;
|
|
295
283
|
//collect leading annotations
|
|
296
284
|
if (this.check(TokenKind_1.TokenKind.At)) {
|
|
@@ -302,7 +290,15 @@ class Parser {
|
|
|
302
290
|
//methods (function/sub keyword followed by opening paren)
|
|
303
291
|
}
|
|
304
292
|
else if (this.checkAny(TokenKind_1.TokenKind.Function, TokenKind_1.TokenKind.Sub) && this.checkAny(TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedProperties)) {
|
|
305
|
-
|
|
293
|
+
const functionStatement = this.functionStatement({
|
|
294
|
+
hasName: true,
|
|
295
|
+
hasBody: false,
|
|
296
|
+
hasEnd: false,
|
|
297
|
+
onlyCallableAsMember: true
|
|
298
|
+
});
|
|
299
|
+
decl = new Statement_1.InterfaceMethodStatement(functionStatement.name, functionStatement.func);
|
|
300
|
+
//refer to this statement as parent of the expression
|
|
301
|
+
functionStatement.func.functionStatement = decl;
|
|
306
302
|
//comments
|
|
307
303
|
}
|
|
308
304
|
else if (this.check(TokenKind_1.TokenKind.Comment)) {
|
|
@@ -312,10 +308,6 @@ class Parser {
|
|
|
312
308
|
this.consumePendingAnnotations(decl);
|
|
313
309
|
body.push(decl);
|
|
314
310
|
}
|
|
315
|
-
else {
|
|
316
|
-
//we didn't find a declaration...flag tokens until next line
|
|
317
|
-
this.flagUntil(TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Colon, TokenKind_1.TokenKind.Eof);
|
|
318
|
-
}
|
|
319
311
|
}
|
|
320
312
|
catch (e) {
|
|
321
313
|
//throw out any failed members and move on to the next line
|
|
@@ -323,24 +315,24 @@ class Parser {
|
|
|
323
315
|
}
|
|
324
316
|
//ensure statement separator
|
|
325
317
|
this.consumeStatementSeparators();
|
|
326
|
-
//break out of this loop if we encountered the `EndInterface` token not followed by `as`
|
|
327
|
-
if (this.check(TokenKind_1.TokenKind.EndInterface) && !this.checkNext(TokenKind_1.TokenKind.As)) {
|
|
328
|
-
break;
|
|
329
|
-
}
|
|
330
318
|
}
|
|
331
319
|
//consume the final `end interface` token
|
|
332
|
-
|
|
333
|
-
|
|
320
|
+
let endingKeyword = this.advance();
|
|
321
|
+
if (endingKeyword.kind !== TokenKind_1.TokenKind.EndInterface) {
|
|
322
|
+
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.couldNotFindMatchingEndKeyword('interface')), { range: endingKeyword.range }));
|
|
323
|
+
}
|
|
324
|
+
const statement = new Statement_1.InterfaceStatement(interfaceToken, nameToken, extendsToken, parentInterfaceName, body, endingKeyword, this.currentNamespaceName);
|
|
334
325
|
this._references.interfaceStatements.push(statement);
|
|
335
326
|
this.exitAnnotationBlock(parentAnnotations);
|
|
336
327
|
return statement;
|
|
337
328
|
}
|
|
338
329
|
enumDeclaration() {
|
|
339
|
-
const result = new Statement_1.EnumStatement({}, [], this.currentNamespaceName);
|
|
340
330
|
this.warnIfNotBrighterScriptMode('enum declarations');
|
|
341
331
|
const parentAnnotations = this.enterAnnotationBlock();
|
|
342
|
-
|
|
343
|
-
|
|
332
|
+
const tokens = {};
|
|
333
|
+
const body = [];
|
|
334
|
+
tokens.enum = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedKeyword(TokenKind_1.TokenKind.Enum), TokenKind_1.TokenKind.Enum);
|
|
335
|
+
tokens.name = this.tryIdentifier();
|
|
344
336
|
this.consumeStatementSeparators();
|
|
345
337
|
//gather up all members
|
|
346
338
|
while (this.checkAny(TokenKind_1.TokenKind.Comment, TokenKind_1.TokenKind.Identifier, TokenKind_1.TokenKind.At, ...TokenKind_1.AllowedProperties)) {
|
|
@@ -360,7 +352,7 @@ class Parser {
|
|
|
360
352
|
}
|
|
361
353
|
if (decl) {
|
|
362
354
|
this.consumePendingAnnotations(decl);
|
|
363
|
-
|
|
355
|
+
body.push(decl);
|
|
364
356
|
}
|
|
365
357
|
else {
|
|
366
358
|
//we didn't find a declaration...flag tokens until next line
|
|
@@ -379,7 +371,8 @@ class Parser {
|
|
|
379
371
|
}
|
|
380
372
|
}
|
|
381
373
|
//consume the final `end interface` token
|
|
382
|
-
|
|
374
|
+
tokens.endEnum = this.consumeToken(TokenKind_1.TokenKind.EndEnum);
|
|
375
|
+
const result = new Statement_1.EnumStatement(tokens, body, this.currentNamespaceName);
|
|
383
376
|
this._references.enumStatements.push(result);
|
|
384
377
|
this.exitAnnotationBlock(parentAnnotations);
|
|
385
378
|
return result;
|
|
@@ -421,16 +414,16 @@ class Parser {
|
|
|
421
414
|
}
|
|
422
415
|
//methods (function/sub keyword OR identifier followed by opening paren)
|
|
423
416
|
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))) {
|
|
424
|
-
const
|
|
425
|
-
//remove this function from the lists because it's not a callable
|
|
426
|
-
const functionStatement = this._references.functionStatements.pop();
|
|
417
|
+
const functionStatement = this.functionStatement({ hasName: true, hasBody: true, hasEnd: true, onlyCallableAsMember: true });
|
|
427
418
|
//if we have an overrides keyword AND this method is called 'new', that's not allowed
|
|
428
|
-
if (overrideKeyword &&
|
|
419
|
+
if (overrideKeyword && functionStatement.name.text.toLowerCase() === 'new') {
|
|
429
420
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.cannotUseOverrideKeywordOnConstructorFunction()), { range: overrideKeyword.range }));
|
|
430
421
|
}
|
|
431
|
-
decl = new Statement_1.ClassMethodStatement(accessModifier,
|
|
422
|
+
decl = new Statement_1.ClassMethodStatement(accessModifier, functionStatement.name, functionStatement.func, overrideKeyword);
|
|
432
423
|
//refer to this statement as parent of the expression
|
|
433
424
|
functionStatement.func.functionStatement = decl;
|
|
425
|
+
//cache the range property so that plugins can't affect it
|
|
426
|
+
decl.cacheRange();
|
|
434
427
|
//fields
|
|
435
428
|
}
|
|
436
429
|
else if (this.checkAny(TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedProperties)) {
|
|
@@ -471,13 +464,13 @@ class Parser {
|
|
|
471
464
|
classFieldDeclaration(accessModifier) {
|
|
472
465
|
let name = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedClassFieldIdentifier(), TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedProperties);
|
|
473
466
|
let asToken;
|
|
474
|
-
let
|
|
467
|
+
let fieldTypeExpr;
|
|
475
468
|
//look for `as SOME_TYPE`
|
|
476
469
|
if (this.check(TokenKind_1.TokenKind.As)) {
|
|
477
470
|
asToken = this.advance();
|
|
478
|
-
|
|
471
|
+
fieldTypeExpr = this.typeExpression();
|
|
479
472
|
//no field type specified
|
|
480
|
-
if (!
|
|
473
|
+
if (!fieldTypeExpr.isValidType(this.options.mode)) {
|
|
481
474
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.expectedValidTypeToFollowAsKeyword()), { range: this.peek().range }));
|
|
482
475
|
}
|
|
483
476
|
}
|
|
@@ -488,22 +481,34 @@ class Parser {
|
|
|
488
481
|
equal = this.advance();
|
|
489
482
|
initialValue = this.expression();
|
|
490
483
|
}
|
|
491
|
-
return new Statement_1.ClassFieldStatement(accessModifier, name, asToken,
|
|
484
|
+
return new Statement_1.ClassFieldStatement(accessModifier, name, asToken, fieldTypeExpr, equal, initialValue, this.currentNamespaceName);
|
|
492
485
|
}
|
|
493
|
-
|
|
486
|
+
functionStatement(options) {
|
|
487
|
+
options.hasName = true;
|
|
488
|
+
const funcResult = this.functionDeclaration(options);
|
|
489
|
+
if (funcResult) {
|
|
490
|
+
let result = new Statement_1.FunctionStatement(funcResult.name, funcResult.functionExpression, this.currentNamespaceName);
|
|
491
|
+
funcResult.functionExpression.functionStatement = result;
|
|
492
|
+
if (!options.onlyCallableAsMember) {
|
|
493
|
+
this._references.functionStatements.push(result);
|
|
494
|
+
}
|
|
495
|
+
return result;
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
functionDeclaration(options = {}) {
|
|
494
499
|
var _a, _b, _c, _d;
|
|
495
500
|
let previousCallExpressions = this.callExpressions;
|
|
496
501
|
this.callExpressions = [];
|
|
497
502
|
try {
|
|
498
503
|
//track depth to help certain statements need to know if they are contained within a function body
|
|
499
504
|
this.namespaceAndFunctionDepth++;
|
|
500
|
-
let
|
|
505
|
+
let functionKeyword;
|
|
501
506
|
if (this.checkAny(TokenKind_1.TokenKind.Sub, TokenKind_1.TokenKind.Function)) {
|
|
502
|
-
|
|
507
|
+
functionKeyword = this.advance();
|
|
503
508
|
}
|
|
504
509
|
else {
|
|
505
510
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.missingCallableKeyword()), { range: this.peek().range }));
|
|
506
|
-
|
|
511
|
+
functionKeyword = {
|
|
507
512
|
isReserved: true,
|
|
508
513
|
kind: TokenKind_1.TokenKind.Function,
|
|
509
514
|
text: 'function',
|
|
@@ -515,30 +520,30 @@ class Parser {
|
|
|
515
520
|
leadingWhitespace: ''
|
|
516
521
|
};
|
|
517
522
|
}
|
|
518
|
-
let isSub = (
|
|
519
|
-
let
|
|
523
|
+
let isSub = (functionKeyword === null || functionKeyword === void 0 ? void 0 : functionKeyword.kind) === TokenKind_1.TokenKind.Sub;
|
|
524
|
+
let functionKeywordText = isSub ? 'sub' : 'function';
|
|
520
525
|
let name;
|
|
521
526
|
let leftParen;
|
|
522
|
-
if (
|
|
523
|
-
leftParen = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedLeftParenAfterCallable(
|
|
527
|
+
if (!options.hasName) {
|
|
528
|
+
leftParen = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedLeftParenAfterCallable(functionKeywordText), TokenKind_1.TokenKind.LeftParen);
|
|
524
529
|
}
|
|
525
530
|
else {
|
|
526
|
-
name = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedNameAfterCallableKeyword(
|
|
527
|
-
leftParen = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedLeftParenAfterCallableName(
|
|
531
|
+
name = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedNameAfterCallableKeyword(functionKeywordText), TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedProperties);
|
|
532
|
+
leftParen = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedLeftParenAfterCallableName(functionKeywordText), TokenKind_1.TokenKind.LeftParen);
|
|
528
533
|
//prevent functions from ending with type designators
|
|
529
534
|
let lastChar = name.text[name.text.length - 1];
|
|
530
535
|
if (['$', '%', '!', '#', '&'].includes(lastChar)) {
|
|
531
536
|
//don't throw this error; let the parser continue
|
|
532
|
-
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.functionNameCannotEndWithTypeDesignator(
|
|
537
|
+
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.functionNameCannotEndWithTypeDesignator(functionKeywordText, name.text, lastChar)), { range: name.range }));
|
|
533
538
|
}
|
|
534
|
-
//flag functions with keywords for names (only for standard functions)
|
|
535
|
-
if (
|
|
539
|
+
//flag functions with keywords for names (only for standard functions - not for class methods)
|
|
540
|
+
if (!options.onlyCallableAsMember && TokenKind_1.DisallowedFunctionIdentifiersText.has(name.text.toLowerCase())) {
|
|
536
541
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.cannotUseReservedWordAsIdentifier(name.text)), { range: name.range }));
|
|
537
542
|
}
|
|
538
543
|
}
|
|
539
544
|
let params = [];
|
|
540
545
|
let asToken;
|
|
541
|
-
let
|
|
546
|
+
let typeExpr;
|
|
542
547
|
if (!this.check(TokenKind_1.TokenKind.RightParen)) {
|
|
543
548
|
do {
|
|
544
549
|
if (params.length >= Expression_1.CallExpression.MaximumArguments) {
|
|
@@ -550,9 +555,9 @@ class Parser {
|
|
|
550
555
|
let rightParen = this.advance();
|
|
551
556
|
if (this.check(TokenKind_1.TokenKind.As)) {
|
|
552
557
|
asToken = this.advance();
|
|
553
|
-
|
|
554
|
-
if (!
|
|
555
|
-
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.invalidFunctionReturnType((_a =
|
|
558
|
+
typeExpr = this.typeExpression();
|
|
559
|
+
if (!typeExpr.isValidType(this.options.mode)) {
|
|
560
|
+
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.invalidFunctionReturnType((_a = typeExpr.getText()) !== null && _a !== void 0 ? _a : '')), { range: typeExpr.range }));
|
|
556
561
|
}
|
|
557
562
|
}
|
|
558
563
|
params.reduce((haveFoundOptional, param) => {
|
|
@@ -561,17 +566,20 @@ class Parser {
|
|
|
561
566
|
}
|
|
562
567
|
return haveFoundOptional || !!param.defaultValue;
|
|
563
568
|
}, false);
|
|
564
|
-
|
|
569
|
+
if (options.hasEnd && options.hasBody) {
|
|
570
|
+
// do not go to next statement - we don't care about any other statement
|
|
571
|
+
this.consumeStatementSeparators(true);
|
|
572
|
+
}
|
|
565
573
|
let func = new Expression_1.FunctionExpression(params, undefined, //body
|
|
566
|
-
|
|
567
|
-
leftParen, rightParen, asToken,
|
|
574
|
+
functionKeyword, undefined, //ending keyword
|
|
575
|
+
leftParen, rightParen, asToken, typeExpr, //return type
|
|
568
576
|
this.currentFunctionExpression, this.currentNamespaceName, (_c = (_b = this.currentNamespace) === null || _b === void 0 ? void 0 : _b.symbolTable) !== null && _c !== void 0 ? _c : this.symbolTable);
|
|
569
577
|
//if there is a parent function, register this function with the parent
|
|
570
578
|
if (this.currentFunctionExpression) {
|
|
571
579
|
this.currentFunctionExpression.childFunctionExpressions.push(func);
|
|
572
580
|
}
|
|
573
581
|
// add the function to the relevant symbol tables
|
|
574
|
-
if (!
|
|
582
|
+
if (!options.onlyCallableAsMember && name) {
|
|
575
583
|
const funcType = func.getFunctionType();
|
|
576
584
|
funcType.setName(name.text);
|
|
577
585
|
// add the function as declared to the current namespace's table
|
|
@@ -584,38 +592,35 @@ class Parser {
|
|
|
584
592
|
this.currentSymbolTable.addSymbol(fullyQualifiedName, name.range, funcType);
|
|
585
593
|
}
|
|
586
594
|
this._references.functionExpressions.push(func);
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
595
|
+
if (options.hasBody) {
|
|
596
|
+
let previousFunctionExpression = this.currentFunctionExpression;
|
|
597
|
+
this.currentFunctionExpression = func;
|
|
598
|
+
//make sure to restore the currentFunctionExpression even if the body block fails to parse
|
|
599
|
+
try {
|
|
600
|
+
//support ending the function with `end sub` OR `end function`
|
|
601
|
+
func.body = this.block();
|
|
602
|
+
}
|
|
603
|
+
finally {
|
|
604
|
+
this.currentFunctionExpression = previousFunctionExpression;
|
|
605
|
+
}
|
|
606
|
+
if (!func.body) {
|
|
607
|
+
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.callableBlockMissingEndKeyword(functionKeywordText)), { range: this.peek().range }));
|
|
608
|
+
throw this.lastDiagnosticAsError();
|
|
609
|
+
}
|
|
600
610
|
}
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
611
|
+
if (options.hasEnd) {
|
|
612
|
+
// consume 'end sub' or 'end function'
|
|
613
|
+
func.end = this.advance();
|
|
614
|
+
let expectedEndKind = isSub ? TokenKind_1.TokenKind.EndSub : TokenKind_1.TokenKind.EndFunction;
|
|
615
|
+
//if `function` is ended with `end sub`, or `sub` is ended with `end function`, then
|
|
616
|
+
//add an error but don't hard-fail so the AST can continue more gracefully
|
|
617
|
+
if (func.end.kind !== expectedEndKind) {
|
|
618
|
+
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.mismatchedEndCallableKeyword(functionKeywordText, func.end.text)), { range: this.peek().range }));
|
|
619
|
+
}
|
|
608
620
|
}
|
|
609
621
|
func.callExpressions = this.callExpressions;
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
}
|
|
613
|
-
else {
|
|
614
|
-
let result = new Statement_1.FunctionStatement(name, func, this.currentNamespaceName);
|
|
615
|
-
func.functionStatement = result;
|
|
616
|
-
this._references.functionStatements.push(result);
|
|
617
|
-
return result;
|
|
618
|
-
}
|
|
622
|
+
func.cacheRange();
|
|
623
|
+
return { name: name, functionExpression: func };
|
|
619
624
|
}
|
|
620
625
|
finally {
|
|
621
626
|
this.namespaceAndFunctionDepth--;
|
|
@@ -629,7 +634,7 @@ class Parser {
|
|
|
629
634
|
throw this.lastDiagnosticAsError();
|
|
630
635
|
}
|
|
631
636
|
const name = this.identifier(...TokenKind_1.AllowedLocalIdentifiers);
|
|
632
|
-
let
|
|
637
|
+
let typeExpr;
|
|
633
638
|
let defaultValue;
|
|
634
639
|
let equalsToken;
|
|
635
640
|
// parse argument default value
|
|
@@ -641,26 +646,26 @@ class Parser {
|
|
|
641
646
|
let asToken = null;
|
|
642
647
|
if (this.check(TokenKind_1.TokenKind.As)) {
|
|
643
648
|
asToken = this.advance();
|
|
644
|
-
|
|
645
|
-
if (!
|
|
646
|
-
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.functionParameterTypeIsInvalid(name.text,
|
|
649
|
+
typeExpr = this.typeExpression();
|
|
650
|
+
if (!typeExpr.isValidType(this.options.mode)) {
|
|
651
|
+
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.functionParameterTypeIsInvalid(name.text, typeExpr.getText())), { range: typeExpr.range }));
|
|
647
652
|
throw this.lastDiagnosticAsError();
|
|
648
653
|
}
|
|
649
654
|
}
|
|
650
|
-
let
|
|
651
|
-
if (
|
|
652
|
-
|
|
655
|
+
let typeInContext;
|
|
656
|
+
if (typeExpr) {
|
|
657
|
+
typeInContext = typeExpr.type;
|
|
653
658
|
}
|
|
654
659
|
else if (defaultValue) {
|
|
655
|
-
|
|
656
|
-
if ((0, reflection_1.isInvalidType)(
|
|
657
|
-
|
|
660
|
+
typeInContext = getBscTypeFromExpression(defaultValue, this.currentFunctionExpression);
|
|
661
|
+
if ((0, reflection_1.isInvalidType)(typeInContext)) {
|
|
662
|
+
typeInContext = new DynamicType_1.DynamicType();
|
|
658
663
|
}
|
|
659
664
|
}
|
|
660
665
|
else {
|
|
661
|
-
|
|
666
|
+
typeInContext = new DynamicType_1.DynamicType();
|
|
662
667
|
}
|
|
663
|
-
return new Expression_1.FunctionParameterExpression(name,
|
|
668
|
+
return new Expression_1.FunctionParameterExpression(name, typeInContext, equalsToken, defaultValue, asToken, typeExpr, this.currentNamespaceName);
|
|
664
669
|
}
|
|
665
670
|
assignment() {
|
|
666
671
|
let name = this.identifier(...this.allowedLocalIdentifiers);
|
|
@@ -854,6 +859,12 @@ class Parser {
|
|
|
854
859
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.expectedExpressionAfterForEachIn()), { range: this.peek().range }));
|
|
855
860
|
throw this.lastDiagnosticAsError();
|
|
856
861
|
}
|
|
862
|
+
let itemType = new DynamicType_1.DynamicType();
|
|
863
|
+
const targetType = getBscTypeFromExpression(target, this.currentFunctionExpression);
|
|
864
|
+
if ((0, reflection_1.isArrayType)(targetType)) {
|
|
865
|
+
itemType = targetType.getDefaultType();
|
|
866
|
+
}
|
|
867
|
+
this.currentSymbolTable.addSymbol(name.text, name.range, itemType);
|
|
857
868
|
this.consumeStatementSeparators();
|
|
858
869
|
let body = this.block(TokenKind_1.TokenKind.EndFor, TokenKind_1.TokenKind.Next);
|
|
859
870
|
if (!body) {
|
|
@@ -861,12 +872,6 @@ class Parser {
|
|
|
861
872
|
throw this.lastDiagnosticAsError();
|
|
862
873
|
}
|
|
863
874
|
let endFor = this.advance();
|
|
864
|
-
let itemType = new DynamicType_1.DynamicType();
|
|
865
|
-
const targetType = getBscTypeFromExpression(target, this.currentFunctionExpression);
|
|
866
|
-
if ((0, reflection_1.isArrayType)(targetType)) {
|
|
867
|
-
itemType = targetType.getDefaultType();
|
|
868
|
-
}
|
|
869
|
-
this.currentSymbolTable.addSymbol(name.text, name.range, itemType);
|
|
870
875
|
return new Statement_1.ForEachStatement(forEach, name, maybeIn, target, body, endFor);
|
|
871
876
|
}
|
|
872
877
|
exitFor() {
|
|
@@ -917,6 +922,8 @@ class Parser {
|
|
|
917
922
|
result.body = body;
|
|
918
923
|
result.endKeyword = endKeyword;
|
|
919
924
|
this._references.namespaceStatements.push(result);
|
|
925
|
+
//cache the range property so that plugins can't affect it
|
|
926
|
+
result.cacheRange();
|
|
920
927
|
return result;
|
|
921
928
|
}
|
|
922
929
|
/**
|
|
@@ -999,6 +1006,8 @@ class Parser {
|
|
|
999
1006
|
let leftParen = this.advance();
|
|
1000
1007
|
annotation.call = this.finishCall(leftParen, annotation, false);
|
|
1001
1008
|
}
|
|
1009
|
+
//cache the range property so that plugins can't affect it
|
|
1010
|
+
annotation.cacheRange();
|
|
1002
1011
|
return annotation;
|
|
1003
1012
|
}
|
|
1004
1013
|
ternaryExpression(test) {
|
|
@@ -1107,7 +1116,7 @@ class Parser {
|
|
|
1107
1116
|
}
|
|
1108
1117
|
tryCatchStatement() {
|
|
1109
1118
|
const tryToken = this.advance();
|
|
1110
|
-
const statement = new Statement_1.TryCatchStatement(tryToken);
|
|
1119
|
+
const statement = new Statement_1.TryCatchStatement({ try: tryToken });
|
|
1111
1120
|
//ensure statement separator
|
|
1112
1121
|
this.consumeStatementSeparators();
|
|
1113
1122
|
statement.tryBranch = this.block(TokenKind_1.TokenKind.Catch, TokenKind_1.TokenKind.EndTry);
|
|
@@ -1116,27 +1125,26 @@ class Parser {
|
|
|
1116
1125
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.expectedCatchBlockInTryCatch()), { range: this.peek().range }));
|
|
1117
1126
|
//gracefully handle end-try
|
|
1118
1127
|
if (peek.kind === TokenKind_1.TokenKind.EndTry) {
|
|
1119
|
-
statement.
|
|
1128
|
+
statement.tokens.endTry = this.advance();
|
|
1120
1129
|
}
|
|
1121
1130
|
return statement;
|
|
1122
1131
|
}
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
}
|
|
1132
|
+
const catchStmt = new Statement_1.CatchStatement({ catch: this.advance() });
|
|
1133
|
+
statement.catchStatement = catchStmt;
|
|
1126
1134
|
const exceptionVarToken = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.missingExceptionVarToFollowCatch(), TokenKind_1.TokenKind.Identifier, ...this.allowedLocalIdentifiers);
|
|
1127
1135
|
if (exceptionVarToken) {
|
|
1128
1136
|
// force it into an identifier so the AST makes some sense
|
|
1129
1137
|
exceptionVarToken.kind = TokenKind_1.TokenKind.Identifier;
|
|
1130
|
-
|
|
1138
|
+
catchStmt.exceptionVariable = exceptionVarToken;
|
|
1131
1139
|
}
|
|
1132
1140
|
//ensure statement sepatator
|
|
1133
1141
|
this.consumeStatementSeparators();
|
|
1134
|
-
|
|
1142
|
+
catchStmt.catchBranch = this.block(TokenKind_1.TokenKind.EndTry);
|
|
1135
1143
|
if (this.peek().kind !== TokenKind_1.TokenKind.EndTry) {
|
|
1136
1144
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.expectedEndTryToTerminateTryCatch()), { range: this.peek().range }));
|
|
1137
1145
|
}
|
|
1138
1146
|
else {
|
|
1139
|
-
statement.
|
|
1147
|
+
statement.tokens.endTry = this.advance();
|
|
1140
1148
|
}
|
|
1141
1149
|
return statement;
|
|
1142
1150
|
}
|
|
@@ -1403,12 +1411,10 @@ class Parser {
|
|
|
1403
1411
|
if ((0, reflection_1.isIndexedGetExpression)(left)) {
|
|
1404
1412
|
return new Statement_1.IndexedSetStatement(left.obj, left.index, operator.kind === TokenKind_1.TokenKind.Equal
|
|
1405
1413
|
? right
|
|
1406
|
-
: new Expression_1.BinaryExpression(left, operator, right), left.openingSquare, left.closingSquare);
|
|
1414
|
+
: new Expression_1.BinaryExpression(left, operator, right), left.openingSquare, left.closingSquare, operator);
|
|
1407
1415
|
}
|
|
1408
1416
|
else if ((0, reflection_1.isDottedGetExpression)(left)) {
|
|
1409
|
-
const dottedSetStmt = new Statement_1.DottedSetStatement(left.obj, left.name, operator.kind === TokenKind_1.TokenKind.Equal
|
|
1410
|
-
? right
|
|
1411
|
-
: new Expression_1.BinaryExpression(left, operator, right));
|
|
1417
|
+
const dottedSetStmt = new Statement_1.DottedSetStatement(left.obj, left.name, operator.kind === TokenKind_1.TokenKind.Equal ? right : new Expression_1.BinaryExpression(left, operator, right), left.dot, operator);
|
|
1412
1418
|
this._references.dottedSetStatements.push(dottedSetStmt);
|
|
1413
1419
|
return dottedSetStmt;
|
|
1414
1420
|
}
|
|
@@ -1584,7 +1590,7 @@ class Parser {
|
|
|
1584
1590
|
}
|
|
1585
1591
|
anonymousFunction() {
|
|
1586
1592
|
if (this.checkAny(TokenKind_1.TokenKind.Sub, TokenKind_1.TokenKind.Function)) {
|
|
1587
|
-
const func = this.functionDeclaration(true);
|
|
1593
|
+
const func = this.functionDeclaration({ hasName: false, hasBody: true, hasEnd: true }).functionExpression;
|
|
1588
1594
|
//if there's an open paren after this, this is an IIFE
|
|
1589
1595
|
if (this.check(TokenKind_1.TokenKind.LeftParen)) {
|
|
1590
1596
|
return this.finishCall(this.advance(), func);
|
|
@@ -1762,9 +1768,6 @@ class Parser {
|
|
|
1762
1768
|
}
|
|
1763
1769
|
while (this.match(TokenKind_1.TokenKind.Newline)) { }
|
|
1764
1770
|
const closingParen = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedRightParenAfterFunctionCallArguments(), TokenKind_1.TokenKind.RightParen);
|
|
1765
|
-
if ((0, reflection_1.isVariableExpression)(callee)) {
|
|
1766
|
-
callee.isCalled = true;
|
|
1767
|
-
}
|
|
1768
1771
|
let expression = new Expression_1.CallExpression(callee, openingParen, closingParen, args, this.currentNamespaceName);
|
|
1769
1772
|
if (addToCallExpressionList) {
|
|
1770
1773
|
this.callExpressions.push(expression);
|
|
@@ -1776,7 +1779,7 @@ class Parser {
|
|
|
1776
1779
|
* Allows for built-in types (double, string, etc.) or namespaced custom types in Brighterscript mode
|
|
1777
1780
|
* Will return a token of whatever is next to be parsed (unless `advanceIfUnknown` is false, in which case undefined will be returned instead
|
|
1778
1781
|
*/
|
|
1779
|
-
|
|
1782
|
+
typeExpression() {
|
|
1780
1783
|
let typeToken;
|
|
1781
1784
|
if (this.checkAny(...TokenKind_1.DeclarableTypes)) {
|
|
1782
1785
|
// Token is a built in type
|
|
@@ -1797,18 +1800,23 @@ class Parser {
|
|
|
1797
1800
|
// just get whatever's next
|
|
1798
1801
|
typeToken = this.advance();
|
|
1799
1802
|
}
|
|
1800
|
-
|
|
1803
|
+
//TODO: to support InterfaceTypeLiterals - (eg. `{name as string; age as integer}`), check if "typeToken" is a curly bracket, and do something else
|
|
1804
|
+
let typeExpr = new Expression_1.TypeExpression({ type: typeToken }, this.currentNamespaceName);
|
|
1805
|
+
if (this.options.mode === ParseMode.BrighterScript) {
|
|
1801
1806
|
// Check if it is an array - that is, if it has `[]` after the type
|
|
1802
|
-
// eg. `string[]` or `SomeKlass[]`
|
|
1803
|
-
|
|
1804
|
-
this.advance();
|
|
1807
|
+
// eg. `string[]` or `SomeKlass[]` or `float[][][]`
|
|
1808
|
+
while (this.check(TokenKind_1.TokenKind.LeftSquareBracket)) {
|
|
1809
|
+
const leftBracket = this.advance();
|
|
1805
1810
|
if (this.check(TokenKind_1.TokenKind.RightSquareBracket)) {
|
|
1806
1811
|
const rightBracket = this.advance();
|
|
1807
|
-
|
|
1812
|
+
typeExpr = new Expression_1.ArrayTypeExpression([typeExpr], { leftBracket: leftBracket, rightBracket: rightBracket }, this.currentNamespaceName);
|
|
1813
|
+
}
|
|
1814
|
+
else {
|
|
1815
|
+
break;
|
|
1808
1816
|
}
|
|
1809
1817
|
}
|
|
1810
1818
|
}
|
|
1811
|
-
return
|
|
1819
|
+
return typeExpr;
|
|
1812
1820
|
}
|
|
1813
1821
|
primary() {
|
|
1814
1822
|
switch (true) {
|
|
@@ -2389,6 +2397,9 @@ class Parser {
|
|
|
2389
2397
|
this._references.expressions.add(s.initialValue);
|
|
2390
2398
|
}
|
|
2391
2399
|
},
|
|
2400
|
+
InterfaceStatement: s => {
|
|
2401
|
+
this._references.interfaceStatements.push(s);
|
|
2402
|
+
},
|
|
2392
2403
|
NamespaceStatement: s => {
|
|
2393
2404
|
this._references.namespaceStatements.push(s);
|
|
2394
2405
|
},
|
|
@@ -2402,7 +2413,7 @@ class Parser {
|
|
|
2402
2413
|
this._references.libraryStatements.push(s);
|
|
2403
2414
|
},
|
|
2404
2415
|
FunctionExpression: (expression, parent) => {
|
|
2405
|
-
if (!(0, reflection_1.isClassMethodStatement)(parent)) {
|
|
2416
|
+
if (!(0, reflection_1.isClassMethodStatement)(parent) && !(0, reflection_1.isInterfaceMethodStatement)(parent)) {
|
|
2406
2417
|
this._references.functionExpressions.push(expression);
|
|
2407
2418
|
}
|
|
2408
2419
|
},
|
|
@@ -2534,7 +2545,7 @@ class References {
|
|
|
2534
2545
|
if (!this._interfaceStatementLookup) {
|
|
2535
2546
|
this._interfaceStatementLookup = new Map();
|
|
2536
2547
|
for (const stmt of this.interfaceStatements) {
|
|
2537
|
-
this._interfaceStatementLookup.set(stmt.
|
|
2548
|
+
this._interfaceStatementLookup.set(stmt.getName(ParseMode.BrighterScript).toLowerCase(), stmt);
|
|
2538
2549
|
}
|
|
2539
2550
|
}
|
|
2540
2551
|
return this._interfaceStatementLookup;
|
|
@@ -2579,7 +2590,7 @@ function getBscTypeFromExpression(expression, functionExpression) {
|
|
|
2579
2590
|
//Associative array literal
|
|
2580
2591
|
}
|
|
2581
2592
|
else if ((0, reflection_1.isAALiteralExpression)(expression)) {
|
|
2582
|
-
return new ObjectType_1.ObjectType(expression.memberTable);
|
|
2593
|
+
return new ObjectType_1.ObjectType('object', expression.memberTable);
|
|
2583
2594
|
//Array literal
|
|
2584
2595
|
}
|
|
2585
2596
|
else if ((0, reflection_1.isArrayLiteralExpression)(expression)) {
|
|
@@ -2590,7 +2601,7 @@ function getBscTypeFromExpression(expression, functionExpression) {
|
|
|
2590
2601
|
//function call
|
|
2591
2602
|
}
|
|
2592
2603
|
else if ((0, reflection_1.isNewExpression)(expression)) {
|
|
2593
|
-
return (0, helpers_1.getTypeFromNewExpression)(expression, functionExpression);
|
|
2604
|
+
return (0, helpers_1.getTypeFromNewExpression)(expression, functionExpression);
|
|
2594
2605
|
//Function call
|
|
2595
2606
|
}
|
|
2596
2607
|
else if ((0, reflection_1.isCallExpression)(expression)) {
|