brighterscript 0.41.2 → 1.0.0-alpha.12

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 (170) hide show
  1. package/CHANGELOG.md +112 -0
  2. package/README.md +2 -2
  3. package/dist/DiagnosticCollection.js +2 -2
  4. package/dist/DiagnosticCollection.js.map +1 -1
  5. package/dist/DiagnosticFilterer.js +2 -2
  6. package/dist/DiagnosticFilterer.js.map +1 -1
  7. package/dist/DiagnosticMessages.d.ts +6 -1
  8. package/dist/DiagnosticMessages.js +5 -0
  9. package/dist/DiagnosticMessages.js.map +1 -1
  10. package/dist/LanguageServer.d.ts +8 -2
  11. package/dist/LanguageServer.js +50 -44
  12. package/dist/LanguageServer.js.map +1 -1
  13. package/dist/Program.d.ts +61 -45
  14. package/dist/Program.js +305 -188
  15. package/dist/Program.js.map +1 -1
  16. package/dist/ProgramBuilder.d.ts +7 -7
  17. package/dist/ProgramBuilder.js +60 -51
  18. package/dist/ProgramBuilder.js.map +1 -1
  19. package/dist/Scope.d.ts +42 -19
  20. package/dist/Scope.js +261 -129
  21. package/dist/Scope.js.map +1 -1
  22. package/dist/SymbolTable.d.ts +73 -0
  23. package/dist/SymbolTable.js +157 -0
  24. package/dist/SymbolTable.js.map +1 -0
  25. package/dist/XmlScope.d.ts +5 -0
  26. package/dist/XmlScope.js +66 -28
  27. package/dist/XmlScope.js.map +1 -1
  28. package/dist/astUtils/creators.d.ts +15 -1
  29. package/dist/astUtils/creators.js +39 -9
  30. package/dist/astUtils/creators.js.map +1 -1
  31. package/dist/astUtils/reflection.d.ts +28 -16
  32. package/dist/astUtils/reflection.js +52 -30
  33. package/dist/astUtils/reflection.js.map +1 -1
  34. package/dist/astUtils/reflection.spec.js +3 -3
  35. package/dist/astUtils/reflection.spec.js.map +1 -1
  36. package/dist/astUtils/visitors.spec.js +12 -13
  37. package/dist/astUtils/visitors.spec.js.map +1 -1
  38. package/dist/astUtils/xml.d.ts +3 -3
  39. package/dist/astUtils/xml.js +2 -2
  40. package/dist/astUtils/xml.js.map +1 -1
  41. package/dist/bscPlugin/codeActions/CodeActionsProcessor.js +5 -6
  42. package/dist/bscPlugin/codeActions/CodeActionsProcessor.js.map +1 -1
  43. package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js +24 -22
  44. package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js.map +1 -1
  45. package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.spec.js +2 -2
  46. package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.spec.js.map +1 -1
  47. package/dist/examples/plugins/removePrint.js +1 -1
  48. package/dist/examples/plugins/removePrint.js.map +1 -1
  49. package/dist/files/BrsFile.Class.spec.js +356 -41
  50. package/dist/files/BrsFile.Class.spec.js.map +1 -1
  51. package/dist/files/BrsFile.d.ts +55 -37
  52. package/dist/files/BrsFile.js +430 -399
  53. package/dist/files/BrsFile.js.map +1 -1
  54. package/dist/files/BrsFile.spec.js +199 -158
  55. package/dist/files/BrsFile.spec.js.map +1 -1
  56. package/dist/files/XmlFile.d.ts +20 -9
  57. package/dist/files/XmlFile.js +36 -31
  58. package/dist/files/XmlFile.js.map +1 -1
  59. package/dist/files/XmlFile.spec.js +113 -113
  60. package/dist/files/XmlFile.spec.js.map +1 -1
  61. package/dist/files/tests/imports.spec.js +32 -32
  62. package/dist/files/tests/imports.spec.js.map +1 -1
  63. package/dist/globalCallables.js +17 -6
  64. package/dist/globalCallables.js.map +1 -1
  65. package/dist/interfaces.d.ts +155 -39
  66. package/dist/parser/BrsTranspileState.d.ts +7 -0
  67. package/dist/parser/BrsTranspileState.js +10 -1
  68. package/dist/parser/BrsTranspileState.js.map +1 -1
  69. package/dist/parser/Expression.d.ts +23 -12
  70. package/dist/parser/Expression.js +45 -30
  71. package/dist/parser/Expression.js.map +1 -1
  72. package/dist/parser/Parser.Class.spec.js +100 -1
  73. package/dist/parser/Parser.Class.spec.js.map +1 -1
  74. package/dist/parser/Parser.d.ts +118 -5
  75. package/dist/parser/Parser.js +398 -37
  76. package/dist/parser/Parser.js.map +1 -1
  77. package/dist/parser/Parser.spec.js +404 -7
  78. package/dist/parser/Parser.spec.js.map +1 -1
  79. package/dist/parser/SGParser.d.ts +41 -4
  80. package/dist/parser/SGParser.js +185 -174
  81. package/dist/parser/SGParser.js.map +1 -1
  82. package/dist/parser/SGParser.spec.js +17 -4
  83. package/dist/parser/SGParser.spec.js.map +1 -1
  84. package/dist/parser/SGTypes.d.ts +203 -38
  85. package/dist/parser/SGTypes.js +464 -160
  86. package/dist/parser/SGTypes.js.map +1 -1
  87. package/dist/parser/SGTypes.spec.d.ts +1 -0
  88. package/dist/parser/SGTypes.spec.js +351 -0
  89. package/dist/parser/SGTypes.spec.js.map +1 -0
  90. package/dist/parser/Statement.d.ts +37 -26
  91. package/dist/parser/Statement.js +81 -20
  92. package/dist/parser/Statement.js.map +1 -1
  93. package/dist/parser/Statement.spec.js +5 -5
  94. package/dist/parser/Statement.spec.js.map +1 -1
  95. package/dist/parser/TranspileState.d.ts +1 -1
  96. package/dist/parser/TranspileState.js +15 -7
  97. package/dist/parser/TranspileState.js.map +1 -1
  98. package/dist/parser/tests/controlFlow/ForEach.spec.js +5 -4
  99. package/dist/parser/tests/controlFlow/ForEach.spec.js.map +1 -1
  100. package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js +1 -1
  101. package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js.map +1 -1
  102. package/dist/parser/tests/expression/RegexLiteralExpression.spec.js +1 -1
  103. package/dist/parser/tests/expression/RegexLiteralExpression.spec.js.map +1 -1
  104. package/dist/parser/tests/expression/TemplateStringExpression.spec.js +1 -1
  105. package/dist/parser/tests/expression/TemplateStringExpression.spec.js.map +1 -1
  106. package/dist/parser/tests/expression/TernaryExpression.spec.js +1 -1
  107. package/dist/parser/tests/expression/TernaryExpression.spec.js.map +1 -1
  108. package/dist/types/ArrayType.d.ts +1 -0
  109. package/dist/types/ArrayType.js +23 -19
  110. package/dist/types/ArrayType.js.map +1 -1
  111. package/dist/types/BooleanType.d.ts +3 -2
  112. package/dist/types/BooleanType.js +6 -3
  113. package/dist/types/BooleanType.js.map +1 -1
  114. package/dist/types/BscType.d.ts +19 -4
  115. package/dist/types/BscType.js +9 -0
  116. package/dist/types/BscType.js.map +1 -1
  117. package/dist/types/CustomType.d.ts +8 -5
  118. package/dist/types/CustomType.js +12 -12
  119. package/dist/types/CustomType.js.map +1 -1
  120. package/dist/types/DoubleType.d.ts +1 -0
  121. package/dist/types/DoubleType.js +11 -11
  122. package/dist/types/DoubleType.js.map +1 -1
  123. package/dist/types/DynamicType.d.ts +1 -0
  124. package/dist/types/DynamicType.js +4 -0
  125. package/dist/types/DynamicType.js.map +1 -1
  126. package/dist/types/FloatType.d.ts +2 -1
  127. package/dist/types/FloatType.js +11 -11
  128. package/dist/types/FloatType.js.map +1 -1
  129. package/dist/types/FunctionType.d.ts +13 -10
  130. package/dist/types/FunctionType.js +34 -18
  131. package/dist/types/FunctionType.js.map +1 -1
  132. package/dist/types/FunctionType.spec.js +8 -2
  133. package/dist/types/FunctionType.spec.js.map +1 -1
  134. package/dist/types/IntegerType.d.ts +2 -1
  135. package/dist/types/IntegerType.js +11 -11
  136. package/dist/types/IntegerType.js.map +1 -1
  137. package/dist/types/InvalidType.d.ts +3 -2
  138. package/dist/types/InvalidType.js +7 -4
  139. package/dist/types/InvalidType.js.map +1 -1
  140. package/dist/types/LazyType.d.ts +17 -0
  141. package/dist/types/LazyType.js +44 -0
  142. package/dist/types/LazyType.js.map +1 -0
  143. package/dist/types/LongIntegerType.d.ts +2 -1
  144. package/dist/types/LongIntegerType.js +11 -11
  145. package/dist/types/LongIntegerType.js.map +1 -1
  146. package/dist/types/ObjectType.d.ts +6 -2
  147. package/dist/types/ObjectType.js +9 -3
  148. package/dist/types/ObjectType.js.map +1 -1
  149. package/dist/types/StringType.d.ts +3 -2
  150. package/dist/types/StringType.js +6 -3
  151. package/dist/types/StringType.js.map +1 -1
  152. package/dist/types/UninitializedType.d.ts +4 -2
  153. package/dist/types/UninitializedType.js +8 -3
  154. package/dist/types/UninitializedType.js.map +1 -1
  155. package/dist/types/VoidType.d.ts +3 -2
  156. package/dist/types/VoidType.js +6 -3
  157. package/dist/types/VoidType.js.map +1 -1
  158. package/dist/types/helpers.d.ts +42 -0
  159. package/dist/types/helpers.js +113 -0
  160. package/dist/types/helpers.js.map +1 -0
  161. package/dist/util.d.ts +68 -15
  162. package/dist/util.js +193 -45
  163. package/dist/util.js.map +1 -1
  164. package/dist/validators/ClassValidator.d.ts +5 -1
  165. package/dist/validators/ClassValidator.js +31 -17
  166. package/dist/validators/ClassValidator.js.map +1 -1
  167. package/package.json +1 -1
  168. package/dist/FunctionScope.d.ts +0 -27
  169. package/dist/FunctionScope.js +0 -49
  170. package/dist/FunctionScope.js.map +0 -1
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.References = exports.ParseMode = exports.Parser = void 0;
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");
@@ -10,6 +10,11 @@ const Logger_1 = require("../Logger");
10
10
  const reflection_1 = require("../astUtils/reflection");
