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.
Files changed (316) hide show
  1. package/CHANGELOG.md +362 -248
  2. package/README.md +2 -2
  3. package/bsconfig.schema.json +1 -1
  4. package/dist/CodeActionUtil.d.ts +11 -2
  5. package/dist/CodeActionUtil.js +17 -3
  6. package/dist/CodeActionUtil.js.map +1 -1
  7. package/dist/CommentFlagProcessor.d.ts +4 -4
  8. package/dist/CommentFlagProcessor.js +5 -3
  9. package/dist/CommentFlagProcessor.js.map +1 -1
  10. package/dist/DependencyGraph.js.map +1 -1
  11. package/dist/DiagnosticCollection.js +2 -2
  12. package/dist/DiagnosticCollection.js.map +1 -1
  13. package/dist/DiagnosticFilterer.js +3 -3
  14. package/dist/DiagnosticFilterer.js.map +1 -1
  15. package/dist/DiagnosticMessages.d.ts +15 -5
  16. package/dist/DiagnosticMessages.js +19 -9
  17. package/dist/DiagnosticMessages.js.map +1 -1
  18. package/dist/LanguageServer.d.ts +11 -10
  19. package/dist/LanguageServer.js +87 -58
  20. package/dist/LanguageServer.js.map +1 -1
  21. package/dist/Logger.d.ts +2 -0
  22. package/dist/Logger.js +5 -3
  23. package/dist/Logger.js.map +1 -1
  24. package/dist/Program.d.ts +76 -46
  25. package/dist/Program.js +254 -180
  26. package/dist/Program.js.map +1 -1
  27. package/dist/ProgramBuilder.d.ts +7 -7
  28. package/dist/ProgramBuilder.js +37 -43
  29. package/dist/ProgramBuilder.js.map +1 -1
  30. package/dist/Scope.d.ts +33 -23
  31. package/dist/Scope.js +222 -147
  32. package/dist/Scope.js.map +1 -1
  33. package/dist/SemanticTokenUtils.d.ts +14 -0
  34. package/dist/SemanticTokenUtils.js +81 -0
  35. package/dist/SemanticTokenUtils.js.map +1 -0
  36. package/dist/SymbolTable.d.ts +9 -3
  37. package/dist/SymbolTable.js +40 -13
  38. package/dist/SymbolTable.js.map +1 -1
  39. package/dist/XmlScope.d.ts +7 -2
  40. package/dist/XmlScope.js +67 -29
  41. package/dist/XmlScope.js.map +1 -1
  42. package/dist/astUtils/AstEditor.d.ts +27 -0
  43. package/dist/astUtils/AstEditor.js +97 -0
  44. package/dist/astUtils/AstEditor.js.map +1 -0
  45. package/dist/astUtils/AstEditor.spec.d.ts +1 -0
  46. package/dist/astUtils/AstEditor.spec.js +133 -0
  47. package/dist/astUtils/AstEditor.spec.js.map +1 -0
  48. package/dist/astUtils/creators.d.ts +15 -1
  49. package/dist/astUtils/creators.js +39 -9
  50. package/dist/astUtils/creators.js.map +1 -1
  51. package/dist/astUtils/creators.spec.js +4 -4
  52. package/dist/astUtils/creators.spec.js.map +1 -1
  53. package/dist/astUtils/index.js +1 -1
  54. package/dist/astUtils/reflection.d.ts +20 -8
  55. package/dist/astUtils/reflection.js +42 -1
  56. package/dist/astUtils/reflection.js.map +1 -1
  57. package/dist/astUtils/reflection.spec.js +115 -115
  58. package/dist/astUtils/reflection.spec.js.map +1 -1
  59. package/dist/astUtils/stackedVisitor.js.map +1 -1
  60. package/dist/astUtils/stackedVisitor.spec.js +13 -13
  61. package/dist/astUtils/stackedVisitor.spec.js.map +1 -1
  62. package/dist/astUtils/visitors.js +1 -1
  63. package/dist/astUtils/visitors.js.map +1 -1
  64. package/dist/astUtils/visitors.spec.js +28 -28
  65. package/dist/astUtils/visitors.spec.js.map +1 -1
  66. package/dist/astUtils/xml.d.ts +4 -3
  67. package/dist/astUtils/xml.js +8 -3
  68. package/dist/astUtils/xml.js.map +1 -1
  69. package/dist/bscPlugin/BscPlugin.d.ts +2 -1
  70. package/dist/bscPlugin/BscPlugin.js +4 -0
  71. package/dist/bscPlugin/BscPlugin.js.map +1 -1
  72. package/dist/bscPlugin/codeActions/CodeActionsProcessor.js +5 -6
  73. package/dist/bscPlugin/codeActions/CodeActionsProcessor.js.map +1 -1
  74. package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js +30 -30
  75. package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js.map +1 -1
  76. package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.d.ts +7 -0
  77. package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.js +63 -0
  78. package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.js.map +1 -0
  79. package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.spec.d.ts +1 -0
  80. package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.spec.js +45 -0
  81. package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.spec.js.map +1 -0
  82. package/dist/diagnosticUtils.d.ts +1 -0
  83. package/dist/diagnosticUtils.js +14 -7
  84. package/dist/diagnosticUtils.js.map +1 -1
  85. package/dist/examples/plugins/removePrint.js +2 -2
  86. package/dist/examples/plugins/removePrint.js.map +1 -1
  87. package/dist/files/BrsFile.Class.spec.js +486 -71
  88. package/dist/files/BrsFile.Class.spec.js.map +1 -1
  89. package/dist/files/BrsFile.d.ts +48 -23
  90. package/dist/files/BrsFile.js +403 -233
  91. package/dist/files/BrsFile.js.map +1 -1
  92. package/dist/files/BrsFile.spec.js +367 -316
  93. package/dist/files/BrsFile.spec.js.map +1 -1
  94. package/dist/files/XmlFile.d.ts +13 -6
  95. package/dist/files/XmlFile.js +27 -21
  96. package/dist/files/XmlFile.js.map +1 -1
  97. package/dist/files/XmlFile.spec.js +274 -228
  98. package/dist/files/XmlFile.spec.js.map +1 -1
  99. package/dist/files/tests/imports.spec.js +49 -49
  100. package/dist/files/tests/imports.spec.js.map +1 -1
  101. package/dist/globalCallables.d.ts +3 -1
  102. package/dist/globalCallables.js +359 -87
  103. package/dist/globalCallables.js.map +1 -1
  104. package/dist/index.js +2 -1
  105. package/dist/index.js.map +1 -1
  106. package/dist/interfaces.d.ts +51 -14
  107. package/dist/lexer/Lexer.d.ts +14 -1
  108. package/dist/lexer/Lexer.js +91 -21
  109. package/dist/lexer/Lexer.js.map +1 -1
  110. package/dist/lexer/Lexer.spec.js +187 -132
  111. package/dist/lexer/Lexer.spec.js.map +1 -1
  112. package/dist/lexer/Token.d.ts +2 -2
  113. package/dist/lexer/TokenKind.d.ts +7 -1
  114. package/dist/lexer/TokenKind.js +51 -3
  115. package/dist/lexer/TokenKind.js.map +1 -1
  116. package/dist/lexer/index.js +2 -1
  117. package/dist/lexer/index.js.map +1 -1
  118. package/dist/parser/BrsTranspileState.d.ts +7 -0
  119. package/dist/parser/BrsTranspileState.js +10 -1
  120. package/dist/parser/BrsTranspileState.js.map +1 -1
  121. package/dist/parser/Expression.d.ts +23 -5
  122. package/dist/parser/Expression.js +124 -75
  123. package/dist/parser/Expression.js.map +1 -1
  124. package/dist/parser/Parser.Class.spec.js +159 -60
  125. package/dist/parser/Parser.Class.spec.js.map +1 -1
  126. package/dist/parser/Parser.d.ts +114 -26
  127. package/dist/parser/Parser.js +471 -126
  128. package/dist/parser/Parser.js.map +1 -1
  129. package/dist/parser/Parser.spec.js +396 -235
  130. package/dist/parser/Parser.spec.js.map +1 -1
  131. package/dist/parser/SGParser.d.ts +41 -4
  132. package/dist/parser/SGParser.js +186 -175
  133. package/dist/parser/SGParser.js.map +1 -1
  134. package/dist/parser/SGParser.spec.js +35 -22
  135. package/dist/parser/SGParser.spec.js.map +1 -1
  136. package/dist/parser/SGTypes.d.ts +206 -38
  137. package/dist/parser/SGTypes.js +470 -161
  138. package/dist/parser/SGTypes.js.map +1 -1
  139. package/dist/parser/SGTypes.spec.d.ts +1 -0
  140. package/dist/parser/SGTypes.spec.js +351 -0
  141. package/dist/parser/SGTypes.spec.js.map +1 -0
  142. package/dist/parser/Statement.d.ts +92 -18
  143. package/dist/parser/Statement.js +287 -58
  144. package/dist/parser/Statement.js.map +1 -1
  145. package/dist/parser/Statement.spec.js +11 -11
  146. package/dist/parser/Statement.spec.js.map +1 -1
  147. package/dist/parser/TranspileState.d.ts +1 -1
  148. package/dist/parser/TranspileState.js +15 -7
  149. package/dist/parser/TranspileState.js.map +1 -1
  150. package/dist/parser/index.js +1 -1
  151. package/dist/parser/tests/Parser.spec.d.ts +8 -7
  152. package/dist/parser/tests/Parser.spec.js +12 -8
  153. package/dist/parser/tests/Parser.spec.js.map +1 -1
  154. package/dist/parser/tests/controlFlow/For.spec.js +50 -50
  155. package/dist/parser/tests/controlFlow/For.spec.js.map +1 -1
  156. package/dist/parser/tests/controlFlow/ForEach.spec.js +31 -31
  157. package/dist/parser/tests/controlFlow/ForEach.spec.js.map +1 -1
  158. package/dist/parser/tests/controlFlow/If.spec.js +174 -156
  159. package/dist/parser/tests/controlFlow/If.spec.js.map +1 -1
  160. package/dist/parser/tests/controlFlow/While.spec.js +32 -32
  161. package/dist/parser/tests/controlFlow/While.spec.js.map +1 -1
  162. package/dist/parser/tests/expression/Additive.spec.js +21 -21
  163. package/dist/parser/tests/expression/Additive.spec.js.map +1 -1
  164. package/dist/parser/tests/expression/ArrayLiterals.spec.js +105 -105
  165. package/dist/parser/tests/expression/ArrayLiterals.spec.js.map +1 -1
  166. package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js +148 -124
  167. package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js.map +1 -1
  168. package/dist/parser/tests/expression/Boolean.spec.js +17 -17
  169. package/dist/parser/tests/expression/Boolean.spec.js.map +1 -1
  170. package/dist/parser/tests/expression/Call.spec.js +30 -30
  171. package/dist/parser/tests/expression/Call.spec.js.map +1 -1
  172. package/dist/parser/tests/expression/Exponential.spec.js +16 -16
  173. package/dist/parser/tests/expression/Exponential.spec.js.map +1 -1
  174. package/dist/parser/tests/expression/Function.spec.js +247 -247
  175. package/dist/parser/tests/expression/Function.spec.js.map +1 -1
  176. package/dist/parser/tests/expression/Indexing.spec.js +73 -73
  177. package/dist/parser/tests/expression/Indexing.spec.js.map +1 -1
  178. package/dist/parser/tests/expression/Multiplicative.spec.js +36 -36
  179. package/dist/parser/tests/expression/Multiplicative.spec.js.map +1 -1
  180. package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js +59 -47
  181. package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js.map +1 -1
  182. package/dist/parser/tests/expression/PrefixUnary.spec.js +35 -35
  183. package/dist/parser/tests/expression/PrefixUnary.spec.js.map +1 -1
  184. package/dist/parser/tests/expression/Primary.spec.js +26 -26
  185. package/dist/parser/tests/expression/Primary.spec.js.map +1 -1
  186. package/dist/parser/tests/expression/RegexLiteralExpression.spec.d.ts +1 -0
  187. package/dist/parser/tests/expression/RegexLiteralExpression.spec.js +170 -0
  188. package/dist/parser/tests/expression/RegexLiteralExpression.spec.js.map +1 -0
  189. package/dist/parser/tests/expression/Relational.spec.js +42 -42
  190. package/dist/parser/tests/expression/Relational.spec.js.map +1 -1
  191. package/dist/parser/tests/expression/SourceLiteralExpression.spec.js +8 -8
  192. package/dist/parser/tests/expression/SourceLiteralExpression.spec.js.map +1 -1
  193. package/dist/parser/tests/expression/TemplateStringExpression.spec.js +12 -12
  194. package/dist/parser/tests/expression/TemplateStringExpression.spec.js.map +1 -1
  195. package/dist/parser/tests/expression/TernaryExpression.spec.js +100 -100
  196. package/dist/parser/tests/expression/TernaryExpression.spec.js.map +1 -1
  197. package/dist/parser/tests/statement/AssignmentOperators.spec.js +35 -35
  198. package/dist/parser/tests/statement/AssignmentOperators.spec.js.map +1 -1
  199. package/dist/parser/tests/statement/Declaration.spec.js +39 -39
  200. package/dist/parser/tests/statement/Declaration.spec.js.map +1 -1
  201. package/dist/parser/tests/statement/Dim.spec.js +21 -21
  202. package/dist/parser/tests/statement/Dim.spec.js.map +1 -1
  203. package/dist/parser/tests/statement/Function.spec.js +192 -192
  204. package/dist/parser/tests/statement/Function.spec.js.map +1 -1
  205. package/dist/parser/tests/statement/Goto.spec.js +11 -11
  206. package/dist/parser/tests/statement/Goto.spec.js.map +1 -1
  207. package/dist/parser/tests/statement/Increment.spec.js +46 -46
  208. package/dist/parser/tests/statement/Increment.spec.js.map +1 -1
  209. package/dist/parser/tests/statement/InterfaceStatement.spec.d.ts +1 -0
  210. package/dist/parser/tests/statement/InterfaceStatement.spec.js +61 -0
  211. package/dist/parser/tests/statement/InterfaceStatement.spec.js.map +1 -0
  212. package/dist/parser/tests/statement/LibraryStatement.spec.js +10 -10
  213. package/dist/parser/tests/statement/LibraryStatement.spec.js.map +1 -1
  214. package/dist/parser/tests/statement/Misc.spec.js +37 -36
  215. package/dist/parser/tests/statement/Misc.spec.js.map +1 -1
  216. package/dist/parser/tests/statement/PrintStatement.spec.js +30 -30
  217. package/dist/parser/tests/statement/PrintStatement.spec.js.map +1 -1
  218. package/dist/parser/tests/statement/ReturnStatement.spec.js +43 -43
  219. package/dist/parser/tests/statement/ReturnStatement.spec.js.map +1 -1
  220. package/dist/parser/tests/statement/Set.spec.js +69 -69
  221. package/dist/parser/tests/statement/Set.spec.js.map +1 -1
  222. package/dist/parser/tests/statement/Stop.spec.js +9 -9
  223. package/dist/parser/tests/statement/Stop.spec.js.map +1 -1
  224. package/dist/parser/tests/statement/Throw.spec.js +5 -5
  225. package/dist/parser/tests/statement/Throw.spec.js.map +1 -1
  226. package/dist/parser/tests/statement/TryCatch.spec.js +13 -13
  227. package/dist/parser/tests/statement/TryCatch.spec.js.map +1 -1
  228. package/dist/preprocessor/Chunk.js.map +1 -1
  229. package/dist/preprocessor/Manifest.d.ts +1 -1
  230. package/dist/preprocessor/Preprocessor.js +1 -1
  231. package/dist/preprocessor/Preprocessor.js.map +1 -1
  232. package/dist/preprocessor/Preprocessor.spec.js +49 -49
  233. package/dist/preprocessor/Preprocessor.spec.js.map +1 -1
  234. package/dist/preprocessor/PreprocessorParser.spec.js +72 -72
  235. package/dist/preprocessor/PreprocessorParser.spec.js.map +1 -1
  236. package/dist/preprocessor/index.js +1 -1
  237. package/dist/types/ArrayType.js +5 -4
  238. package/dist/types/ArrayType.js.map +1 -1
  239. package/dist/types/ArrayType.spec.js +8 -8
  240. package/dist/types/ArrayType.spec.js.map +1 -1
  241. package/dist/types/BooleanType.js +3 -3
  242. package/dist/types/BooleanType.js.map +1 -1
  243. package/dist/types/BooleanType.spec.js +2 -2
  244. package/dist/types/BooleanType.spec.js.map +1 -1
  245. package/dist/types/BscType.d.ts +19 -5
  246. package/dist/types/BscType.js +9 -0
  247. package/dist/types/BscType.js.map +1 -1
  248. package/dist/types/CustomType.d.ts +8 -5
  249. package/dist/types/CustomType.js +17 -6
  250. package/dist/types/CustomType.js.map +1 -1
  251. package/dist/types/DoubleType.js +8 -8
  252. package/dist/types/DoubleType.js.map +1 -1
  253. package/dist/types/DoubleType.spec.js +2 -2
  254. package/dist/types/DoubleType.spec.js.map +1 -1
  255. package/dist/types/DynamicType.js +1 -1
  256. package/dist/types/DynamicType.js.map +1 -1
  257. package/dist/types/DynamicType.spec.js +2 -2
  258. package/dist/types/DynamicType.spec.js.map +1 -1
  259. package/dist/types/FloatType.d.ts +1 -1
  260. package/dist/types/FloatType.js +8 -8
  261. package/dist/types/FloatType.js.map +1 -1
  262. package/dist/types/FloatType.spec.js +2 -2
  263. package/dist/types/FloatType.spec.js.map +1 -1
  264. package/dist/types/FunctionType.d.ts +5 -11
  265. package/dist/types/FunctionType.js +24 -13
  266. package/dist/types/FunctionType.js.map +1 -1
  267. package/dist/types/FunctionType.spec.js +11 -5
  268. package/dist/types/FunctionType.spec.js.map +1 -1
  269. package/dist/types/IntegerType.d.ts +1 -1
  270. package/dist/types/IntegerType.js +8 -8
  271. package/dist/types/IntegerType.js.map +1 -1
  272. package/dist/types/IntegerType.spec.js +2 -2
  273. package/dist/types/IntegerType.spec.js.map +1 -1
  274. package/dist/types/InterfaceType.d.ts +8 -2
  275. package/dist/types/InterfaceType.js +42 -6
  276. package/dist/types/InterfaceType.js.map +1 -1
  277. package/dist/types/InterfaceType.spec.d.ts +1 -0
  278. package/dist/types/InterfaceType.spec.js +174 -0
  279. package/dist/types/InterfaceType.spec.js.map +1 -0
  280. package/dist/types/InvalidType.js +4 -4
  281. package/dist/types/InvalidType.js.map +1 -1
  282. package/dist/types/InvalidType.spec.js +2 -2
  283. package/dist/types/InvalidType.spec.js.map +1 -1
  284. package/dist/types/LazyType.d.ts +9 -7
  285. package/dist/types/LazyType.js +22 -10
  286. package/dist/types/LazyType.js.map +1 -1
  287. package/dist/types/LongIntegerType.d.ts +1 -1
  288. package/dist/types/LongIntegerType.js +8 -8
  289. package/dist/types/LongIntegerType.js.map +1 -1
  290. package/dist/types/LongIntegerType.spec.js +2 -2
  291. package/dist/types/LongIntegerType.spec.js.map +1 -1
  292. package/dist/types/ObjectType.d.ts +7 -4
  293. package/dist/types/ObjectType.js +6 -3
  294. package/dist/types/ObjectType.js.map +1 -1
  295. package/dist/types/ObjectType.spec.js +2 -2
  296. package/dist/types/ObjectType.spec.js.map +1 -1
  297. package/dist/types/StringType.js +3 -3
  298. package/dist/types/StringType.js.map +1 -1
  299. package/dist/types/StringType.spec.js +2 -2
  300. package/dist/types/StringType.spec.js.map +1 -1
  301. package/dist/types/UninitializedType.js +3 -3
  302. package/dist/types/UninitializedType.js.map +1 -1
  303. package/dist/types/VoidType.js +3 -3
  304. package/dist/types/VoidType.js.map +1 -1
  305. package/dist/types/VoidType.spec.js +2 -2
  306. package/dist/types/VoidType.spec.js.map +1 -1
  307. package/dist/types/helpers.d.ts +42 -0
  308. package/dist/types/helpers.js +113 -0
  309. package/dist/types/helpers.js.map +1 -0
  310. package/dist/util.d.ts +77 -17
  311. package/dist/util.js +247 -59
  312. package/dist/util.js.map +1 -1
  313. package/dist/validators/ClassValidator.d.ts +5 -1
  314. package/dist/validators/ClassValidator.js +59 -24
  315. package/dist/validators/ClassValidator.js.map +1 -1
  316. package/package.json +13 -13
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getTypeFromVariableExpression = exports.getTypeFromCallExpression = exports.getBscTypeFromExpression = 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");
@@ -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.expectedClassKeyword(), lexer_1.TokenKind.Class);
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) && !this.check(lexer_1.TokenKind.Identifier)) {
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.foundUnexpectedToken(this.peek().text), lexer_1.TokenKind.Dot);
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.foundUnexpectedToken(token.text)), { range: token.range }));
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.tryConsume(DiagnosticMessages_1.DiagnosticMessages.expectedTokenAButFoundTokenB(lexer_1.TokenKind.Colon, this.peek().text), lexer_1.TokenKind.Colon);
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.foundUnexpectedToken(colon.text)), { range: colon.range }));
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, this.peek().range);
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
- return new Statement_1.DottedSetStatement(left.obj, left.name, operator.kind === lexer_1.TokenKind.Equal
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.foundUnexpectedToken(this.peek().text), lexer_1.TokenKind.LeftParen);
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 always return a token of whatever is next to be parsed
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
- members.push(new Expression_1.AAMemberExpression(k.keyToken, k.colonToken, expr));
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
- while (this.matchAny(lexer_1.TokenKind.Newline, lexer_1.TokenKind.Colon)) {
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
- members.push(new Expression_1.AAMemberExpression(k.keyToken, k.colonToken, expr));
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.foundUnexpectedToken(this.peek().text)), { range: this.peek().range }));
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
- //function
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 CustomType_1.CustomType(expression.className.getName(ParseMode.BrighterScript));
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.isVariableExpression(expression)) {
2008
- return getTypeFromVariableExpression(expression, functionExpression);
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