brighterscript 1.0.0-alpha.22 → 1.0.0-alpha.24

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.
Files changed (132) hide show
  1. package/CHANGELOG.md +140 -0
  2. package/dist/DiagnosticCollection.d.ts +3 -1
  3. package/dist/DiagnosticCollection.js +3 -5
  4. package/dist/DiagnosticCollection.js.map +1 -1
  5. package/dist/DiagnosticMessages.d.ts +24 -3
  6. package/dist/DiagnosticMessages.js +28 -7
  7. package/dist/DiagnosticMessages.js.map +1 -1
  8. package/dist/LanguageServer.d.ts +2 -1
  9. package/dist/LanguageServer.js +96 -31
  10. package/dist/LanguageServer.js.map +1 -1
  11. package/dist/Program.d.ts +14 -8
  12. package/dist/Program.js +125 -71
  13. package/dist/Program.js.map +1 -1
  14. package/dist/ProgramBuilder.js +2 -1
  15. package/dist/ProgramBuilder.js.map +1 -1
  16. package/dist/Scope.d.ts +23 -15
  17. package/dist/Scope.js +124 -122
  18. package/dist/Scope.js.map +1 -1
  19. package/dist/SymbolTable.d.ts +17 -6
  20. package/dist/SymbolTable.js +38 -9
  21. package/dist/SymbolTable.js.map +1 -1
  22. package/dist/XmlScope.js +3 -2
  23. package/dist/XmlScope.js.map +1 -1
  24. package/dist/astUtils/reflection.d.ts +5 -1
  25. package/dist/astUtils/reflection.js +15 -2
  26. package/dist/astUtils/reflection.js.map +1 -1
  27. package/dist/astUtils/visitors.d.ts +2 -1
  28. package/dist/astUtils/visitors.js.map +1 -1
  29. package/dist/bscPlugin/BscPlugin.d.ts +3 -1
  30. package/dist/bscPlugin/BscPlugin.js +8 -0
  31. package/dist/bscPlugin/BscPlugin.js.map +1 -1
  32. package/dist/bscPlugin/codeActions/CodeActionsProcessor.d.ts +1 -1
  33. package/dist/bscPlugin/codeActions/CodeActionsProcessor.js +11 -5
  34. package/dist/bscPlugin/codeActions/CodeActionsProcessor.js.map +1 -1
  35. package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js +75 -1
  36. package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js.map +1 -1
  37. package/dist/bscPlugin/completions/CompletionsProcessor.d.ts +6 -0
  38. package/dist/bscPlugin/completions/CompletionsProcessor.js +53 -0
  39. package/dist/bscPlugin/completions/CompletionsProcessor.js.map +1 -0
  40. package/dist/bscPlugin/hover/HoverProcessor.d.ts +17 -0
  41. package/dist/bscPlugin/hover/HoverProcessor.js +190 -0
  42. package/dist/bscPlugin/hover/HoverProcessor.js.map +1 -0
  43. package/dist/bscPlugin/hover/HoverProcessor.spec.d.ts +1 -0
  44. package/dist/bscPlugin/hover/HoverProcessor.spec.js +195 -0
  45. package/dist/bscPlugin/hover/HoverProcessor.spec.js.map +1 -0
  46. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.d.ts +8 -1
  47. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js +64 -63
  48. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js.map +1 -1
  49. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js +238 -23
  50. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js.map +1 -1
  51. package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.d.ts +7 -1
  52. package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.js +77 -30
  53. package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.js.map +1 -1
  54. package/dist/bscPlugin/validation/BrsFileValidator.d.ts +14 -1
  55. package/dist/bscPlugin/validation/BrsFileValidator.js +104 -27
  56. package/dist/bscPlugin/validation/BrsFileValidator.js.map +1 -1
  57. package/dist/bscPlugin/validation/BrsFileValidator.spec.d.ts +1 -0
  58. package/dist/bscPlugin/validation/BrsFileValidator.spec.js +48 -0
  59. package/dist/bscPlugin/validation/BrsFileValidator.spec.js.map +1 -0
  60. package/dist/bscPlugin/validation/ScopeValidator.d.ts +24 -3
  61. package/dist/bscPlugin/validation/ScopeValidator.js +251 -44
  62. package/dist/bscPlugin/validation/ScopeValidator.js.map +1 -1
  63. package/dist/cli.js +18 -10
  64. package/dist/cli.js.map +1 -1
  65. package/dist/files/BrsFile.Class.spec.js +135 -38
  66. package/dist/files/BrsFile.Class.spec.js.map +1 -1
  67. package/dist/files/BrsFile.d.ts +21 -10
  68. package/dist/files/BrsFile.js +158 -179
  69. package/dist/files/BrsFile.js.map +1 -1
  70. package/dist/files/BrsFile.spec.js +222 -126
  71. package/dist/files/BrsFile.spec.js.map +1 -1
  72. package/dist/files/XmlFile.d.ts +2 -2
  73. package/dist/files/XmlFile.js +1 -0
  74. package/dist/files/XmlFile.js.map +1 -1
  75. package/dist/files/tests/imports.spec.js +1 -1
  76. package/dist/files/tests/imports.spec.js.map +1 -1
  77. package/dist/files/tests/optionalChaning.spec.js +20 -16
  78. package/dist/files/tests/optionalChaning.spec.js.map +1 -1
  79. package/dist/globalCallables.js +3 -0
  80. package/dist/globalCallables.js.map +1 -1
  81. package/dist/index.d.ts +1 -1
  82. package/dist/index.js +3 -1
  83. package/dist/index.js.map +1 -1
  84. package/dist/interfaces.d.ts +77 -3
  85. package/dist/lexer/Lexer.spec.js +7 -0
  86. package/dist/lexer/Lexer.spec.js.map +1 -1
  87. package/dist/lexer/TokenKind.d.ts +1 -0
  88. package/dist/lexer/TokenKind.js +8 -3
  89. package/dist/lexer/TokenKind.js.map +1 -1
  90. package/dist/parser/Expression.d.ts +12 -3
  91. package/dist/parser/Expression.js +16 -4
  92. package/dist/parser/Expression.js.map +1 -1
  93. package/dist/parser/Parser.Class.spec.js +1 -1
  94. package/dist/parser/Parser.d.ts +14 -3
  95. package/dist/parser/Parser.js +138 -48
  96. package/dist/parser/Parser.js.map +1 -1
  97. package/dist/parser/Parser.spec.js +232 -115
  98. package/dist/parser/Parser.spec.js.map +1 -1
  99. package/dist/parser/Statement.d.ts +41 -7
  100. package/dist/parser/Statement.js +85 -12
  101. package/dist/parser/Statement.js.map +1 -1
  102. package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js +73 -31
  103. package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js.map +1 -1
  104. package/dist/parser/tests/expression/TemplateStringExpression.spec.js +148 -47
  105. package/dist/parser/tests/expression/TemplateStringExpression.spec.js.map +1 -1
  106. package/dist/parser/tests/expression/TernaryExpression.spec.js +219 -37
  107. package/dist/parser/tests/expression/TernaryExpression.spec.js.map +1 -1
  108. package/dist/parser/tests/statement/ConstStatement.spec.d.ts +1 -0
  109. package/dist/parser/tests/statement/ConstStatement.spec.js +213 -0
  110. package/dist/parser/tests/statement/ConstStatement.spec.js.map +1 -0
  111. package/dist/parser/tests/statement/Enum.spec.js +56 -8
  112. package/dist/parser/tests/statement/Enum.spec.js.map +1 -1
  113. package/dist/parser/tests/statement/InterfaceStatement.spec.js +16 -2
  114. package/dist/parser/tests/statement/InterfaceStatement.spec.js.map +1 -1
  115. package/dist/parser/tests/statement/PrintStatement.spec.js +72 -57
  116. package/dist/parser/tests/statement/PrintStatement.spec.js.map +1 -1
  117. package/dist/preprocessor/Manifest.js +2 -2
  118. package/dist/preprocessor/Manifest.js.map +1 -1
  119. package/dist/preprocessor/Preprocessor.js +10 -6
  120. package/dist/preprocessor/Preprocessor.js.map +1 -1
  121. package/dist/roku-types/data.json +1002 -788
  122. package/dist/roku-types/index.d.ts +64 -239
  123. package/dist/types/DynamicType.d.ts +1 -0
  124. package/dist/types/DynamicType.js +1 -0
  125. package/dist/types/DynamicType.js.map +1 -1
  126. package/dist/util.d.ts +57 -16
  127. package/dist/util.js +139 -30
  128. package/dist/util.js.map +1 -1
  129. package/dist/validators/ClassValidator.d.ts +4 -1
  130. package/dist/validators/ClassValidator.js +34 -25
  131. package/dist/validators/ClassValidator.js.map +1 -1
  132. package/package.json +5 -2