11
11
  const visitors_1 = require("../astUtils/visitors");
12
12
  const creators_1 = require("../astUtils/creators");
13
+ const DynamicType_1 = require("../types/DynamicType");
14
+ const SymbolTable_1 = require("../SymbolTable");
15
+ const ObjectType_1 = require("../types/ObjectType");
16
+ const ArrayType_1 = require("../types/ArrayType");
17
+ const helpers_1 = require("../types/helpers");
13
18
  const _1 = require(".");
14
19
  class Parser {
15
20
  constructor() {
@@ -21,6 +26,7 @@ class Parser {
21
26
  * The list of statements for the parsed file
22
27
  */
23
28
  this.ast = new Statement_1.Body([]);
29
+ this.symbolTable = new SymbolTable_1.SymbolTable();
24
30
  this._references = new References();
25
31
  this.globalTerminators = [];
26
32
  /**
@@ -31,6 +37,10 @@ class Parser {
31
37
  get statements() {
32
38
  return this.ast.statements;
33
39
  }
40
+ get currentSymbolTable() {
41
+ var _a, _b;
42
+ return (_b = (_a = this.currentFunctionExpression) === null || _a === void 0 ? void 0 : _a.symbolTable) !== null && _b !== void 0 ? _b : this.symbolTable;
43
+ }
34
44
  /**
35
45
  * References for significant statements/expressions in the parser.
36
46
  * These are initially extracted during parse-time to improve performance, but will also be dynamically regenerated if need be.
@@ -66,6 +76,10 @@ class Parser {
66
76
  }
67
77
  }
68
78
  }
79
+ get currentNamespaceName() {
80
+ var _a;
81
+ return (_a = this.currentNamespace) === null || _a === void 0 ? void 0 : _a.nameExpression;
82
+ }
69
83
  /**
70
84
  * Get the currently active global terminators
71
85
  */
@@ -242,7 +256,7 @@ class Parser {
242
256
  this.warnIfNotBrighterScriptMode('interface declarations');
243
257
  const parentAnnotations = this.enterAnnotationBlock();
244
258
  const interfaceToken = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedKeyword(lexer_1.TokenKind.Interface), lexer_1.TokenKind.Interface);
245
- const nameToken = this.identifier();
259
+ const nameToken = this.identifier(...this.allowedLocalIdentifiers);
246
260
  let extendsToken;
247
261
  let parentInterfaceName;
248
262
  if (this.peek().text.toLowerCase() === 'extends') {
@@ -336,7 +350,7 @@ class Parser {
336
350
  }
337
351
  //methods (function/sub keyword OR identifier followed by opening paren)
338
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))) {
339
- const funcDeclaration = this.functionDeclaration(false, false);
353
+ const funcDeclaration = this.functionDeclaration(false, false, true);
340
354
  //remove this function from the lists because it's not a callable
341
355
  const functionStatement = this._references.functionStatements.pop();
342
356
  //if we have an overrides keyword AND this method is called 'new', that's not allowed
@@ -375,7 +389,10 @@ class Parser {
375
389
  if (endingKeyword.kind !== lexer_1.TokenKind.EndClass) {
376
390
  this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.couldNotFindMatchingEndKeyword('class')), { range: endingKeyword.range }));
377
391
  }
