brighterscript 1.0.0-alpha.1 → 1.0.0-alpha.13
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 +362 -248
- package/README.md +2 -2
- package/bsconfig.schema.json +1 -1
- package/dist/CodeActionUtil.d.ts +11 -2
- package/dist/CodeActionUtil.js +17 -3
- package/dist/CodeActionUtil.js.map +1 -1
- package/dist/CommentFlagProcessor.d.ts +4 -4
- package/dist/CommentFlagProcessor.js +5 -3
- package/dist/CommentFlagProcessor.js.map +1 -1
- package/dist/DependencyGraph.js.map +1 -1
- package/dist/DiagnosticCollection.js +2 -2
- package/dist/DiagnosticCollection.js.map +1 -1
- package/dist/DiagnosticFilterer.js +3 -3
- package/dist/DiagnosticFilterer.js.map +1 -1
- package/dist/DiagnosticMessages.d.ts +15 -5
- package/dist/DiagnosticMessages.js +19 -9
- package/dist/DiagnosticMessages.js.map +1 -1
- package/dist/LanguageServer.d.ts +11 -10
- package/dist/LanguageServer.js +87 -58
- package/dist/LanguageServer.js.map +1 -1
- package/dist/Logger.d.ts +2 -0
- package/dist/Logger.js +5 -3
- package/dist/Logger.js.map +1 -1
- package/dist/Program.d.ts +76 -46
- package/dist/Program.js +254 -180
- package/dist/Program.js.map +1 -1
- package/dist/ProgramBuilder.d.ts +7 -7
- package/dist/ProgramBuilder.js +37 -43
- package/dist/ProgramBuilder.js.map +1 -1
- package/dist/Scope.d.ts +33 -23
- package/dist/Scope.js +222 -147
- package/dist/Scope.js.map +1 -1
- package/dist/SemanticTokenUtils.d.ts +14 -0
- package/dist/SemanticTokenUtils.js +81 -0
- package/dist/SemanticTokenUtils.js.map +1 -0
- package/dist/SymbolTable.d.ts +9 -3
- package/dist/SymbolTable.js +40 -13
- package/dist/SymbolTable.js.map +1 -1
- package/dist/XmlScope.d.ts +7 -2
- package/dist/XmlScope.js +67 -29
- package/dist/XmlScope.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/creators.d.ts +15 -1
- package/dist/astUtils/creators.js +39 -9
- package/dist/astUtils/creators.js.map +1 -1
- package/dist/astUtils/creators.spec.js +4 -4
- package/dist/astUtils/creators.spec.js.map +1 -1
- package/dist/astUtils/index.js +1 -1
- package/dist/astUtils/reflection.d.ts +20 -8
- package/dist/astUtils/reflection.js +42 -1
- package/dist/astUtils/reflection.js.map +1 -1
- package/dist/astUtils/reflection.spec.js +115 -115
- package/dist/astUtils/reflection.spec.js.map +1 -1
- package/dist/astUtils/stackedVisitor.js.map +1 -1
- package/dist/astUtils/stackedVisitor.spec.js +13 -13
- package/dist/astUtils/stackedVisitor.spec.js.map +1 -1
- package/dist/astUtils/visitors.js +1 -1
- package/dist/astUtils/visitors.js.map +1 -1
- package/dist/astUtils/visitors.spec.js +28 -28
- package/dist/astUtils/visitors.spec.js.map +1 -1
- package/dist/astUtils/xml.d.ts +4 -3
- package/dist/astUtils/xml.js +8 -3
- package/dist/astUtils/xml.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/codeActions/CodeActionsProcessor.js +5 -6
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.js.map +1 -1
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js +30 -30
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js.map +1 -1
- package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.d.ts +7 -0
- package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.js +63 -0
- package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.js.map +1 -0
- package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.spec.d.ts +1 -0
- package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.spec.js +45 -0
- package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.spec.js.map +1 -0
- package/dist/diagnosticUtils.d.ts +1 -0
- package/dist/diagnosticUtils.js +14 -7
- package/dist/diagnosticUtils.js.map +1 -1
- package/dist/examples/plugins/removePrint.js +2 -2
- package/dist/examples/plugins/removePrint.js.map +1 -1
- package/dist/files/BrsFile.Class.spec.js +486 -71
- package/dist/files/BrsFile.Class.spec.js.map +1 -1
- package/dist/files/BrsFile.d.ts +48 -23
- package/dist/files/BrsFile.js +403 -233
- package/dist/files/BrsFile.js.map +1 -1
- package/dist/files/BrsFile.spec.js +367 -316
- package/dist/files/BrsFile.spec.js.map +1 -1
- package/dist/files/XmlFile.d.ts +13 -6
- package/dist/files/XmlFile.js +27 -21
- package/dist/files/XmlFile.js.map +1 -1
- package/dist/files/XmlFile.spec.js +274 -228
- package/dist/files/XmlFile.spec.js.map +1 -1
- package/dist/files/tests/imports.spec.js +49 -49
- package/dist/files/tests/imports.spec.js.map +1 -1
- package/dist/globalCallables.d.ts +3 -1
- package/dist/globalCallables.js +359 -87
- package/dist/globalCallables.js.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/interfaces.d.ts +51 -14
- package/dist/lexer/Lexer.d.ts +14 -1
- package/dist/lexer/Lexer.js +91 -21
- package/dist/lexer/Lexer.js.map +1 -1
- package/dist/lexer/Lexer.spec.js +187 -132
- package/dist/lexer/Lexer.spec.js.map +1 -1
- package/dist/lexer/Token.d.ts +2 -2
- package/dist/lexer/TokenKind.d.ts +7 -1
- package/dist/lexer/TokenKind.js +51 -3
- package/dist/lexer/TokenKind.js.map +1 -1
- package/dist/lexer/index.js +2 -1
- package/dist/lexer/index.js.map +1 -1
- package/dist/parser/BrsTranspileState.d.ts +7 -0
- package/dist/parser/BrsTranspileState.js +10 -1
- package/dist/parser/BrsTranspileState.js.map +1 -1
- package/dist/parser/Expression.d.ts +23 -5
- package/dist/parser/Expression.js +124 -75
- package/dist/parser/Expression.js.map +1 -1
- package/dist/parser/Parser.Class.spec.js +159 -60
- package/dist/parser/Parser.Class.spec.js.map +1 -1
- package/dist/parser/Parser.d.ts +114 -26
- package/dist/parser/Parser.js +471 -126
- package/dist/parser/Parser.js.map +1 -1
- package/dist/parser/Parser.spec.js +396 -235
- package/dist/parser/Parser.spec.js.map +1 -1
- package/dist/parser/SGParser.d.ts +41 -4
- package/dist/parser/SGParser.js +186 -175
- package/dist/parser/SGParser.js.map +1 -1
- package/dist/parser/SGParser.spec.js +35 -22
- package/dist/parser/SGParser.spec.js.map +1 -1
- package/dist/parser/SGTypes.d.ts +206 -38
- package/dist/parser/SGTypes.js +470 -161
- package/dist/parser/SGTypes.js.map +1 -1
- package/dist/parser/SGTypes.spec.d.ts +1 -0
- package/dist/parser/SGTypes.spec.js +351 -0
- package/dist/parser/SGTypes.spec.js.map +1 -0
- package/dist/parser/Statement.d.ts +92 -18
- package/dist/parser/Statement.js +287 -58
- package/dist/parser/Statement.js.map +1 -1
- package/dist/parser/Statement.spec.js +11 -11
- package/dist/parser/Statement.spec.js.map +1 -1
- package/dist/parser/TranspileState.d.ts +1 -1
- package/dist/parser/TranspileState.js +15 -7
- package/dist/parser/TranspileState.js.map +1 -1
- package/dist/parser/index.js +1 -1
- package/dist/parser/tests/Parser.spec.d.ts +8 -7
- package/dist/parser/tests/Parser.spec.js +12 -8
- package/dist/parser/tests/Parser.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/For.spec.js +50 -50
- package/dist/parser/tests/controlFlow/For.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/ForEach.spec.js +31 -31
- package/dist/parser/tests/controlFlow/ForEach.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/If.spec.js +174 -156
- package/dist/parser/tests/controlFlow/If.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/While.spec.js +32 -32
- 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 +105 -105
- package/dist/parser/tests/expression/ArrayLiterals.spec.js.map +1 -1
- package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js +148 -124
- package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js.map +1 -1
- package/dist/parser/tests/expression/Boolean.spec.js +17 -17
- package/dist/parser/tests/expression/Boolean.spec.js.map +1 -1
- package/dist/parser/tests/expression/Call.spec.js +30 -30
- package/dist/parser/tests/expression/Call.spec.js.map +1 -1
- package/dist/parser/tests/expression/Exponential.spec.js +16 -16
- package/dist/parser/tests/expression/Exponential.spec.js.map +1 -1
- package/dist/parser/tests/expression/Function.spec.js +247 -247
- package/dist/parser/tests/expression/Function.spec.js.map +1 -1
- package/dist/parser/tests/expression/Indexing.spec.js +73 -73
- package/dist/parser/tests/expression/Indexing.spec.js.map +1 -1
- package/dist/parser/tests/expression/Multiplicative.spec.js +36 -36
- package/dist/parser/tests/expression/Multiplicative.spec.js.map +1 -1
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js +59 -47
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/PrefixUnary.spec.js +35 -35
- package/dist/parser/tests/expression/PrefixUnary.spec.js.map +1 -1
- package/dist/parser/tests/expression/Primary.spec.js +26 -26
- package/dist/parser/tests/expression/Primary.spec.js.map +1 -1
- package/dist/parser/tests/expression/RegexLiteralExpression.spec.d.ts +1 -0
- package/dist/parser/tests/expression/RegexLiteralExpression.spec.js +170 -0
- package/dist/parser/tests/expression/RegexLiteralExpression.spec.js.map +1 -0
- package/dist/parser/tests/expression/Relational.spec.js +42 -42
- package/dist/parser/tests/expression/Relational.spec.js.map +1 -1
- package/dist/parser/tests/expression/SourceLiteralExpression.spec.js +8 -8
- package/dist/parser/tests/expression/SourceLiteralExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/TemplateStringExpression.spec.js +12 -12
- package/dist/parser/tests/expression/TemplateStringExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/TernaryExpression.spec.js +100 -100
- package/dist/parser/tests/expression/TernaryExpression.spec.js.map +1 -1
- package/dist/parser/tests/statement/AssignmentOperators.spec.js +35 -35
- package/dist/parser/tests/statement/AssignmentOperators.spec.js.map +1 -1
- package/dist/parser/tests/statement/Declaration.spec.js +39 -39
- package/dist/parser/tests/statement/Declaration.spec.js.map +1 -1
- package/dist/parser/tests/statement/Dim.spec.js +21 -21
- package/dist/parser/tests/statement/Dim.spec.js.map +1 -1
- package/dist/parser/tests/statement/Function.spec.js +192 -192
- package/dist/parser/tests/statement/Function.spec.js.map +1 -1
- package/dist/parser/tests/statement/Goto.spec.js +11 -11
- package/dist/parser/tests/statement/Goto.spec.js.map +1 -1
- package/dist/parser/tests/statement/Increment.spec.js +46 -46
- package/dist/parser/tests/statement/Increment.spec.js.map +1 -1
- package/dist/parser/tests/statement/InterfaceStatement.spec.d.ts +1 -0
- package/dist/parser/tests/statement/InterfaceStatement.spec.js +61 -0
- package/dist/parser/tests/statement/InterfaceStatement.spec.js.map +1 -0
- package/dist/parser/tests/statement/LibraryStatement.spec.js +10 -10
- package/dist/parser/tests/statement/LibraryStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/Misc.spec.js +37 -36
- package/dist/parser/tests/statement/Misc.spec.js.map +1 -1
- package/dist/parser/tests/statement/PrintStatement.spec.js +30 -30
- package/dist/parser/tests/statement/PrintStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/ReturnStatement.spec.js +43 -43
- package/dist/parser/tests/statement/ReturnStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/Set.spec.js +69 -69
- package/dist/parser/tests/statement/Set.spec.js.map +1 -1
- package/dist/parser/tests/statement/Stop.spec.js +9 -9
- package/dist/parser/tests/statement/Stop.spec.js.map +1 -1
- package/dist/parser/tests/statement/Throw.spec.js +5 -5
- package/dist/parser/tests/statement/Throw.spec.js.map +1 -1
- package/dist/parser/tests/statement/TryCatch.spec.js +13 -13
- package/dist/parser/tests/statement/TryCatch.spec.js.map +1 -1
- package/dist/preprocessor/Chunk.js.map +1 -1
- package/dist/preprocessor/Manifest.d.ts +1 -1
- package/dist/preprocessor/Preprocessor.js +1 -1
- package/dist/preprocessor/Preprocessor.js.map +1 -1
- package/dist/preprocessor/Preprocessor.spec.js +49 -49
- package/dist/preprocessor/Preprocessor.spec.js.map +1 -1
- package/dist/preprocessor/PreprocessorParser.spec.js +72 -72
- package/dist/preprocessor/PreprocessorParser.spec.js.map +1 -1
- package/dist/preprocessor/index.js +1 -1
- package/dist/types/ArrayType.js +5 -4
- package/dist/types/ArrayType.js.map +1 -1
- package/dist/types/ArrayType.spec.js +8 -8
- package/dist/types/ArrayType.spec.js.map +1 -1
- package/dist/types/BooleanType.js +3 -3
- package/dist/types/BooleanType.js.map +1 -1
- package/dist/types/BooleanType.spec.js +2 -2
- package/dist/types/BooleanType.spec.js.map +1 -1
- package/dist/types/BscType.d.ts +19 -5
- package/dist/types/BscType.js +9 -0
- package/dist/types/BscType.js.map +1 -1
- package/dist/types/CustomType.d.ts +8 -5
- package/dist/types/CustomType.js +17 -6
- package/dist/types/CustomType.js.map +1 -1
- package/dist/types/DoubleType.js +8 -8
- package/dist/types/DoubleType.js.map +1 -1
- package/dist/types/DoubleType.spec.js +2 -2
- package/dist/types/DoubleType.spec.js.map +1 -1
- package/dist/types/DynamicType.js +1 -1
- package/dist/types/DynamicType.js.map +1 -1
- package/dist/types/DynamicType.spec.js +2 -2
- package/dist/types/DynamicType.spec.js.map +1 -1
- package/dist/types/FloatType.d.ts +1 -1
- package/dist/types/FloatType.js +8 -8
- package/dist/types/FloatType.js.map +1 -1
- package/dist/types/FloatType.spec.js +2 -2
- package/dist/types/FloatType.spec.js.map +1 -1
- package/dist/types/FunctionType.d.ts +5 -11
- package/dist/types/FunctionType.js +24 -13
- package/dist/types/FunctionType.js.map +1 -1
- package/dist/types/FunctionType.spec.js +11 -5
- package/dist/types/FunctionType.spec.js.map +1 -1
- package/dist/types/IntegerType.d.ts +1 -1
- package/dist/types/IntegerType.js +8 -8
- package/dist/types/IntegerType.js.map +1 -1
- package/dist/types/IntegerType.spec.js +2 -2
- package/dist/types/IntegerType.spec.js.map +1 -1
- package/dist/types/InterfaceType.d.ts +8 -2
- package/dist/types/InterfaceType.js +42 -6
- package/dist/types/InterfaceType.js.map +1 -1
- package/dist/types/InterfaceType.spec.d.ts +1 -0
- package/dist/types/InterfaceType.spec.js +174 -0
- package/dist/types/InterfaceType.spec.js.map +1 -0
- package/dist/types/InvalidType.js +4 -4
- package/dist/types/InvalidType.js.map +1 -1
- package/dist/types/InvalidType.spec.js +2 -2
- package/dist/types/InvalidType.spec.js.map +1 -1
- package/dist/types/LazyType.d.ts +9 -7
- package/dist/types/LazyType.js +22 -10
- package/dist/types/LazyType.js.map +1 -1
- package/dist/types/LongIntegerType.d.ts +1 -1
- package/dist/types/LongIntegerType.js +8 -8
- package/dist/types/LongIntegerType.js.map +1 -1
- package/dist/types/LongIntegerType.spec.js +2 -2
- package/dist/types/LongIntegerType.spec.js.map +1 -1
- package/dist/types/ObjectType.d.ts +7 -4
- package/dist/types/ObjectType.js +6 -3
- package/dist/types/ObjectType.js.map +1 -1
- package/dist/types/ObjectType.spec.js +2 -2
- package/dist/types/ObjectType.spec.js.map +1 -1
- package/dist/types/StringType.js +3 -3
- package/dist/types/StringType.js.map +1 -1
- package/dist/types/StringType.spec.js +2 -2
- package/dist/types/StringType.spec.js.map +1 -1
- package/dist/types/UninitializedType.js +3 -3
- package/dist/types/UninitializedType.js.map +1 -1
- package/dist/types/VoidType.js +3 -3
- package/dist/types/VoidType.js.map +1 -1
- package/dist/types/VoidType.spec.js +2 -2
- package/dist/types/VoidType.spec.js.map +1 -1
- package/dist/types/helpers.d.ts +42 -0
- package/dist/types/helpers.js +113 -0
- package/dist/types/helpers.js.map +1 -0
- package/dist/util.d.ts +77 -17
- package/dist/util.js +247 -59
- package/dist/util.js.map +1 -1
- package/dist/validators/ClassValidator.d.ts +5 -1
- package/dist/validators/ClassValidator.js +59 -24
- package/dist/validators/ClassValidator.js.map +1 -1
- package/package.json +13 -13
package/dist/parser/Parser.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.getBscTypeFromExpression = exports.TokenUsage = exports.References = exports.ParseMode = exports.Parser = void 0;
|
|
4
4
|
const lexer_1 = require("../lexer");
|
|
5
5
|
const Statement_1 = require("./Statement");
|
|
6
6
|
const DiagnosticMessages_1 = require("../DiagnosticMessages");
|
|
@@ -11,11 +11,11 @@ const reflection_1 = require("../astUtils/reflection");
|
|
|
11
11
|
const visitors_1 = require("../astUtils/visitors");
|
|
12
12
|
const creators_1 = require("../astUtils/creators");
|
|
13
13
|
const DynamicType_1 = require("../types/DynamicType");
|
|
14
|
-
const LazyType_1 = require("../types/LazyType");
|
|
15
14
|
const SymbolTable_1 = require("../SymbolTable");
|
|
16
15
|
const ObjectType_1 = require("../types/ObjectType");
|
|
17
|
-
const CustomType_1 = require("../types/CustomType");
|
|
18
16
|
const ArrayType_1 = require("../types/ArrayType");
|
|
17
|
+
const helpers_1 = require("../types/helpers");
|
|
18
|
+
const _1 = require(".");
|
|
19
19
|
class Parser {
|
|
20
20
|
constructor() {
|
|
21
21
|
/**
|
|
@@ -61,13 +61,13 @@ class Parser {
|
|
|
61
61
|
this._references = undefined;
|
|
62
62
|
}
|
|
63
63
|
addPropertyHints(item) {
|
|
64
|
-
if (lexer_1.isToken(item)) {
|
|
64
|
+
if ((0, lexer_1.isToken)(item)) {
|
|
65
65
|
const name = item.text;
|
|
66
66
|
this._references.propertyHints[name.toLowerCase()] = name;
|
|
67
67
|
}
|
|
68
68
|
else {
|
|
69
69
|
for (const member of item.elements) {
|
|
70
|
-
if (!reflection_1.isCommentStatement(member)) {
|
|
70
|
+
if (!(0, reflection_1.isCommentStatement)(member)) {
|
|
71
71
|
const name = member.keyToken.text;
|
|
72
72
|
if (!name.startsWith('"')) {
|
|
73
73
|
this._references.propertyHints[name.toLowerCase()] = name;
|
|
@@ -87,6 +87,9 @@ class Parser {
|
|
|
87
87
|
var _a;
|
|
88
88
|
return (_a = this.globalTerminators[this.globalTerminators.length - 1]) !== null && _a !== void 0 ? _a : [];
|
|
89
89
|
}
|
|
90
|
+
/**
|
|
91
|
+
* Static wrapper around creating a new parser and parsing a list of tokens
|
|
92
|
+
*/
|
|
90
93
|
static parse(toParse, options) {
|
|
91
94
|
let tokens;
|
|
92
95
|
if (typeof toParse === 'string') {
|
|
@@ -132,7 +135,7 @@ class Parser {
|
|
|
132
135
|
!this.checkAny(...this.peekGlobalTerminators())) {
|
|
133
136
|
let dec = this.declaration();
|
|
134
137
|
if (dec) {
|
|
135
|
-
if (!reflection_1.isAnnotationExpression(dec)) {
|
|
138
|
+
if (!(0, reflection_1.isAnnotationExpression)(dec)) {
|
|
136
139
|
this.consumePendingAnnotations(dec);
|
|
137
140
|
body.statements.push(dec);
|
|
138
141
|
//ensure statement separator
|
|
@@ -181,18 +184,12 @@ class Parser {
|
|
|
181
184
|
}
|
|
182
185
|
declaration() {
|
|
183
186
|
try {
|
|
184
|
-
if (this.check(lexer_1.TokenKind.Class)) {
|
|
185
|
-
return this.classDeclaration();
|
|
186
|
-
}
|
|
187
187
|
if (this.checkAny(lexer_1.TokenKind.Sub, lexer_1.TokenKind.Function)) {
|
|
188
188
|
return this.functionDeclaration(false);
|
|
189
189
|
}
|
|
190
190
|
if (this.checkLibrary()) {
|
|
191
191
|
return this.libraryStatement();
|
|
192
192
|
}
|
|
193
|
-
if (this.check(lexer_1.TokenKind.Namespace)) {
|
|
194
|
-
return this.namespaceStatement();
|
|
195
|
-
}
|
|
196
193
|
if (this.check(lexer_1.TokenKind.At) && this.checkNext(lexer_1.TokenKind.Identifier)) {
|
|
197
194
|
return this.annotationExpression();
|
|
198
195
|
}
|
|
@@ -213,13 +210,116 @@ class Parser {
|
|
|
213
210
|
this.synchronize();
|
|
214
211
|
}
|
|
215
212
|
}
|
|
213
|
+
identifier(...additionalTokenKinds) {
|
|
214
|
+
const identifier = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier(), lexer_1.TokenKind.Identifier, ...additionalTokenKinds);
|
|
215
|
+
// force the name into an identifier so the AST makes some sense
|
|
216
|
+
identifier.kind = lexer_1.TokenKind.Identifier;
|
|
217
|
+
return identifier;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Create a new InterfaceMethodStatement. This should only be called from within `interfaceDeclaration`
|
|
221
|
+
*/
|
|
222
|
+
interfaceFieldStatement() {
|
|
223
|
+
const name = this.identifier(...lexer_1.AllowedProperties);
|
|
224
|
+
let asToken = this.consumeToken(lexer_1.TokenKind.As);
|
|
225
|
+
let typeToken = this.typeToken();
|
|
226
|
+
const type = util_1.util.tokenToBscType(typeToken);
|
|
227
|
+
if (!type) {
|
|
228
|
+
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.functionParameterTypeIsInvalid(name.text, typeToken.text)), { range: typeToken.range }));
|
|
229
|
+
throw this.lastDiagnosticAsError();
|
|
230
|
+
}
|
|
231
|
+
return new Statement_1.InterfaceFieldStatement(name, asToken, typeToken, type);
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Create a new InterfaceMethodStatement. This should only be called from within `interfaceDeclaration()`
|
|
235
|
+
*/
|
|
236
|
+
interfaceMethodStatement() {
|
|
237
|
+
const functionType = this.advance();
|
|
238
|
+
const name = this.identifier(...lexer_1.AllowedProperties);
|
|
239
|
+
const leftParen = this.consumeToken(lexer_1.TokenKind.LeftParen);
|
|
240
|
+
const params = [];
|
|
241
|
+
const rightParen = this.consumeToken(lexer_1.TokenKind.RightParen);
|
|
242
|
+
let asToken = null;
|
|
243
|
+
let returnTypeToken = null;
|
|
244
|
+
if (this.check(lexer_1.TokenKind.As)) {
|
|
245
|
+
asToken = this.advance();
|
|
246
|
+
returnTypeToken = this.typeToken();
|
|
247
|
+
const returnType = util_1.util.tokenToBscType(returnTypeToken);
|
|
248
|
+
if (!returnType) {
|
|
249
|
+
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.functionParameterTypeIsInvalid(name.text, returnTypeToken.text)), { range: returnTypeToken.range }));
|
|
250
|
+
throw this.lastDiagnosticAsError();
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
return new Statement_1.InterfaceMethodStatement(functionType, name, leftParen, params, rightParen, asToken, returnTypeToken, util_1.util.tokenToBscType(returnTypeToken));
|
|
254
|
+
}
|
|
255
|
+
interfaceDeclaration() {
|
|
256
|
+
this.warnIfNotBrighterScriptMode('interface declarations');
|
|
257
|
+
const parentAnnotations = this.enterAnnotationBlock();
|
|
258
|
+
const interfaceToken = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedKeyword(lexer_1.TokenKind.Interface), lexer_1.TokenKind.Interface);
|
|
259
|
+
const nameToken = this.identifier(...this.allowedLocalIdentifiers);
|
|
260
|
+
let extendsToken;
|
|
261
|
+
let parentInterfaceName;
|
|
262
|
+
if (this.peek().text.toLowerCase() === 'extends') {
|
|
263
|
+
extendsToken = this.advance();
|
|
264
|
+
parentInterfaceName = this.getNamespacedVariableNameExpression();
|
|
265
|
+
}
|
|
266
|
+
this.consumeStatementSeparators();
|
|
267
|
+
//gather up all interface members (Fields, Methods)
|
|
268
|
+
let body = [];
|
|
269
|
+
while (this.checkAny(lexer_1.TokenKind.Comment, lexer_1.TokenKind.Identifier, lexer_1.TokenKind.At, ...lexer_1.AllowedProperties)) {
|
|
270
|
+
try {
|
|
271
|
+
let decl;
|
|
272
|
+
//collect leading annotations
|
|
273
|
+
if (this.check(lexer_1.TokenKind.At)) {
|
|
274
|
+
this.annotationExpression();
|
|
275
|
+
}
|
|
276
|
+
//fields
|
|
277
|
+
if (this.checkAny(lexer_1.TokenKind.Identifier, ...lexer_1.AllowedProperties) && this.checkNext(lexer_1.TokenKind.As)) {
|
|
278
|
+
decl = this.interfaceFieldStatement();
|
|
279
|
+
//methods (function/sub keyword followed by opening paren)
|
|
280
|
+
}
|
|
281
|
+
else if (this.checkAny(lexer_1.TokenKind.Function, lexer_1.TokenKind.Sub) && this.checkAny(lexer_1.TokenKind.Identifier, ...lexer_1.AllowedProperties)) {
|
|
282
|
+
decl = this.interfaceMethodStatement();
|
|
283
|
+
//comments
|
|
284
|
+
}
|
|
285
|
+
else if (this.check(lexer_1.TokenKind.Comment)) {
|
|
286
|
+
decl = this.commentStatement();
|
|
287
|
+
}
|
|
288
|
+
if (decl) {
|
|
289
|
+
this.consumePendingAnnotations(decl);
|
|
290
|
+
body.push(decl);
|
|
291
|
+
}
|
|
292
|
+
else {
|
|
293
|
+
//we didn't find a declaration...flag tokens until next line
|
|
294
|
+
this.flagUntil(lexer_1.TokenKind.Newline, lexer_1.TokenKind.Colon, lexer_1.TokenKind.Eof);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
catch (e) {
|
|
298
|
+
//throw out any failed members and move on to the next line
|
|
299
|
+
this.flagUntil(lexer_1.TokenKind.Newline, lexer_1.TokenKind.Colon, lexer_1.TokenKind.Eof);
|
|
300
|
+
}
|
|
301
|
+
//ensure statement separator
|
|
302
|
+
this.consumeStatementSeparators();
|
|
303
|
+
//break out of this loop if we encountered the `EndInterface` token not followed by `as`
|
|
304
|
+
if (this.check(lexer_1.TokenKind.EndInterface) && !this.checkNext(lexer_1.TokenKind.As)) {
|
|
305
|
+
break;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
//consume the final `end interface` token
|
|
309
|
+
const endInterfaceToken = this.consumeToken(lexer_1.TokenKind.EndInterface);
|
|
310
|
+
this.consumeStatementSeparators();
|
|
311
|
+
const statement = new Statement_1.InterfaceStatement(interfaceToken, nameToken, extendsToken, parentInterfaceName, body, endInterfaceToken, this.currentNamespaceName);
|
|
312
|
+
this._references.interfaceStatements.push(statement);
|
|
313
|
+
this.exitAnnotationBlock(parentAnnotations);
|
|
314
|
+
return statement;
|
|
315
|
+
}
|
|
216
316
|
/**
|
|
217
317
|
* A BrighterScript class declaration
|
|
218
318
|
*/
|
|
219
319
|
classDeclaration() {
|
|
220
320
|
this.warnIfNotBrighterScriptMode('class declarations');
|
|
221
321
|
const parentAnnotations = this.enterAnnotationBlock();
|
|
222
|
-
let classKeyword = this.consume(DiagnosticMessages_1.DiagnosticMessages.
|
|
322
|
+
let classKeyword = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedKeyword(lexer_1.TokenKind.Class), lexer_1.TokenKind.Class);
|
|
223
323
|
let extendsKeyword;
|
|
224
324
|
let parentClassName;
|
|
225
325
|
//get the class name
|
|
@@ -250,7 +350,7 @@ class Parser {
|
|
|
250
350
|
}
|
|
251
351
|
//methods (function/sub keyword OR identifier followed by opening paren)
|
|
252
352
|
if (this.checkAny(lexer_1.TokenKind.Function, lexer_1.TokenKind.Sub) || (this.checkAny(lexer_1.TokenKind.Identifier, ...lexer_1.AllowedProperties) && this.checkNext(lexer_1.TokenKind.LeftParen))) {
|
|
253
|
-
const funcDeclaration = this.functionDeclaration(false, false);
|
|
353
|
+
const funcDeclaration = this.functionDeclaration(false, false, true);
|
|
254
354
|
//remove this function from the lists because it's not a callable
|
|
255
355
|
const functionStatement = this._references.functionStatements.pop();
|
|
256
356
|
//if we have an overrides keyword AND this method is called 'new', that's not allowed
|
|
@@ -289,7 +389,10 @@ class Parser {
|
|
|
289
389
|
if (endingKeyword.kind !== lexer_1.TokenKind.EndClass) {
|
|
290
390
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.couldNotFindMatchingEndKeyword('class')), { range: endingKeyword.range }));
|
|
291
391
|
}
|
|
292
|
-
const result = new Statement_1.ClassStatement(classKeyword, className, body, endingKeyword, extendsKeyword, parentClassName, this.currentNamespaceName);
|
|
392
|
+
const result = new Statement_1.ClassStatement(classKeyword, className, body, endingKeyword, extendsKeyword, parentClassName, this.currentNamespaceName, this.currentSymbolTable);
|
|
393
|
+
if (className) {
|
|
394
|
+
this.currentSymbolTable.addSymbol(className.text, className.range, result.getConstructorFunctionType());
|
|
395
|
+
}
|
|
293
396
|
this._references.classStatements.push(result);
|
|
294
397
|
this.exitAnnotationBlock(parentAnnotations);
|
|
295
398
|
return result;
|
|
@@ -303,7 +406,7 @@ class Parser {
|
|
|
303
406
|
asToken = this.advance();
|
|
304
407
|
fieldType = this.typeToken();
|
|
305
408
|
//no field type specified
|
|
306
|
-
if (!util_1.util.tokenToBscType(fieldType
|
|
409
|
+
if (!util_1.util.tokenToBscType(fieldType, true, this.currentNamespaceName)) {
|
|
307
410
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.expectedValidTypeToFollowAsKeyword()), { range: this.peek().range }));
|
|
308
411
|
}
|
|
309
412
|
}
|
|
@@ -314,9 +417,9 @@ class Parser {
|
|
|
314
417
|
equal = this.advance();
|
|
315
418
|
initialValue = this.expression();
|
|
316
419
|
}
|
|
317
|
-
return new Statement_1.ClassFieldStatement(accessModifier, name, asToken, fieldType, equal, initialValue);
|
|
420
|
+
return new Statement_1.ClassFieldStatement(accessModifier, name, asToken, fieldType, equal, initialValue, this.currentNamespaceName);
|
|
318
421
|
}
|
|
319
|
-
functionDeclaration(isAnonymous, checkIdentifier = true) {
|
|
422
|
+
functionDeclaration(isAnonymous, checkIdentifier = true, forClassMethod = false) {
|
|
320
423
|
var _a, _b, _c, _d;
|
|
321
424
|
let previousCallExpressions = this.callExpressions;
|
|
322
425
|
this.callExpressions = [];
|
|
@@ -377,7 +480,7 @@ class Parser {
|
|
|
377
480
|
if (this.check(lexer_1.TokenKind.As)) {
|
|
378
481
|
asToken = this.advance();
|
|
379
482
|
typeToken = this.typeToken();
|
|
380
|
-
if (!util_1.util.tokenToBscType(typeToken, this.options.mode === ParseMode.BrighterScript)) {
|
|
483
|
+
if (!util_1.util.tokenToBscType(typeToken, this.options.mode === ParseMode.BrighterScript, this.currentNamespaceName)) {
|
|
381
484
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.invalidFunctionReturnType((_a = typeToken.text) !== null && _a !== void 0 ? _a : '')), { range: typeToken.range }));
|
|
382
485
|
}
|
|
383
486
|
}
|
|
@@ -397,7 +500,7 @@ class Parser {
|
|
|
397
500
|
this.currentFunctionExpression.childFunctionExpressions.push(func);
|
|
398
501
|
}
|
|
399
502
|
// add the function to the relevant symbol tables
|
|
400
|
-
if (!isAnonymous) {
|
|
503
|
+
if (!isAnonymous && !forClassMethod) {
|
|
401
504
|
const funcType = func.getFunctionType();
|
|
402
505
|
funcType.setName(name.text);
|
|
403
506
|
// add the function as declared to the current namespace's table
|
|
@@ -449,18 +552,12 @@ class Parser {
|
|
|
449
552
|
this.callExpressions = previousCallExpressions;
|
|
450
553
|
}
|
|
451
554
|
}
|
|
452
|
-
identifier() {
|
|
453
|
-
const identifier = this.advance();
|
|
454
|
-
// force the name into an identifier so the AST makes some sense
|
|
455
|
-
identifier.kind = lexer_1.TokenKind.Identifier;
|
|
456
|
-
return identifier;
|
|
457
|
-
}
|
|
458
555
|
functionParameter() {
|
|
459
556
|
if (!this.checkAny(lexer_1.TokenKind.Identifier, ...this.allowedLocalIdentifiers)) {
|
|
460
557
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.expectedParameterNameButFound(this.peek().text)), { range: this.peek().range }));
|
|
461
558
|
throw this.lastDiagnosticAsError();
|
|
462
559
|
}
|
|
463
|
-
const name = this.identifier();
|
|
560
|
+
const name = this.identifier(...lexer_1.AllowedLocalIdentifiers);
|
|
464
561
|
let typeToken;
|
|
465
562
|
let defaultValue;
|
|
466
563
|
let equalsToken;
|
|
@@ -474,17 +571,20 @@ class Parser {
|
|
|
474
571
|
if (this.check(lexer_1.TokenKind.As)) {
|
|
475
572
|
asToken = this.advance();
|
|
476
573
|
typeToken = this.typeToken();
|
|
477
|
-
if (!util_1.util.tokenToBscType(typeToken, this.options.mode === ParseMode.BrighterScript)) {
|
|
574
|
+
if (!util_1.util.tokenToBscType(typeToken, this.options.mode === ParseMode.BrighterScript, this.currentNamespaceName)) {
|
|
478
575
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.functionParameterTypeIsInvalid(name.text, typeToken.text)), { range: typeToken.range }));
|
|
479
576
|
throw this.lastDiagnosticAsError();
|
|
480
577
|
}
|
|
481
578
|
}
|
|
482
579
|
let type;
|
|
483
580
|
if (typeToken) {
|
|
484
|
-
type = util_1.util.tokenToBscType(typeToken);
|
|
581
|
+
type = util_1.util.tokenToBscType(typeToken, true, this.currentNamespaceName);
|
|
485
582
|
}
|
|
486
583
|
else if (defaultValue) {
|
|
487
584
|
type = getBscTypeFromExpression(defaultValue, this.currentFunctionExpression);
|
|
585
|
+
if ((0, reflection_1.isInvalidType)(type)) {
|
|
586
|
+
type = new DynamicType_1.DynamicType();
|
|
587
|
+
}
|
|
488
588
|
}
|
|
489
589
|
else {
|
|
490
590
|
type = new DynamicType_1.DynamicType();
|
|
@@ -492,7 +592,7 @@ class Parser {
|
|
|
492
592
|
return new Expression_1.FunctionParameterExpression(name, type, equalsToken, defaultValue, asToken, typeToken, this.currentNamespaceName);
|
|
493
593
|
}
|
|
494
594
|
assignment() {
|
|
495
|
-
let name = this.identifier();
|
|
595
|
+
let name = this.identifier(...this.allowedLocalIdentifiers);
|
|
496
596
|
//add diagnostic if name is a reserved word that cannot be used as an identifier
|
|
497
597
|
if (lexer_1.DisallowedLocalIdentifiersText.has(name.text.toLowerCase())) {
|
|
498
598
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.cannotUseReservedWordAsIdentifier(name.text)), { range: name.range }));
|
|
@@ -596,6 +696,16 @@ class Parser {
|
|
|
596
696
|
this.checkAnyNext(...lexer_1.AssignmentOperators)) {
|
|
597
697
|
return this.assignment();
|
|
598
698
|
}
|
|
699
|
+
//some BrighterScript keywords are allowed as a local identifiers, so we need to check for them AFTER the assignment check
|
|
700
|
+
if (this.check(lexer_1.TokenKind.Interface)) {
|
|
701
|
+
return this.interfaceDeclaration();
|
|
702
|
+
}
|
|
703
|
+
if (this.check(lexer_1.TokenKind.Class)) {
|
|
704
|
+
return this.classDeclaration();
|
|
705
|
+
}
|
|
706
|
+
if (this.check(lexer_1.TokenKind.Namespace)) {
|
|
707
|
+
return this.namespaceStatement();
|
|
708
|
+
}
|
|
599
709
|
// TODO: support multi-statements
|
|
600
710
|
return this.setStatement();
|
|
601
711
|
}
|
|
@@ -653,7 +763,7 @@ class Parser {
|
|
|
653
763
|
}
|
|
654
764
|
forEachStatement() {
|
|
655
765
|
let forEach = this.advance();
|
|
656
|
-
let name = this.identifier();
|
|
766
|
+
let name = this.identifier(...this.allowedLocalIdentifiers);
|
|
657
767
|
let maybeIn = this.peek();
|
|
658
768
|
if (this.check(lexer_1.TokenKind.Identifier) && maybeIn.text.toLowerCase() === 'in') {
|
|
659
769
|
this.advance();
|
|
@@ -674,7 +784,7 @@ class Parser {
|
|
|
674
784
|
throw this.lastDiagnosticAsError();
|
|
675
785
|
}
|
|
676
786
|
let endFor = this.advance();
|
|
677
|
-
//TODO infer type from `target`
|
|
787
|
+
//TODO TYPES infer type from `target`
|
|
678
788
|
const itemType = new DynamicType_1.DynamicType();
|
|
679
789
|
this.currentSymbolTable.addSymbol(name.text, name.range, itemType);
|
|
680
790
|
return new Statement_1.ForEachStatement(forEach, name, maybeIn, target, body, endFor);
|
|
@@ -741,7 +851,7 @@ class Parser {
|
|
|
741
851
|
expr = new Expression_1.VariableExpression(firstIdentifier, null);
|
|
742
852
|
//consume multiple dot identifiers (i.e. `Name.Space.Can.Have.Many.Parts`)
|
|
743
853
|
while (this.check(lexer_1.TokenKind.Dot)) {
|
|
744
|
-
let dot = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.
|
|
854
|
+
let dot = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.unexpectedToken(this.peek().text), lexer_1.TokenKind.Dot);
|
|
745
855
|
if (!dot) {
|
|
746
856
|
break;
|
|
747
857
|
}
|
|
@@ -762,7 +872,7 @@ class Parser {
|
|
|
762
872
|
flagUntil(...stopTokens) {
|
|
763
873
|
while (!this.checkAny(...stopTokens) && !this.isAtEnd()) {
|
|
764
874
|
let token = this.advance();
|
|
765
|
-
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.
|
|
875
|
+
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.unexpectedToken(token.text)), { range: token.range }));
|
|
766
876
|
}
|
|
767
877
|
}
|
|
768
878
|
/**
|
|
@@ -829,7 +939,7 @@ class Parser {
|
|
|
829
939
|
while (this.checkAny(lexer_1.TokenKind.Newline, lexer_1.TokenKind.Comment)) {
|
|
830
940
|
this.advance();
|
|
831
941
|
}
|
|
832
|
-
const colonToken = this.
|
|
942
|
+
const colonToken = this.tryConsumeToken(lexer_1.TokenKind.Colon);
|
|
833
943
|
//consume newlines
|
|
834
944
|
while (this.checkAny(lexer_1.TokenKind.Newline, lexer_1.TokenKind.Comment)) {
|
|
835
945
|
this.advance();
|
|
@@ -847,6 +957,12 @@ class Parser {
|
|
|
847
957
|
const alternate = this.expression();
|
|
848
958
|
return new Expression_1.NullCoalescingExpression(test, questionQuestionToken, alternate);
|
|
849
959
|
}
|
|
960
|
+
regexLiteralExpression() {
|
|
961
|
+
this.warnIfNotBrighterScriptMode('regular expression literal');
|
|
962
|
+
return new _1.RegexLiteralExpression({
|
|
963
|
+
regexLiteral: this.advance()
|
|
964
|
+
});
|
|
965
|
+
}
|
|
850
966
|
templateString(isTagged) {
|
|
851
967
|
this.warnIfNotBrighterScriptMode('template string');
|
|
852
968
|
//get the tag name
|
|
@@ -1047,7 +1163,7 @@ class Parser {
|
|
|
1047
1163
|
throw this.lastDiagnosticAsError();
|
|
1048
1164
|
}
|
|
1049
1165
|
}
|
|
1050
|
-
if (!elseBranch || !reflection_1.isIfStatement(elseBranch)) {
|
|
1166
|
+
if (!elseBranch || !(0, reflection_1.isIfStatement)(elseBranch)) {
|
|
1051
1167
|
//enforce newline at the end of the inline if statement
|
|
1052
1168
|
const peek = this.peek();
|
|
1053
1169
|
if (peek.kind !== lexer_1.TokenKind.Newline && peek.kind !== lexer_1.TokenKind.Comment && !this.isAtEnd()) {
|
|
@@ -1079,7 +1195,7 @@ class Parser {
|
|
|
1079
1195
|
this.ensureNewLineOrColon();
|
|
1080
1196
|
}
|
|
1081
1197
|
}
|
|
1082
|
-
if (!reflection_1.isIfStatement(elseBranch)) {
|
|
1198
|
+
if (!(0, reflection_1.isIfStatement)(elseBranch)) {
|
|
1083
1199
|
if (this.check(lexer_1.TokenKind.EndIf)) {
|
|
1084
1200
|
endIfToken = this.advance();
|
|
1085
1201
|
}
|
|
@@ -1128,7 +1244,7 @@ class Parser {
|
|
|
1128
1244
|
//ensure each statement of an inline block is single-line
|
|
1129
1245
|
ensureInline(statements) {
|
|
1130
1246
|
for (const stat of statements) {
|
|
1131
|
-
if (reflection_1.isIfStatement(stat) && !stat.isInline) {
|
|
1247
|
+
if ((0, reflection_1.isIfStatement)(stat) && !stat.isInline) {
|
|
1132
1248
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.expectedInlineIfStatement()), { range: stat.range }));
|
|
1133
1249
|
}
|
|
1134
1250
|
}
|
|
@@ -1143,6 +1259,7 @@ class Parser {
|
|
|
1143
1259
|
return undefined;
|
|
1144
1260
|
}
|
|
1145
1261
|
statements.push(statement);
|
|
1262
|
+
const startingRange = statement.range;
|
|
1146
1263
|
//look for colon statement separator
|
|
1147
1264
|
let foundColon = false;
|
|
1148
1265
|
while (this.match(lexer_1.TokenKind.Colon)) {
|
|
@@ -1161,10 +1278,10 @@ class Parser {
|
|
|
1161
1278
|
else {
|
|
1162
1279
|
//error: colon before next keyword
|
|
1163
1280
|
const colon = this.previous();
|
|
1164
|
-
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.
|
|
1281
|
+
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.unexpectedToken(colon.text)), { range: colon.range }));
|
|
1165
1282
|
}
|
|
1166
1283
|
}
|
|
1167
|
-
return new Statement_1.Block(statements,
|
|
1284
|
+
return new Statement_1.Block(statements, startingRange);
|
|
1168
1285
|
}
|
|
1169
1286
|
expressionStatement(expr) {
|
|
1170
1287
|
let expressionStart = this.peek();
|
|
@@ -1174,13 +1291,13 @@ class Parser {
|
|
|
1174
1291
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.consecutiveIncrementDecrementOperatorsAreNotAllowed()), { range: this.peek().range }));
|
|
1175
1292
|
throw this.lastDiagnosticAsError();
|
|
1176
1293
|
}
|
|
1177
|
-
else if (reflection_1.isCallExpression(expr)) {
|
|
1294
|
+
else if ((0, reflection_1.isCallExpression)(expr)) {
|
|
1178
1295
|
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.incrementDecrementOperatorsAreNotAllowedAsResultOfFunctionCall()), { range: expressionStart.range }));
|
|
1179
1296
|
throw this.lastDiagnosticAsError();
|
|
1180
1297
|
}
|
|
1181
1298
|
return new Statement_1.IncrementStatement(expr, operator);
|
|
1182
1299
|
}
|
|
1183
|
-
if (reflection_1.isCallExpression(expr) || reflection_1.isCallfuncExpression(expr)) {
|
|
1300
|
+
if ((0, reflection_1.isCallExpression)(expr) || (0, reflection_1.isCallfuncExpression)(expr)) {
|
|
1184
1301
|
return new Statement_1.ExpressionStatement(expr);
|
|
1185
1302
|
}
|
|
1186
1303
|
//at this point, it's probably an error. However, we recover a little more gracefully by creating an assignment
|
|
@@ -1195,20 +1312,22 @@ class Parser {
|
|
|
1195
1312
|
* priority as standalone function calls though, so we can parse them in the same way.
|
|
1196
1313
|
*/
|
|
1197
1314
|
let expr = this.call();
|
|
1198
|
-
if (this.checkAny(...lexer_1.AssignmentOperators) && !(reflection_1.isCallExpression(expr))) {
|
|
1315
|
+
if (this.checkAny(...lexer_1.AssignmentOperators) && !((0, reflection_1.isCallExpression)(expr))) {
|
|
1199
1316
|
let left = expr;
|
|
1200
1317
|
let operator = this.advance();
|
|
1201
1318
|
let right = this.expression();
|
|
1202
1319
|
// Create a dotted or indexed "set" based on the left-hand side's type
|
|
1203
|
-
if (reflection_1.isIndexedGetExpression(left)) {
|
|
1320
|
+
if ((0, reflection_1.isIndexedGetExpression)(left)) {
|
|
1204
1321
|
return new Statement_1.IndexedSetStatement(left.obj, left.index, operator.kind === lexer_1.TokenKind.Equal
|
|
1205
1322
|
? right
|
|
1206
1323
|
: new Expression_1.BinaryExpression(left, operator, right), left.openingSquare, left.closingSquare);
|
|
1207
1324
|
}
|
|
1208
|
-
else if (reflection_1.isDottedGetExpression(left)) {
|
|
1209
|
-
|
|
1325
|
+
else if ((0, reflection_1.isDottedGetExpression)(left)) {
|
|
1326
|
+
const dottedSetStmt = new Statement_1.DottedSetStatement(left.obj, left.name, operator.kind === lexer_1.TokenKind.Equal
|
|
1210
1327
|
? right
|
|
1211
1328
|
: new Expression_1.BinaryExpression(left, operator, right));
|
|
1329
|
+
this._references.dottedSetStatements.push(dottedSetStmt);
|
|
1330
|
+
return dottedSetStmt;
|
|
1212
1331
|
}
|
|
1213
1332
|
}
|
|
1214
1333
|
return this.expressionStatement(expr);
|
|
@@ -1232,11 +1351,11 @@ class Parser {
|
|
|
1232
1351
|
}
|
|
1233
1352
|
//print statements can be empty, so look for empty print conditions
|
|
1234
1353
|
if (!values.length) {
|
|
1235
|
-
let emptyStringLiteral = creators_1.createStringLiteral('');
|
|
1354
|
+
let emptyStringLiteral = (0, creators_1.createStringLiteral)('');
|
|
1236
1355
|
values.push(emptyStringLiteral);
|
|
1237
1356
|
}
|
|
1238
1357
|
let last = values[values.length - 1];
|
|
1239
|
-
if (lexer_1.isToken(last)) {
|
|
1358
|
+
if ((0, lexer_1.isToken)(last)) {
|
|
1240
1359
|
// TODO: error, expected value
|
|
1241
1360
|
}
|
|
1242
1361
|
return new Statement_1.PrintStatement({ print: printKeyword }, values);
|
|
@@ -1315,7 +1434,7 @@ class Parser {
|
|
|
1315
1434
|
let loopCurrent = this.current;
|
|
1316
1435
|
let dec = this.declaration();
|
|
1317
1436
|
if (dec) {
|
|
1318
|
-
if (!reflection_1.isAnnotationExpression(dec)) {
|
|
1437
|
+
if (!(0, reflection_1.isAnnotationExpression)(dec)) {
|
|
1319
1438
|
this.consumePendingAnnotations(dec);
|
|
1320
1439
|
statements.push(dec);
|
|
1321
1440
|
}
|
|
@@ -1468,7 +1587,7 @@ class Parser {
|
|
|
1468
1587
|
this.warnIfNotBrighterScriptMode(`using 'new' keyword to construct a class`);
|
|
1469
1588
|
let newToken = this.advance();
|
|
1470
1589
|
let nameExpr = this.getNamespacedVariableNameExpression();
|
|
1471
|
-
let leftParen = this.consume(DiagnosticMessages_1.DiagnosticMessages.
|
|
1590
|
+
let leftParen = this.consume(DiagnosticMessages_1.DiagnosticMessages.unexpectedToken(this.peek().text), lexer_1.TokenKind.LeftParen);
|
|
1472
1591
|
let call = this.finishCall(leftParen, nameExpr);
|
|
1473
1592
|
//pop the call from the callExpressions list because this is technically something else
|
|
1474
1593
|
this.callExpressions.pop();
|
|
@@ -1548,7 +1667,7 @@ class Parser {
|
|
|
1548
1667
|
}
|
|
1549
1668
|
while (this.match(lexer_1.TokenKind.Newline)) { }
|
|
1550
1669
|
const closingParen = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedRightParenAfterFunctionCallArguments(), lexer_1.TokenKind.RightParen);
|
|
1551
|
-
if (reflection_1.isVariableExpression(callee)) {
|
|
1670
|
+
if ((0, reflection_1.isVariableExpression)(callee)) {
|
|
1552
1671
|
callee.isCalled = true;
|
|
1553
1672
|
}
|
|
1554
1673
|
let expression = new Expression_1.CallExpression(callee, openingParen, closingParen, args, this.currentNamespaceName);
|
|
@@ -1560,7 +1679,7 @@ class Parser {
|
|
|
1560
1679
|
/**
|
|
1561
1680
|
* Tries to get the next token as a type
|
|
1562
1681
|
* Allows for built-in types (double, string, etc.) or namespaced custom types in Brighterscript mode
|
|
1563
|
-
* Will
|
|
1682
|
+
* Will return a token of whatever is next to be parsed (unless `advanceIfUnknown` is false, in which case undefined will be returned instead
|
|
1564
1683
|
*/
|
|
1565
1684
|
typeToken() {
|
|
1566
1685
|
let typeToken;
|
|
@@ -1572,7 +1691,7 @@ class Parser {
|
|
|
1572
1691
|
try {
|
|
1573
1692
|
// see if we can get a namespaced identifer
|
|
1574
1693
|
const qualifiedType = this.getNamespacedVariableNameExpression();
|
|
1575
|
-
typeToken = creators_1.createToken(lexer_1.TokenKind.Identifier, qualifiedType.getName(this.options.mode), qualifiedType.range);
|
|
1694
|
+
typeToken = (0, creators_1.createToken)(lexer_1.TokenKind.Identifier, qualifiedType.getName(this.options.mode), qualifiedType.range);
|
|
1576
1695
|
}
|
|
1577
1696
|
catch (_a) {
|
|
1578
1697
|
//could not get an identifier - just get whatever's next
|
|
@@ -1659,26 +1778,33 @@ class Parser {
|
|
|
1659
1778
|
while (this.match(lexer_1.TokenKind.Newline)) {
|
|
1660
1779
|
}
|
|
1661
1780
|
if (!this.match(lexer_1.TokenKind.RightCurlyBrace)) {
|
|
1781
|
+
let lastAAMember;
|
|
1662
1782
|
if (this.check(lexer_1.TokenKind.Comment)) {
|
|
1783
|
+
lastAAMember = null;
|
|
1663
1784
|
members.push(new Statement_1.CommentStatement([this.advance()]));
|
|
1664
1785
|
}
|
|
1665
1786
|
else {
|
|
1666
1787
|
let k = key();
|
|
1667
1788
|
let expr = this.expression();
|
|
1668
|
-
|
|
1789
|
+
lastAAMember = new Expression_1.AAMemberExpression(k.keyToken, k.colonToken, expr, getBscTypeFromExpression(expr, this.currentFunctionExpression));
|
|
1790
|
+
members.push(lastAAMember);
|
|
1669
1791
|
}
|
|
1670
1792
|
while (this.matchAny(lexer_1.TokenKind.Comma, lexer_1.TokenKind.Newline, lexer_1.TokenKind.Colon, lexer_1.TokenKind.Comment)) {
|
|
1793
|
+
// collect comma at end of expression
|
|
1794
|
+
if (lastAAMember && this.checkPrevious(lexer_1.TokenKind.Comma)) {
|
|
1795
|
+
lastAAMember.commaToken = this.previous();
|
|
1796
|
+
}
|
|
1671
1797
|
//check for comment at the end of the current line
|
|
1672
1798
|
if (this.check(lexer_1.TokenKind.Comment) || this.checkPrevious(lexer_1.TokenKind.Comment)) {
|
|
1673
1799
|
let token = this.checkPrevious(lexer_1.TokenKind.Comment) ? this.previous() : this.advance();
|
|
1674
1800
|
members.push(new Statement_1.CommentStatement([token]));
|
|
1675
1801
|
}
|
|
1676
1802
|
else {
|
|
1677
|
-
|
|
1678
|
-
}
|
|
1803
|
+
this.consumeStatementSeparators(true);
|
|
1679
1804
|
//check for a comment on its own line
|
|
1680
1805
|
if (this.check(lexer_1.TokenKind.Comment) || this.checkPrevious(lexer_1.TokenKind.Comment)) {
|
|
1681
1806
|
let token = this.checkPrevious(lexer_1.TokenKind.Comment) ? this.previous() : this.advance();
|
|
1807
|
+
lastAAMember = null;
|
|
1682
1808
|
members.push(new Statement_1.CommentStatement([token]));
|
|
1683
1809
|
continue;
|
|
1684
1810
|
}
|
|
@@ -1687,13 +1813,15 @@ class Parser {
|
|
|
1687
1813
|
}
|
|
1688
1814
|
let k = key();
|
|
1689
1815
|
let expr = this.expression();
|
|
1690
|
-
|
|
1816
|
+
lastAAMember = new Expression_1.AAMemberExpression(k.keyToken, k.colonToken, expr, getBscTypeFromExpression(expr, this.currentFunctionExpression));
|
|
1817
|
+
members.push(lastAAMember);
|
|
1691
1818
|
}
|
|
1692
1819
|
}
|
|
1693
1820
|
this.consume(DiagnosticMessages_1.DiagnosticMessages.unmatchedLeftCurlyAfterAALiteral(), lexer_1.TokenKind.RightCurlyBrace);
|
|
1694
1821
|
}
|
|
1695
1822
|
let closingBrace = this.previous();
|
|
1696
|
-
const aaExpr = new Expression_1.AALiteralExpression(members, openingBrace, closingBrace);
|
|
1823
|
+
const aaExpr = new Expression_1.AALiteralExpression(members, openingBrace, closingBrace, this.currentFunctionExpression);
|
|
1824
|
+
this._references.aaLiterals.push(aaExpr);
|
|
1697
1825
|
this.addPropertyHints(aaExpr);
|
|
1698
1826
|
return aaExpr;
|
|
1699
1827
|
case this.matchAny(lexer_1.TokenKind.Pos, lexer_1.TokenKind.Tab):
|
|
@@ -1703,6 +1831,8 @@ class Parser {
|
|
|
1703
1831
|
return new Expression_1.VariableExpression(token, this.currentNamespaceName);
|
|
1704
1832
|
case this.checkAny(lexer_1.TokenKind.Function, lexer_1.TokenKind.Sub):
|
|
1705
1833
|
return this.anonymousFunction();
|
|
1834
|
+
case this.check(lexer_1.TokenKind.RegexLiteral):
|
|
1835
|
+
return this.regexLiteralExpression();
|
|
1706
1836
|
case this.check(lexer_1.TokenKind.Comment):
|
|
1707
1837
|
return new Statement_1.CommentStatement([this.advance()]);
|
|
1708
1838
|
default:
|
|
@@ -1712,7 +1842,7 @@ class Parser {
|
|
|
1712
1842
|
//something went wrong...throw an error so the upstream processor can scrap this line and move on
|
|
1713
1843
|
}
|
|
1714
1844
|
else {
|
|
1715
|
-
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.
|
|
1845
|
+
this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.unexpectedToken(this.peek().text)), { range: this.peek().range }));
|
|
1716
1846
|
throw this.lastDiagnosticAsError();
|
|
1717
1847
|
}
|
|
1718
1848
|
}
|
|
@@ -1754,6 +1884,9 @@ class Parser {
|
|
|
1754
1884
|
throw error;
|
|
1755
1885
|
}
|
|
1756
1886
|
}
|
|
1887
|
+
consumeToken(tokenKind) {
|
|
1888
|
+
return this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedToken(tokenKind), tokenKind);
|
|
1889
|
+
}
|
|
1757
1890
|
/**
|
|
1758
1891
|
* Consume, or add a message if not found. But then continue and return undefined
|
|
1759
1892
|
*/
|
|
@@ -1765,6 +1898,9 @@ class Parser {
|
|
|
1765
1898
|
}
|
|
1766
1899
|
this.diagnostics.push(Object.assign(Object.assign({}, diagnostic), { range: this.peek().range }));
|
|
1767
1900
|
}
|
|
1901
|
+
tryConsumeToken(tokenKind) {
|
|
1902
|
+
return this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.expectedToken(tokenKind), tokenKind);
|
|
1903
|
+
}
|
|
1768
1904
|
consumeStatementSeparators(optional = false) {
|
|
1769
1905
|
//a comment or EOF mark the end of the statement
|
|
1770
1906
|
if (this.isAtEnd() || this.check(lexer_1.TokenKind.Comment)) {
|
|
@@ -1861,6 +1997,235 @@ class Parser {
|
|
|
1861
1997
|
this.advance();
|
|
1862
1998
|
}
|
|
1863
1999
|
}
|
|
2000
|
+
/**
|
|
2001
|
+
* Get the token at the specified position
|
|
2002
|
+
* @param position
|
|
2003
|
+
*/
|
|
2004
|
+
getTokenAt(position) {
|
|
2005
|
+
for (let token of this.tokens) {
|
|
2006
|
+
if (util_1.util.rangeContains(token.range, position)) {
|
|
2007
|
+
return token;
|
|
2008
|
+
}
|
|
2009
|
+
}
|
|
2010
|
+
}
|
|
2011
|
+
/**
|
|
2012
|
+
* Get the token closest to the position. if no token is found, the previous token is returned
|
|
2013
|
+
* @param position
|
|
2014
|
+
* @param tokens
|
|
2015
|
+
*/
|
|
2016
|
+
getClosestToken(position) {
|
|
2017
|
+
let tokens = this.tokens;
|
|
2018
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
2019
|
+
let token = tokens[i];
|
|
2020
|
+
if (util_1.util.rangeContains(token.range, position)) {
|
|
2021
|
+
return token;
|
|
2022
|
+
}
|
|
2023
|
+
//if the position less than this token range, then this position touches no token,
|
|
2024
|
+
if (util_1.util.positionIsGreaterThanRange(position, token.range) === false) {
|
|
2025
|
+
let t = tokens[i - 1];
|
|
2026
|
+
//return the token or the first token
|
|
2027
|
+
return t ? t : tokens[0];
|
|
2028
|
+
}
|
|
2029
|
+
}
|
|
2030
|
+
//return the last token
|
|
2031
|
+
return tokens[tokens.length - 1];
|
|
2032
|
+
}
|
|
2033
|
+
isPositionNextToTokenKind(position, tokenKind) {
|
|
2034
|
+
const closestToken = this.getClosestToken(position);
|
|
2035
|
+
const previousToken = this.getPreviousToken(closestToken);
|
|
2036
|
+
const previousTokenKind = previousToken === null || previousToken === void 0 ? void 0 : previousToken.kind;
|
|
2037
|
+
//next to matched token
|
|
2038
|
+
if (!closestToken || closestToken.kind === lexer_1.TokenKind.Eof) {
|
|
2039
|
+
return false;
|
|
2040
|
+
}
|
|
2041
|
+
else if (closestToken.kind === tokenKind) {
|
|
2042
|
+
return true;
|
|
2043
|
+
}
|
|
2044
|
+
else if (closestToken.kind === lexer_1.TokenKind.Newline || previousTokenKind === lexer_1.TokenKind.Newline) {
|
|
2045
|
+
return false;
|
|
2046
|
+
//next to an identifier, which is next to token kind
|
|
2047
|
+
}
|
|
2048
|
+
else if (closestToken.kind === lexer_1.TokenKind.Identifier && previousTokenKind === tokenKind) {
|
|
2049
|
+
return true;
|
|
2050
|
+
}
|
|
2051
|
+
else {
|
|
2052
|
+
return false;
|
|
2053
|
+
}
|
|
2054
|
+
}
|
|
2055
|
+
getTokenBefore(currentToken, tokenKind) {
|
|
2056
|
+
const index = this.tokens.indexOf(currentToken);
|
|
2057
|
+
for (let i = index - 1; i >= 0; i--) {
|
|
2058
|
+
currentToken = this.tokens[i];
|
|
2059
|
+
if (currentToken.kind === lexer_1.TokenKind.Newline) {
|
|
2060
|
+
break;
|
|
2061
|
+
}
|
|
2062
|
+
else if (currentToken.kind === tokenKind) {
|
|
2063
|
+
return currentToken;
|
|
2064
|
+
}
|
|
2065
|
+
}
|
|
2066
|
+
return undefined;
|
|
2067
|
+
}
|
|
2068
|
+
tokenFollows(currentToken, tokenKind) {
|
|
2069
|
+
const index = this.tokens.indexOf(currentToken);
|
|
2070
|
+
if (index > 0) {
|
|
2071
|
+
return this.tokens[index - 1].kind === tokenKind;
|
|
2072
|
+
}
|
|
2073
|
+
return false;
|
|
2074
|
+
}
|
|
2075
|
+
getTokensUntil(currentToken, tokenKind, direction = -1) {
|
|
2076
|
+
let tokens = [];
|
|
2077
|
+
for (let i = this.tokens.indexOf(currentToken); direction === -1 ? i >= 0 : i === this.tokens.length; i += direction) {
|
|
2078
|
+
currentToken = this.tokens[i];
|
|
2079
|
+
if (currentToken.kind === lexer_1.TokenKind.Newline || currentToken.kind === tokenKind) {
|
|
2080
|
+
break;
|
|
2081
|
+
}
|
|
2082
|
+
tokens.push(currentToken);
|
|
2083
|
+
}
|
|
2084
|
+
return tokens;
|
|
2085
|
+
}
|
|
2086
|
+
getPreviousToken(token) {
|
|
2087
|
+
let idx = this.tokens.indexOf(token);
|
|
2088
|
+
return this.tokens[idx - 1];
|
|
2089
|
+
}
|
|
2090
|
+
getPreviousTokenFromIndex(idx) {
|
|
2091
|
+
return { token: this.tokens[idx - 1], index: idx - 1 };
|
|
2092
|
+
}
|
|
2093
|
+
getPreviousTokenIgnoreNests(currentTokenIndex, leftBracketType, rightBracketType) {
|
|
2094
|
+
let currentToken = this.tokens[currentTokenIndex];
|
|
2095
|
+
let previousTokenResult;
|
|
2096
|
+
function isRightBracket(token) {
|
|
2097
|
+
return (token === null || token === void 0 ? void 0 : token.kind) === rightBracketType;
|
|
2098
|
+
}
|
|
2099
|
+
function isLeftBracket(token) {
|
|
2100
|
+
return (token === null || token === void 0 ? void 0 : token.kind) === leftBracketType;
|
|
2101
|
+
}
|
|
2102
|
+
let lastTokenHadLeadingWhitespace = (currentToken === null || currentToken === void 0 ? void 0 : currentToken.leadingWhitespace.length) > 0;
|
|
2103
|
+
let lastTokenWasLeftBracket = false;
|
|
2104
|
+
let bracketNestCount = 0;
|
|
2105
|
+
let hasBrackets = false;
|
|
2106
|
+
// check for nested function call
|
|
2107
|
+
if (isRightBracket(currentToken)) {
|
|
2108
|
+
bracketNestCount++;
|
|
2109
|
+
hasBrackets = true;
|
|
2110
|
+
}
|
|
2111
|
+
while (currentToken && bracketNestCount > 0) {
|
|
2112
|
+
previousTokenResult = this.getPreviousTokenFromIndex(currentTokenIndex);
|
|
2113
|
+
currentToken = previousTokenResult === null || previousTokenResult === void 0 ? void 0 : previousTokenResult.token;
|
|
2114
|
+
currentTokenIndex = previousTokenResult === null || previousTokenResult === void 0 ? void 0 : previousTokenResult.index;
|
|
2115
|
+
lastTokenWasLeftBracket = false;
|
|
2116
|
+
if (isRightBracket(currentToken)) {
|
|
2117
|
+
bracketNestCount++;
|
|
2118
|
+
}
|
|
2119
|
+
while (isLeftBracket(currentToken)) {
|
|
2120
|
+
bracketNestCount--;
|
|
2121
|
+
lastTokenWasLeftBracket = true;
|
|
2122
|
+
lastTokenHadLeadingWhitespace = (currentToken === null || currentToken === void 0 ? void 0 : currentToken.leadingWhitespace.length) > 0;
|
|
2123
|
+
previousTokenResult = this.getPreviousTokenFromIndex(currentTokenIndex);
|
|
2124
|
+
currentToken = previousTokenResult === null || previousTokenResult === void 0 ? void 0 : previousTokenResult.token;
|
|
2125
|
+
currentTokenIndex = previousTokenResult === null || previousTokenResult === void 0 ? void 0 : previousTokenResult.index;
|
|
2126
|
+
}
|
|
2127
|
+
}
|
|
2128
|
+
// We will not be able to decipher the token type if it was in brackets
|
|
2129
|
+
// e.g (someVar+otherVar).toStr() -- we don't bother trying to decipher what "(someVar+otherVar)" is
|
|
2130
|
+
let isUnknown = (lastTokenWasLeftBracket && (lastTokenHadLeadingWhitespace || !this.isAcceptableChainToken(currentToken)));
|
|
2131
|
+
const tokenWithIndex = { token: currentToken, index: currentTokenIndex, tokenTypeIsNotKnowable: isUnknown, hasBrackets: hasBrackets };
|
|
2132
|
+
return tokenWithIndex;
|
|
2133
|
+
}
|
|
2134
|
+
/**
|
|
2135
|
+
* Finds the previous token in a chain (e.g. 'm.obj.func(someFunc()).value'), skipping over any arguments of function calls
|
|
2136
|
+
* If this function was called with the token at 'value' above, the previous identifier in the chain is 'func'
|
|
2137
|
+
* @param currentTokenIndex token index to start from
|
|
2138
|
+
* @param allowCurrent can the current token be the token that's the identifier?
|
|
2139
|
+
* @returns the previous identifer
|
|
2140
|
+
*/
|
|
2141
|
+
getPreviousTokenInChain(currentTokenIndex, allowCurrent = false) {
|
|
2142
|
+
let currentToken = this.tokens[currentTokenIndex];
|
|
2143
|
+
let previousTokenResult;
|
|
2144
|
+
let usage = TokenUsage.Direct;
|
|
2145
|
+
if (!allowCurrent) {
|
|
2146
|
+
previousTokenResult = this.getPreviousTokenFromIndex(currentTokenIndex);
|
|
2147
|
+
currentToken = previousTokenResult === null || previousTokenResult === void 0 ? void 0 : previousTokenResult.token;
|
|
2148
|
+
currentTokenIndex = previousTokenResult === null || previousTokenResult === void 0 ? void 0 : previousTokenResult.index;
|
|
2149
|
+
}
|
|
2150
|
+
if ((currentToken === null || currentToken === void 0 ? void 0 : currentToken.kind) === lexer_1.TokenKind.Dot) {
|
|
2151
|
+
previousTokenResult = this.getPreviousTokenFromIndex(currentTokenIndex);
|
|
2152
|
+
currentToken = previousTokenResult.token;
|
|
2153
|
+
currentTokenIndex = previousTokenResult.index;
|
|
2154
|
+
}
|
|
2155
|
+
previousTokenResult = this.getPreviousTokenIgnoreNests(currentTokenIndex, lexer_1.TokenKind.LeftParen, lexer_1.TokenKind.RightParen);
|
|
2156
|
+
currentToken = previousTokenResult === null || previousTokenResult === void 0 ? void 0 : previousTokenResult.token;
|
|
2157
|
+
currentTokenIndex = previousTokenResult === null || previousTokenResult === void 0 ? void 0 : previousTokenResult.index;
|
|
2158
|
+
if (previousTokenResult.hasBrackets) {
|
|
2159
|
+
usage = TokenUsage.Call;
|
|
2160
|
+
}
|
|
2161
|
+
let tokenTypeIsNotKnowable = previousTokenResult === null || previousTokenResult === void 0 ? void 0 : previousTokenResult.tokenTypeIsNotKnowable;
|
|
2162
|
+
if (currentTokenIndex) {
|
|
2163
|
+
previousTokenResult = this.getPreviousTokenIgnoreNests(currentTokenIndex, lexer_1.TokenKind.LeftSquareBracket, lexer_1.TokenKind.RightSquareBracket);
|
|
2164
|
+
currentToken = previousTokenResult === null || previousTokenResult === void 0 ? void 0 : previousTokenResult.token;
|
|
2165
|
+
currentTokenIndex = previousTokenResult === null || previousTokenResult === void 0 ? void 0 : previousTokenResult.index;
|
|
2166
|
+
if (previousTokenResult.hasBrackets) {
|
|
2167
|
+
usage = TokenUsage.ArrayReference;
|
|
2168
|
+
}
|
|
2169
|
+
}
|
|
2170
|
+
tokenTypeIsNotKnowable = tokenTypeIsNotKnowable || (previousTokenResult === null || previousTokenResult === void 0 ? void 0 : previousTokenResult.tokenTypeIsNotKnowable);
|
|
2171
|
+
if (tokenTypeIsNotKnowable || this.isAcceptableChainToken(currentToken)) {
|
|
2172
|
+
// either we have a valid chain token, or we can't know what the token type is
|
|
2173
|
+
return { token: currentToken, index: currentTokenIndex, tokenTypeIsNotKnowable: tokenTypeIsNotKnowable, usage: usage };
|
|
2174
|
+
}
|
|
2175
|
+
return undefined;
|
|
2176
|
+
}
|
|
2177
|
+
isAcceptableChainToken(currentToken, lastTokenHasWhitespace = false) {
|
|
2178
|
+
if (!currentToken || lastTokenHasWhitespace) {
|
|
2179
|
+
return false;
|
|
2180
|
+
}
|
|
2181
|
+
if (currentToken.kind === lexer_1.TokenKind.Identifier) {
|
|
2182
|
+
return true;
|
|
2183
|
+
}
|
|
2184
|
+
if (currentToken.leadingWhitespace.length === 0) {
|
|
2185
|
+
// start of the chain
|
|
2186
|
+
return lexer_1.AllowedLocalIdentifiers.includes(currentToken.kind);
|
|
2187
|
+
}
|
|
2188
|
+
// not the start of the chain
|
|
2189
|
+
return lexer_1.AllowedProperties.includes(currentToken.kind);
|
|
2190
|
+
}
|
|
2191
|
+
/**
|
|
2192
|
+
* Builds up a chain of tokens, starting with the first in the chain, and ending with currentToken
|
|
2193
|
+
* e.g. m.prop.method().field (with 'field' as currentToken) -> ["m", "prop", "method", "field"], with each element as a token
|
|
2194
|
+
* @param currentToken the token that is the end of the chain
|
|
2195
|
+
* @returns array of tokens
|
|
2196
|
+
*/
|
|
2197
|
+
getTokenChain(currentToken) {
|
|
2198
|
+
const tokenChain = [];
|
|
2199
|
+
let currentTokenIndex = this.tokens.indexOf(currentToken);
|
|
2200
|
+
let previousTokenResult;
|
|
2201
|
+
let lastTokenHasWhitespace = false;
|
|
2202
|
+
let includesUnknown = false;
|
|
2203
|
+
previousTokenResult = this.getPreviousTokenInChain(currentTokenIndex, true);
|
|
2204
|
+
currentToken = previousTokenResult === null || previousTokenResult === void 0 ? void 0 : previousTokenResult.token;
|
|
2205
|
+
currentTokenIndex = previousTokenResult === null || previousTokenResult === void 0 ? void 0 : previousTokenResult.index;
|
|
2206
|
+
if (this.isAcceptableChainToken(currentToken)) {
|
|
2207
|
+
tokenChain.push(previousTokenResult);
|
|
2208
|
+
lastTokenHasWhitespace = (currentToken === null || currentToken === void 0 ? void 0 : currentToken.leadingWhitespace.length) > 0;
|
|
2209
|
+
}
|
|
2210
|
+
if (!lastTokenHasWhitespace) {
|
|
2211
|
+
previousTokenResult = this.getPreviousTokenInChain(currentTokenIndex);
|
|
2212
|
+
currentToken = previousTokenResult === null || previousTokenResult === void 0 ? void 0 : previousTokenResult.token;
|
|
2213
|
+
currentTokenIndex = previousTokenResult === null || previousTokenResult === void 0 ? void 0 : previousTokenResult.index;
|
|
2214
|
+
includesUnknown = !!(previousTokenResult === null || previousTokenResult === void 0 ? void 0 : previousTokenResult.tokenTypeIsNotKnowable);
|
|
2215
|
+
while (!includesUnknown && this.isAcceptableChainToken(currentToken, lastTokenHasWhitespace)) {
|
|
2216
|
+
tokenChain.push(previousTokenResult);
|
|
2217
|
+
lastTokenHasWhitespace = (currentToken === null || currentToken === void 0 ? void 0 : currentToken.leadingWhitespace.length) > 0;
|
|
2218
|
+
if (!lastTokenHasWhitespace) {
|
|
2219
|
+
previousTokenResult = this.getPreviousTokenInChain(currentTokenIndex);
|
|
2220
|
+
currentToken = previousTokenResult === null || previousTokenResult === void 0 ? void 0 : previousTokenResult.token;
|
|
2221
|
+
currentTokenIndex = previousTokenResult === null || previousTokenResult === void 0 ? void 0 : previousTokenResult.index;
|
|
2222
|
+
includesUnknown = includesUnknown || (previousTokenResult === null || previousTokenResult === void 0 ? void 0 : previousTokenResult.tokenTypeIsNotKnowable);
|
|
2223
|
+
}
|
|
2224
|
+
}
|
|
2225
|
+
}
|
|
2226
|
+
tokenChain.reverse();
|
|
2227
|
+
return { chain: tokenChain, includesUnknowableTokenType: !!includesUnknown };
|
|
2228
|
+
}
|
|
1864
2229
|
/**
|
|
1865
2230
|
* References are found during the initial parse.
|
|
1866
2231
|
* However, sometimes plugins can modify the AST, requiring a full walk to re-compute all references.
|
|
@@ -1869,7 +2234,7 @@ class Parser {
|
|
|
1869
2234
|
findReferences() {
|
|
1870
2235
|
this._references = new References();
|
|
1871
2236
|
//gather up all the top-level statements
|
|
1872
|
-
this.ast.walk(visitors_1.createVisitor({
|
|
2237
|
+
this.ast.walk((0, visitors_1.createVisitor)({
|
|
1873
2238
|
ClassStatement: s => {
|
|
1874
2239
|
this._references.classStatements.push(s);
|
|
1875
2240
|
},
|
|
@@ -1891,12 +2256,12 @@ class Parser {
|
|
|
1891
2256
|
walkMode: visitors_1.WalkMode.visitStatements
|
|
1892
2257
|
});
|
|
1893
2258
|
let func;
|
|
1894
|
-
let visitor = visitors_1.createVisitor({
|
|
2259
|
+
let visitor = (0, visitors_1.createVisitor)({
|
|
1895
2260
|
AssignmentStatement: s => {
|
|
1896
2261
|
this._references.assignmentStatements.push(s);
|
|
1897
2262
|
},
|
|
1898
2263
|
FunctionExpression: (expression, parent) => {
|
|
1899
|
-
if (!reflection_1.isClassMethodStatement(parent)) {
|
|
2264
|
+
if (!(0, reflection_1.isClassMethodStatement)(parent)) {
|
|
1900
2265
|
this._references.functionExpressions.push(expression);
|
|
1901
2266
|
}
|
|
1902
2267
|
},
|
|
@@ -1922,6 +2287,18 @@ class Parser {
|
|
|
1922
2287
|
});
|
|
1923
2288
|
}
|
|
1924
2289
|
}
|
|
2290
|
+
getContainingClass(currentToken) {
|
|
2291
|
+
return this.references.classStatements.find((cs) => util_1.util.rangeContains(cs.range, currentToken.range.start));
|
|
2292
|
+
}
|
|
2293
|
+
getContainingAA(currentToken) {
|
|
2294
|
+
return this.references.aaLiterals.find((aa) => util_1.util.rangeContains(aa.range, currentToken.range.start));
|
|
2295
|
+
}
|
|
2296
|
+
getContainingNamespace(currentToken) {
|
|
2297
|
+
return this.references.namespaceStatements.find((cs) => util_1.util.rangeContains(cs.range, currentToken.range.start));
|
|
2298
|
+
}
|
|
2299
|
+
getContainingFunctionExpression(currentToken) {
|
|
2300
|
+
return this.references.functionExpressions.find((fe) => util_1.util.rangeContains(fe.range, currentToken.range.start));
|
|
2301
|
+
}
|
|
1925
2302
|
dispose() {
|
|
1926
2303
|
}
|
|
1927
2304
|
}
|
|
@@ -1935,8 +2312,11 @@ class References {
|
|
|
1935
2312
|
constructor() {
|
|
1936
2313
|
this.assignmentStatements = [];
|
|
1937
2314
|
this.classStatements = [];
|
|
2315
|
+
this.dottedSetStatements = [];
|
|
2316
|
+
this.aaLiterals = [];
|
|
1938
2317
|
this.functionExpressions = [];
|
|
1939
2318
|
this.functionStatements = [];
|
|
2319
|
+
this.interfaceStatements = [];
|
|
1940
2320
|
this.importStatements = [];
|
|
1941
2321
|
this.libraryStatements = [];
|
|
1942
2322
|
this.namespaceStatements = [];
|
|
@@ -1964,8 +2344,23 @@ class References {
|
|
|
1964
2344
|
}
|
|
1965
2345
|
return this._functionStatementLookup;
|
|
1966
2346
|
}
|
|
2347
|
+
get interfaceStatementLookup() {
|
|
2348
|
+
if (!this._interfaceStatementLookup) {
|
|
2349
|
+
this._interfaceStatementLookup = new Map();
|
|
2350
|
+
for (const stmt of this.interfaceStatements) {
|
|
2351
|
+
this._interfaceStatementLookup.set(stmt.fullName.toLowerCase(), stmt);
|
|
2352
|
+
}
|
|
2353
|
+
}
|
|
2354
|
+
return this._interfaceStatementLookup;
|
|
2355
|
+
}
|
|
1967
2356
|
}
|
|
1968
2357
|
exports.References = References;
|
|
2358
|
+
var TokenUsage;
|
|
2359
|
+
(function (TokenUsage) {
|
|
2360
|
+
TokenUsage[TokenUsage["Direct"] = 1] = "Direct";
|
|
2361
|
+
TokenUsage[TokenUsage["Call"] = 2] = "Call";
|
|
2362
|
+
TokenUsage[TokenUsage["ArrayReference"] = 3] = "ArrayReference";
|
|
2363
|
+
})(TokenUsage = exports.TokenUsage || (exports.TokenUsage = {}));
|
|
1969
2364
|
class CancelStatementError extends Error {
|
|
1970
2365
|
constructor() {
|
|
1971
2366
|
super('CancelStatement');
|
|
@@ -1980,32 +2375,34 @@ class CancelStatementError extends Error {
|
|
|
1980
2375
|
*/
|
|
1981
2376
|
function getBscTypeFromExpression(expression, functionExpression) {
|
|
1982
2377
|
try {
|
|
1983
|
-
|
|
1984
|
-
if (reflection_1.isFunctionExpression(expression)) {
|
|
2378
|
+
if ((0, reflection_1.isFunctionExpression)(expression)) {
|
|
1985
2379
|
return expression.getFunctionType();
|
|
1986
2380
|
//literal
|
|
1987
2381
|
}
|
|
1988
|
-
else if (reflection_1.isLiteralExpression(expression)) {
|
|
2382
|
+
else if ((0, reflection_1.isLiteralExpression)(expression)) {
|
|
1989
2383
|
return expression.type;
|
|
1990
2384
|
//Associative array literal
|
|
1991
2385
|
}
|
|
1992
|
-
else if (reflection_1.isAALiteralExpression(expression)) {
|
|
1993
|
-
return new ObjectType_1.ObjectType();
|
|
2386
|
+
else if ((0, reflection_1.isAALiteralExpression)(expression)) {
|
|
2387
|
+
return new ObjectType_1.ObjectType(expression.memberTable);
|
|
1994
2388
|
//Array literal
|
|
1995
2389
|
}
|
|
1996
|
-
else if (reflection_1.isArrayLiteralExpression(expression)) {
|
|
2390
|
+
else if ((0, reflection_1.isArrayLiteralExpression)(expression)) {
|
|
1997
2391
|
return new ArrayType_1.ArrayType();
|
|
1998
2392
|
//function call
|
|
1999
2393
|
}
|
|
2000
|
-
else if (reflection_1.isNewExpression(expression)) {
|
|
2001
|
-
return new
|
|
2394
|
+
else if ((0, reflection_1.isNewExpression)(expression)) {
|
|
2395
|
+
return (0, helpers_1.getTypeFromNewExpression)(expression, functionExpression); // new CustomType(expression.className.getName(ParseMode.BrighterScript));
|
|
2002
2396
|
//Function call
|
|
2003
2397
|
}
|
|
2004
|
-
else if (reflection_1.isCallExpression(expression)) {
|
|
2005
|
-
return getTypeFromCallExpression(expression, functionExpression);
|
|
2398
|
+
else if ((0, reflection_1.isCallExpression)(expression)) {
|
|
2399
|
+
return (0, helpers_1.getTypeFromCallExpression)(expression, functionExpression);
|
|
2400
|
+
}
|
|
2401
|
+
else if ((0, reflection_1.isVariableExpression)(expression)) {
|
|
2402
|
+
return (0, helpers_1.getTypeFromVariableExpression)(expression, functionExpression);
|
|
2006
2403
|
}
|
|
2007
|
-
else if (reflection_1.
|
|
2008
|
-
return
|
|
2404
|
+
else if ((0, reflection_1.isDottedGetExpression)(expression)) {
|
|
2405
|
+
return (0, helpers_1.getTypeFromDottedGetExpression)(expression, functionExpression);
|
|
2009
2406
|
}
|
|
2010
2407
|
}
|
|
2011
2408
|
catch (e) {
|
|
@@ -2015,56 +2412,4 @@ function getBscTypeFromExpression(expression, functionExpression) {
|
|
|
2015
2412
|
return new DynamicType_1.DynamicType();
|
|
2016
2413
|
}
|
|
2017
2414
|
exports.getBscTypeFromExpression = getBscTypeFromExpression;
|
|
2018
|
-
/**
|
|
2019
|
-
* Gets the return type of a function, taking into account that the function may not have been declared yet
|
|
2020
|
-
* If the callee already exists in symbol table, use that return type
|
|
2021
|
-
* otherwise, make a lazy type which will not compute its type until the file is done parsing
|
|
2022
|
-
*
|
|
2023
|
-
* @param call the Expression to process
|
|
2024
|
-
* @param functionExpression the wrapping function expression
|
|
2025
|
-
* @return the best guess type of that expression
|
|
2026
|
-
*/
|
|
2027
|
-
function getTypeFromCallExpression(call, functionExpression) {
|
|
2028
|
-
var _a;
|
|
2029
|
-
let calleeName = (_a = call.callee.name.text) === null || _a === void 0 ? void 0 : _a.toLowerCase();
|
|
2030
|
-
if (calleeName) {
|
|
2031
|
-
// i
|
|
2032
|
-
const currentKnownType = functionExpression.symbolTable.getSymbolType(calleeName);
|
|
2033
|
-
if (reflection_1.isFunctionType(currentKnownType)) {
|
|
2034
|
-
return currentKnownType.returnType;
|
|
2035
|
-
}
|
|
2036
|
-
if (!reflection_1.isUninitializedType(currentKnownType)) {
|
|
2037
|
-
// this will probably only happen if a functionName has been assigned to something else previously?
|
|
2038
|
-
return currentKnownType;
|
|
2039
|
-
}
|
|
2040
|
-
return new LazyType_1.LazyType(() => {
|
|
2041
|
-
const futureType = functionExpression.symbolTable.getSymbolType(calleeName);
|
|
2042
|
-
if (reflection_1.isFunctionType(futureType)) {
|
|
2043
|
-
return futureType.returnType;
|
|
2044
|
-
}
|
|
2045
|
-
return futureType;
|
|
2046
|
-
});
|
|
2047
|
-
}
|
|
2048
|
-
}
|
|
2049
|
-
exports.getTypeFromCallExpression = getTypeFromCallExpression;
|
|
2050
|
-
/**
|
|
2051
|
-
* Gets the type of a variable
|
|
2052
|
-
* if it already exists in symbol table, use that type
|
|
2053
|
-
* otherwise defer the type until first read, which will allow us to derive types from variables defined after this one (like from a loop perhaps)
|
|
2054
|
-
*
|
|
2055
|
-
* @param variable the Expression to process
|
|
2056
|
-
* @param functionExpression the wrapping function expression
|
|
2057
|
-
* @return the best guess type of that expression
|
|
2058
|
-
*/
|
|
2059
|
-
function getTypeFromVariableExpression(variable, functionExpression) {
|
|
2060
|
-
let variableName = variable.name.text.toLowerCase();
|
|
2061
|
-
const currentKnownType = functionExpression.symbolTable.getSymbolType(variableName);
|
|
2062
|
-
if (!reflection_1.isUninitializedType(currentKnownType)) {
|
|
2063
|
-
return currentKnownType;
|
|
2064
|
-
}
|
|
2065
|
-
return new LazyType_1.LazyType(() => {
|
|
2066
|
-
return functionExpression.symbolTable.getSymbolType(variableName);
|
|
2067
|
-
});
|
|
2068
|
-
}
|
|
2069
|
-
exports.getTypeFromVariableExpression = getTypeFromVariableExpression;
|
|
2070
2415
|
//# sourceMappingURL=Parser.js.map
|