brighterscript 0.42.0 → 0.43.0

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 (148) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/LanguageServer.js +0 -9
  3. package/dist/LanguageServer.js.map +1 -1
  4. package/dist/Program.d.ts +1 -1
  5. package/dist/Program.js +35 -9
  6. package/dist/Program.js.map +1 -1
  7. package/dist/ProgramBuilder.js +3 -3
  8. package/dist/ProgramBuilder.js.map +1 -1
  9. package/dist/Scope.d.ts +3 -2
  10. package/dist/Scope.js +13 -13
  11. package/dist/Scope.js.map +1 -1
  12. package/dist/astUtils/reflection.d.ts +2 -1
  13. package/dist/astUtils/reflection.js +6 -2
  14. package/dist/astUtils/reflection.js.map +1 -1
  15. package/dist/astUtils/reflection.spec.js +6 -6
  16. package/dist/astUtils/reflection.spec.js.map +1 -1
  17. package/dist/astUtils/visitors.spec.js +13 -16
  18. package/dist/astUtils/visitors.spec.js.map +1 -1
  19. package/dist/bscPlugin/codeActions/CodeActionsProcessor.js +3 -3
  20. package/dist/bscPlugin/codeActions/CodeActionsProcessor.js.map +1 -1
  21. package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.js +4 -4
  22. package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.js.map +1 -1
  23. package/dist/files/BrsFile.Class.spec.js +182 -78
  24. package/dist/files/BrsFile.Class.spec.js.map +1 -1
  25. package/dist/files/BrsFile.d.ts +11 -5
  26. package/dist/files/BrsFile.js +106 -67
  27. package/dist/files/BrsFile.js.map +1 -1
  28. package/dist/files/BrsFile.spec.js +150 -101
  29. package/dist/files/BrsFile.spec.js.map +1 -1
  30. package/dist/files/XmlFile.d.ts +1 -0
  31. package/dist/files/XmlFile.js +9 -8
  32. package/dist/files/XmlFile.js.map +1 -1
  33. package/dist/files/XmlFile.spec.js +41 -39
  34. package/dist/files/XmlFile.spec.js.map +1 -1
  35. package/dist/files/tests/imports.spec.js +6 -4
  36. package/dist/files/tests/imports.spec.js.map +1 -1
  37. package/dist/index.d.ts +12 -3
  38. package/dist/index.js +21 -4
  39. package/dist/index.js.map +1 -1
  40. package/dist/interfaces.d.ts +21 -1
  41. package/dist/lexer/Lexer.js +1 -2
  42. package/dist/lexer/Lexer.js.map +1 -1
  43. package/dist/lexer/Lexer.spec.js +462 -462
  44. package/dist/lexer/Lexer.spec.js.map +1 -1
  45. package/dist/parser/Expression.d.ts +1 -1
  46. package/dist/parser/Expression.js +10 -10
  47. package/dist/parser/Expression.js.map +1 -1
  48. package/dist/parser/Parser.Class.spec.js +32 -31
  49. package/dist/parser/Parser.Class.spec.js.map +1 -1
  50. package/dist/parser/Parser.d.ts +13 -1
  51. package/dist/parser/Parser.js +355 -253
  52. package/dist/parser/Parser.js.map +1 -1
  53. package/dist/parser/Parser.spec.js +86 -24
  54. package/dist/parser/Parser.spec.js.map +1 -1
  55. package/dist/parser/Statement.d.ts +2 -2
  56. package/dist/parser/Statement.js +8 -8
  57. package/dist/parser/Statement.js.map +1 -1
  58. package/dist/parser/Statement.spec.js +4 -4
  59. package/dist/parser/Statement.spec.js.map +1 -1
  60. package/dist/parser/tests/Parser.spec.d.ts +3 -3
  61. package/dist/parser/tests/Parser.spec.js +4 -4
  62. package/dist/parser/tests/Parser.spec.js.map +1 -1
  63. package/dist/parser/tests/controlFlow/For.spec.js +40 -40
  64. package/dist/parser/tests/controlFlow/For.spec.js.map +1 -1
  65. package/dist/parser/tests/controlFlow/ForEach.spec.js +22 -21
  66. package/dist/parser/tests/controlFlow/ForEach.spec.js.map +1 -1
  67. package/dist/parser/tests/controlFlow/If.spec.js +100 -99
  68. package/dist/parser/tests/controlFlow/If.spec.js.map +1 -1
  69. package/dist/parser/tests/controlFlow/While.spec.js +25 -25
  70. package/dist/parser/tests/controlFlow/While.spec.js.map +1 -1
  71. package/dist/parser/tests/expression/Additive.spec.js +21 -21
  72. package/dist/parser/tests/expression/Additive.spec.js.map +1 -1
  73. package/dist/parser/tests/expression/ArrayLiterals.spec.js +91 -91
  74. package/dist/parser/tests/expression/ArrayLiterals.spec.js.map +1 -1
  75. package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js +102 -102
  76. package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js.map +1 -1
  77. package/dist/parser/tests/expression/Boolean.spec.js +15 -15
  78. package/dist/parser/tests/expression/Boolean.spec.js.map +1 -1
  79. package/dist/parser/tests/expression/Call.spec.js +22 -21
  80. package/dist/parser/tests/expression/Call.spec.js.map +1 -1
  81. package/dist/parser/tests/expression/Exponential.spec.js +11 -11
  82. package/dist/parser/tests/expression/Exponential.spec.js.map +1 -1
  83. package/dist/parser/tests/expression/Function.spec.js +171 -171
  84. package/dist/parser/tests/expression/Function.spec.js.map +1 -1
  85. package/dist/parser/tests/expression/Indexing.spec.js +50 -50
  86. package/dist/parser/tests/expression/Indexing.spec.js.map +1 -1
  87. package/dist/parser/tests/expression/Multiplicative.spec.js +25 -25
  88. package/dist/parser/tests/expression/Multiplicative.spec.js.map +1 -1
  89. package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js +16 -16
  90. package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js.map +1 -1
  91. package/dist/parser/tests/expression/PrefixUnary.spec.js +26 -26
  92. package/dist/parser/tests/expression/PrefixUnary.spec.js.map +1 -1
  93. package/dist/parser/tests/expression/Primary.spec.js +27 -27
  94. package/dist/parser/tests/expression/Primary.spec.js.map +1 -1
  95. package/dist/parser/tests/expression/RegexLiteralExpression.spec.js +3 -2
  96. package/dist/parser/tests/expression/RegexLiteralExpression.spec.js.map +1 -1
  97. package/dist/parser/tests/expression/Relational.spec.js +25 -25
  98. package/dist/parser/tests/expression/Relational.spec.js.map +1 -1
  99. package/dist/parser/tests/expression/TemplateStringExpression.spec.js +7 -7
  100. package/dist/parser/tests/expression/TemplateStringExpression.spec.js.map +1 -1
  101. package/dist/parser/tests/expression/TernaryExpression.spec.js +6 -6
  102. package/dist/parser/tests/expression/TernaryExpression.spec.js.map +1 -1
  103. package/dist/parser/tests/statement/AssignmentOperators.spec.js +15 -15
  104. package/dist/parser/tests/statement/AssignmentOperators.spec.js.map +1 -1
  105. package/dist/parser/tests/statement/Declaration.spec.js +20 -20
  106. package/dist/parser/tests/statement/Declaration.spec.js.map +1 -1
  107. package/dist/parser/tests/statement/Function.spec.js +121 -120
  108. package/dist/parser/tests/statement/Function.spec.js.map +1 -1
  109. package/dist/parser/tests/statement/Goto.spec.js +9 -8
  110. package/dist/parser/tests/statement/Goto.spec.js.map +1 -1
  111. package/dist/parser/tests/statement/Increment.spec.js +22 -22
  112. package/dist/parser/tests/statement/Increment.spec.js.map +1 -1
  113. package/dist/parser/tests/statement/InterfaceStatement.spec.js +12 -0
  114. package/dist/parser/tests/statement/InterfaceStatement.spec.js.map +1 -1
  115. package/dist/parser/tests/statement/LibraryStatement.spec.js +7 -7
  116. package/dist/parser/tests/statement/LibraryStatement.spec.js.map +1 -1
  117. package/dist/parser/tests/statement/Misc.spec.js +71 -70
  118. package/dist/parser/tests/statement/Misc.spec.js.map +1 -1
  119. package/dist/parser/tests/statement/PrintStatement.spec.js +17 -17
  120. package/dist/parser/tests/statement/PrintStatement.spec.js.map +1 -1
  121. package/dist/parser/tests/statement/ReturnStatement.spec.js +33 -33
  122. package/dist/parser/tests/statement/ReturnStatement.spec.js.map +1 -1
  123. package/dist/parser/tests/statement/Set.spec.js +53 -53
  124. package/dist/parser/tests/statement/Set.spec.js.map +1 -1
  125. package/dist/parser/tests/statement/Stop.spec.js +7 -6
  126. package/dist/parser/tests/statement/Stop.spec.js.map +1 -1
  127. package/dist/preprocessor/Chunk.d.ts +1 -1
  128. package/dist/preprocessor/Preprocessor.d.ts +1 -1
  129. package/dist/preprocessor/Preprocessor.js +7 -7
  130. package/dist/preprocessor/Preprocessor.js.map +1 -1
  131. package/dist/util.d.ts +5 -1
  132. package/dist/util.js +36 -29
  133. package/dist/util.js.map +1 -1
  134. package/dist/validators/ClassValidator.js +20 -27
  135. package/dist/validators/ClassValidator.js.map +1 -1
  136. package/package.json +2 -1
  137. package/dist/astUtils/index.d.ts +0 -7
  138. package/dist/astUtils/index.js +0 -26
  139. package/dist/astUtils/index.js.map +0 -1
  140. package/dist/lexer/index.d.ts +0 -3
  141. package/dist/lexer/index.js +0 -18
  142. package/dist/lexer/index.js.map +0 -1
  143. package/dist/parser/index.d.ts +0 -3
  144. package/dist/parser/index.js +0 -16
  145. package/dist/parser/index.js.map +0 -1
  146. package/dist/preprocessor/index.d.ts +0 -3
  147. package/dist/preprocessor/index.js +0 -16
  148. package/dist/preprocessor/index.js.map +0 -1
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.References = exports.ParseMode = exports.Parser = void 0;
4
- const lexer_1 = require("../lexer");
4
+ const Token_1 = require("../lexer/Token");
5
+ const Lexer_1 = require("../lexer/Lexer");
6
+ const TokenKind_1 = require("../lexer/TokenKind");
5
7
  const Statement_1 = require("./Statement");
6
8
  const DiagnosticMessages_1 = require("../DiagnosticMessages");
7
9
  const util_1 = require("../util");
@@ -10,7 +12,6 @@ const Logger_1 = require("../Logger");
10
12
  const reflection_1 = require("../astUtils/reflection");
11
13
  const visitors_1 = require("../astUtils/visitors");
12
14
  const creators_1 = require("../astUtils/creators");