378
- 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
+ }
379
396
  this._references.classStatements.push(result);
380
397
  this.exitAnnotationBlock(parentAnnotations);
381
398
  return result;
@@ -389,7 +406,7 @@ class Parser {
389
406
  asToken = this.advance();
390
407
  fieldType = this.typeToken();
391
408
  //no field type specified
392
- if (!util_1.util.tokenToBscType(fieldType)) {
409
+ if (!util_1.util.tokenToBscType(fieldType, true, this.currentNamespaceName)) {
393
410
  this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.expectedValidTypeToFollowAsKeyword()), { range: this.peek().range }));
394
411
  }
395
412
  }
@@ -400,10 +417,10 @@ class Parser {
400
417
  equal = this.advance();
401
418
  initialValue = this.expression();
402
419
  }
403
- 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);
404
421
  }
405
- functionDeclaration(isAnonymous, checkIdentifier = true) {
406
- var _a;
422
+ functionDeclaration(isAnonymous, checkIdentifier = true, forClassMethod = false) {
423
+ var _a, _b, _c, _d;
407
424
  let previousCallExpressions = this.callExpressions;
408
425
  this.callExpressions = [];
409
426
  try {
@@ -463,7 +480,7 @@ class Parser {
463
480
  if (this.check(lexer_1.TokenKind.As)) {
464
481
  asToken = this.advance();
465
482
  typeToken = this.typeToken();
466
- 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)) {
467
484
  this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.invalidFunctionReturnType((_a = typeToken.text) !== null && _a !== void 0 ? _a : '')), { range: typeToken.range }));
468
485
  }