@@ -13,10 +13,10 @@ const reflection_1 = require("../astUtils/reflection");
13
13
  const visitors_1 = require("../astUtils/visitors");
14
14
  const creators_1 = require("../astUtils/creators");
15
15
  const Cache_1 = require("../Cache");
16
+ const SymbolTable_1 = require("../SymbolTable");
16
17
  const DynamicType_1 = require("../types/DynamicType");
17
18
  const ArrayType_1 = require("../types/ArrayType");
18
19
  const helpers_1 = require("../types/helpers");
19
- const SymbolTable_1 = require("../SymbolTable");
20
20
  const ObjectType_1 = require("../types/ObjectType");
21
21
  class Parser {
22
22
  constructor() {
@@ -28,7 +28,10 @@ class Parser {
28
28
  * The list of statements for the parsed file
29
29
  */
30
30
  this.ast = new Statement_1.Body([]);
31
- this.symbolTable = new SymbolTable_1.SymbolTable();
31
+ /**
32
+ * The top-level symbol table for this file. Things like top-level namespaces, non-namespaced classes, enums, interfaces, and functions beling here.
33
+ */
34
+ this.symbolTable = new SymbolTable_1.SymbolTable(undefined, `File Parser`);
32
35
  this._references = new References();
33
36
  this.globalTerminators = [];
34
37
  /**
@@ -40,8 +43,8 @@ class Parser {
40
43
  return this.ast.statements;
41
44
  }
42
45
  get currentSymbolTable() {
43
- var _a, _b;
44
- return (_b = (_a = this.currentFunctionExpression) === null || _a === void 0 ? void 0 : _a.symbolTable) !== null && _b !== void 0 ? _b : this.symbolTable;
46
+ var _a, _b, _c, _d;
47
+ return (_d = (_b = (_a = this.currentFunctionExpression) === null || _a === void 0 ? void 0 : _a.symbolTable) !== null && _b !== void 0 ? _b : (_c = this.currentNamespace) === null || _c === void 0 ? void 0 : _c.symbolTable) !== null && _d !== void 0 ? _d : this.symbolTable;
45
48
  }
46
49
  /**
47
50
  * References for significant statements/expressions in the parser.
@@ -93,22 +96,22 @@ class Parser {
93
96
  * Static wrapper around creating a new parser and parsing a list of tokens
94
97
  */
95
98
  static parse(toParse, options) {
96
- let tokens;
97
- if (typeof toParse === 'string') {
98
- tokens = Lexer_1.Lexer.scan(toParse).tokens;
99
- }
100
- else {
101
- tokens = toParse;
102
- }
103
- return new Parser().parse(tokens, options);
99
+ return new Parser().parse(toParse, options);
104
100
  }
105
101
  /**
106
102
  * Parses an array of `Token`s into an abstract syntax tree
107
103
  * @param toParse the array of tokens to parse. May not contain any whitespace tokens
108
104
  * @returns the same instance of the parser which contains the diagnostics and statements
109
105
  */
110
- parse(tokens, options) {
106
+ parse(toParse, options) {
111
107
  var _a;
108
+ let tokens;
109
+ if (typeof toParse === 'string') {
110
+ tokens = Lexer_1.Lexer.scan(toParse).tokens;
111
+ }
112
+ else {
113
+ tokens = toParse;
114
+ }
112
115
  this.logger = (_a = options === null || options === void 0 ? void 0 : options.logger) !== null && _a !== void 0 ? _a : new Logger_1.Logger();
113
116
  this.tokens = tokens;
114
117
  this.options = this.sanitizeParseOptions(options);
@@ -126,7 +129,7 @@ class Parser {
126
129
  }
127
130
  body() {
128
131
  const parentAnnotations = this.enterAnnotationBlock();
129
- let body = new Statement_1.Body([]);
132
+ let body = new Statement_1.Body([], this.symbolTable);
130
133
  if (this.tokens.length > 0) {
131
134
  this.consumeStatementSeparators(true);
132
135
  try {
@@ -192,6 +195,9 @@ class Parser {
192
195
  if (this.checkLibrary()) {
193
196
  return this.libraryStatement();
194
197
  }
198
+ if (this.check(TokenKind_1.TokenKind.Const) && this.checkAnyNext(TokenKind_1.TokenKind.Identifier, ...this.allowedLocalIdentifiers)) {
199
+ return this.constDeclaration();
200
+ }
195
201
  if (this.check(TokenKind_1.TokenKind.At) && this.checkNext(TokenKind_1.TokenKind.Identifier)) {
196
202
  return this.annotationExpression();
197
203
  }
@@ -495,11 +501,20 @@ class Parser {
495
501
  if (!options.onlyCallableAsMember) {
496
502
  this._references.functionStatements.push(result);
497
503
  }
504
+ // Add the transpiled name for namespace functions
505
+ // to consider an edge case when defining namespaces in .bs files
506
+ // and using them in .brs files.
507
+ if (result.func.namespaceName) {
508
+ const transpiledNamespaceFunctionName = result.getName(ParseMode.BrightScript);
509
+ const funcType = result.func.getFunctionType();
510
+ funcType.setName(transpiledNamespaceFunctionName);
511
+ this.symbolTable.addSymbol(transpiledNamespaceFunctionName, result.name.range, funcType);
512
+ }
498
513
  return result;
499
514
  }
500
515
  }
501
516
  functionDeclaration(options = {}) {
502
- var _a, _b, _c, _d;
517
+ var _a, _b, _c;
503
518
  let previousCallExpressions = this.callExpressions;
504
519
  this.callExpressions = [];
505
520
  try {
@@ -573,10 +588,12 @@ class Parser {
573
588
  // do not go to next statement - we don't care about any other statement
574
589
  this.consumeStatementSeparators(true);
575
590
  }
591
+ // Can Not use the current function expression symbol table for a function expression inside of itself
592
+ const funcExprParentSymbolTable = (_c = (_b = this.currentNamespace) === null || _b === void 0 ? void 0 : _b.symbolTable) !== null && _c !== void 0 ? _c : this.symbolTable;
576
593
  let func = new Expression_1.FunctionExpression(params, undefined, //body
577
594
  functionKeyword, undefined, //ending keyword
578
595
  leftParen, rightParen, asToken, typeExpr, //return type
579
- this.currentFunctionExpression, this.currentNamespaceName, (_c = (_b = this.currentNamespace) === null || _b === void 0 ? void 0 : _b.symbolTable) !== null && _c !== void 0 ? _c : this.symbolTable);
596
+ this.currentFunctionExpression, this.currentNamespaceName, funcExprParentSymbolTable);
580
597
  //if there is a parent function, register this function with the parent
581
598
  if (this.currentFunctionExpression) {
582
599
  this.currentFunctionExpression.childFunctionExpressions.push(func);
@@ -585,14 +602,8 @@ class Parser {
585
602
  if (!options.onlyCallableAsMember && name) {
586
603
  const funcType = func.getFunctionType();
587
604
  funcType.setName(name.text);
588
- // add the function as declared to the current namespace's table
589
- (_d = this.currentNamespace) === null || _d === void 0 ? void 0 : _d.symbolTable.addSymbol(name.text, name.range, funcType);
590
- let fullyQualifiedName = name.text;
591
- if (this.currentNamespaceName) {
592
- // add the "namespaced" name of this function to the parent symbol table
593
- fullyQualifiedName = this.currentNamespaceName.getName(ParseMode.BrighterScript) + '.' + name.text;
594
- }
595
- this.currentSymbolTable.addSymbol(fullyQualifiedName, name.range, funcType);
605
+ // add the function as declared to the current symbol table
606
+ this.currentSymbolTable.addSymbol(name.text, name.range, funcType);
596
607
  }
597
608
  this._references.functionExpressions.push(func);
598
609
  if (options.hasBody) {
@@ -683,9 +694,13 @@ class Parser {
683
694
  result = new Statement_1.AssignmentStatement(name, operator, value, this.currentFunctionExpression);
684
695
  }
685
696
  else {
686
- result = new Statement_1.AssignmentStatement(name, operator, new Expression_1.BinaryExpression(new Expression_1.VariableExpression(name, this.currentNamespaceName), operator, value), this.currentFunctionExpression);
687
- //remove the right-hand-side expression from this assignment operator, and replace with the full assignment expression
688
- this._references.expressions.delete(value);
697
+ const nameExpression = new Expression_1.VariableExpression(name, this.currentNamespaceName);
698
+ result = new Statement_1.AssignmentStatement(name, operator, new Expression_1.BinaryExpression(nameExpression, operator, value), this.currentFunctionExpression);
699
+ this.addExpressionsToReferences(nameExpression);
700
+ if ((0, reflection_1.isBinaryExpression)(value)) {
701
+ //remove the right-hand-side expression from this assignment operator, and replace with the full assignment expression
702
+ this._references.expressions.delete(value);
703
+ }
689
704
  this._references.expressions.add(result);
690
705
  }
691
706
  this._references.assignmentStatements.push(result);
@@ -927,6 +942,9 @@ class Parser {
927
942
  this._references.namespaceStatements.push(result);
928
943
  //cache the range property so that plugins can't affect it
929
944
  result.cacheRange();
945
+ if (result.name) {
946
+ this.symbolTable.addSymbol(result.name.split('.')[0], result.nameExpression.range, DynamicType_1.DynamicType.instance);
947
+ }
930
948
  return result;
931
949
  }
932
950
  /**
@@ -979,6 +997,23 @@ class Parser {
979
997
  }
980
998
  return result;
981
999
  }
1000
+ constDeclaration() {
1001
+ this.warnIfNotBrighterScriptMode('const declaration');
1002
+ const constToken = this.advance();
1003
+ const nameToken = this.identifier(...this.allowedLocalIdentifiers);
1004
+ const equalToken = this.consumeToken(TokenKind_1.TokenKind.Equal);
1005
+ const expression = this.expression();
1006
+ const statement = new Statement_1.ConstStatement({
1007
+ const: constToken,
1008
+ name: nameToken,
1009
+ equals: equalToken
1010
+ }, expression, this.currentNamespaceName);
1011
+ if (nameToken) {
1012
+ this.currentSymbolTable.addSymbol(nameToken.text, nameToken.range, getBscTypeFromExpression(expression));
1013
+ }
1014
+ this._references.constStatements.push(statement);
1015
+ return statement;
1016
+ }
982
1017
  libraryStatement() {
983
1018
  let libStatement = new Statement_1.LibraryStatement({
984
1019
  library: this.advance(),
@@ -1149,6 +1184,9 @@ class Parser {
1149
1184
  else {
1150
1185
  statement.tokens.endTry = this.advance();
1151
1186
  }
1187
+ if (exceptionVarToken) {
1188
+ this.currentSymbolTable.addSymbol(exceptionVarToken.text, exceptionVarToken.range, DynamicType_1.DynamicType.instance);
1189
+ }
1152
1190
  return statement;
1153
1191
  }
1154
1192
  throwStatement() {
@@ -1191,6 +1229,9 @@ class Parser {
1191
1229
  this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.missingExpressionsInDimStatement()), { range: this.peek().range }));
1192
1230
  }
1193
1231
  let rightSquareBracket = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.missingRightSquareBracketAfterDimIdentifier(), TokenKind_1.TokenKind.RightSquareBracket);
1232
+ if (identifier) {
1233
+ this.currentSymbolTable.addSymbol(identifier.text, identifier.range, new ArrayType_1.ArrayType(DynamicType_1.DynamicType.instance));
1234
+ }
1194
1235
  return new Statement_1.DimStatement(dim, identifier, leftSquareBracket, expressions, rightSquareBracket);
1195
1236
  }
1196
1237
  ifStatement() {
@@ -1396,6 +1437,8 @@ class Parser {
1396
1437
  }
1397
1438
  //at this point, it's probably an error. However, we recover a little more gracefully by creating an assignment
1398
1439
  this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.expectedStatementOrFunctionCallButReceivedExpression()), { range: expressionStart.range }));
1440
+ // we can also add this expression to the references, for type checking purposes
1441
+ this._references.expressions.add(expr);
1399
1442
  throw this.lastDiagnosticAsError();
1400
1443
  }
1401
1444
  setStatement() {
@@ -1618,6 +1661,7 @@ class Parser {
1618
1661
  while (this.matchAny(TokenKind_1.TokenKind.And, TokenKind_1.TokenKind.Or)) {
1619
1662
  let operator = this.previous();
1620
1663
  let right = this.relational();
1664
+ this.addExpressionsToReferences(expr, right);
1621
1665
  expr = new Expression_1.BinaryExpression(expr, operator, right);
1622
1666
  }
1623
1667
  return expr;
@@ -1627,16 +1671,25 @@ class Parser {
1627
1671
  while (this.matchAny(TokenKind_1.TokenKind.Equal, TokenKind_1.TokenKind.LessGreater, TokenKind_1.TokenKind.Greater, TokenKind_1.TokenKind.GreaterEqual, TokenKind_1.TokenKind.Less, TokenKind_1.TokenKind.LessEqual)) {
1628
1672
  let operator = this.previous();
1629
1673
  let right = this.additive();
1674
+ this.addExpressionsToReferences(expr, right);
1630
1675
  expr = new Expression_1.BinaryExpression(expr, operator, right);
1631
1676
  }
1632
1677
  return expr;
1633
1678
  }
1679
+ addExpressionsToReferences(...expressions) {
1680
+ for (const expression of expressions) {
1681
+ if (!(0, reflection_1.isBinaryExpression)(expression)) {
1682
+ this.references.expressions.add(expression);
1683
+ }
1684
+ }
1685
+ }
1634
1686
  // TODO: bitshift
1635
1687
  additive() {
1636
1688
  let expr = this.multiplicative();
1637
1689
  while (this.matchAny(TokenKind_1.TokenKind.Plus, TokenKind_1.TokenKind.Minus)) {
1638
1690
  let operator = this.previous();
1639
1691
  let right = this.multiplicative();
1692
+ this.addExpressionsToReferences(expr, right);
1640
1693
  expr = new Expression_1.BinaryExpression(expr, operator, right);
1641
1694
  }
1642
1695
  return expr;
@@ -1646,6 +1699,7 @@ class Parser {
1646
1699
  while (this.matchAny(TokenKind_1.TokenKind.Forwardslash, TokenKind_1.TokenKind.Backslash, TokenKind_1.TokenKind.Star, TokenKind_1.TokenKind.Mod, TokenKind_1.TokenKind.LeftShift, TokenKind_1.TokenKind.RightShift)) {
1647
1700
  let operator = this.previous();
1648
1701
  let right = this.exponential();
1702
+ this.addExpressionsToReferences(expr, right);
1649
1703
  expr = new Expression_1.BinaryExpression(expr, operator, right);
1650
1704
  }
1651
1705
  return expr;
@@ -1655,6 +1709,7 @@ class Parser {
1655
1709
  while (this.match(TokenKind_1.TokenKind.Caret)) {
1656
1710
  let operator = this.previous();
1657
1711
  let right = this.prefixUnary();
1712
+ this.addExpressionsToReferences(expr, right);
1658
1713
  expr = new Expression_1.BinaryExpression(expr, operator, right);
1659
1714
  }
1660
1715
  return expr;
@@ -1907,7 +1962,7 @@ class Parser {
1907
1962
  range: null
1908
1963
  };
1909
1964
  if (this.checkAny(TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedProperties)) {
1910
- result.keyToken = this.advance();
1965
+ result.keyToken = this.identifier(...TokenKind_1.AllowedProperties);
1911
1966
  }
1912
1967
  else if (this.check(TokenKind_1.TokenKind.StringLiteral)) {
1913
1968
  result.keyToken = this.advance();
@@ -2276,9 +2331,10 @@ class Parser {
2276
2331
  currentTokenIndex = previousTokenResult === null || previousTokenResult === void 0 ? void 0 : previousTokenResult.index;
2277
2332
  }
2278
2333
  }
2334
+ const isLiteral = (currentToken === null || currentToken === void 0 ? void 0 : currentToken.kind) === TokenKind_1.TokenKind.StringLiteral || (currentToken === null || currentToken === void 0 ? void 0 : currentToken.kind) === TokenKind_1.TokenKind.IntegerLiteral || (currentToken === null || currentToken === void 0 ? void 0 : currentToken.kind) === TokenKind_1.TokenKind.FloatLiteral || (currentToken === null || currentToken === void 0 ? void 0 : currentToken.kind) === TokenKind_1.TokenKind.Boolean;
2279
2335
  // We will not be able to decipher the token type if it was in brackets
2280
2336
  // e.g (someVar+otherVar).toStr() -- we don't bother trying to decipher what "(someVar+otherVar)" is
2281
- let isUnknown = (lastTokenWasLeftBracket && (lastTokenHadLeadingWhitespace || !this.isAcceptableChainToken(currentToken)));
2337
+ let isUnknown = isLiteral || (lastTokenWasLeftBracket && (lastTokenHadLeadingWhitespace || !this.isAcceptableChainToken(currentToken)));
2282
2338
  const tokenWithIndex = { token: currentToken, index: currentTokenIndex, tokenTypeIsNotKnowable: isUnknown, hasBrackets: hasBrackets };
2283
2339
  return tokenWithIndex;
2284
2340
  }
@@ -2298,7 +2354,7 @@ class Parser {
2298
2354
  currentToken = previousTokenResult === null || previousTokenResult === void 0 ? void 0 : previousTokenResult.token;
2299
2355
  currentTokenIndex = previousTokenResult === null || previousTokenResult === void 0 ? void 0 : previousTokenResult.index;
2300
2356
  }
2301
- if ((currentToken === null || currentToken === void 0 ? void 0 : currentToken.kind) === TokenKind_1.TokenKind.Dot) {
2357
+ if ((currentToken === null || currentToken === void 0 ? void 0 : currentToken.kind) === TokenKind_1.TokenKind.Dot || (currentToken === null || currentToken === void 0 ? void 0 : currentToken.kind) === TokenKind_1.TokenKind.QuestionDot) {
2302
2358
  previousTokenResult = this.getPreviousTokenFromIndex(currentTokenIndex);
2303
2359
  currentToken = previousTokenResult.token;
2304
2360
  currentTokenIndex = previousTokenResult.index;
@@ -2478,6 +2534,19 @@ class Parser {
2478
2534
  }
2479
2535
  }
2480
2536
  },
2537
+ BinaryExpression: (e, parent) => {
2538
+ //walk the chain of binary expressions and add each one to the list of expressions
2539
+ const expressions = [e];
2540
+ let expression;
2541
+ while ((expression = expressions.pop())) {
2542
+ if ((0, reflection_1.isBinaryExpression)(expression)) {
2543
+ expressions.push(expression.left, expression.right);
2544
+ }
2545
+ else {
2546
+ this._references.expressions.add(expression);
2547
+ }
2548
+ }
2549
+ },
2481
2550
  ArrayLiteralExpression: e => {
2482
2551
  for (const element of e.elements) {
2483
2552
  //keep everything except comments
@@ -2495,6 +2564,9 @@ class Parser {
2495
2564
  EnumStatement: e => {
2496
2565
  this._references.enumStatements.push(e);
2497
2566
  },
2567
+ ConstStatement: s => {
2568
+ this._references.constStatements.push(s);
2569
+ },
2498
2570
  UnaryExpression: e => {
2499
2571
  this._references.expressions.add(e);
2500
2572
  },
@@ -2505,6 +2577,9 @@ class Parser {
2505
2577
  walkMode: visitors_1.WalkMode.visitAllRecursive
2506
2578
  });
2507
2579
  }
2580
+ getContainingExpression(currentToken) {
2581
+ return [...this.references.expressions].find((cs) => util_1.util.rangeContainsRange(cs.range, currentToken.range));
2582
+ }
2508
2583
  getContainingClass(currentToken) {
2509
2584
  return this.references.classStatements.find((cs) => util_1.util.rangeContains(cs.range, currentToken.range.start));
2510
2585
  }
@@ -2540,6 +2615,7 @@ class References {
2540
2615
  this.functionStatements = [];
2541
2616
  this.interfaceStatements = [];
2542
2617
  this.enumStatements = [];
2618
+ this.constStatements = [];
2543
2619
  /**
2544
2620
  * A collection of full expressions. This excludes intermediary expressions.
2545
2621
  *
@@ -2549,6 +2625,9 @@ class References {
2549
2625
  *
2550
2626
  * Example 2:
2551
2627
  * `name.space.doSomething(a.b.c)` will result in 2 entries in this list. the `CallExpression` for `doSomething`, and the `.c` DottedGetExpression.
2628
+ *
2629
+ * Example 3:
2630
+ * `value = SomeEnum.value > 2 or SomeEnum.otherValue < 10` will result in 4 entries. `SomeEnum.value`, `2`, `SomeEnum.otherValue`, `10`
2552
2631
  */
2553
2632
  this.expressions = new Set();
2554
2633
  this.importStatements = [];
@@ -2596,6 +2675,15 @@ class References {
2596
2675
  return result;
2597
2676
  });
2598
2677
  }
2678
+ get constStatementLookup() {
2679
+ return this.cache.getOrAdd('consts', () => {
2680
+ const result = new Map();
2681
+ for (const stmt of this.constStatements) {
2682
+ result.set(stmt.fullName.toLowerCase(), stmt);
2683
+ }
2684
+ return result;
2685
+ });
2686
+ }
2599
2687
  }
2600
2688
  exports.References = References;
2601
2689
  var TokenUsage;
@@ -2637,23 +2725,25 @@ function getBscTypeFromExpression(expression, functionExpression) {
2637
2725
  return new ArrayType_1.ArrayType(...innerTypes);
2638
2726
  //function call
2639
2727
  }
2640
- else if ((0, reflection_1.isNewExpression)(expression)) {
2641
- return (0, helpers_1.getTypeFromNewExpression)(expression, functionExpression);
2642
- //Function call
2643
- }
2644
- else if ((0, reflection_1.isCallExpression)(expression)) {
2645
- return (0, helpers_1.getTypeFromCallExpression)(expression, functionExpression);
2646
- }
2647
- else if ((0, reflection_1.isVariableExpression)(expression)) {
2648
- return (0, helpers_1.getTypeFromVariableExpression)(expression, functionExpression);
2649
- }
2650
- else if ((0, reflection_1.isDottedGetExpression)(expression)) {
2651
- return (0, helpers_1.getTypeFromDottedGetExpression)(expression, functionExpression);
2652
- }
2653
- else if ((0, reflection_1.isIndexedGetExpression)(expression)) {
2654
- const source = getBscTypeFromExpression(expression.obj, functionExpression);
2655
- if ((0, reflection_1.isArrayType)(source)) {
2656
- return source.getDefaultType();
2728
+ else if (functionExpression) {
2729
+ // These are more precise, and can't be determined without knowing the function expression you're in
2730
+ if ((0, reflection_1.isNewExpression)(expression)) {
2731
+ return (0, helpers_1.getTypeFromNewExpression)(expression, functionExpression);
2732
+ }
2733
+ else if ((0, reflection_1.isCallExpression)(expression)) {
2734
+ return (0, helpers_1.getTypeFromCallExpression)(expression, functionExpression);
2735
+ }
2736
+ else if ((0, reflection_1.isVariableExpression)(expression)) {
2737
+ return (0, helpers_1.getTypeFromVariableExpression)(expression, functionExpression);
2738
+ }
2739
+ else if ((0, reflection_1.isDottedGetExpression)(expression)) {
2740
+ return (0, helpers_1.getTypeFromDottedGetExpression)(expression, functionExpression);
2741
+ }
2742
+ else if ((0, reflection_1.isIndexedGetExpression)(expression)) {
2743
+ const source = getBscTypeFromExpression(expression.obj, functionExpression);
2744
+ if ((0, reflection_1.isArrayType)(source)) {
2745
+ return source.getDefaultType();
2746
+ }
2657
2747
  }
2658
2748
  }
2659
2749
  }
@@ -2661,7 +2751,7 @@ function getBscTypeFromExpression(expression, functionExpression) {
2661
2751
  //do nothing. Just return dynamic
2662
2752
  }
2663
2753
  //fallback to dynamic
2664
- return new DynamicType_1.DynamicType();
2754
+ return DynamicType_1.DynamicType.instance;
2665
2755
  }
2666
2756
  exports.getBscTypeFromExpression = getBscTypeFromExpression;
2667
2757
  //# sourceMappingURL=Parser.js.map