13
- const _1 = require(".");
14
15
  class Parser {
15
16
  constructor() {
16
17
  /**
@@ -51,7 +52,7 @@ class Parser {
51
52
  this._references = undefined;
52
53
  }
53
54
  addPropertyHints(item) {
54
- if ((0, lexer_1.isToken)(item)) {
55
+ if ((0, Token_1.isToken)(item)) {
55
56
  const name = item.text;
56
57
  this._references.propertyHints[name.toLowerCase()] = name;
57
58
  }
@@ -79,7 +80,7 @@ class Parser {
79
80
  static parse(toParse, options) {
80
81
  let tokens;
81
82
  if (typeof toParse === 'string') {
82
- tokens = lexer_1.Lexer.scan(toParse).tokens;
83
+ tokens = Lexer_1.Lexer.scan(toParse).tokens;
83
84
  }
84
85
  else {
85
86
  tokens = toParse;
@@ -97,9 +98,9 @@ class Parser {
97
98
  this.tokens = tokens;
98
99
  this.options = this.sanitizeParseOptions(options);
99
100
  this.allowedLocalIdentifiers = [
100
- ...lexer_1.AllowedLocalIdentifiers,
101
+ ...TokenKind_1.AllowedLocalIdentifiers,
101
102
  //when in plain brightscript mode, the BrighterScript source literals can be used as regular variables
102
- ...(this.options.mode === ParseMode.BrightScript ? lexer_1.BrighterScriptSourceLiterals : [])
103
+ ...(this.options.mode === ParseMode.BrightScript ? TokenKind_1.BrighterScriptSourceLiterals : [])
103
104
  ];
104
105
  this.current = 0;
105
106
  this.diagnostics = [];
@@ -170,16 +171,16 @@ class Parser {
170
171
  }
171
172
  declaration() {
172
173
  try {
173
- if (this.checkAny(lexer_1.TokenKind.Sub, lexer_1.TokenKind.Function)) {
174
+ if (this.checkAny(TokenKind_1.TokenKind.Sub, TokenKind_1.TokenKind.Function)) {
174
175
  return this.functionDeclaration(false);
175
176
  }
176
177
  if (this.checkLibrary()) {
177
178
  return this.libraryStatement();
178
179
  }
179
- if (this.check(lexer_1.TokenKind.At) && this.checkNext(lexer_1.TokenKind.Identifier)) {
180
+ if (this.check(TokenKind_1.TokenKind.At) && this.checkNext(TokenKind_1.TokenKind.Identifier)) {
180
181
  return this.annotationExpression();
181
182
  }
182
- if (this.check(lexer_1.TokenKind.Comment)) {
183
+ if (this.check(TokenKind_1.TokenKind.Comment)) {
183
184
  return this.commentStatement();
184
185
  }
185
186
  //catch certain global terminators to prevent unnecessary lookahead (i.e. like `end namespace`, no need to continue)
@@ -197,17 +198,17 @@ class Parser {
197
198
  }
198
199
  }
199
200
  identifier(...additionalTokenKinds) {
200
- const identifier = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier(), lexer_1.TokenKind.Identifier, ...additionalTokenKinds);
201
+ const identifier = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier(), TokenKind_1.TokenKind.Identifier, ...additionalTokenKinds);
201
202
  // force the name into an identifier so the AST makes some sense
202
- identifier.kind = lexer_1.TokenKind.Identifier;
203
+ identifier.kind = TokenKind_1.TokenKind.Identifier;
203
204
  return identifier;
204
205
  }
205
206
  /**
206
207
  * Create a new InterfaceMethodStatement. This should only be called from within `interfaceDeclaration`
207
208
  */
208
209
  interfaceFieldStatement() {
209
- const name = this.identifier(...lexer_1.AllowedProperties);
210
- let asToken = this.consumeToken(lexer_1.TokenKind.As);
210
+ const name = this.identifier(...TokenKind_1.AllowedProperties);
211
+ let asToken = this.consumeToken(TokenKind_1.TokenKind.As);
211
212
  let typeToken = this.typeToken();
212
213
  const type = util_1.util.tokenToBscType(typeToken);
213
214
  if (!type) {
@@ -221,13 +222,13 @@ class Parser {
221
222
  */
222
223
  interfaceMethodStatement() {
223
224
  const functionType = this.advance();
224
- const name = this.identifier(...lexer_1.AllowedProperties);
225
- const leftParen = this.consumeToken(lexer_1.TokenKind.LeftParen);
225
+ const name = this.identifier(...TokenKind_1.AllowedProperties);
226
+ const leftParen = this.consumeToken(TokenKind_1.TokenKind.LeftParen);
226
227
  const params = [];
227
- const rightParen = this.consumeToken(lexer_1.TokenKind.RightParen);
228
+ const rightParen = this.consumeToken(TokenKind_1.TokenKind.RightParen);
228
229
  let asToken = null;
229
230
  let returnTypeToken = null;
230
- if (this.check(lexer_1.TokenKind.As)) {
231
+ if (this.check(TokenKind_1.TokenKind.As)) {
231
232
  asToken = this.advance();
232
233
  returnTypeToken = this.typeToken();
233
234
  const returnType = util_1.util.tokenToBscType(returnTypeToken);
@@ -241,7 +242,7 @@ class Parser {
241
242
  interfaceDeclaration() {
242
243
  this.warnIfNotBrighterScriptMode('interface declarations');
243
244
  const parentAnnotations = this.enterAnnotationBlock();
244
- const interfaceToken = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedKeyword(lexer_1.TokenKind.Interface), lexer_1.TokenKind.Interface);
245
+ const interfaceToken = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedKeyword(TokenKind_1.TokenKind.Interface), TokenKind_1.TokenKind.Interface);
245
246
  const nameToken = this.identifier();
246
247
  let extendsToken;
247
248
  let parentInterfaceName;
@@ -252,23 +253,23 @@ class Parser {
252
253
  this.consumeStatementSeparators();
253
254
  //gather up all interface members (Fields, Methods)
254
255
  let body = [];
255
- while (this.checkAny(lexer_1.TokenKind.Comment, lexer_1.TokenKind.Identifier, lexer_1.TokenKind.At, ...lexer_1.AllowedProperties)) {
256
+ while (this.checkAny(TokenKind_1.TokenKind.Comment, TokenKind_1.TokenKind.Identifier, TokenKind_1.TokenKind.At, ...TokenKind_1.AllowedProperties)) {
256
257
  try {
257
258
  let decl;
258
259
  //collect leading annotations
259
- if (this.check(lexer_1.TokenKind.At)) {
260
+ if (this.check(TokenKind_1.TokenKind.At)) {
260
261
  this.annotationExpression();
261
262
  }
262
263
  //fields
263
- if (this.checkAny(lexer_1.TokenKind.Identifier, ...lexer_1.AllowedProperties) && this.checkNext(lexer_1.TokenKind.As)) {
264
+ if (this.checkAny(TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedProperties) && this.checkNext(TokenKind_1.TokenKind.As)) {
264
265
  decl = this.interfaceFieldStatement();
265
266
  //methods (function/sub keyword followed by opening paren)
266
267
  }
267
- else if (this.checkAny(lexer_1.TokenKind.Function, lexer_1.TokenKind.Sub) && this.checkAny(lexer_1.TokenKind.Identifier, ...lexer_1.AllowedProperties)) {
268
+ else if (this.checkAny(TokenKind_1.TokenKind.Function, TokenKind_1.TokenKind.Sub) && this.checkAny(TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedProperties)) {
268
269
  decl = this.interfaceMethodStatement();
269
270
  //comments
270
271
  }
271
- else if (this.check(lexer_1.TokenKind.Comment)) {
272
+ else if (this.check(TokenKind_1.TokenKind.Comment)) {
272
273
  decl = this.commentStatement();
273
274
  }
274
275
  if (decl) {
@@ -277,23 +278,22 @@ class Parser {
277
278
  }
278
279
  else {
279
280
  //we didn't find a declaration...flag tokens until next line
280
- this.flagUntil(lexer_1.TokenKind.Newline, lexer_1.TokenKind.Colon, lexer_1.TokenKind.Eof);
281
+ this.flagUntil(TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Colon, TokenKind_1.TokenKind.Eof);
281
282
  }
282
283
  }
283
284
  catch (e) {
284
285
  //throw out any failed members and move on to the next line
285
- this.flagUntil(lexer_1.TokenKind.Newline, lexer_1.TokenKind.Colon, lexer_1.TokenKind.Eof);
286
+ this.flagUntil(TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Colon, TokenKind_1.TokenKind.Eof);
286
287
  }
287
288
  //ensure statement separator
288
289
  this.consumeStatementSeparators();
289
290
  //break out of this loop if we encountered the `EndInterface` token not followed by `as`
290
- if (this.check(lexer_1.TokenKind.EndInterface) && !this.checkNext(lexer_1.TokenKind.As)) {
291
+ if (this.check(TokenKind_1.TokenKind.EndInterface) && !this.checkNext(TokenKind_1.TokenKind.As)) {
291
292
  break;
292
293
  }
293
294
  }
294
295
  //consume the final `end interface` token
295
- const endInterfaceToken = this.consumeToken(lexer_1.TokenKind.EndInterface);
296
- this.consumeStatementSeparators();
296
+ const endInterfaceToken = this.consumeToken(TokenKind_1.TokenKind.EndInterface);
297
297
  const statement = new Statement_1.InterfaceStatement(interfaceToken, nameToken, extendsToken, parentInterfaceName, body, endInterfaceToken, this.currentNamespaceName);
298
298
  this._references.interfaceStatements.push(statement);
299
299
  this.exitAnnotationBlock(parentAnnotations);
@@ -305,11 +305,11 @@ class Parser {
305
305
  classDeclaration() {
306
306
  this.warnIfNotBrighterScriptMode('class declarations');
307
307
  const parentAnnotations = this.enterAnnotationBlock();
308
- let classKeyword = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedKeyword(lexer_1.TokenKind.Class), lexer_1.TokenKind.Class);
308
+ let classKeyword = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedKeyword(TokenKind_1.TokenKind.Class), TokenKind_1.TokenKind.Class);
309
309
  let extendsKeyword;
310
310
  let parentClassName;
311
311
  //get the class name
312
- let className = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifierAfterKeyword('class'), lexer_1.TokenKind.Identifier, ...this.allowedLocalIdentifiers);
312
+ let className = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifierAfterKeyword('class'), TokenKind_1.TokenKind.Identifier, ...this.allowedLocalIdentifiers);
313
313
  //see if the class inherits from parent
314
314
  if (this.peek().text.toLowerCase() === 'extends') {
315
315
  extendsKeyword = this.advance();
@@ -319,14 +319,14 @@ class Parser {
319
319
  this.consumeStatementSeparators();
320
320
  //gather up all class members (Fields, Methods)
321
321
  let body = [];
322
- while (this.checkAny(lexer_1.TokenKind.Public, lexer_1.TokenKind.Protected, lexer_1.TokenKind.Private, lexer_1.TokenKind.Function, lexer_1.TokenKind.Sub, lexer_1.TokenKind.Comment, lexer_1.TokenKind.Identifier, lexer_1.TokenKind.At, ...lexer_1.AllowedProperties)) {
322
+ while (this.checkAny(TokenKind_1.TokenKind.Public, TokenKind_1.TokenKind.Protected, TokenKind_1.TokenKind.Private, TokenKind_1.TokenKind.Function, TokenKind_1.TokenKind.Sub, TokenKind_1.TokenKind.Comment, TokenKind_1.TokenKind.Identifier, TokenKind_1.TokenKind.At, ...TokenKind_1.AllowedProperties)) {
323
323
  try {
324
324
  let decl;
325
325
  let accessModifier;
326
- if (this.check(lexer_1.TokenKind.At)) {
326
+ if (this.check(TokenKind_1.TokenKind.At)) {
327
327
  this.annotationExpression();
328
328
  }
329
- if (this.checkAny(lexer_1.TokenKind.Public, lexer_1.TokenKind.Protected, lexer_1.TokenKind.Private)) {
329
+ if (this.checkAny(TokenKind_1.TokenKind.Public, TokenKind_1.TokenKind.Protected, TokenKind_1.TokenKind.Private)) {
330
330
  //use actual access modifier
331
331
  accessModifier = this.advance();
332
332
  }
@@ -335,7 +335,7 @@ class Parser {
335
335
  overrideKeyword = this.advance();
336
336
  }
337
337
  //methods (function/sub keyword OR identifier followed by opening paren)
338
- 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))) {
338
+ if (this.checkAny(TokenKind_1.TokenKind.Function, TokenKind_1.TokenKind.Sub) || (this.checkAny(TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedProperties) && this.checkNext(TokenKind_1.TokenKind.LeftParen))) {
339
339
  const funcDeclaration = this.functionDeclaration(false, false);
340
340
  //remove this function from the lists because it's not a callable
341
341
  const functionStatement = this._references.functionStatements.pop();
@@ -348,7 +348,7 @@ class Parser {
348
348
  functionStatement.func.functionStatement = decl;
349
349
  //fields
350
350
  }
351
- else if (this.checkAny(lexer_1.TokenKind.Identifier, ...lexer_1.AllowedProperties)) {
351
+ else if (this.checkAny(TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedProperties)) {
352
352
  decl = this.classFieldDeclaration(accessModifier);
353
353
  //class fields cannot be overridden
354
354
  if (overrideKeyword) {
@@ -356,7 +356,7 @@ class Parser {
356
356
  }
357
357
  //comments
358
358
  }
359
- else if (this.check(lexer_1.TokenKind.Comment)) {
359
+ else if (this.check(TokenKind_1.TokenKind.Comment)) {
360
360
  decl = this.commentStatement();
361
361
  }
362
362
  if (decl) {
@@ -366,13 +366,13 @@ class Parser {
366
366
  }
367
367
  catch (e) {
368
368
  //throw out any failed members and move on to the next line
369
- this.flagUntil(lexer_1.TokenKind.Newline, lexer_1.TokenKind.Colon, lexer_1.TokenKind.Eof);
369
+ this.flagUntil(TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Colon, TokenKind_1.TokenKind.Eof);
370
370
  }
371
371
  //ensure statement separator
372
372
  this.consumeStatementSeparators();
373
373
  }
374
374
  let endingKeyword = this.advance();
375
- if (endingKeyword.kind !== lexer_1.TokenKind.EndClass) {
375
+ if (endingKeyword.kind !== TokenKind_1.TokenKind.EndClass) {
376
376
  this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.couldNotFindMatchingEndKeyword('class')), { range: endingKeyword.range }));
377
377
  }
378
378
  const result = new Statement_1.ClassStatement(classKeyword, className, body, endingKeyword, extendsKeyword, parentClassName, this.currentNamespaceName);
@@ -381,11 +381,11 @@ class Parser {
381
381
  return result;
382
382
  }
383
383
  classFieldDeclaration(accessModifier) {
384
- let name = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedClassFieldIdentifier(), lexer_1.TokenKind.Identifier, ...lexer_1.AllowedProperties);
384
+ let name = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedClassFieldIdentifier(), TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedProperties);
385
385
  let asToken;
386
386
  let fieldType;
387
387
  //look for `as SOME_TYPE`
388
- if (this.check(lexer_1.TokenKind.As)) {
388
+ if (this.check(TokenKind_1.TokenKind.As)) {
389
389
  asToken = this.advance();
390
390
  fieldType = this.typeToken();
391
391
  //no field type specified
@@ -396,7 +396,7 @@ class Parser {
396
396
  let initialValue;
397
397
  let equal;
398
398
  //if there is a field initializer
399
- if (this.check(lexer_1.TokenKind.Equal)) {
399
+ if (this.check(TokenKind_1.TokenKind.Equal)) {
400
400
  equal = this.advance();
401
401
  initialValue = this.expression();
402
402
  }
@@ -410,14 +410,14 @@ class Parser {
410
410
  //track depth to help certain statements need to know if they are contained within a function body
411
411
  this.namespaceAndFunctionDepth++;
412
412
  let functionType;
413
- if (this.checkAny(lexer_1.TokenKind.Sub, lexer_1.TokenKind.Function)) {
413
+ if (this.checkAny(TokenKind_1.TokenKind.Sub, TokenKind_1.TokenKind.Function)) {
414
414
  functionType = this.advance();
415
415
  }
416
416
  else {
417
417
  this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.missingCallableKeyword()), { range: this.peek().range }));
418
418
  functionType = {
419
419
  isReserved: true,
420
- kind: lexer_1.TokenKind.Function,
420
+ kind: TokenKind_1.TokenKind.Function,
421
421
  text: 'function',
422
422
  //zero-length location means derived
423
423
  range: {
@@ -427,16 +427,16 @@ class Parser {
427
427
  leadingWhitespace: ''
428
428
  };
429
429
  }
430
- let isSub = (functionType === null || functionType === void 0 ? void 0 : functionType.kind) === lexer_1.TokenKind.Sub;
430
+ let isSub = (functionType === null || functionType === void 0 ? void 0 : functionType.kind) === TokenKind_1.TokenKind.Sub;
431
431
  let functionTypeText = isSub ? 'sub' : 'function';
432
432
  let name;
433
433
  let leftParen;
434
434
  if (isAnonymous) {
435
- leftParen = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedLeftParenAfterCallable(functionTypeText), lexer_1.TokenKind.LeftParen);
435
+ leftParen = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedLeftParenAfterCallable(functionTypeText), TokenKind_1.TokenKind.LeftParen);
436
436
  }
437
437
  else {
438
- name = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedNameAfterCallableKeyword(functionTypeText), lexer_1.TokenKind.Identifier, ...lexer_1.AllowedProperties);
439
- leftParen = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedLeftParenAfterCallableName(functionTypeText), lexer_1.TokenKind.LeftParen);
438
+ name = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedNameAfterCallableKeyword(functionTypeText), TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedProperties);
439
+ leftParen = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedLeftParenAfterCallableName(functionTypeText), TokenKind_1.TokenKind.LeftParen);
440
440
  //prevent functions from ending with type designators
441
441
  let lastChar = name.text[name.text.length - 1];
442
442
  if (['$', '%', '!', '#', '&'].includes(lastChar)) {
@@ -444,23 +444,23 @@ class Parser {
444
444
  this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.functionNameCannotEndWithTypeDesignator(functionTypeText, name.text, lastChar)), { range: name.range }));
445
445
  }
446
446
  //flag functions with keywords for names (only for standard functions)
447
- if (checkIdentifier && lexer_1.DisallowedFunctionIdentifiersText.has(name.text.toLowerCase())) {
447
+ if (checkIdentifier && TokenKind_1.DisallowedFunctionIdentifiersText.has(name.text.toLowerCase())) {
448
448
  this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.cannotUseReservedWordAsIdentifier(name.text)), { range: name.range }));
449
449
  }
450
450
  }
451
451
  let params = [];
452
452
  let asToken;
453
453
  let typeToken;
454
- if (!this.check(lexer_1.TokenKind.RightParen)) {
454
+ if (!this.check(TokenKind_1.TokenKind.RightParen)) {
455
455
  do {
456
456
  if (params.length >= Expression_1.CallExpression.MaximumArguments) {
457
457
  this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.tooManyCallableParameters(params.length, Expression_1.CallExpression.MaximumArguments)), { range: this.peek().range }));
458
458
  }
459
459
  params.push(this.functionParameter());
460
- } while (this.match(lexer_1.TokenKind.Comma));
460
+ } while (this.match(TokenKind_1.TokenKind.Comma));
461
461
  }
462
462
  let rightParen = this.advance();
463
- if (this.check(lexer_1.TokenKind.As)) {
463
+ if (this.check(TokenKind_1.TokenKind.As)) {
464
464
  asToken = this.advance();
465
465
  typeToken = this.typeToken();
466
466
  if (!util_1.util.tokenToBscType(typeToken, this.options.mode === ParseMode.BrighterScript)) {
@@ -498,7 +498,7 @@ class Parser {
498
498
  }
499
499
  // consume 'end sub' or 'end function'
500
500
  func.end = this.advance();
501
- let expectedEndKind = isSub ? lexer_1.TokenKind.EndSub : lexer_1.TokenKind.EndFunction;
501
+ let expectedEndKind = isSub ? TokenKind_1.TokenKind.EndSub : TokenKind_1.TokenKind.EndFunction;
502
502
  //if `function` is ended with `end sub`, or `sub` is ended with `end function`, then
503
503
  //add an error but don't hard-fail so the AST can continue more gracefully
504
504
  if (func.end.kind !== expectedEndKind) {
@@ -522,22 +522,22 @@ class Parser {
522
522
  }
523
523
  }
524
524
  functionParameter() {
525
- if (!this.checkAny(lexer_1.TokenKind.Identifier, ...this.allowedLocalIdentifiers)) {
525
+ if (!this.checkAny(TokenKind_1.TokenKind.Identifier, ...this.allowedLocalIdentifiers)) {
526
526
  this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.expectedParameterNameButFound(this.peek().text)), { range: this.peek().range }));
527
527
  throw this.lastDiagnosticAsError();
528
528
  }
529
529
  let name = this.advance();
530
530
  // force the name into an identifier so the AST makes some sense
531
- name.kind = lexer_1.TokenKind.Identifier;
531
+ name.kind = TokenKind_1.TokenKind.Identifier;
532
532
  let typeToken;
533
533
  let defaultValue;
534
534
  // parse argument default value
535
- if (this.match(lexer_1.TokenKind.Equal)) {
535
+ if (this.match(TokenKind_1.TokenKind.Equal)) {
536
536
  // it seems any expression is allowed here -- including ones that operate on other arguments!
537
537
  defaultValue = this.expression();
538
538
  }
539
539
  let asToken = null;
540
- if (this.check(lexer_1.TokenKind.As)) {
540
+ if (this.check(TokenKind_1.TokenKind.As)) {
541
541
  asToken = this.advance();
542
542
  typeToken = this.typeToken();
543
543
  if (!util_1.util.tokenToBscType(typeToken, this.options.mode === ParseMode.BrighterScript)) {
@@ -550,30 +550,33 @@ class Parser {
550
550
  assignment() {
551
551
  let name = this.advance();
552
552
  //add diagnostic if name is a reserved word that cannot be used as an identifier
553
- if (lexer_1.DisallowedLocalIdentifiersText.has(name.text.toLowerCase())) {
553
+ if (TokenKind_1.DisallowedLocalIdentifiersText.has(name.text.toLowerCase())) {
554
554
  this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.cannotUseReservedWordAsIdentifier(name.text)), { range: name.range }));
555
555
  }
556
- let operator = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedOperatorAfterIdentifier(lexer_1.AssignmentOperators, name.text), ...lexer_1.AssignmentOperators);
556
+ let operator = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedOperatorAfterIdentifier(TokenKind_1.AssignmentOperators, name.text), ...TokenKind_1.AssignmentOperators);
557
557
  let value = this.expression();
558
558
  let result;
559
- if (operator.kind === lexer_1.TokenKind.Equal) {
559
+ if (operator.kind === TokenKind_1.TokenKind.Equal) {
560
560
  result = new Statement_1.AssignmentStatement(operator, name, value, this.currentFunctionExpression);
561
561
  }
562
562
  else {
563
563
  result = new Statement_1.AssignmentStatement(operator, name, new Expression_1.BinaryExpression(new Expression_1.VariableExpression(name, this.currentNamespaceName), operator, value), this.currentFunctionExpression);
564
+ //remove the right-hand-side expression from this assignment operator, and replace with the full assignment expression
565
+ this._references.expressions.delete(value);
566
+ this._references.expressions.add(result);
564
567
  }
565
568
  this._references.assignmentStatements.push(result);
566
569
  return result;
567
570
  }
568
571
  checkLibrary() {
569
- let isLibraryToken = this.check(lexer_1.TokenKind.Library);
572
+ let isLibraryToken = this.check(TokenKind_1.TokenKind.Library);
570
573
  //if we are at the top level, any line that starts with "library" should be considered a library statement
571
574
  if (this.isAtRootLevel() && isLibraryToken) {
572
575
  return true;
573
576
  //not at root level, library statements are all invalid here, but try to detect if the tokens look
574
577
  //like a library statement (and let the libraryStatement function handle emitting the diagnostics)
575
578
  }
576
- else if (isLibraryToken && this.checkNext(lexer_1.TokenKind.StringLiteral)) {
579
+ else if (isLibraryToken && this.checkNext(TokenKind_1.TokenKind.StringLiteral)) {
577
580
  return true;
578
581
  //definitely not a library statement
579
582
  }
@@ -585,54 +588,54 @@ class Parser {
585
588
  if (this.checkLibrary()) {
586
589
  return this.libraryStatement();
587
590
  }
588
- if (this.check(lexer_1.TokenKind.Import)) {
591
+ if (this.check(TokenKind_1.TokenKind.Import)) {
589
592
  return this.importStatement();
590
593
  }
591
- if (this.check(lexer_1.TokenKind.Stop)) {
594
+ if (this.check(TokenKind_1.TokenKind.Stop)) {
592
595
  return this.stopStatement();
593
596
  }
594
- if (this.check(lexer_1.TokenKind.If)) {
597
+ if (this.check(TokenKind_1.TokenKind.If)) {
595
598
  return this.ifStatement();
596
599
  }
597
600
  //`try` must be followed by a block, otherwise it could be a local variable
598
- if (this.check(lexer_1.TokenKind.Try) && this.checkAnyNext(lexer_1.TokenKind.Newline, lexer_1.TokenKind.Colon, lexer_1.TokenKind.Comment)) {
601
+ if (this.check(TokenKind_1.TokenKind.Try) && this.checkAnyNext(TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Colon, TokenKind_1.TokenKind.Comment)) {
599
602
  return this.tryCatchStatement();
600
603
  }
601
- if (this.check(lexer_1.TokenKind.Throw)) {
604
+ if (this.check(TokenKind_1.TokenKind.Throw)) {
602
605
  return this.throwStatement();
603
606
  }
604
- if (this.checkAny(lexer_1.TokenKind.Print, lexer_1.TokenKind.Question)) {
607
+ if (this.checkAny(TokenKind_1.TokenKind.Print, TokenKind_1.TokenKind.Question)) {
605
608
  return this.printStatement();
606
609
  }
607
- if (this.check(lexer_1.TokenKind.Dim)) {
610
+ if (this.check(TokenKind_1.TokenKind.Dim)) {
608
611
  return this.dimStatement();
609
612
  }
610
- if (this.check(lexer_1.TokenKind.While)) {
613
+ if (this.check(TokenKind_1.TokenKind.While)) {
611
614
  return this.whileStatement();
612
615
  }
613
- if (this.check(lexer_1.TokenKind.ExitWhile)) {
616
+ if (this.check(TokenKind_1.TokenKind.ExitWhile)) {
614
617
  return this.exitWhile();
615
618
  }
616
- if (this.check(lexer_1.TokenKind.For)) {
619
+ if (this.check(TokenKind_1.TokenKind.For)) {
617
620
  return this.forStatement();
618
621
  }
619
- if (this.check(lexer_1.TokenKind.ForEach)) {
622
+ if (this.check(TokenKind_1.TokenKind.ForEach)) {
620
623
  return this.forEachStatement();
621
624
  }
622
- if (this.check(lexer_1.TokenKind.ExitFor)) {
625
+ if (this.check(TokenKind_1.TokenKind.ExitFor)) {
623
626
  return this.exitFor();
624
627
  }
625
- if (this.check(lexer_1.TokenKind.End)) {
628
+ if (this.check(TokenKind_1.TokenKind.End)) {
626
629
  return this.endStatement();
627
630
  }
628
- if (this.match(lexer_1.TokenKind.Return)) {
631
+ if (this.match(TokenKind_1.TokenKind.Return)) {
629
632
  return this.returnStatement();
630
633
  }
631
- if (this.check(lexer_1.TokenKind.Goto)) {
634
+ if (this.check(TokenKind_1.TokenKind.Goto)) {
632
635
  return this.gotoStatement();
633
636
  }
634
637
  //does this line look like a label? (i.e. `someIdentifier:` )
635
- if (this.check(lexer_1.TokenKind.Identifier) && this.checkNext(lexer_1.TokenKind.Colon) && this.checkPrevious(lexer_1.TokenKind.Newline)) {
638
+ if (this.check(TokenKind_1.TokenKind.Identifier) && this.checkNext(TokenKind_1.TokenKind.Colon) && this.checkPrevious(TokenKind_1.TokenKind.Newline)) {
636
639
  try {
637
640
  return this.labelStatement();
638
641
  }
@@ -646,18 +649,18 @@ class Parser {
646
649
  // BrightScript is like python, in that variables can be declared without a `var`,
647
650
  // `let`, (...) keyword. As such, we must check the token *after* an identifier to figure
648
651
  // out what to do with it.
649
- if (this.checkAny(lexer_1.TokenKind.Identifier, ...this.allowedLocalIdentifiers) &&
650
- this.checkAnyNext(...lexer_1.AssignmentOperators)) {
652
+ if (this.checkAny(TokenKind_1.TokenKind.Identifier, ...this.allowedLocalIdentifiers) &&
653
+ this.checkAnyNext(...TokenKind_1.AssignmentOperators)) {
651
654
  return this.assignment();
652
655
  }
653
656
  //some BrighterScript keywords are allowed as a local identifiers, so we need to check for them AFTER the assignment check
654
- if (this.check(lexer_1.TokenKind.Interface)) {
657
+ if (this.check(TokenKind_1.TokenKind.Interface)) {
655
658
  return this.interfaceDeclaration();
656
659
  }
657
- if (this.check(lexer_1.TokenKind.Class)) {
660
+ if (this.check(TokenKind_1.TokenKind.Class)) {
658
661
  return this.classDeclaration();
659
662
  }
660
- if (this.check(lexer_1.TokenKind.Namespace)) {
663
+ if (this.check(TokenKind_1.TokenKind.Namespace)) {
661
664
  return this.namespaceStatement();
662
665
  }
663
666
  // TODO: support multi-statements
@@ -667,9 +670,9 @@ class Parser {
667
670
  const whileKeyword = this.advance();
668
671
  const condition = this.expression();
669
672
  this.consumeStatementSeparators();
670
- const whileBlock = this.block(lexer_1.TokenKind.EndWhile);
673
+ const whileBlock = this.block(TokenKind_1.TokenKind.EndWhile);
671
674
  let endWhile;
672
- if (!whileBlock || this.peek().kind !== lexer_1.TokenKind.EndWhile) {
675
+ if (!whileBlock || this.peek().kind !== TokenKind_1.TokenKind.EndWhile) {
673
676
  this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.couldNotFindMatchingEndKeyword('while')), { range: this.peek().range }));
674
677
  if (!whileBlock) {
675
678
  throw this.lastDiagnosticAsError();
@@ -692,7 +695,7 @@ class Parser {
692
695
  const finalValue = this.expression();
693
696
  let incrementExpression;
694
697
  let stepToken;
695
- if (this.check(lexer_1.TokenKind.Step)) {
698
+ if (this.check(TokenKind_1.TokenKind.Step)) {
696
699
  stepToken = this.advance();
697
700
  incrementExpression = this.expression();
698
701
  }
@@ -700,9 +703,9 @@ class Parser {
700
703
  // BrightScript for/to/step loops default to a step of 1 if no `step` is provided
701
704
  }
702
705
  this.consumeStatementSeparators();
703
- let body = this.block(lexer_1.TokenKind.EndFor, lexer_1.TokenKind.Next);
706
+ let body = this.block(TokenKind_1.TokenKind.EndFor, TokenKind_1.TokenKind.Next);
704
707
  let endForToken;
705
- if (!body || !this.checkAny(lexer_1.TokenKind.EndFor, lexer_1.TokenKind.Next)) {
708
+ if (!body || !this.checkAny(TokenKind_1.TokenKind.EndFor, TokenKind_1.TokenKind.Next)) {
706
709
  this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.expectedEndForOrNextToTerminateForLoop()), { range: this.peek().range }));
707
710
  if (!body) {
708
711
  throw this.lastDiagnosticAsError();
@@ -719,7 +722,7 @@ class Parser {
719
722
  let forEach = this.advance();
720
723
  let name = this.advance();
721
724
  let maybeIn = this.peek();
722
- if (this.check(lexer_1.TokenKind.Identifier) && maybeIn.text.toLowerCase() === 'in') {
725
+ if (this.check(TokenKind_1.TokenKind.Identifier) && maybeIn.text.toLowerCase() === 'in') {
723
726
  this.advance();
724
727
  }
725
728
  else {
@@ -732,7 +735,7 @@ class Parser {
732
735
  throw this.lastDiagnosticAsError();
733
736
  }
734
737
  this.consumeStatementSeparators();
735
- let body = this.block(lexer_1.TokenKind.EndFor, lexer_1.TokenKind.Next);
738
+ let body = this.block(TokenKind_1.TokenKind.EndFor, TokenKind_1.TokenKind.Next);
736
739
  if (!body) {
737
740
  this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.expectedEndForOrNextToTerminateForLoop()), { range: this.peek().range }));
738
741
  throw this.lastDiagnosticAsError();
@@ -757,7 +760,7 @@ class Parser {
757
760
  }
758
761
  else {
759
762
  let comments = [this.advance()];
760
- while (this.check(lexer_1.TokenKind.Newline) && this.checkNext(lexer_1.TokenKind.Comment)) {
763
+ while (this.check(TokenKind_1.TokenKind.Newline) && this.checkNext(TokenKind_1.TokenKind.Comment)) {
761
764
  this.advance();
762
765
  comments.push(this.advance());
763
766
  }
@@ -774,13 +777,13 @@ class Parser {
774
777
  let name = this.getNamespacedVariableNameExpression();
775
778
  //set the current namespace name
776
779
  this.currentNamespaceName = name;
777
- this.globalTerminators.push([lexer_1.TokenKind.EndNamespace]);
780
+ this.globalTerminators.push([TokenKind_1.TokenKind.EndNamespace]);
778
781
  let body = this.body();
779
782
  this.globalTerminators.pop();
780
783
  //unset the current namespace name
781
784
  this.currentNamespaceName = undefined;
782
785
  let endKeyword;
783
- if (this.check(lexer_1.TokenKind.EndNamespace)) {
786
+ if (this.check(TokenKind_1.TokenKind.EndNamespace)) {
784
787
  endKeyword = this.advance();
785
788
  }
786
789
  else {
@@ -796,24 +799,24 @@ class Parser {
796
799
  * Get an expression with identifiers separated by periods. Useful for namespaces and class extends
797
800
  */
798
801
  getNamespacedVariableNameExpression() {
799
- let firstIdentifier = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifierAfterKeyword(this.previous().text), lexer_1.TokenKind.Identifier, ...this.allowedLocalIdentifiers);
802
+ let firstIdentifier = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifierAfterKeyword(this.previous().text), TokenKind_1.TokenKind.Identifier, ...this.allowedLocalIdentifiers);
800
803
  let expr;
801
804
  if (firstIdentifier) {
802
805
  // force it into an identifier so the AST makes some sense
803
- firstIdentifier.kind = lexer_1.TokenKind.Identifier;
806
+ firstIdentifier.kind = TokenKind_1.TokenKind.Identifier;
804
807
  expr = new Expression_1.VariableExpression(firstIdentifier, null);
805
808
  //consume multiple dot identifiers (i.e. `Name.Space.Can.Have.Many.Parts`)
806
- while (this.check(lexer_1.TokenKind.Dot)) {
807
- let dot = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.unexpectedToken(this.peek().text), lexer_1.TokenKind.Dot);
809
+ while (this.check(TokenKind_1.TokenKind.Dot)) {
810
+ let dot = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.unexpectedToken(this.peek().text), TokenKind_1.TokenKind.Dot);
808
811
  if (!dot) {
809
812
  break;
810
813
  }
811
- let identifier = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier(), lexer_1.TokenKind.Identifier, ...this.allowedLocalIdentifiers, ...lexer_1.AllowedProperties);
814
+ let identifier = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier(), TokenKind_1.TokenKind.Identifier, ...this.allowedLocalIdentifiers, ...TokenKind_1.AllowedProperties);
812
815
  if (!identifier) {
813
816
  break;
814
817
  }
815
818
  // force it into an identifier so the AST makes some sense
816
- identifier.kind = lexer_1.TokenKind.Identifier;
819
+ identifier.kind = TokenKind_1.TokenKind.Identifier;
817
820
  expr = new Expression_1.DottedGetExpression(expr, identifier, dot);
818
821
  }
819
822
  }
@@ -845,7 +848,7 @@ class Parser {
845
848
  let libStatement = new Statement_1.LibraryStatement({
846
849
  library: this.advance(),
847
850
  //grab the next token only if it's a string
848
- filePath: this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.expectedStringLiteralAfterKeyword('library'), lexer_1.TokenKind.StringLiteral)
851
+ filePath: this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.expectedStringLiteralAfterKeyword('library'), TokenKind_1.TokenKind.StringLiteral)
849
852
  });
850
853
  this._references.libraryStatements.push(libStatement);
851
854
  return libStatement;
@@ -854,20 +857,20 @@ class Parser {
854
857
  this.warnIfNotBrighterScriptMode('import statements');
855
858
  let importStatement = new Statement_1.ImportStatement(this.advance(),
856
859
  //grab the next token only if it's a string
857
- this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.expectedStringLiteralAfterKeyword('import'), lexer_1.TokenKind.StringLiteral));
860
+ this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.expectedStringLiteralAfterKeyword('import'), TokenKind_1.TokenKind.StringLiteral));
858
861
  this._references.importStatements.push(importStatement);
859
862
  return importStatement;
860
863
  }
861
864
  annotationExpression() {
862
865
  const atToken = this.advance();
863
- const identifier = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier(), lexer_1.TokenKind.Identifier, ...lexer_1.AllowedProperties);
866
+ const identifier = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier(), TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedProperties);
864
867
  if (identifier) {
865
- identifier.kind = lexer_1.TokenKind.Identifier;
868
+ identifier.kind = TokenKind_1.TokenKind.Identifier;
866
869
  }
867
870
  let annotation = new Expression_1.AnnotationExpression(atToken, identifier);
868
871
  this.pendingAnnotations.push(annotation);
869
872
  //optional arguments
870
- if (this.check(lexer_1.TokenKind.LeftParen)) {
873
+ if (this.check(TokenKind_1.TokenKind.LeftParen)) {
871
874
  let leftParen = this.advance();
872
875
  annotation.call = this.finishCall(leftParen, annotation, false);
873
876
  }
@@ -880,7 +883,7 @@ class Parser {
880
883
  }
881
884
  const questionMarkToken = this.advance();
882
885
  //consume newlines or comments
883
- while (this.checkAny(lexer_1.TokenKind.Newline, lexer_1.TokenKind.Comment)) {
886
+ while (this.checkAny(TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Comment)) {
884
887
  this.advance();
885
888
  }
886
889
  let consequent;
@@ -889,12 +892,12 @@ class Parser {
889
892
  }
890
893
  catch (_a) { }
891
894
  //consume newlines or comments
892
- while (this.checkAny(lexer_1.TokenKind.Newline, lexer_1.TokenKind.Comment)) {
895
+ while (this.checkAny(TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Comment)) {
893
896
  this.advance();
894
897
  }
895
- const colonToken = this.tryConsumeToken(lexer_1.TokenKind.Colon);
898
+ const colonToken = this.tryConsumeToken(TokenKind_1.TokenKind.Colon);
896
899
  //consume newlines
897
- while (this.checkAny(lexer_1.TokenKind.Newline, lexer_1.TokenKind.Comment)) {
900
+ while (this.checkAny(TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Comment)) {
898
901
  this.advance();
899
902
  }
900
903
  let alternate;
@@ -912,7 +915,7 @@ class Parser {
912
915
  }
913
916
  regexLiteralExpression() {
914
917
  this.warnIfNotBrighterScriptMode('regular expression literal');
915
- return new _1.RegexLiteralExpression({
918
+ return new Expression_1.RegexLiteralExpression({
916
919
  regexLiteral: this.advance()
917
920
  });
918
921
  }
@@ -921,23 +924,23 @@ class Parser {
921
924
  //get the tag name
922
925
  let tagName;
923
926
  if (isTagged) {
924
- tagName = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier(), lexer_1.TokenKind.Identifier, ...lexer_1.AllowedProperties);
927
+ tagName = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier(), TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedProperties);
925
928
  // force it into an identifier so the AST makes some sense
926
- tagName.kind = lexer_1.TokenKind.Identifier;
929
+ tagName.kind = TokenKind_1.TokenKind.Identifier;
927
930
  }
928
931
  let quasis = [];
929
932
  let expressions = [];
930
933
  let openingBacktick = this.peek();
931
934
  this.advance();
932
935
  let currentQuasiExpressionParts = [];
933
- while (!this.isAtEnd() && !this.check(lexer_1.TokenKind.BackTick)) {
936
+ while (!this.isAtEnd() && !this.check(TokenKind_1.TokenKind.BackTick)) {
934
937
  let next = this.peek();
935
- if (next.kind === lexer_1.TokenKind.TemplateStringQuasi) {
938
+ if (next.kind === TokenKind_1.TokenKind.TemplateStringQuasi) {
936
939
  //a quasi can actually be made up of multiple quasis when it includes char literals
937
940
  currentQuasiExpressionParts.push(new Expression_1.LiteralExpression(next));
938
941
  this.advance();
939
942
  }
940
- else if (next.kind === lexer_1.TokenKind.EscapedCharCodeLiteral) {
943
+ else if (next.kind === TokenKind_1.TokenKind.EscapedCharCodeLiteral) {
941
944
  currentQuasiExpressionParts.push(new Expression_1.EscapedCharCodeLiteralExpression(next));
942
945
  this.advance();
943
946
  }
@@ -945,12 +948,12 @@ class Parser {
945
948
  //finish up the current quasi
946
949
  quasis.push(new Expression_1.TemplateStringQuasiExpression(currentQuasiExpressionParts));
947
950
  currentQuasiExpressionParts = [];
948
- if (next.kind === lexer_1.TokenKind.TemplateStringExpressionBegin) {
951
+ if (next.kind === TokenKind_1.TokenKind.TemplateStringExpressionBegin) {
949
952
  this.advance();
950
953
  }
951
954
  //now keep this expression
952
955
  expressions.push(this.expression());
953
- if (!this.isAtEnd() && this.check(lexer_1.TokenKind.TemplateStringExpressionEnd)) {
956
+ if (!this.isAtEnd() && this.check(TokenKind_1.TokenKind.TemplateStringExpressionEnd)) {
954
957
  //TODO is it an error if this is not present?
955
958
  this.advance();
956
959
  }
@@ -982,12 +985,12 @@ class Parser {
982
985
  const statement = new Statement_1.TryCatchStatement(tryToken);
983
986
  //ensure statement separator
984
987
  this.consumeStatementSeparators();
985
- statement.tryBranch = this.block(lexer_1.TokenKind.Catch, lexer_1.TokenKind.EndTry);
988
+ statement.tryBranch = this.block(TokenKind_1.TokenKind.Catch, TokenKind_1.TokenKind.EndTry);
986
989
  const peek = this.peek();
987
- if (peek.kind !== lexer_1.TokenKind.Catch) {
990
+ if (peek.kind !== TokenKind_1.TokenKind.Catch) {
988
991
  this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.expectedCatchBlockInTryCatch()), { range: this.peek().range }));
989
992
  //gracefully handle end-try
990
- if (peek.kind === lexer_1.TokenKind.EndTry) {
993
+ if (peek.kind === TokenKind_1.TokenKind.EndTry) {
991
994
  statement.endTryToken = this.advance();
992
995
  }
993
996
  return statement;
@@ -995,16 +998,16 @@ class Parser {
995
998
  else {
996
999
  statement.catchToken = this.advance();
997
1000
  }
998
- const exceptionVarToken = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.missingExceptionVarToFollowCatch(), lexer_1.TokenKind.Identifier, ...this.allowedLocalIdentifiers);
1001
+ const exceptionVarToken = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.missingExceptionVarToFollowCatch(), TokenKind_1.TokenKind.Identifier, ...this.allowedLocalIdentifiers);
999
1002
  if (exceptionVarToken) {
1000
1003
  // force it into an identifier so the AST makes some sense
1001
- exceptionVarToken.kind = lexer_1.TokenKind.Identifier;
1004
+ exceptionVarToken.kind = TokenKind_1.TokenKind.Identifier;
1002
1005
  statement.exceptionVariable = exceptionVarToken;
1003
1006
  }
1004
1007
  //ensure statement sepatator
1005
1008
  this.consumeStatementSeparators();
1006
- statement.catchBranch = this.block(lexer_1.TokenKind.EndTry);
1007
- if (this.peek().kind !== lexer_1.TokenKind.EndTry) {
1009
+ statement.catchBranch = this.block(TokenKind_1.TokenKind.EndTry);
1010
+ if (this.peek().kind !== TokenKind_1.TokenKind.EndTry) {
1008
1011
  this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.expectedEndTryToTerminateTryCatch()), { range: this.peek().range }));
1009
1012
  }
1010
1013
  else {
@@ -1015,7 +1018,7 @@ class Parser {
1015
1018
  throwStatement() {
1016
1019
  const throwToken = this.advance();
1017
1020
  let expression;
1018
- if (this.checkAny(lexer_1.TokenKind.Newline, lexer_1.TokenKind.Colon)) {
1021
+ if (this.checkAny(TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Colon)) {
1019
1022
  this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.missingExceptionExpressionAfterThrowKeyword()), { range: throwToken.range }));
1020
1023
  }
1021
1024
  else {
@@ -1025,19 +1028,19 @@ class Parser {
1025
1028
  }
1026
1029
  dimStatement() {
1027
1030
  const dim = this.advance();
1028
- let identifier = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifierAfterKeyword('dim'), lexer_1.TokenKind.Identifier, ...this.allowedLocalIdentifiers);
1031
+ let identifier = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifierAfterKeyword('dim'), TokenKind_1.TokenKind.Identifier, ...this.allowedLocalIdentifiers);
1029
1032
  // force to an identifier so the AST makes some sense
1030
1033
  if (identifier) {
1031
- identifier.kind = lexer_1.TokenKind.Identifier;
1034
+ identifier.kind = TokenKind_1.TokenKind.Identifier;
1032
1035
  }
1033
- let leftSquareBracket = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.missingLeftSquareBracketAfterDimIdentifier(), lexer_1.TokenKind.LeftSquareBracket);
1036
+ let leftSquareBracket = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.missingLeftSquareBracketAfterDimIdentifier(), TokenKind_1.TokenKind.LeftSquareBracket);
1034
1037
  let expressions = [];
1035
1038
  let expression;
1036
1039
  do {
1037
1040
  try {
1038
1041
  expression = this.expression();
1039
1042
  expressions.push(expression);
1040
- if (this.check(lexer_1.TokenKind.Comma)) {
1043
+ if (this.check(TokenKind_1.TokenKind.Comma)) {
1041
1044
  this.advance();
1042
1045
  }
1043
1046
  else {
@@ -1051,15 +1054,15 @@ class Parser {
1051
1054
  if (expressions.length === 0) {
1052
1055
  this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.missingExpressionsInDimStatement()), { range: this.peek().range }));
1053
1056
  }
1054
- let rightSquareBracket = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.missingRightSquareBracketAfterDimIdentifier(), lexer_1.TokenKind.RightSquareBracket);
1057
+ let rightSquareBracket = this.tryConsume(DiagnosticMessages_1.DiagnosticMessages.missingRightSquareBracketAfterDimIdentifier(), TokenKind_1.TokenKind.RightSquareBracket);
1055
1058
  return new Statement_1.DimStatement(dim, identifier, leftSquareBracket, expressions, rightSquareBracket);
1056
1059
  }
1057
1060
  ifStatement() {
1058
1061
  // colon before `if` is usually not allowed, unless it's after `then`
1059
1062
  if (this.current > 0) {
1060
1063
  const prev = this.previous();
1061
- if (prev.kind === lexer_1.TokenKind.Colon) {
1062
- if (this.current > 1 && this.tokens[this.current - 2].kind !== lexer_1.TokenKind.Then) {
1064
+ if (prev.kind === TokenKind_1.TokenKind.Colon) {
1065
+ if (this.current > 1 && this.tokens[this.current - 2].kind !== TokenKind_1.TokenKind.Then) {
1063
1066
  this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.unexpectedColonBeforeIfStatement()), { range: prev.range }));
1064
1067
  }
1065
1068
  }
@@ -1073,14 +1076,14 @@ class Parser {
1073
1076
  let endIfToken;
1074
1077
  let elseToken;
1075
1078
  //optional `then`
1076
- if (this.check(lexer_1.TokenKind.Then)) {
1079
+ if (this.check(TokenKind_1.TokenKind.Then)) {
1077
1080
  thenToken = this.advance();
1078
1081
  }
1079
1082
  //is it inline or multi-line if?
1080
- const isInlineIfThen = !this.checkAny(lexer_1.TokenKind.Newline, lexer_1.TokenKind.Colon, lexer_1.TokenKind.Comment);
1083
+ const isInlineIfThen = !this.checkAny(TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Colon, TokenKind_1.TokenKind.Comment);
1081
1084
  if (isInlineIfThen) {
1082
1085
  /*** PARSE INLINE IF STATEMENT ***/
1083
- thenBranch = this.inlineConditionalBranch(lexer_1.TokenKind.Else, lexer_1.TokenKind.EndIf);
1086
+ thenBranch = this.inlineConditionalBranch(TokenKind_1.TokenKind.Else, TokenKind_1.TokenKind.EndIf);
1084
1087
  if (!thenBranch) {
1085
1088
  this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.expectedStatementToFollowConditionalCondition(ifToken.text)), { range: this.peek().range }));
1086
1089
  throw this.lastDiagnosticAsError();
@@ -1089,9 +1092,9 @@ class Parser {
1089
1092
  this.ensureInline(thenBranch.statements);
1090
1093
  }
1091
1094
  //else branch
1092
- if (this.check(lexer_1.TokenKind.Else)) {
1095
+ if (this.check(TokenKind_1.TokenKind.Else)) {
1093
1096
  elseToken = this.advance();
1094
- if (this.check(lexer_1.TokenKind.If)) {
1097
+ if (this.check(TokenKind_1.TokenKind.If)) {
1095
1098
  // recurse-read `else if`
1096
1099
  elseBranch = this.ifStatement();
1097
1100
  //no multi-line if chained with an inline if
@@ -1099,13 +1102,13 @@ class Parser {
1099
1102
  this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.expectedInlineIfStatement()), { range: elseBranch.range }));
1100
1103
  }
1101
1104
  }
1102
- else if (this.checkAny(lexer_1.TokenKind.Newline, lexer_1.TokenKind.Colon)) {
1105
+ else if (this.checkAny(TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Colon)) {
1103
1106
  //expecting inline else branch
1104
1107
  this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.expectedInlineIfStatement()), { range: this.peek().range }));
1105
1108
  throw this.lastDiagnosticAsError();
1106
1109
  }
1107
1110
  else {
1108
- elseBranch = this.inlineConditionalBranch(lexer_1.TokenKind.Else, lexer_1.TokenKind.EndIf);
1111
+ elseBranch = this.inlineConditionalBranch(TokenKind_1.TokenKind.Else, TokenKind_1.TokenKind.EndIf);
1109
1112
  if (elseBranch) {
1110
1113
  this.ensureInline(elseBranch.statements);
1111
1114
  }
@@ -1119,9 +1122,9 @@ class Parser {
1119
1122
  if (!elseBranch || !(0, reflection_1.isIfStatement)(elseBranch)) {
1120
1123
  //enforce newline at the end of the inline if statement
1121
1124
  const peek = this.peek();
1122
- if (peek.kind !== lexer_1.TokenKind.Newline && peek.kind !== lexer_1.TokenKind.Comment && !this.isAtEnd()) {
1125
+ if (peek.kind !== TokenKind_1.TokenKind.Newline && peek.kind !== TokenKind_1.TokenKind.Comment && !this.isAtEnd()) {
1123
1126
  //ignore last error if it was about a colon
1124
- if (this.previous().kind === lexer_1.TokenKind.Colon) {
1127
+ if (this.previous().kind === TokenKind_1.TokenKind.Colon) {
1125
1128
  this.diagnostics.pop();
1126
1129
  this.current--;
1127
1130
  }
@@ -1136,9 +1139,9 @@ class Parser {
1136
1139
  //ensure newline/colon before next keyword
1137
1140
  this.ensureNewLineOrColon();
1138
1141
  //else branch
1139
- if (this.check(lexer_1.TokenKind.Else)) {
1142
+ if (this.check(TokenKind_1.TokenKind.Else)) {
1140
1143
  elseToken = this.advance();
1141
- if (this.check(lexer_1.TokenKind.If)) {
1144
+ if (this.check(TokenKind_1.TokenKind.If)) {
1142
1145
  // recurse-read `else if`
1143
1146
  elseBranch = this.ifStatement();
1144
1147
  }
@@ -1149,7 +1152,7 @@ class Parser {
1149
1152
  }
1150
1153
  }
1151
1154
  if (!(0, reflection_1.isIfStatement)(elseBranch)) {
1152
- if (this.check(lexer_1.TokenKind.EndIf)) {
1155
+ if (this.check(TokenKind_1.TokenKind.EndIf)) {
1153
1156
  endIfToken = this.advance();
1154
1157
  }
1155
1158
  else {
@@ -1172,7 +1175,7 @@ class Parser {
1172
1175
  let diagnosticsLengthBeforeBlock = this.diagnostics.length;
1173
1176
  // we're parsing a multi-line ("block") form of the BrightScript if/then and must find
1174
1177
  // a trailing "end if" or "else if"
1175
- let branch = this.block(lexer_1.TokenKind.EndIf, lexer_1.TokenKind.Else);
1178
+ let branch = this.block(TokenKind_1.TokenKind.EndIf, TokenKind_1.TokenKind.Else);
1176
1179
  if (!branch) {
1177
1180
  //throw out any new diagnostics created as a result of a `then` block parse failure.
1178
1181
  //the block() function will discard the current line, so any discarded diagnostics will
@@ -1186,7 +1189,7 @@ class Parser {
1186
1189
  }
1187
1190
  ensureNewLineOrColon(silent = false) {
1188
1191
  const prev = this.previous().kind;
1189
- if (prev !== lexer_1.TokenKind.Newline && prev !== lexer_1.TokenKind.Colon) {
1192
+ if (prev !== TokenKind_1.TokenKind.Newline && prev !== TokenKind_1.TokenKind.Colon) {
1190
1193
  if (!silent) {
1191
1194
  this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.expectedNewlineOrColon()), { range: this.peek().range }));
1192
1195
  }
@@ -1215,12 +1218,12 @@ class Parser {
1215
1218
  const startingRange = statement.range;
1216
1219
  //look for colon statement separator
1217
1220
  let foundColon = false;
1218
- while (this.match(lexer_1.TokenKind.Colon)) {
1221
+ while (this.match(TokenKind_1.TokenKind.Colon)) {
1219
1222
  foundColon = true;
1220
1223
  }
1221
1224
  //if a colon was found, add the next statement or err if unexpected
1222
1225
  if (foundColon) {
1223
- if (!this.checkAny(lexer_1.TokenKind.Newline, ...additionalTerminators)) {
1226
+ if (!this.checkAny(TokenKind_1.TokenKind.Newline, ...additionalTerminators)) {
1224
1227
  //if not an ending keyword, add next statement
1225
1228
  let extra = this.inlineConditionalBranch(...additionalTerminators);
1226
1229
  if (!extra) {
@@ -1238,9 +1241,9 @@ class Parser {
1238
1241
  }
1239
1242
  expressionStatement(expr) {
1240
1243
  let expressionStart = this.peek();
1241
- if (this.checkAny(lexer_1.TokenKind.PlusPlus, lexer_1.TokenKind.MinusMinus)) {
1244
+ if (this.checkAny(TokenKind_1.TokenKind.PlusPlus, TokenKind_1.TokenKind.MinusMinus)) {
1242
1245
  let operator = this.advance();
1243
- if (this.checkAny(lexer_1.TokenKind.PlusPlus, lexer_1.TokenKind.MinusMinus)) {
1246
+ if (this.checkAny(TokenKind_1.TokenKind.PlusPlus, TokenKind_1.TokenKind.MinusMinus)) {
1244
1247
  this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.consecutiveIncrementDecrementOperatorsAreNotAllowed()), { range: this.peek().range }));
1245
1248
  throw this.lastDiagnosticAsError();
1246
1249
  }
@@ -1248,7 +1251,9 @@ class Parser {
1248
1251
  this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.incrementDecrementOperatorsAreNotAllowedAsResultOfFunctionCall()), { range: expressionStart.range }));
1249
1252
  throw this.lastDiagnosticAsError();
1250
1253
  }
1251
- return new Statement_1.IncrementStatement(expr, operator);
1254
+ const result = new Statement_1.IncrementStatement(expr, operator);
1255
+ this._references.expressions.add(result);
1256
+ return result;
1252
1257
  }
1253
1258
  if ((0, reflection_1.isCallExpression)(expr) || (0, reflection_1.isCallfuncExpression)(expr)) {
1254
1259
  return new Statement_1.ExpressionStatement(expr);
@@ -1265,18 +1270,18 @@ class Parser {
1265
1270
  * priority as standalone function calls though, so we can parse them in the same way.
1266
1271
  */
1267
1272
  let expr = this.call();
1268
- if (this.checkAny(...lexer_1.AssignmentOperators) && !((0, reflection_1.isCallExpression)(expr))) {
1273
+ if (this.checkAny(...TokenKind_1.AssignmentOperators) && !((0, reflection_1.isCallExpression)(expr))) {
1269
1274
  let left = expr;
1270
1275
  let operator = this.advance();
1271
1276
  let right = this.expression();
1272
1277
  // Create a dotted or indexed "set" based on the left-hand side's type
1273
1278
  if ((0, reflection_1.isIndexedGetExpression)(left)) {
1274
- return new Statement_1.IndexedSetStatement(left.obj, left.index, operator.kind === lexer_1.TokenKind.Equal
1279
+ return new Statement_1.IndexedSetStatement(left.obj, left.index, operator.kind === TokenKind_1.TokenKind.Equal
1275
1280
  ? right
1276
1281
  : new Expression_1.BinaryExpression(left, operator, right), left.openingSquare, left.closingSquare);
1277
1282
  }
1278
1283
  else if ((0, reflection_1.isDottedGetExpression)(left)) {
1279
- return new Statement_1.DottedSetStatement(left.obj, left.name, operator.kind === lexer_1.TokenKind.Equal
1284
+ return new Statement_1.DottedSetStatement(left.obj, left.name, operator.kind === TokenKind_1.TokenKind.Equal
1280
1285
  ? right
1281
1286
  : new Expression_1.BinaryExpression(left, operator, right));
1282
1287
  }
@@ -1287,13 +1292,13 @@ class Parser {
1287
1292
  let printKeyword = this.advance();
1288
1293
  let values = [];
1289
1294
  while (!this.checkEndOfStatement()) {
1290
- if (this.check(lexer_1.TokenKind.Semicolon)) {
1295
+ if (this.check(TokenKind_1.TokenKind.Semicolon)) {
1291
1296
  values.push(this.advance());
1292
1297
  }
1293
- else if (this.check(lexer_1.TokenKind.Comma)) {
1298
+ else if (this.check(TokenKind_1.TokenKind.Comma)) {
1294
1299
  values.push(this.advance());
1295
1300
  }
1296
- else if (this.check(lexer_1.TokenKind.Else)) {
1301
+ else if (this.check(TokenKind_1.TokenKind.Else)) {
1297
1302
  break; // inline branch
1298
1303
  }
1299
1304
  else {
@@ -1306,7 +1311,7 @@ class Parser {
1306
1311
  values.push(emptyStringLiteral);
1307
1312
  }
1308
1313
  let last = values[values.length - 1];
1309
- if ((0, lexer_1.isToken)(last)) {
1314
+ if ((0, Token_1.isToken)(last)) {
1310
1315
  // TODO: error, expected value
1311
1316
  }
1312
1317
  return new Statement_1.PrintStatement({ print: printKeyword }, values);
@@ -1320,7 +1325,7 @@ class Parser {
1320
1325
  if (this.checkEndOfStatement()) {
1321
1326
  return new Statement_1.ReturnStatement(tokens);
1322
1327
  }
1323
- let toReturn = this.check(lexer_1.TokenKind.Else) ? undefined : this.expression();
1328
+ let toReturn = this.check(TokenKind_1.TokenKind.Else) ? undefined : this.expression();
1324
1329
  return new Statement_1.ReturnStatement(tokens, toReturn);
1325
1330
  }
1326
1331
  /**
@@ -1333,7 +1338,7 @@ class Parser {
1333
1338
  colon: this.advance()
1334
1339
  };
1335
1340
  //label must be alone on its line, this is probably not a label
1336
- if (!this.checkAny(lexer_1.TokenKind.Newline, lexer_1.TokenKind.Comment)) {
1341
+ if (!this.checkAny(TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Comment)) {
1337
1342
  //rewind and cancel
1338
1343
  this.current -= 2;
1339
1344
  throw new CancelStatementError();
@@ -1347,7 +1352,7 @@ class Parser {
1347
1352
  gotoStatement() {
1348
1353
  let tokens = {
1349
1354
  goto: this.advance(),
1350
- label: this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedLabelIdentifierAfterGotoKeyword(), lexer_1.TokenKind.Identifier)
1355
+ label: this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedLabelIdentifierAfterGotoKeyword(), TokenKind_1.TokenKind.Identifier)
1351
1356
  };
1352
1357
  return new Statement_1.GotoStatement(tokens);
1353
1358
  }
@@ -1378,7 +1383,7 @@ class Parser {
1378
1383
  this.consumeStatementSeparators(true);
1379
1384
  let startingToken = this.peek();
1380
1385
  const statements = [];
1381
- while (!this.isAtEnd() && !this.checkAny(lexer_1.TokenKind.EndSub, lexer_1.TokenKind.EndFunction, ...terminators)) {
1386
+ while (!this.isAtEnd() && !this.checkAny(TokenKind_1.TokenKind.EndSub, TokenKind_1.TokenKind.EndFunction, ...terminators)) {
1382
1387
  //grab the location of the current token
1383
1388
  let loopCurrent = this.current;
1384
1389
  let dec = this.declaration();
@@ -1394,7 +1399,7 @@ class Parser {
1394
1399
  //something went wrong. reset to the top of the loop
1395
1400
  this.current = loopCurrent;
1396
1401
  //scrap the entire line (hopefully whatever failed has added a diagnostic)
1397
- this.consumeUntil(lexer_1.TokenKind.Newline, lexer_1.TokenKind.Colon, lexer_1.TokenKind.Eof);
1402
+ this.consumeUntil(TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Colon, TokenKind_1.TokenKind.Eof);
1398
1403
  //trash the next token. this prevents an infinite loop. not exactly sure why we need this,
1399
1404
  //but there's already an error in the file being parsed, so just leave this line here
1400
1405
  this.advance();
@@ -1411,8 +1416,8 @@ class Parser {
1411
1416
  //if so, we need to restore the statement separator
1412
1417
  let prev = this.previous().kind;
1413
1418
  let peek = this.peek().kind;
1414
- if ((peek === lexer_1.TokenKind.EndSub || peek === lexer_1.TokenKind.EndFunction) &&
1415
- (prev === lexer_1.TokenKind.Newline || prev === lexer_1.TokenKind.Colon)) {
1419
+ if ((peek === TokenKind_1.TokenKind.EndSub || peek === TokenKind_1.TokenKind.EndFunction) &&
1420
+ (prev === TokenKind_1.TokenKind.Newline || prev === TokenKind_1.TokenKind.Colon)) {
1416
1421
  this.current--;
1417
1422
  }
1418
1423
  }
@@ -1444,13 +1449,15 @@ class Parser {
1444
1449
  this.pendingAnnotations = parentAnnotations;
1445
1450
  }
1446
1451
  expression() {
1447
- return this.anonymousFunction();
1452
+ const expression = this.anonymousFunction();
1453
+ this._references.expressions.add(expression);
1454
+ return expression;
1448
1455
  }
1449
1456
  anonymousFunction() {
1450
- if (this.checkAny(lexer_1.TokenKind.Sub, lexer_1.TokenKind.Function)) {
1457
+ if (this.checkAny(TokenKind_1.TokenKind.Sub, TokenKind_1.TokenKind.Function)) {
1451
1458
  const func = this.functionDeclaration(true);
1452
1459
  //if there's an open paren after this, this is an IIFE
1453
- if (this.check(lexer_1.TokenKind.LeftParen)) {
1460
+ if (this.check(TokenKind_1.TokenKind.LeftParen)) {
1454
1461
  return this.finishCall(this.advance(), func);
1455
1462
  }
1456
1463
  else {
@@ -1458,10 +1465,10 @@ class Parser {
1458
1465
  }
1459
1466
  }
1460
1467
  let expr = this.boolean();
1461
- if (this.check(lexer_1.TokenKind.Question)) {
1468
+ if (this.check(TokenKind_1.TokenKind.Question)) {
1462
1469
  return this.ternaryExpression(expr);
1463
1470
  }
1464
- else if (this.check(lexer_1.TokenKind.QuestionQuestion)) {
1471
+ else if (this.check(TokenKind_1.TokenKind.QuestionQuestion)) {
1465
1472
  return this.nullCoalescingExpression(expr);
1466
1473
  }
1467
1474
  else {
@@ -1470,7 +1477,7 @@ class Parser {
1470
1477
  }
1471
1478
  boolean() {
1472
1479
  let expr = this.relational();
1473
- while (this.matchAny(lexer_1.TokenKind.And, lexer_1.TokenKind.Or)) {
1480
+ while (this.matchAny(TokenKind_1.TokenKind.And, TokenKind_1.TokenKind.Or)) {
1474
1481
  let operator = this.previous();
1475
1482
  let right = this.relational();
1476
1483
  expr = new Expression_1.BinaryExpression(expr, operator, right);
@@ -1479,7 +1486,7 @@ class Parser {
1479
1486
  }
1480
1487
  relational() {
1481
1488
  let expr = this.additive();
1482
- while (this.matchAny(lexer_1.TokenKind.Equal, lexer_1.TokenKind.LessGreater, lexer_1.TokenKind.Greater, lexer_1.TokenKind.GreaterEqual, lexer_1.TokenKind.Less, lexer_1.TokenKind.LessEqual)) {
1489
+ while (this.matchAny(TokenKind_1.TokenKind.Equal, TokenKind_1.TokenKind.LessGreater, TokenKind_1.TokenKind.Greater, TokenKind_1.TokenKind.GreaterEqual, TokenKind_1.TokenKind.Less, TokenKind_1.TokenKind.LessEqual)) {
1483
1490
  let operator = this.previous();
1484
1491
  let right = this.additive();
1485
1492
  expr = new Expression_1.BinaryExpression(expr, operator, right);
@@ -1489,7 +1496,7 @@ class Parser {
1489
1496
  // TODO: bitshift
1490
1497
  additive() {
1491
1498
  let expr = this.multiplicative();
1492
- while (this.matchAny(lexer_1.TokenKind.Plus, lexer_1.TokenKind.Minus)) {
1499
+ while (this.matchAny(TokenKind_1.TokenKind.Plus, TokenKind_1.TokenKind.Minus)) {
1493
1500
  let operator = this.previous();
1494
1501
  let right = this.multiplicative();
1495
1502
  expr = new Expression_1.BinaryExpression(expr, operator, right);
@@ -1498,7 +1505,7 @@ class Parser {
1498
1505
  }
1499
1506
  multiplicative() {
1500
1507
  let expr = this.exponential();
1501
- while (this.matchAny(lexer_1.TokenKind.Forwardslash, lexer_1.TokenKind.Backslash, lexer_1.TokenKind.Star, lexer_1.TokenKind.Mod, lexer_1.TokenKind.LeftShift, lexer_1.TokenKind.RightShift)) {
1508
+ while (this.matchAny(TokenKind_1.TokenKind.Forwardslash, TokenKind_1.TokenKind.Backslash, TokenKind_1.TokenKind.Star, TokenKind_1.TokenKind.Mod, TokenKind_1.TokenKind.LeftShift, TokenKind_1.TokenKind.RightShift)) {
1502
1509
  let operator = this.previous();
1503
1510
  let right = this.exponential();
1504
1511
  expr = new Expression_1.BinaryExpression(expr, operator, right);
@@ -1507,7 +1514,7 @@ class Parser {
1507
1514
  }
1508
1515
  exponential() {
1509
1516
  let expr = this.prefixUnary();
1510
- while (this.match(lexer_1.TokenKind.Caret)) {
1517
+ while (this.match(TokenKind_1.TokenKind.Caret)) {
1511
1518
  let operator = this.previous();
1512
1519
  let right = this.prefixUnary();
1513
1520
  expr = new Expression_1.BinaryExpression(expr, operator, right);
@@ -1516,7 +1523,7 @@ class Parser {
1516
1523
  }
1517
1524
  prefixUnary() {
1518
1525
  const nextKind = this.peek().kind;
1519
- if (nextKind === lexer_1.TokenKind.Not || nextKind === lexer_1.TokenKind.Minus) {
1526
+ if (nextKind === TokenKind_1.TokenKind.Not || nextKind === TokenKind_1.TokenKind.Minus) {
1520
1527
  this.current++; //advance
1521
1528
  let operator = this.previous();
1522
1529
  let right = this.prefixUnary();
@@ -1526,17 +1533,17 @@ class Parser {
1526
1533
  }
1527
1534
  indexedGet(expr) {
1528
1535
  let openingSquare = this.previous();
1529
- while (this.match(lexer_1.TokenKind.Newline)) { }
1536
+ while (this.match(TokenKind_1.TokenKind.Newline)) { }
1530
1537
  let index = this.expression();
1531
- while (this.match(lexer_1.TokenKind.Newline)) { }
1532
- let closingSquare = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedRightSquareBraceAfterArrayOrObjectIndex(), lexer_1.TokenKind.RightSquareBracket);
1538
+ while (this.match(TokenKind_1.TokenKind.Newline)) { }
1539
+ let closingSquare = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedRightSquareBraceAfterArrayOrObjectIndex(), TokenKind_1.TokenKind.RightSquareBracket);
1533
1540
  return new Expression_1.IndexedGetExpression(expr, index, openingSquare, closingSquare);
1534
1541
  }
1535
1542
  newExpression() {
1536
1543
  this.warnIfNotBrighterScriptMode(`using 'new' keyword to construct a class`);
1537
1544
  let newToken = this.advance();
1538
1545
  let nameExpr = this.getNamespacedVariableNameExpression();
1539
- let leftParen = this.consume(DiagnosticMessages_1.DiagnosticMessages.unexpectedToken(this.peek().text), lexer_1.TokenKind.LeftParen);
1546
+ let leftParen = this.consume(DiagnosticMessages_1.DiagnosticMessages.unexpectedToken(this.peek().text), TokenKind_1.TokenKind.LeftParen);
1540
1547
  let call = this.finishCall(leftParen, nameExpr);
1541
1548
  //pop the call from the callExpressions list because this is technically something else
1542
1549
  this.callExpressions.pop();
@@ -1550,46 +1557,52 @@ class Parser {
1550
1557
  callfunc(callee) {
1551
1558
  this.warnIfNotBrighterScriptMode('callfunc operator');
1552
1559
  let operator = this.previous();
1553
- let methodName = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier(), lexer_1.TokenKind.Identifier, ...lexer_1.AllowedProperties);
1560
+ let methodName = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier(), TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedProperties);
1554
1561
  // force it into an identifier so the AST makes some sense
1555
- methodName.kind = lexer_1.TokenKind.Identifier;
1556
- let openParen = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedOpenParenToFollowCallfuncIdentifier(), lexer_1.TokenKind.LeftParen);
1562
+ methodName.kind = TokenKind_1.TokenKind.Identifier;
1563
+ let openParen = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedOpenParenToFollowCallfuncIdentifier(), TokenKind_1.TokenKind.LeftParen);
1557
1564
  let call = this.finishCall(openParen, callee, false);
1558
1565
  return new Expression_1.CallfuncExpression(callee, operator, methodName, openParen, call.args, call.closingParen);
1559
1566
  }
1560
1567
  call() {
1561
- if (this.check(lexer_1.TokenKind.New) && this.checkAnyNext(lexer_1.TokenKind.Identifier, ...this.allowedLocalIdentifiers)) {
1568
+ if (this.check(TokenKind_1.TokenKind.New) && this.checkAnyNext(TokenKind_1.TokenKind.Identifier, ...this.allowedLocalIdentifiers)) {
1562
1569
  return this.newExpression();
1563
1570
  }
1564
1571
  let expr = this.primary();
1572
+ //an expression to keep for _references
1573
+ let referenceCallExpression;
1565
1574
  while (true) {
1566
- if (this.match(lexer_1.TokenKind.LeftParen)) {
1575
+ if (this.match(TokenKind_1.TokenKind.LeftParen)) {
1567
1576
  expr = this.finishCall(this.previous(), expr);
1577
+ //store this call expression in references
1578
+ referenceCallExpression = expr;
1568
1579
  }
1569
- else if (this.match(lexer_1.TokenKind.LeftSquareBracket)) {
1580
+ else if (this.match(TokenKind_1.TokenKind.LeftSquareBracket)) {
1570
1581
  expr = this.indexedGet(expr);
1571
1582
  }
1572
- else if (this.match(lexer_1.TokenKind.Callfunc)) {
1583
+ else if (this.match(TokenKind_1.TokenKind.Callfunc)) {
1573
1584
  expr = this.callfunc(expr);
1585
+ //store this callfunc expression in references
1586
+ referenceCallExpression = expr;
1574
1587
  }
1575
- else if (this.match(lexer_1.TokenKind.Dot)) {
1576
- if (this.match(lexer_1.TokenKind.LeftSquareBracket)) {
1588
+ else if (this.match(TokenKind_1.TokenKind.Dot)) {
1589
+ if (this.match(TokenKind_1.TokenKind.LeftSquareBracket)) {
1577
1590
  expr = this.indexedGet(expr);
1578
1591
  }
1579
1592
  else {
1580
1593
  let dot = this.previous();
1581
- let name = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedPropertyNameAfterPeriod(), lexer_1.TokenKind.Identifier, ...lexer_1.AllowedProperties);
1594
+ let name = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedPropertyNameAfterPeriod(), TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedProperties);
1582
1595
  // force it into an identifier so the AST makes some sense
1583
- name.kind = lexer_1.TokenKind.Identifier;
1596
+ name.kind = TokenKind_1.TokenKind.Identifier;
1584
1597
  expr = new Expression_1.DottedGetExpression(expr, name, dot);
1585
1598
  this.addPropertyHints(name);
1586
1599
  }
1587
1600
  }
1588
- else if (this.check(lexer_1.TokenKind.At)) {
1601
+ else if (this.check(TokenKind_1.TokenKind.At)) {
1589
1602
  let dot = this.advance();
1590
- let name = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedAttributeNameAfterAtSymbol(), lexer_1.TokenKind.Identifier, ...lexer_1.AllowedProperties);
1603
+ let name = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedAttributeNameAfterAtSymbol(), TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedProperties);
1591
1604
  // force it into an identifier so the AST makes some sense
1592
- name.kind = lexer_1.TokenKind.Identifier;
1605
+ name.kind = TokenKind_1.TokenKind.Identifier;
1593
1606
  expr = new Expression_1.XmlAttributeGetExpression(expr, name, dot);
1594
1607
  //only allow a single `@` expression
1595
1608
  break;
@@ -1598,24 +1611,28 @@ class Parser {
1598
1611
  break;
1599
1612
  }
1600
1613
  }
1614
+ //if we found a callExpression, add it to `expressions` in references
1615
+ if (referenceCallExpression) {
1616
+ this._references.expressions.add(referenceCallExpression);
1617
+ }
1601
1618
  return expr;
1602
1619
  }
1603
1620
  finishCall(openingParen, callee, addToCallExpressionList = true) {
1604
1621
  let args = [];
1605
- while (this.match(lexer_1.TokenKind.Newline)) {
1622
+ while (this.match(TokenKind_1.TokenKind.Newline)) {
1606
1623
  }
1607
- if (!this.check(lexer_1.TokenKind.RightParen)) {
1624
+ if (!this.check(TokenKind_1.TokenKind.RightParen)) {
1608
1625
  do {
1609
- while (this.match(lexer_1.TokenKind.Newline)) { }
1626
+ while (this.match(TokenKind_1.TokenKind.Newline)) { }
1610
1627
  if (args.length >= Expression_1.CallExpression.MaximumArguments) {
1611
1628
  this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.tooManyCallableArguments(args.length, Expression_1.CallExpression.MaximumArguments)), { range: this.peek().range }));
1612
1629
  throw this.lastDiagnosticAsError();
1613
1630
  }
1614
1631
  args.push(this.expression());
1615
- } while (this.match(lexer_1.TokenKind.Comma));
1632
+ } while (this.match(TokenKind_1.TokenKind.Comma));
1616
1633
  }
1617
- while (this.match(lexer_1.TokenKind.Newline)) { }
1618
- const closingParen = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedRightParenAfterFunctionCallArguments(), lexer_1.TokenKind.RightParen);
1634
+ while (this.match(TokenKind_1.TokenKind.Newline)) { }
1635
+ const closingParen = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedRightParenAfterFunctionCallArguments(), TokenKind_1.TokenKind.RightParen);
1619
1636
  if ((0, reflection_1.isVariableExpression)(callee)) {
1620
1637
  callee.isCalled = true;
1621
1638
  }
@@ -1632,7 +1649,7 @@ class Parser {
1632
1649
  */
1633
1650
  typeToken() {
1634
1651
  let typeToken;
1635
- if (this.checkAny(...lexer_1.DeclarableTypes)) {
1652
+ if (this.checkAny(...TokenKind_1.DeclarableTypes)) {
1636
1653
  // Token is a built in type
1637
1654
  typeToken = this.advance();
1638
1655
  }
@@ -1640,7 +1657,7 @@ class Parser {
1640
1657
  try {
1641
1658
  // see if we can get a namespaced identifer
1642
1659
  const qualifiedType = this.getNamespacedVariableNameExpression();
1643
- typeToken = (0, creators_1.createToken)(lexer_1.TokenKind.Identifier, qualifiedType.getName(this.options.mode), qualifiedType.range);
1660
+ typeToken = (0, creators_1.createToken)(TokenKind_1.TokenKind.Identifier, qualifiedType.getName(this.options.mode), qualifiedType.range);
1644
1661
  }
1645
1662
  catch (_a) {
1646
1663
  //could not get an identifier - just get whatever's next
@@ -1655,53 +1672,53 @@ class Parser {
1655
1672
  }
1656
1673
  primary() {
1657
1674
  switch (true) {
1658
- case this.matchAny(lexer_1.TokenKind.False, lexer_1.TokenKind.True, lexer_1.TokenKind.Invalid, lexer_1.TokenKind.IntegerLiteral, lexer_1.TokenKind.LongIntegerLiteral, lexer_1.TokenKind.FloatLiteral, lexer_1.TokenKind.DoubleLiteral, lexer_1.TokenKind.StringLiteral):
1675
+ case this.matchAny(TokenKind_1.TokenKind.False, TokenKind_1.TokenKind.True, TokenKind_1.TokenKind.Invalid, TokenKind_1.TokenKind.IntegerLiteral, TokenKind_1.TokenKind.LongIntegerLiteral, TokenKind_1.TokenKind.FloatLiteral, TokenKind_1.TokenKind.DoubleLiteral, TokenKind_1.TokenKind.StringLiteral):
1659
1676
  return new Expression_1.LiteralExpression(this.previous());
1660
1677
  //capture source literals (LINE_NUM if brightscript, or a bunch of them if brighterscript)
1661
- case this.matchAny(lexer_1.TokenKind.LineNumLiteral, ...(this.options.mode === ParseMode.BrightScript ? [] : lexer_1.BrighterScriptSourceLiterals)):
1678
+ case this.matchAny(TokenKind_1.TokenKind.LineNumLiteral, ...(this.options.mode === ParseMode.BrightScript ? [] : TokenKind_1.BrighterScriptSourceLiterals)):
1662
1679
  return new Expression_1.SourceLiteralExpression(this.previous());
1663
1680
  //template string
1664
- case this.check(lexer_1.TokenKind.BackTick):
1681
+ case this.check(TokenKind_1.TokenKind.BackTick):
1665
1682
  return this.templateString(false);
1666
1683
  //tagged template string (currently we do not support spaces between the identifier and the backtick)
1667
- case this.checkAny(lexer_1.TokenKind.Identifier, ...lexer_1.AllowedLocalIdentifiers) && this.checkNext(lexer_1.TokenKind.BackTick):
1684
+ case this.checkAny(TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedLocalIdentifiers) && this.checkNext(TokenKind_1.TokenKind.BackTick):
1668
1685
  return this.templateString(true);
1669
- case this.matchAny(lexer_1.TokenKind.Identifier, ...this.allowedLocalIdentifiers):
1686
+ case this.matchAny(TokenKind_1.TokenKind.Identifier, ...this.allowedLocalIdentifiers):
1670
1687
  return new Expression_1.VariableExpression(this.previous(), this.currentNamespaceName);
1671
- case this.match(lexer_1.TokenKind.LeftParen):
1688
+ case this.match(TokenKind_1.TokenKind.LeftParen):
1672
1689
  let left = this.previous();
1673
1690
  let expr = this.expression();
1674
- let right = this.consume(DiagnosticMessages_1.DiagnosticMessages.unmatchedLeftParenAfterExpression(), lexer_1.TokenKind.RightParen);
1691
+ let right = this.consume(DiagnosticMessages_1.DiagnosticMessages.unmatchedLeftParenAfterExpression(), TokenKind_1.TokenKind.RightParen);
1675
1692
  return new Expression_1.GroupingExpression({ left: left, right: right }, expr);
1676
- case this.match(lexer_1.TokenKind.LeftSquareBracket):
1693
+ case this.match(TokenKind_1.TokenKind.LeftSquareBracket):
1677
1694
  let elements = [];
1678
1695
  let openingSquare = this.previous();
1679
1696
  //add any comment found right after the opening square
1680
- if (this.check(lexer_1.TokenKind.Comment)) {
1697
+ if (this.check(TokenKind_1.TokenKind.Comment)) {
1681
1698
  elements.push(new Statement_1.CommentStatement([this.advance()]));
1682
1699
  }
1683
- while (this.match(lexer_1.TokenKind.Newline)) {
1700
+ while (this.match(TokenKind_1.TokenKind.Newline)) {
1684
1701
  }
1685
- if (!this.match(lexer_1.TokenKind.RightSquareBracket)) {
1702
+ if (!this.match(TokenKind_1.TokenKind.RightSquareBracket)) {
1686
1703
  elements.push(this.expression());
1687
- while (this.matchAny(lexer_1.TokenKind.Comma, lexer_1.TokenKind.Newline, lexer_1.TokenKind.Comment)) {
1688
- if (this.checkPrevious(lexer_1.TokenKind.Comment) || this.check(lexer_1.TokenKind.Comment)) {
1689
- let comment = this.check(lexer_1.TokenKind.Comment) ? this.advance() : this.previous();
1704
+ while (this.matchAny(TokenKind_1.TokenKind.Comma, TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Comment)) {
1705
+ if (this.checkPrevious(TokenKind_1.TokenKind.Comment) || this.check(TokenKind_1.TokenKind.Comment)) {
1706
+ let comment = this.check(TokenKind_1.TokenKind.Comment) ? this.advance() : this.previous();
1690
1707
  elements.push(new Statement_1.CommentStatement([comment]));
1691
1708
  }
1692
- while (this.match(lexer_1.TokenKind.Newline)) {
1709
+ while (this.match(TokenKind_1.TokenKind.Newline)) {
1693
1710
  }
1694
- if (this.check(lexer_1.TokenKind.RightSquareBracket)) {
1711
+ if (this.check(TokenKind_1.TokenKind.RightSquareBracket)) {
1695
1712
  break;
1696
1713
  }
1697
1714
  elements.push(this.expression());
1698
1715
  }
1699
- this.consume(DiagnosticMessages_1.DiagnosticMessages.unmatchedLeftSquareBraceAfterArrayLiteral(), lexer_1.TokenKind.RightSquareBracket);
1716
+ this.consume(DiagnosticMessages_1.DiagnosticMessages.unmatchedLeftSquareBraceAfterArrayLiteral(), TokenKind_1.TokenKind.RightSquareBracket);
1700
1717
  }
1701
1718
  let closingSquare = this.previous();
1702
1719
  //this.consume("Expected newline or ':' after array literal", TokenKind.Newline, TokenKind.Colon, TokenKind.Eof);
1703
1720
  return new Expression_1.ArrayLiteralExpression(elements, openingSquare, closingSquare);
1704
- case this.match(lexer_1.TokenKind.LeftCurlyBrace):
1721
+ case this.match(TokenKind_1.TokenKind.LeftCurlyBrace):
1705
1722
  let openingBrace = this.previous();
1706
1723
  let members = [];
1707
1724
  let key = () => {
@@ -1710,25 +1727,25 @@ class Parser {
1710
1727
  keyToken: null,
1711
1728
  range: null
1712
1729
  };
1713
- if (this.checkAny(lexer_1.TokenKind.Identifier, ...lexer_1.AllowedProperties)) {
1730
+ if (this.checkAny(TokenKind_1.TokenKind.Identifier, ...TokenKind_1.AllowedProperties)) {
1714
1731
  result.keyToken = this.advance();
1715
1732
  }
1716
- else if (this.check(lexer_1.TokenKind.StringLiteral)) {
1733
+ else if (this.check(TokenKind_1.TokenKind.StringLiteral)) {
1717
1734
  result.keyToken = this.advance();
1718
1735
  }
1719
1736
  else {
1720
1737
  this.diagnostics.push(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.unexpectedAAKey()), { range: this.peek().range }));
1721
1738
  throw this.lastDiagnosticAsError();
1722
1739
  }
1723
- result.colonToken = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedColonBetweenAAKeyAndvalue(), lexer_1.TokenKind.Colon);
1740
+ result.colonToken = this.consume(DiagnosticMessages_1.DiagnosticMessages.expectedColonBetweenAAKeyAndvalue(), TokenKind_1.TokenKind.Colon);
1724
1741
  result.range = util_1.util.getRange(result.keyToken, result.colonToken);
1725
1742
  return result;
1726
1743
  };
1727
- while (this.match(lexer_1.TokenKind.Newline)) {
1744
+ while (this.match(TokenKind_1.TokenKind.Newline)) {
1728
1745
  }
1729
- if (!this.match(lexer_1.TokenKind.RightCurlyBrace)) {
1746
+ if (!this.match(TokenKind_1.TokenKind.RightCurlyBrace)) {
1730
1747
  let lastAAMember;
1731
- if (this.check(lexer_1.TokenKind.Comment)) {
1748
+ if (this.check(TokenKind_1.TokenKind.Comment)) {
1732
1749
  lastAAMember = null;
1733
1750
  members.push(new Statement_1.CommentStatement([this.advance()]));
1734
1751
  }
@@ -1738,26 +1755,26 @@ class Parser {
1738
1755
  lastAAMember = new Expression_1.AAMemberExpression(k.keyToken, k.colonToken, expr);
1739
1756
  members.push(lastAAMember);
1740
1757
  }
1741
- while (this.matchAny(lexer_1.TokenKind.Comma, lexer_1.TokenKind.Newline, lexer_1.TokenKind.Colon, lexer_1.TokenKind.Comment)) {
1758
+ while (this.matchAny(TokenKind_1.TokenKind.Comma, TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Colon, TokenKind_1.TokenKind.Comment)) {
1742
1759
  // collect comma at end of expression
1743
- if (lastAAMember && this.checkPrevious(lexer_1.TokenKind.Comma)) {
1760
+ if (lastAAMember && this.checkPrevious(TokenKind_1.TokenKind.Comma)) {
1744
1761
  lastAAMember.commaToken = this.previous();
1745
1762
  }
1746
1763
  //check for comment at the end of the current line
1747
- if (this.check(lexer_1.TokenKind.Comment) || this.checkPrevious(lexer_1.TokenKind.Comment)) {
1748
- let token = this.checkPrevious(lexer_1.TokenKind.Comment) ? this.previous() : this.advance();
1764
+ if (this.check(TokenKind_1.TokenKind.Comment) || this.checkPrevious(TokenKind_1.TokenKind.Comment)) {
1765
+ let token = this.checkPrevious(TokenKind_1.TokenKind.Comment) ? this.previous() : this.advance();
1749
1766
  members.push(new Statement_1.CommentStatement([token]));
1750
1767
  }
1751
1768
  else {
1752
1769
  this.consumeStatementSeparators(true);
1753
1770
  //check for a comment on its own line
1754
- if (this.check(lexer_1.TokenKind.Comment) || this.checkPrevious(lexer_1.TokenKind.Comment)) {
1755
- let token = this.checkPrevious(lexer_1.TokenKind.Comment) ? this.previous() : this.advance();
1771
+ if (this.check(TokenKind_1.TokenKind.Comment) || this.checkPrevious(TokenKind_1.TokenKind.Comment)) {
1772
+ let token = this.checkPrevious(TokenKind_1.TokenKind.Comment) ? this.previous() : this.advance();
1756
1773
  lastAAMember = null;
1757
1774
  members.push(new Statement_1.CommentStatement([token]));
1758
1775
  continue;
1759
1776
  }
1760
- if (this.check(lexer_1.TokenKind.RightCurlyBrace)) {
1777
+ if (this.check(TokenKind_1.TokenKind.RightCurlyBrace)) {
1761
1778
  break;
1762
1779
  }
1763
1780
  let k = key();
@@ -1766,22 +1783,22 @@ class Parser {
1766
1783
  members.push(lastAAMember);
1767
1784
  }
1768
1785
  }
1769
- this.consume(DiagnosticMessages_1.DiagnosticMessages.unmatchedLeftCurlyAfterAALiteral(), lexer_1.TokenKind.RightCurlyBrace);
1786
+ this.consume(DiagnosticMessages_1.DiagnosticMessages.unmatchedLeftCurlyAfterAALiteral(), TokenKind_1.TokenKind.RightCurlyBrace);
1770
1787
  }
1771
1788
  let closingBrace = this.previous();
1772
1789
  const aaExpr = new Expression_1.AALiteralExpression(members, openingBrace, closingBrace);
1773
1790
  this.addPropertyHints(aaExpr);
1774
1791
  return aaExpr;
1775
- case this.matchAny(lexer_1.TokenKind.Pos, lexer_1.TokenKind.Tab):
1792
+ case this.matchAny(TokenKind_1.TokenKind.Pos, TokenKind_1.TokenKind.Tab):
1776
1793
  let token = Object.assign(this.previous(), {
1777
- kind: lexer_1.TokenKind.Identifier
1794
+ kind: TokenKind_1.TokenKind.Identifier
1778
1795
  });
1779
1796
  return new Expression_1.VariableExpression(token, this.currentNamespaceName);
1780
- case this.checkAny(lexer_1.TokenKind.Function, lexer_1.TokenKind.Sub):
1797
+ case this.checkAny(TokenKind_1.TokenKind.Function, TokenKind_1.TokenKind.Sub):
1781
1798
  return this.anonymousFunction();
1782
- case this.check(lexer_1.TokenKind.RegexLiteral):
1799
+ case this.check(TokenKind_1.TokenKind.RegexLiteral):
1783
1800
  return this.regexLiteralExpression();
1784
- case this.check(lexer_1.TokenKind.Comment):
1801
+ case this.check(TokenKind_1.TokenKind.Comment):
1785
1802
  return new Statement_1.CommentStatement([this.advance()]);
1786
1803
  default:
1787
1804
  //if we found an expected terminator, don't throw a diagnostic...just return undefined
@@ -1851,12 +1868,12 @@ class Parser {
1851
1868
  }
1852
1869
  consumeStatementSeparators(optional = false) {
1853
1870
  //a comment or EOF mark the end of the statement
1854
- if (this.isAtEnd() || this.check(lexer_1.TokenKind.Comment)) {
1871
+ if (this.isAtEnd() || this.check(TokenKind_1.TokenKind.Comment)) {
1855
1872
  return true;
1856
1873
  }
1857
1874
  let consumed = false;
1858
1875
  //consume any newlines and colons
1859
- while (this.matchAny(lexer_1.TokenKind.Newline, lexer_1.TokenKind.Colon)) {
1876
+ while (this.matchAny(TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Colon)) {
1860
1877
  consumed = true;
1861
1878
  }
1862
1879
  if (!optional && !consumed) {
@@ -1872,7 +1889,7 @@ class Parser {
1872
1889
  }
1873
1890
  checkEndOfStatement() {
1874
1891
  const nextKind = this.peek().kind;
1875
- return [lexer_1.TokenKind.Colon, lexer_1.TokenKind.Newline, lexer_1.TokenKind.Comment, lexer_1.TokenKind.Eof].includes(nextKind);
1892
+ return [TokenKind_1.TokenKind.Colon, TokenKind_1.TokenKind.Newline, TokenKind_1.TokenKind.Comment, TokenKind_1.TokenKind.Eof].includes(nextKind);
1876
1893
  }
1877
1894
  checkPrevious(tokenKind) {
1878
1895
  var _a;
@@ -1880,14 +1897,14 @@ class Parser {
1880
1897
  }
1881
1898
  check(tokenKind) {
1882
1899
  const nextKind = this.peek().kind;
1883
- if (nextKind === lexer_1.TokenKind.Eof) {
1900
+ if (nextKind === TokenKind_1.TokenKind.Eof) {
1884
1901
  return false;
1885
1902
  }
1886
1903
  return nextKind === tokenKind;
1887
1904
  }
1888
1905
  checkAny(...tokenKinds) {
1889
1906
  const nextKind = this.peek().kind;
1890
- if (nextKind === lexer_1.TokenKind.Eof) {
1907
+ if (nextKind === TokenKind_1.TokenKind.Eof) {
1891
1908
  return false;
1892
1909
  }
1893
1910
  return tokenKinds.includes(nextKind);
@@ -1906,7 +1923,7 @@ class Parser {
1906
1923
  return tokenKinds.includes(nextKind);
1907
1924
  }
1908
1925
  isAtEnd() {
1909
- return this.peek().kind === lexer_1.TokenKind.Eof;
1926
+ return this.peek().kind === TokenKind_1.TokenKind.Eof;
1910
1927
  }
1911
1928
  peekNext() {
1912
1929
  if (this.isAtEnd()) {
@@ -1928,16 +1945,16 @@ class Parser {
1928
1945
  return;
1929
1946
  }
1930
1947
  switch (this.peek().kind) { //eslint-disable-line @typescript-eslint/switch-exhaustiveness-check
1931
- case lexer_1.TokenKind.Namespace:
1932
- case lexer_1.TokenKind.Class:
1933
- case lexer_1.TokenKind.Function:
1934
- case lexer_1.TokenKind.Sub:
1935
- case lexer_1.TokenKind.If:
1936
- case lexer_1.TokenKind.For:
1937
- case lexer_1.TokenKind.ForEach:
1938
- case lexer_1.TokenKind.While:
1939
- case lexer_1.TokenKind.Print:
1940
- case lexer_1.TokenKind.Return:
1948
+ case TokenKind_1.TokenKind.Namespace:
1949
+ case TokenKind_1.TokenKind.Class:
1950
+ case TokenKind_1.TokenKind.Function:
1951
+ case TokenKind_1.TokenKind.Sub:
1952
+ case TokenKind_1.TokenKind.If:
1953
+ case TokenKind_1.TokenKind.For:
1954
+ case TokenKind_1.TokenKind.ForEach:
1955
+ case TokenKind_1.TokenKind.While:
1956
+ case TokenKind_1.TokenKind.Print:
1957
+ case TokenKind_1.TokenKind.Return:
1941
1958
  // start parsing again from the next block starter or obvious
1942
1959
  // expression start
1943
1960
  return;
@@ -1952,13 +1969,55 @@ class Parser {
1952
1969
  */
1953
1970
  findReferences() {
1954
1971
  this._references = new References();
1972
+ const excludedExpressions = new Set();
1973
+ const visitCallExpression = (e) => {
1974
+ for (const p of e.args) {
1975
+ this._references.expressions.add(p);
1976
+ }
1977
+ //add calls that were not excluded (from loop below)
1978
+ if (!excludedExpressions.has(e)) {
1979
+ this._references.expressions.add(e);
1980
+ }
1981
+ //if this call is part of a longer expression that includes a call higher up, find that higher one and remove it
1982
+ if (e.callee) {
1983
+ let node = e.callee;
1984
+ while (node) {
1985
+ //the primary goal for this loop. If we found a parent call expression, remove it from `references`
1986
+ if ((0, reflection_1.isCallExpression)(node)) {
1987
+ this.references.expressions.delete(node);
1988
+ excludedExpressions.add(node);
1989
+ //stop here. even if there are multiple calls in the chain, each child will find and remove its closest parent, so that reduces excess walking.
1990
+ break;
1991
+ //when we hit a variable expression, we're definitely at the leftmost expression so stop
1992
+ }
1993
+ else if ((0, reflection_1.isVariableExpression)(node)) {
1994
+ break;
1995
+ //if
1996
+ }
1997
+ else if ((0, reflection_1.isDottedGetExpression)(node) || (0, reflection_1.isIndexedGetExpression)(node)) {
1998
+ node = node.obj;
1999
+ }
2000
+ else {
2001
+ //some expression we don't understand. log it and quit the loop
2002
+ this.logger.info('Encountered unknown expression while calculating function expression chain', node);
2003
+ break;
2004
+ }
2005
+ }
2006
+ }
2007
+ };
1955
2008
  this.ast.walk((0, visitors_1.createVisitor)({
1956
2009
  AssignmentStatement: s => {
1957
2010
  this._references.assignmentStatements.push(s);
2011
+ this.references.expressions.add(s.value);
1958
2012
  },
1959
2013
  ClassStatement: s => {
1960
2014
  this._references.classStatements.push(s);
1961
2015
  },
2016
+ ClassFieldStatement: s => {
2017
+ if (s.initialValue) {
2018
+ this._references.expressions.add(s.initialValue);
2019
+ }
2020
+ },
1962
2021
  NamespaceStatement: s => {
1963
2022
  this._references.namespaceStatements.push(s);
1964
2023
  },
@@ -1978,15 +2037,47 @@ class Parser {
1978
2037
  },
1979
2038
  NewExpression: e => {
1980
2039
  this._references.newExpressions.push(e);
2040
+ for (const p of e.call.args) {
2041
+ this._references.expressions.add(p);
2042
+ }
2043
+ },
2044
+ ExpressionStatement: s => {
2045
+ this._references.expressions.add(s.expression);
2046
+ },
2047
+ CallfuncExpression: e => {
2048
+ visitCallExpression(e);
2049
+ },
2050
+ CallExpression: e => {
2051
+ visitCallExpression(e);
1981
2052
  },
1982
2053
  AALiteralExpression: e => {
1983
2054
  this.addPropertyHints(e);
2055
+ this._references.expressions.add(e);
2056
+ for (const member of e.elements) {
2057
+ if ((0, reflection_1.isAAMemberExpression)(member)) {
2058
+ this._references.expressions.add(member.value);
2059
+ }
2060
+ }
2061
+ },
2062
+ ArrayLiteralExpression: e => {
2063
+ for (const element of e.elements) {
2064
+ //keep everything except comments
2065
+ if (!(0, reflection_1.isCommentStatement)(element)) {
2066
+ this._references.expressions.add(element);
2067
+ }
2068
+ }
1984
2069
  },
1985
2070
  DottedGetExpression: e => {
1986
2071
  this.addPropertyHints(e.name);
1987
2072
  },
1988
2073
  DottedSetStatement: e => {
1989
2074
  this.addPropertyHints(e.name);
2075
+ },
2076
+ UnaryExpression: e => {
2077
+ this._references.expressions.add(e);
2078
+ },
2079
+ IncrementStatement: e => {
2080
+ this._references.expressions.add(e);
1990
2081
  }
1991
2082
  }), {
1992
2083
  walkMode: visitors_1.WalkMode.visitAllRecursive
@@ -2008,6 +2099,17 @@ class References {
2008
2099
  this.functionExpressions = [];
2009
2100
  this.functionStatements = [];
2010
2101
  this.interfaceStatements = [];
2102
+ /**
2103
+ * A collection of full expressions. This excludes intermediary expressions.
2104
+ *
2105
+ * Example 1:
2106
+ * `a.b.c` is composed of `a` (variableExpression) `.b` (DottedGetExpression) `.c` (DottedGetExpression)
2107
+ * This will only contain the final `.c` DottedGetExpression because `.b` and `a` can both be derived by walking back from the `.c` DottedGetExpression.
2108
+ *
2109
+ * Example 2:
2110
+ * `name.space.doSomething(a.b.c)` will result in 2 entries in this list. the `CallExpression` for `doSomething`, and the `.c` DottedGetExpression.
2111
+ */
2112
+ this.expressions = new Set();
2011
2113
  this.importStatements = [];
2012
2114
  this.libraryStatements = [];
2013
2115
  this.namespaceStatements = [];