469
486
  }
@@ -476,11 +493,25 @@ class Parser {
476
493
  this.consumeStatementSeparators(true);
477
494
  let func = new Expression_1.FunctionExpression(params, undefined, //body
478
495
  functionType, undefined, //ending keyword
479
- leftParen, rightParen, asToken, typeToken, this.currentFunctionExpression, this.currentNamespaceName);
496
+ leftParen, rightParen, asToken, typeToken, //return type
497
+ this.currentFunctionExpression, this.currentNamespaceName, (_c = (_b = this.currentNamespace) === null || _b === void 0 ? void 0 : _b.symbolTable) !== null && _c !== void 0 ? _c : this.symbolTable);
480
498
  //if there is a parent function, register this function with the parent
481
499
  if (this.currentFunctionExpression) {
482
500
  this.currentFunctionExpression.childFunctionExpressions.push(func);
483
501
  }
502
+ // add the function to the relevant symbol tables
503
+ if (!isAnonymous && !forClassMethod) {
504
+ const funcType = func.getFunctionType();
505
+ funcType.setName(name.text);
506
+ // add the function as declared to the current namespace's table
507
+ (_d = this.currentNamespace) === null || _d === void 0 ? void 0 : _d.symbolTable.addSymbol(name.text, name.range, funcType);
508
+ let fullyQualifiedName = name.text;
509
+ if (this.currentNamespaceName) {
510
+ // add the "namespaced" name of this function to the parent symbol table
511
+ fullyQualifiedName = this.currentNamespaceName.getName(ParseMode.BrighterScript) + '.' + name.text;
512
+ }
513
+ this.currentSymbolTable.addSymbol(fullyQualifiedName, name.range, funcType);
514
+ }
484
515
  this._references.functionExpressions.push(func);
485
516
  let previousFunctionExpression = this.currentFunctionExpression;
486
517
  this.currentFunctionExpression = func;
@@ -526,13 +557,13 @@ class Parser {
526
557
  this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.expectedParameterNameButFound(this.peek().text)), { range: this.peek().range }));
527
558
  throw this.lastDiagnosticAsError();
528
559
  }
529
- let name = this.advance();
530
- // force the name into an identifier so the AST makes some sense
531
- name.kind = lexer_1.TokenKind.Identifier;
560
+ const name = this.identifier(...lexer_1.AllowedLocalIdentifiers);
532
561
  let typeToken;
533
562
  let defaultValue;
563
+ let equalsToken;
534
564
  // parse argument default value
535
565
  if (this.match(lexer_1.TokenKind.Equal)) {
566
+ equalsToken = this.previous();
536
567
  // it seems any expression is allowed here -- including ones that operate on other arguments!
537
568
  defaultValue = this.expression();
538
569
  }
@@ -540,15 +571,28 @@ class Parser {
540
571
  if (this.check(lexer_1.TokenKind.As)) {
541
572
  asToken = this.advance();
542
573
  typeToken = this.typeToken();
543
- 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)) {
544
575
  this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.functionParameterTypeIsInvalid(name.text, typeToken.text)), { range: typeToken.range }));
545
576
  throw this.lastDiagnosticAsError();
546
577
  }
547
578
  }
548
- return new Expression_1.FunctionParameterExpression(name, typeToken, defaultValue, asToken, this.currentNamespaceName);
579
+ let type;
580
+ if (typeToken) {
581
+ type = util_1.util.tokenToBscType(typeToken, true, this.currentNamespaceName);
582
+ }
583
+ else if (defaultValue) {
584
+ type = getBscTypeFromExpression(defaultValue, this.currentFunctionExpression);
585
+ if ((0, reflection_1.isInvalidType)(type)) {
586
+ type = new DynamicType_1.DynamicType();
587
+ }
588
+ }
589
+ else {
590
+ type = new DynamicType_1.DynamicType();
591
+ }
592
+ return new Expression_1.FunctionParameterExpression(name, type, equalsToken, defaultValue, asToken, typeToken, this.currentNamespaceName);
549
593
  }
550
594
  assignment() {
551
- let name = this.advance();
595
+ let name = this.identifier(...this.allowedLocalIdentifiers);
552
596
  //add diagnostic if name is a reserved word that cannot be used as an identifier
553
597
  if (lexer_1.DisallowedLocalIdentifiersText.has(name.text.toLowerCase())) {
554
598
  this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.cannotUseReservedWordAsIdentifier(name.text)), { range: name.range }));
@@ -557,12 +601,14 @@ class Parser {
557
601
  let value = this.expression();
558
602
  let result;
559
603
  if (operator.kind === lexer_1.TokenKind.Equal) {
560
- result = new Statement_1.AssignmentStatement(operator, name, value, this.currentFunctionExpression);
604
+ result = new Statement_1.AssignmentStatement(name, operator, value, this.currentFunctionExpression);
561
605
  }
562
606
  else {
563
- result = new Statement_1.AssignmentStatement(operator, name, new Expression_1.BinaryExpression(new Expression_1.VariableExpression(name, this.currentNamespaceName), operator, value), this.currentFunctionExpression);
607
+ result = new Statement_1.AssignmentStatement(name, operator, new Expression_1.BinaryExpression(new Expression_1.VariableExpression(name, this.currentNamespaceName), operator, value), this.currentFunctionExpression);
564
608
  }
565
609
  this._references.assignmentStatements.push(result);
610
+ const assignmentType = getBscTypeFromExpression(result.value, this.currentFunctionExpression);
611
+ this.currentSymbolTable.addSymbol(name.text, name.range, assignmentType);
566
612
  return result;
567
613
  }
568
614
  checkLibrary() {
@@ -717,7 +763,7 @@ class Parser {
717
763
  }
718
764
  forEachStatement() {
719
765
  let forEach = this.advance();
720
- let name = this.advance();
766
+ let name = this.identifier(...this.allowedLocalIdentifiers);
721
767
  let maybeIn = this.peek();
722
768
  if (this.check(lexer_1.TokenKind.Identifier) && maybeIn.text.toLowerCase() === 'in') {
723
769
  this.advance();
@@ -738,11 +784,10 @@ class Parser {
738
784
  throw this.lastDiagnosticAsError();
739
785
  }
740
786
  let endFor = this.advance();
741
- return new Statement_1.ForEachStatement({
742
- forEach: forEach,
743
- in: maybeIn,
744
- endFor: endFor
745
- }, name, target, body);
787
+ //TODO TYPES infer type from `target`
788
+ const itemType = new DynamicType_1.DynamicType();
789
+ this.currentSymbolTable.addSymbol(name.text, name.range, itemType);
790
+ return new Statement_1.ForEachStatement(forEach, name, maybeIn, target, body, endFor);
746
791
  }
747
792
  exitFor() {
748
793
  let keyword = this.advance();
@@ -773,12 +818,13 @@ class Parser {
773
818
  this.namespaceAndFunctionDepth++;
774
819
  let name = this.getNamespacedVariableNameExpression();
775
820
  //set the current namespace name
776
- this.currentNamespaceName = name;
821
+ let result = new Statement_1.NamespaceStatement(keyword, name, null, null, this.currentSymbolTable);
822
+ this.currentNamespace = result;
777
823
  this.globalTerminators.push([lexer_1.TokenKind.EndNamespace]);
778
824
  let body = this.body();
779
825
  this.globalTerminators.pop();
780
826
  //unset the current namespace name
781
- this.currentNamespaceName = undefined;
827
+ this.currentNamespace = undefined;
782
828
  let endKeyword;
783
829
  if (this.check(lexer_1.TokenKind.EndNamespace)) {
784
830
  endKeyword = this.advance();
@@ -788,7 +834,8 @@ class Parser {
788
834
  this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.couldNotFindMatchingEndKeyword('namespace')), { range: keyword.range }));
789
835
  }
790
836
  this.namespaceAndFunctionDepth--;
791
- let result = new Statement_1.NamespaceStatement(keyword, name, body, endKeyword);
837
+ result.body = body;
838
+ result.endKeyword = endKeyword;
792
839
  this._references.namespaceStatements.push(result);
793
840
  return result;
794
841
  }
@@ -1276,9 +1323,11 @@ class Parser {
1276
1323
  : new Expression_1.BinaryExpression(left, operator, right), left.openingSquare, left.closingSquare);
1277
1324
  }
1278
1325
  else if ((0, reflection_1.isDottedGetExpression)(left)) {
1279
- return new Statement_1.DottedSetStatement(left.obj, left.name, operator.kind === lexer_1.TokenKind.Equal
1326
+ const dottedSetStmt = new Statement_1.DottedSetStatement(left.obj, left.name, operator.kind === lexer_1.TokenKind.Equal
1280
1327
  ? right
1281
1328
  : new Expression_1.BinaryExpression(left, operator, right));
1329
+ this._references.dottedSetStatements.push(dottedSetStmt);
1330
+ return dottedSetStmt;
1282
1331
  }
1283
1332
  }
1284
1333
  return this.expressionStatement(expr);
@@ -1338,7 +1387,9 @@ class Parser {
1338
1387
  this.current -= 2;
1339
1388
  throw new CancelStatementError();
1340
1389
  }
1341
- return new Statement_1.LabelStatement(tokens);
1390
+ const stmt = new Statement_1.LabelStatement(tokens);
1391
+ this.currentFunctionExpression.labelStatements.push(stmt);
1392
+ return stmt;
1342
1393
  }
1343
1394
  /**
1344
1395
  * Parses a `goto` statement
@@ -1735,7 +1786,7 @@ class Parser {
1735
1786
  else {
1736
1787
  let k = key();
1737
1788
  let expr = this.expression();
1738
- lastAAMember = new Expression_1.AAMemberExpression(k.keyToken, k.colonToken, expr);
1789
+ lastAAMember = new Expression_1.AAMemberExpression(k.keyToken, k.colonToken, expr, getBscTypeFromExpression(expr, this.currentFunctionExpression));
1739
1790
  members.push(lastAAMember);
1740
1791
  }
1741
1792
  while (this.matchAny(lexer_1.TokenKind.Comma, lexer_1.TokenKind.Newline, lexer_1.TokenKind.Colon, lexer_1.TokenKind.Comment)) {
@@ -1762,14 +1813,15 @@ class Parser {
1762
1813
  }
1763
1814
  let k = key();
1764
1815
  let expr = this.expression();
1765
- lastAAMember = new Expression_1.AAMemberExpression(k.keyToken, k.colonToken, expr);
1816
+ lastAAMember = new Expression_1.AAMemberExpression(k.keyToken, k.colonToken, expr, getBscTypeFromExpression(expr, this.currentFunctionExpression));
1766
1817
  members.push(lastAAMember);
1767
1818
  }
1768
1819
  }
1769
1820
  this.consume(DiagnosticMessages_1.DiagnosticMessages.unmatchedLeftCurlyAfterAALiteral(), lexer_1.TokenKind.RightCurlyBrace);
1770
1821
  }
1771
1822
  let closingBrace = this.previous();
1772
- 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);
1773
1825
  this.addPropertyHints(aaExpr);
1774
1826
  return aaExpr;
1775
1827
  case this.matchAny(lexer_1.TokenKind.Pos, lexer_1.TokenKind.Tab):
@@ -1945,6 +1997,235 @@ class Parser {
1945
1997
  this.advance();
1946
1998
  }
1947
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
+ }
1948
2229
  /**
1949
2230
  * References are found during the initial parse.
1950
2231
  * However, sometimes plugins can modify the AST, requiring a full walk to re-compute all references.
@@ -1952,10 +2233,8 @@ class Parser {
1952
2233
  */
1953
2234
  findReferences() {
1954
2235
  this._references = new References();
2236
+ //gather up all the top-level statements
1955
2237
  this.ast.walk((0, visitors_1.createVisitor)({
1956
- AssignmentStatement: s => {
1957
- this._references.assignmentStatements.push(s);
1958
- },
1959
2238
  ClassStatement: s => {
1960
2239
  this._references.classStatements.push(s);
1961
2240
  },
@@ -1964,12 +2243,22 @@ class Parser {
1964
2243
  },
1965
2244
  FunctionStatement: s => {
1966
2245
  this._references.functionStatements.push(s);
2246
+ //add the initial set of function expressions for function statements
2247
+ this._references.functionExpressions.push(s.func);
1967
2248
  },
1968
2249
  ImportStatement: s => {
1969
2250
  this._references.importStatements.push(s);
1970
2251
  },
1971
2252
  LibraryStatement: s => {
1972
2253
  this._references.libraryStatements.push(s);
2254
+ }
2255
+ }), {
2256
+ walkMode: visitors_1.WalkMode.visitStatements
2257
+ });
2258
+ let func;
2259
+ let visitor = (0, visitors_1.createVisitor)({
2260
+ AssignmentStatement: s => {
2261
+ this._references.assignmentStatements.push(s);
1973
2262
  },
1974
2263
  FunctionExpression: (expression, parent) => {
1975
2264
  if (!(0, reflection_1.isClassMethodStatement)(parent)) {
@@ -1988,9 +2277,27 @@ class Parser {
1988
2277
  DottedSetStatement: e => {
1989
2278
  this.addPropertyHints(e.name);
1990
2279
  }
1991
- }), {
1992
- walkMode: visitors_1.WalkMode.visitAllRecursive
1993
2280
  });
2281
+ //walk all function expressions (we'll add new ones as we move along too)
2282
+ for (let i = 0; i < this._references.functionExpressions.length; i++) {
2283
+ func = this._references.functionExpressions[i];
2284
+ //walk this function expression
2285
+ func.body.walk(visitor, {
2286
+ walkMode: visitors_1.WalkMode.visitAll
2287
+ });
2288
+ }
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));
1994
2301
  }
1995
2302
  dispose() {
1996
2303
  }
@@ -2005,6 +2312,8 @@ class References {
2005
2312
  constructor() {
2006
2313
  this.assignmentStatements = [];
2007
2314
  this.classStatements = [];
2315
+ this.dottedSetStatements = [];
2316
+ this.aaLiterals = [];
2008
2317
  this.functionExpressions = [];
2009
2318
  this.functionStatements = [];
2010
2319
  this.interfaceStatements = [];
@@ -2046,9 +2355,61 @@ class References {
2046
2355
  }
2047
2356
  }
2048
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 = {}));
2049
2364
  class CancelStatementError extends Error {
2050
2365
  constructor() {
2051
2366
  super('CancelStatement');
2052
2367
  }
2053
2368
  }
2369
+ /**
2370
+ * Gets the type of an expression. If it can not be processed, will return DynamicType
2371
+ *
2372
+ * @param expression the Expression to process
2373
+ * @param functionExpression the wrapping function expression
2374
+ * @return the best guess type of that expression
2375
+ */
2376
+ function getBscTypeFromExpression(expression, functionExpression) {
2377
+ try {
2378
+ if ((0, reflection_1.isFunctionExpression)(expression)) {
2379
+ return expression.getFunctionType();
2380
+ //literal
2381
+ }
2382
+ else if ((0, reflection_1.isLiteralExpression)(expression)) {
2383
+ return expression.type;
2384
+ //Associative array literal
2385
+ }
2386
+ else if ((0, reflection_1.isAALiteralExpression)(expression)) {
2387
+ return new ObjectType_1.ObjectType(expression.memberTable);
2388
+ //Array literal
2389
+ }
2390
+ else if ((0, reflection_1.isArrayLiteralExpression)(expression)) {
2391
+ return new ArrayType_1.ArrayType();
2392
+ //function call
2393
+ }
2394
+ else if ((0, reflection_1.isNewExpression)(expression)) {
2395
+ return (0, helpers_1.getTypeFromNewExpression)(expression, functionExpression); // new CustomType(expression.className.getName(ParseMode.BrighterScript));
2396
+ //Function call
2397
+ }
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);
2403
+ }
2404
+ else if ((0, reflection_1.isDottedGetExpression)(expression)) {
2405
+ return (0, helpers_1.getTypeFromDottedGetExpression)(expression, functionExpression);
2406
+ }
2407
+ }
2408
+ catch (e) {
2409
+ //do nothing. Just return dynamic
2410
+ }
2411
+ //fallback to dynamic
2412
+ return new DynamicType_1.DynamicType();
2413
+ }
2414
+ exports.getBscTypeFromExpression = getBscTypeFromExpression;
2054
2415
  //# sourceMappingURL=Parser.js.map