brighterscript 1.0.0-alpha.15 → 1.0.0-alpha.18

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 (163) hide show
  1. package/CHANGELOG.md +83 -0
  2. package/README.md +28 -9
  3. package/dist/DependencyGraph.js +5 -4
  4. package/dist/DependencyGraph.js.map +1 -1
  5. package/dist/DiagnosticMessages.d.ts +16 -1
  6. package/dist/DiagnosticMessages.js +15 -0
  7. package/dist/DiagnosticMessages.js.map +1 -1
  8. package/dist/Logger.js +5 -5
  9. package/dist/Logger.js.map +1 -1
  10. package/dist/Program.d.ts +2 -2
  11. package/dist/Program.js +5 -3
  12. package/dist/Program.js.map +1 -1
  13. package/dist/ProgramBuilder.js +1 -1
  14. package/dist/ProgramBuilder.js.map +1 -1
  15. package/dist/Scope.d.ts +58 -8
  16. package/dist/Scope.js +142 -23
  17. package/dist/Scope.js.map +1 -1
  18. package/dist/XmlScope.js +1 -1
  19. package/dist/XmlScope.js.map +1 -1
  20. package/dist/astUtils/creators.d.ts +10 -6
  21. package/dist/astUtils/creators.js +93 -12
  22. package/dist/astUtils/creators.js.map +1 -1
  23. package/dist/astUtils/creators.spec.js +10 -0
  24. package/dist/astUtils/creators.spec.js.map +1 -1
  25. package/dist/astUtils/reflection.d.ts +8 -3
  26. package/dist/astUtils/reflection.js +18 -2
  27. package/dist/astUtils/reflection.js.map +1 -1
  28. package/dist/astUtils/reflection.spec.js +15 -4
  29. package/dist/astUtils/reflection.spec.js.map +1 -1
  30. package/dist/astUtils/visitors.d.ts +4 -1
  31. package/dist/astUtils/visitors.js.map +1 -1
  32. package/dist/astUtils/visitors.spec.js +2 -0
  33. package/dist/astUtils/visitors.spec.js.map +1 -1
  34. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js +2 -2
  35. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js.map +1 -1
  36. package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.js +7 -3
  37. package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.js.map +1 -1
  38. package/dist/{types/FunctionType.spec.d.ts → bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.d.ts} +0 -0
  39. package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.js +32 -0
  40. package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.js.map +1 -0
  41. package/dist/diagnosticUtils.js +3 -3
  42. package/dist/diagnosticUtils.js.map +1 -1
  43. package/dist/examples/plugins/removePrint.js +12 -14
  44. package/dist/examples/plugins/removePrint.js.map +1 -1
  45. package/dist/files/BrsFile.Class.spec.js +3 -3
  46. package/dist/files/BrsFile.Class.spec.js.map +1 -1
  47. package/dist/files/BrsFile.d.ts +2 -2
  48. package/dist/files/BrsFile.js +99 -63
  49. package/dist/files/BrsFile.js.map +1 -1
  50. package/dist/files/BrsFile.spec.js +187 -67
  51. package/dist/files/BrsFile.spec.js.map +1 -1
  52. package/dist/files/XmlFile.js +3 -3
  53. package/dist/files/XmlFile.js.map +1 -1
  54. package/dist/globalCallables.js +79 -79
  55. package/dist/globalCallables.js.map +1 -1
  56. package/dist/interfaces.d.ts +43 -4
  57. package/dist/parser/Expression.d.ts +91 -22
  58. package/dist/parser/Expression.js +191 -57
  59. package/dist/parser/Expression.js.map +1 -1
  60. package/dist/parser/Parser.Class.spec.js +6 -6
  61. package/dist/parser/Parser.Class.spec.js.map +1 -1
  62. package/dist/parser/Parser.d.ts +3 -6
  63. package/dist/parser/Parser.js +166 -155
  64. package/dist/parser/Parser.js.map +1 -1
  65. package/dist/parser/Parser.spec.js +61 -6
  66. package/dist/parser/Parser.spec.js.map +1 -1
  67. package/dist/parser/SGTypes.d.ts +2 -2
  68. package/dist/parser/SGTypes.js +2 -2
  69. package/dist/parser/SGTypes.js.map +1 -1
  70. package/dist/parser/Statement.d.ts +85 -57
  71. package/dist/parser/Statement.js +228 -173
  72. package/dist/parser/Statement.js.map +1 -1
  73. package/dist/parser/tests/statement/For.spec.d.ts +1 -0
  74. package/dist/parser/tests/statement/For.spec.js +46 -0
  75. package/dist/parser/tests/statement/For.spec.js.map +1 -0
  76. package/dist/parser/tests/statement/ForEach.spec.d.ts +1 -0
  77. package/dist/parser/tests/statement/ForEach.spec.js +37 -0
  78. package/dist/parser/tests/statement/ForEach.spec.js.map +1 -0
  79. package/dist/parser/tests/statement/InterfaceStatement.spec.js +181 -0
  80. package/dist/parser/tests/statement/InterfaceStatement.spec.js.map +1 -1
  81. package/dist/parser/tests/statement/TryCatch.spec.js +7 -5
  82. package/dist/parser/tests/statement/TryCatch.spec.js.map +1 -1
  83. package/dist/types/ArrayType.js +4 -1
  84. package/dist/types/ArrayType.js.map +1 -1
  85. package/dist/types/ArrayType.spec.js +3 -1
  86. package/dist/types/ArrayType.spec.js.map +1 -1
  87. package/dist/types/BooleanType.d.ts +4 -2
  88. package/dist/types/BooleanType.js +7 -2
  89. package/dist/types/BooleanType.js.map +1 -1
  90. package/dist/types/BooleanType.spec.js +3 -1
  91. package/dist/types/BooleanType.spec.js.map +1 -1
  92. package/dist/types/BscType.d.ts +1 -0
  93. package/dist/types/BscType.js +16 -1
  94. package/dist/types/BscType.js.map +1 -1
  95. package/dist/types/CustomType.js +10 -0
  96. package/dist/types/CustomType.js.map +1 -1
  97. package/dist/types/DoubleType.d.ts +2 -0
  98. package/dist/types/DoubleType.js +7 -2
  99. package/dist/types/DoubleType.js.map +1 -1
  100. package/dist/types/DoubleType.spec.js +3 -1
  101. package/dist/types/DoubleType.spec.js.map +1 -1
  102. package/dist/types/DynamicType.d.ts +2 -0
  103. package/dist/types/DynamicType.js +5 -1
  104. package/dist/types/DynamicType.js.map +1 -1
  105. package/dist/types/FloatType.d.ts +3 -1
  106. package/dist/types/FloatType.js +7 -2
  107. package/dist/types/FloatType.js.map +1 -1
  108. package/dist/types/FloatType.spec.js +2 -0
  109. package/dist/types/FloatType.spec.js.map +1 -1
  110. package/dist/types/FunctionType.d.ts +3 -21
  111. package/dist/types/FunctionType.js +8 -65
  112. package/dist/types/FunctionType.js.map +1 -1
  113. package/dist/types/IntegerType.d.ts +3 -1
  114. package/dist/types/IntegerType.js +7 -2
  115. package/dist/types/IntegerType.js.map +1 -1
  116. package/dist/types/IntegerType.spec.js +3 -1
  117. package/dist/types/IntegerType.spec.js.map +1 -1
  118. package/dist/types/InterfaceType.d.ts +13 -10
  119. package/dist/types/InterfaceType.js +33 -29
  120. package/dist/types/InterfaceType.js.map +1 -1
  121. package/dist/types/InterfaceType.spec.js +36 -16
  122. package/dist/types/InterfaceType.spec.js.map +1 -1
  123. package/dist/types/InvalidType.d.ts +4 -2
  124. package/dist/types/InvalidType.js +7 -2
  125. package/dist/types/InvalidType.js.map +1 -1
  126. package/dist/types/InvalidType.spec.js +2 -0
  127. package/dist/types/InvalidType.spec.js.map +1 -1
  128. package/dist/types/LazyType.js +4 -0
  129. package/dist/types/LazyType.js.map +1 -1
  130. package/dist/types/LongIntegerType.d.ts +3 -1
  131. package/dist/types/LongIntegerType.js +7 -2
  132. package/dist/types/LongIntegerType.js.map +1 -1
  133. package/dist/types/LongIntegerType.spec.js +2 -0
  134. package/dist/types/LongIntegerType.spec.js.map +1 -1
  135. package/dist/types/ObjectType.d.ts +2 -1
  136. package/dist/types/ObjectType.js +4 -2
  137. package/dist/types/ObjectType.js.map +1 -1
  138. package/dist/types/StringType.d.ts +4 -2
  139. package/dist/types/StringType.js +7 -2
  140. package/dist/types/StringType.js.map +1 -1
  141. package/dist/types/StringType.spec.js +2 -0
  142. package/dist/types/StringType.spec.js.map +1 -1
  143. package/dist/types/TypedFunctionType.d.ts +28 -0
  144. package/dist/types/TypedFunctionType.js +88 -0
  145. package/dist/types/TypedFunctionType.js.map +1 -0
  146. package/dist/types/TypedFunctionType.spec.d.ts +1 -0
  147. package/dist/types/TypedFunctionType.spec.js +37 -0
  148. package/dist/types/TypedFunctionType.spec.js.map +1 -0
  149. package/dist/types/UninitializedType.js.map +1 -1
  150. package/dist/types/VoidType.d.ts +4 -2
  151. package/dist/types/VoidType.js +5 -1
  152. package/dist/types/VoidType.js.map +1 -1
  153. package/dist/types/helpers.js +7 -2
  154. package/dist/types/helpers.js.map +1 -1
  155. package/dist/util.d.ts +2 -2
  156. package/dist/util.js +39 -46
  157. package/dist/util.js.map +1 -1
  158. package/dist/validators/ClassValidator.d.ts +14 -1
  159. package/dist/validators/ClassValidator.js +129 -82
  160. package/dist/validators/ClassValidator.js.map +1 -1
  161. package/package.json +2 -3
  162. package/dist/types/FunctionType.spec.js +0 -29
  163. package/dist/types/FunctionType.spec.js.map +0 -1
@@ -1,10 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.EnumMemberStatement = exports.EnumStatement = exports.ThrowStatement = exports.TryCatchStatement = exports.ClassFieldStatement = exports.ClassMethodStatement = exports.ClassStatement = exports.InterfaceMethodStatement = exports.InterfaceFieldStatement = exports.InterfaceStatement = exports.ImportStatement = exports.NamespaceStatement = exports.LibraryStatement = exports.IndexedSetStatement = exports.DottedSetStatement = exports.WhileStatement = exports.ForEachStatement = exports.ForStatement = exports.StopStatement = exports.EndStatement = exports.ReturnStatement = exports.LabelStatement = exports.GotoStatement = exports.DimStatement = exports.PrintStatement = exports.IncrementStatement = exports.IfStatement = exports.FunctionStatement = exports.ExitWhileStatement = exports.ExitForStatement = exports.CommentStatement = exports.ExpressionStatement = exports.Block = exports.AssignmentStatement = exports.Body = exports.EmptyStatement = exports.Statement = void 0;
3
+ exports.EnumMemberStatement = exports.EnumStatement = exports.ThrowStatement = exports.CatchStatement = exports.TryCatchStatement = exports.ClassFieldStatement = exports.ClassMethodStatement = exports.ClassStatement = exports.InterfaceMethodStatement = exports.InterfaceFieldStatement = exports.InterfaceStatement = exports.ImportStatement = exports.NamespaceStatement = exports.LibraryStatement = exports.IndexedSetStatement = exports.DottedSetStatement = exports.WhileStatement = exports.ForEachStatement = exports.ForStatement = exports.StopStatement = exports.EndStatement = exports.ReturnStatement = exports.LabelStatement = exports.GotoStatement = exports.DimStatement = exports.PrintStatement = exports.IncrementStatement = exports.IfStatement = exports.FunctionStatement = exports.ExitWhileStatement = exports.ExitForStatement = exports.CommentStatement = exports.ExpressionStatement = exports.Block = exports.AssignmentStatement = exports.Body = exports.EmptyStatement = exports.Statement = void 0;
4
4
  const TokenKind_1 = require("../lexer/TokenKind");
5
5
  const Expression_1 = require("./Expression");
6
6
  const util_1 = require("../util");
7
- const vscode_languageserver_1 = require("vscode-languageserver");
8
7
  const Parser_1 = require("./Parser");
9
8
  const visitors_1 = require("../astUtils/visitors");
10
9
  const reflection_1 = require("../astUtils/reflection");
@@ -12,6 +11,7 @@ const creators_1 = require("../astUtils/creators");
12
11
  const DynamicType_1 = require("../types/DynamicType");
13
12
  const SymbolTable_1 = require("../SymbolTable");
14
13
  const CustomType_1 = require("../types/CustomType");
14
+ const InterfaceType_1 = require("../types/InterfaceType");
15
15
  /**
16
16
  * A BrightScript statement
17
17
  */
@@ -46,12 +46,10 @@ exports.EmptyStatement = EmptyStatement;
46
46
  */
47
47
  class Body extends Statement {
48
48
  constructor(statements = []) {
49
+ var _a;
49
50
  super();
50
51
  this.statements = statements;
51
- }
52
- get range() {
53
- var _a, _b, _c, _d;
54
- return util_1.util.createRangeFromPositions((_b = (_a = this.statements[0]) === null || _a === void 0 ? void 0 : _a.range.start) !== null && _b !== void 0 ? _b : vscode_languageserver_1.Position.create(0, 0), (_d = (_c = this.statements[this.statements.length - 1]) === null || _c === void 0 ? void 0 : _c.range.end) !== null && _d !== void 0 ? _d : vscode_languageserver_1.Position.create(0, 0));
52
+ this.range = (_a = util_1.util.createBoundingRange(...this.statements)) !== null && _a !== void 0 ? _a : creators_1.interpolatedRange;
55
53
  }
56
54
  transpile(state) {
57
55
  let result = [];
@@ -103,12 +101,13 @@ class Body extends Statement {
103
101
  exports.Body = Body;
104
102
  class AssignmentStatement extends Statement {
105
103
  constructor(name, equals, value, containingFunction) {
104
+ var _a;
106
105
  super();
107
106
  this.name = name;
108
107
  this.equals = equals;
109
108
  this.value = value;
110
109
  this.containingFunction = containingFunction;
111
- this.range = util_1.util.createRangeFromPositions(this.name.range.start, this.value.range.end);
110
+ this.range = (_a = util_1.util.createBoundingRange(this.name, this.equals, this.value)) !== null && _a !== void 0 ? _a : creators_1.interpolatedRange;
112
111
  }
113
112
  transpile(state) {
114
113
  var _a, _b;
@@ -135,12 +134,11 @@ class AssignmentStatement extends Statement {
135
134
  exports.AssignmentStatement = AssignmentStatement;
136
135
  class Block extends Statement {
137
136
  constructor(statements, startingRange) {
137
+ var _a;
138
138
  super();
139
139
  this.statements = statements;
140
140
  this.startingRange = startingRange;
141
- this.range = util_1.util.createRangeFromPositions(this.startingRange.start, this.statements.length
142
- ? this.statements[this.statements.length - 1].range.end
143
- : this.startingRange.start);
141
+ this.range = (_a = util_1.util.createBoundingRange({ range: this.startingRange }, ...statements)) !== null && _a !== void 0 ? _a : creators_1.interpolatedRange;
144
142
  }
145
143
  transpile(state) {
146
144
  state.blockDepth++;
@@ -177,9 +175,10 @@ class Block extends Statement {
177
175
  exports.Block = Block;
178
176
  class ExpressionStatement extends Statement {
179
177
  constructor(expression) {
178
+ var _a, _b;
180
179
  super();
181
180
  this.expression = expression;
182
- this.range = this.expression.range;
181
+ this.range = (_b = (_a = this.expression) === null || _a === void 0 ? void 0 : _a.range) !== null && _b !== void 0 ? _b : creators_1.interpolatedRange;
183
182
  }
184
183
  transpile(state) {
185
184
  return this.expression.transpile(state);
@@ -196,10 +195,8 @@ class CommentStatement extends Statement {
196
195
  var _a;
197
196
  super();
198
197
  this.comments = comments;
198
+ this.range = (_a = util_1.util.createBoundingRange(...this.comments)) !== null && _a !== void 0 ? _a : creators_1.interpolatedRange;
199
199
  this.visitMode = visitors_1.InternalWalkMode.visitStatements | visitors_1.InternalWalkMode.visitExpressions;
200
- if (((_a = this.comments) === null || _a === void 0 ? void 0 : _a.length) > 0) {
201
- this.range = util_1.util.createRangeFromPositions(this.comments[0].range.start, this.comments[this.comments.length - 1].range.end);
202
- }
203
200
  }
204
201
  get text() {
205
202
  return this.comments.map(x => x.text).join('\n');
@@ -229,9 +226,10 @@ class CommentStatement extends Statement {
229
226
  exports.CommentStatement = CommentStatement;
230
227
  class ExitForStatement extends Statement {
231
228
  constructor(tokens) {
229
+ var _a, _b, _c;
232
230
  super();
233
231
  this.tokens = tokens;
234
- this.range = this.tokens.exitFor.range;
232
+ this.range = (_c = (_b = (_a = this.tokens) === null || _a === void 0 ? void 0 : _a.exitFor) === null || _b === void 0 ? void 0 : _b.range) !== null && _c !== void 0 ? _c : creators_1.interpolatedRange;
235
233
  }
236
234
  transpile(state) {
237
235
  return [
@@ -245,9 +243,10 @@ class ExitForStatement extends Statement {
245
243
  exports.ExitForStatement = ExitForStatement;
246
244
  class ExitWhileStatement extends Statement {
247
245
  constructor(tokens) {
246
+ var _a, _b, _c;
248
247
  super();
249
248
  this.tokens = tokens;
250
- this.range = this.tokens.exitWhile.range;
249
+ this.range = (_c = (_b = (_a = this.tokens) === null || _a === void 0 ? void 0 : _a.exitWhile) === null || _b === void 0 ? void 0 : _b.range) !== null && _c !== void 0 ? _c : creators_1.interpolatedRange;
251
250
  }
252
251
  transpile(state) {
253
252
  return [
@@ -265,7 +264,16 @@ class FunctionStatement extends Statement {
265
264
  this.name = name;
266
265
  this.func = func;
267
266
  this.namespaceName = namespaceName;
268
- this.range = this.func.range;
267
+ }
268
+ get range() {
269
+ return this.cacheRange();
270
+ }
271
+ cacheRange() {
272
+ var _a, _b;
273
+ if (!this._range) {
274
+ this._range = (_b = (_a = this.func) === null || _a === void 0 ? void 0 : _a.range) !== null && _b !== void 0 ? _b : this.name.range;
275
+ }
276
+ return this._range;
269
277
  }
270
278
  /**
271
279
  * Get the name of this expression based on the parse mode
@@ -303,14 +311,14 @@ class FunctionStatement extends Statement {
303
311
  exports.FunctionStatement = FunctionStatement;
304
312
  class IfStatement extends Statement {
305
313
  constructor(tokens, condition, thenBranch, elseBranch, isInline) {
306
- var _a, _b;
314
+ var _a;
307
315
  super();
308
316
  this.tokens = tokens;
309
317
  this.condition = condition;
310
318
  this.thenBranch = thenBranch;
311
319
  this.elseBranch = elseBranch;
312
320
  this.isInline = isInline;
313
- this.range = util_1.util.createRangeFromPositions(this.tokens.if.range.start, ((_b = (_a = this.tokens.endIf) !== null && _a !== void 0 ? _a : this.elseBranch) !== null && _b !== void 0 ? _b : this.thenBranch).range.end);
321
+ this.range = (_a = util_1.util.createBoundingRange(this.tokens.if, this.condition, this.tokens.then, this.thenBranch, this.tokens.else, this.elseBranch, this.tokens.endIf)) !== null && _a !== void 0 ? _a : creators_1.interpolatedRange;
314
322
  }
315
323
  transpile(state) {
316
324
  let results = [];
@@ -319,14 +327,11 @@ class IfStatement extends Statement {
319
327
  results.push(' ');
320
328
  //conditions
321
329
  results.push(...this.condition.transpile(state));
322
- results.push(' ');
323
330
  //then
324
331
  if (this.tokens.then) {
332
+ results.push(' ');
325
333
  results.push(state.transpileToken(this.tokens.then));
326
334
  }
327
- else {
328
- results.push('then');
329
- }
330
335
  state.lineage.unshift(this);
331
336
  //if statement body
332
337
  let thenNodes = this.thenBranch.transpile(state);
@@ -347,7 +352,8 @@ class IfStatement extends Statement {
347
352
  let body = this.elseBranch.transpile(state);
348
353
  state.lineage.shift();
349
354
  if (body.length > 0) {
350
- results.push(' ');
355
+ //zero or more spaces between the `else` and the `if`
356
+ results.push(this.elseBranch.tokens.if.leadingWhitespace);
351
357
  results.push(...body);
352
358
  // stop here because chained if will transpile the rest
353
359
  return results;
@@ -392,10 +398,11 @@ class IfStatement extends Statement {
392
398
  exports.IfStatement = IfStatement;
393
399
  class IncrementStatement extends Statement {
394
400
  constructor(value, operator) {
401
+ var _a;
395
402
  super();
396
403
  this.value = value;
397
404
  this.operator = operator;
398
- this.range = util_1.util.createRangeFromPositions(this.value.range.start, this.operator.range.end);
405
+ this.range = (_a = util_1.util.createBoundingRange(this.value, this.operator)) !== null && _a !== void 0 ? _a : creators_1.interpolatedRange;
399
406
  }
400
407
  transpile(state) {
401
408
  return [
@@ -420,12 +427,11 @@ class PrintStatement extends Statement {
420
427
  * evaluated and printed.
421
428
  */
422
429
  constructor(tokens, expressions) {
430
+ var _a;
423
431
  super();
424
432
  this.tokens = tokens;
425
433
  this.expressions = expressions;
426
- this.range = util_1.util.createRangeFromPositions(this.tokens.print.range.start, this.expressions.length
427
- ? this.expressions[this.expressions.length - 1].range.end
428
- : this.tokens.print.range.end);
434
+ this.range = (_a = util_1.util.createBoundingRange(this.tokens.print, ...this.expressions)) !== null && _a !== void 0 ? _a : creators_1.interpolatedRange;
429
435
  }
430
436
  transpile(state) {
431
437
  var _a;
@@ -462,14 +468,14 @@ class PrintStatement extends Statement {
462
468
  exports.PrintStatement = PrintStatement;
463
469
  class DimStatement extends Statement {
464
470
  constructor(dimToken, identifier, openingSquare, dimensions, closingSquare) {
465
- var _a, _b, _c, _d;
471
+ var _a;
466
472
  super();
467
473
  this.dimToken = dimToken;
468
474
  this.identifier = identifier;
469
475
  this.openingSquare = openingSquare;
470
476
  this.dimensions = dimensions;
471
477
  this.closingSquare = closingSquare;
472
- this.range = util_1.util.createRangeFromPositions(this.dimToken.range.start, ((_d = (_c = (_b = (_a = this.closingSquare) !== null && _a !== void 0 ? _a : this.dimensions[this.dimensions.length - 1]) !== null && _b !== void 0 ? _b : this.openingSquare) !== null && _c !== void 0 ? _c : this.identifier) !== null && _d !== void 0 ? _d : this.dimToken).range.end);
478
+ this.range = (_a = util_1.util.createBoundingRange(this.dimToken, this.identifier, this.openingSquare, ...this.dimensions, this.closingSquare)) !== null && _a !== void 0 ? _a : creators_1.interpolatedRange;
473
479
  }
474
480
  transpile(state) {
475
481
  let result = [
@@ -499,9 +505,10 @@ class DimStatement extends Statement {
499
505
  exports.DimStatement = DimStatement;
500
506
  class GotoStatement extends Statement {
501
507
  constructor(tokens) {
508
+ var _a;
502
509
  super();
503
510
  this.tokens = tokens;
504
- this.range = util_1.util.createRangeFromPositions(this.tokens.goto.range.start, this.tokens.label.range.end);
511
+ this.range = (_a = util_1.util.createBoundingRange(this.tokens.goto, this.tokens.label)) !== null && _a !== void 0 ? _a : creators_1.interpolatedRange;
505
512
  }
506
513
  transpile(state) {
507
514
  return [
@@ -517,9 +524,10 @@ class GotoStatement extends Statement {
517
524
  exports.GotoStatement = GotoStatement;
518
525
  class LabelStatement extends Statement {
519
526
  constructor(tokens) {
527
+ var _a;
520
528
  super();
521
529
  this.tokens = tokens;
522
- this.range = util_1.util.createRangeFromPositions(this.tokens.identifier.range.start, this.tokens.colon.range.end);
530
+ this.range = (_a = util_1.util.createBoundingRange(this.tokens.identifier, this.tokens.colon)) !== null && _a !== void 0 ? _a : creators_1.interpolatedRange;
523
531
  }
524
532
  transpile(state) {
525
533
  return [
@@ -538,7 +546,7 @@ class ReturnStatement extends Statement {
538
546
  super();
539
547
  this.tokens = tokens;
540
548
  this.value = value;
541
- this.range = util_1.util.createRangeFromPositions(this.tokens.return.range.start, ((_a = this.value) === null || _a === void 0 ? void 0 : _a.range.end) || this.tokens.return.range.end);
549
+ this.range = (_a = util_1.util.createBoundingRange(this.tokens.return, this.value)) !== null && _a !== void 0 ? _a : creators_1.interpolatedRange;
542
550
  }
543
551
  transpile(state) {
544
552
  let result = [];
@@ -558,9 +566,10 @@ class ReturnStatement extends Statement {
558
566
  exports.ReturnStatement = ReturnStatement;
559
567
  class EndStatement extends Statement {
560
568
  constructor(tokens) {
569
+ var _a, _b;
561
570
  super();
562
571
  this.tokens = tokens;
563
- this.range = util_1.util.createRangeFromPositions(this.tokens.end.range.start, this.tokens.end.range.end);
572
+ this.range = (_b = (_a = this.tokens.end) === null || _a === void 0 ? void 0 : _a.range) !== null && _b !== void 0 ? _b : creators_1.interpolatedRange;
564
573
  }
565
574
  transpile(state) {
566
575
  return [
@@ -574,9 +583,10 @@ class EndStatement extends Statement {
574
583
  exports.EndStatement = EndStatement;
575
584
  class StopStatement extends Statement {
576
585
  constructor(tokens) {
586
+ var _a, _b;
577
587
  super();
578
588
  this.tokens = tokens;
579
- this.range = util_1.util.createRangeFromPositions(this.tokens.stop.range.start, this.tokens.stop.range.end);
589
+ this.range = (_b = (_a = this.tokens.stop) === null || _a === void 0 ? void 0 : _a.range) !== null && _b !== void 0 ? _b : creators_1.interpolatedRange;
580
590
  }
581
591
  transpile(state) {
582
592
  return [
@@ -590,7 +600,7 @@ class StopStatement extends Statement {
590
600
  exports.StopStatement = StopStatement;
591
601
  class ForStatement extends Statement {
592
602
  constructor(forToken, counterDeclaration, toToken, finalValue, body, endForToken, stepToken, increment) {
593
- var _a, _b;
603
+ var _a;
594
604
  super();
595
605
  this.forToken = forToken;
596
606
  this.counterDeclaration = counterDeclaration;
@@ -600,8 +610,7 @@ class ForStatement extends Statement {
600
610
  this.endForToken = endForToken;
601
611
  this.stepToken = stepToken;
602
612
  this.increment = increment;
603
- const lastRange = (_b = (_a = this.endForToken) === null || _a === void 0 ? void 0 : _a.range) !== null && _b !== void 0 ? _b : body.range;
604
- this.range = util_1.util.createRangeFromPositions(this.forToken.range.start, lastRange.end);
613
+ this.range = (_a = util_1.util.createBoundingRange(this.forToken, this.counterDeclaration, this.toToken, this.finalValue, this.body, this.stepToken, this.increment, this.endForToken)) !== null && _a !== void 0 ? _a : creators_1.interpolatedRange;
605
614
  }
606
615
  transpile(state) {
607
616
  let result = [];
@@ -621,9 +630,8 @@ class ForStatement extends Statement {
621
630
  state.lineage.unshift(this);
622
631
  result.push(...this.body.transpile(state));
623
632
  state.lineage.shift();
624
- if (this.body.statements.length > 0) {
625
- result.push('\n');
626
- }
633
+ // add new line before "end for"
634
+ result.push('\n');
627
635
  //end for
628
636
  result.push(state.indent(), state.transpileToken(this.endForToken));
629
637
  return result;
@@ -644,7 +652,7 @@ class ForStatement extends Statement {
644
652
  exports.ForStatement = ForStatement;
645
653
  class ForEachStatement extends Statement {
646
654
  constructor(forEachToken, item, inToken, target, body, endForToken) {
647
- var _a, _b, _c, _d, _e;
655
+ var _a;
648
656
  super();
649
657
  this.forEachToken = forEachToken;
650
658
  this.item = item;
@@ -652,7 +660,7 @@ class ForEachStatement extends Statement {
652
660
  this.target = target;
653
661
  this.body = body;
654
662
  this.endForToken = endForToken;
655
- this.range = util_1.util.createRangeFromPositions(this.forEachToken.range.start, ((_e = (_d = (_c = (_b = (_a = this.endForToken) !== null && _a !== void 0 ? _a : this.body) !== null && _b !== void 0 ? _b : this.target) !== null && _c !== void 0 ? _c : this.inToken) !== null && _d !== void 0 ? _d : this.item) !== null && _e !== void 0 ? _e : this.forEachToken).range.end);
663
+ this.range = (_a = util_1.util.createBoundingRange(this.forEachToken, this.item, this.inToken, this.target, this.body, this.endForToken)) !== null && _a !== void 0 ? _a : creators_1.interpolatedRange;
656
664
  }
657
665
  transpile(state) {
658
666
  let result = [];
@@ -668,9 +676,8 @@ class ForEachStatement extends Statement {
668
676
  state.lineage.unshift(this);
669
677
  result.push(...this.body.transpile(state));
670
678
  state.lineage.shift();
671
- if (this.body.statements.length > 0) {
672
- result.push('\n');
673
- }
679
+ // add new line before "end for"
680
+ result.push('\n');
674
681
  //end for
675
682
  result.push(state.indent(), state.transpileToken(this.endForToken));
676
683
  return result;
@@ -687,13 +694,12 @@ class ForEachStatement extends Statement {
687
694
  exports.ForEachStatement = ForEachStatement;
688
695
  class WhileStatement extends Statement {
689
696
  constructor(tokens, condition, body) {
690
- var _a, _b;
697
+ var _a;
691
698
  super();
692
699
  this.tokens = tokens;
693
700
  this.condition = condition;
694
701
  this.body = body;
695
- const lastRange = (_b = (_a = this.tokens.endWhile) === null || _a === void 0 ? void 0 : _a.range) !== null && _b !== void 0 ? _b : body.range;
696
- this.range = util_1.util.createRangeFromPositions(this.tokens.while.range.start, lastRange.end);
702
+ this.range = (_a = util_1.util.createBoundingRange(this.tokens.while, this.condition, this.body, this.tokens.endWhile)) !== null && _a !== void 0 ? _a : creators_1.interpolatedRange;
697
703
  }
698
704
  transpile(state) {
699
705
  let result = [];
@@ -722,12 +728,15 @@ class WhileStatement extends Statement {
722
728
  }
723
729
  exports.WhileStatement = WhileStatement;
724
730
  class DottedSetStatement extends Statement {
725
- constructor(obj, name, value) {
731
+ constructor(obj, name, value, dot, operator) {
732
+ var _a;
726
733
  super();
727
734
  this.obj = obj;
728
735
  this.name = name;
729
736
  this.value = value;
730
- this.range = util_1.util.createRangeFromPositions(this.obj.range.start, this.value.range.end);
737
+ this.dot = dot;
738
+ this.operator = operator;
739
+ this.range = (_a = util_1.util.createBoundingRange(this.obj, this.dot, this.name, this.operator, this.value)) !== null && _a !== void 0 ? _a : creators_1.interpolatedRange;
731
740
  }
732
741
  transpile(state) {
733
742
  var _a, _b;
@@ -757,14 +766,16 @@ class DottedSetStatement extends Statement {
757
766
  }
758
767
  exports.DottedSetStatement = DottedSetStatement;
759
768
  class IndexedSetStatement extends Statement {
760
- constructor(obj, index, value, openingSquare, closingSquare) {
769
+ constructor(obj, index, value, openingSquare, closingSquare, operator) {
770
+ var _a;
761
771
  super();
762
772
  this.obj = obj;
763
773
  this.index = index;
764
774
  this.value = value;
765
775
  this.openingSquare = openingSquare;
766
776
  this.closingSquare = closingSquare;
767
- this.range = util_1.util.createRangeFromPositions(this.obj.range.start, this.value.range.end);
777
+ this.operator = operator;
778
+ this.range = (_a = util_1.util.createBoundingRange(this.obj, this.openingSquare, this.index, this.closingSquare, this.operator, this.value)) !== null && _a !== void 0 ? _a : creators_1.interpolatedRange;
768
779
  }
769
780
  transpile(state) {
770
781
  var _a, _b;
@@ -800,9 +811,10 @@ class IndexedSetStatement extends Statement {
800
811
  exports.IndexedSetStatement = IndexedSetStatement;
801
812
  class LibraryStatement extends Statement {
802
813
  constructor(tokens) {
814
+ var _a;
803
815
  super();
804
816
  this.tokens = tokens;
805
- this.range = util_1.util.createRangeFromPositions(this.tokens.library.range.start, this.tokens.filePath ? this.tokens.filePath.range.end : this.tokens.library.range.end);
817
+ this.range = (_a = util_1.util.createBoundingRange(this.tokens.library, this.tokens.filePath)) !== null && _a !== void 0 ? _a : creators_1.interpolatedRange;
806
818
  }
807
819
  transpile(state) {
808
820
  let result = [];
@@ -835,8 +847,14 @@ class NamespaceStatement extends Statement {
835
847
  this.symbolTable = new SymbolTable_1.SymbolTable(parentSymbolTable);
836
848
  }
837
849
  get range() {
838
- var _a, _b, _c;
839
- return util_1.util.createRangeFromPositions(this.keyword.range.start, ((_c = (_b = (_a = this.endKeyword) !== null && _a !== void 0 ? _a : this.body) !== null && _b !== void 0 ? _b : this.nameExpression) !== null && _c !== void 0 ? _c : this.keyword).range.end);
850
+ return this.cacheRange();
851
+ }
852
+ cacheRange() {
853
+ var _a;
854
+ if (!this._range) {
855
+ this._range = (_a = util_1.util.createBoundingRange(this.keyword, this.nameExpression, this.body, this.endKeyword)) !== null && _a !== void 0 ? _a : creators_1.interpolatedRange;
856
+ }
857
+ return this._range;
840
858
  }
841
859
  getName(parseMode) {
842
860
  return this.nameExpression.getName(parseMode);
@@ -869,10 +887,11 @@ class NamespaceStatement extends Statement {
869
887
  exports.NamespaceStatement = NamespaceStatement;
870
888
  class ImportStatement extends Statement {
871
889
  constructor(importToken, filePathToken) {
890
+ var _a;
872
891
  super();
873
892
  this.importToken = importToken;
874
893
  this.filePathToken = filePathToken;
875
- this.range = util_1.util.createRangeFromPositions(importToken.range.start, (filePathToken !== null && filePathToken !== void 0 ? filePathToken : importToken).range.end);
894
+ this.range = (_a = util_1.util.createBoundingRange(this.importToken, this.filePathToken)) !== null && _a !== void 0 ? _a : creators_1.interpolatedRange;
876
895
  if (this.filePathToken) {
877
896
  //remove quotes
878
897
  this.filePath = this.filePathToken.text.replace(/"/g, '');
@@ -908,26 +927,37 @@ class ImportStatement extends Statement {
908
927
  exports.ImportStatement = ImportStatement;
909
928
  class InterfaceStatement extends Statement {
910
929
  constructor(interfaceToken, name, extendsToken, parentInterfaceName, body, endInterfaceToken, namespaceName) {
930
+ var _a, _b, _c;
911
931
  super();
932
+ this.name = name;
912
933
  this.parentInterfaceName = parentInterfaceName;
913
934
  this.body = body;
914
935
  this.namespaceName = namespaceName;
936
+ this.memberTable = new SymbolTable_1.SymbolTable();
915
937
  this.tokens = {};
938
+ this.memberMap = {};
939
+ this.methods = [];
940
+ this.fields = [];
916
941
  this.tokens.interface = interfaceToken;
917
942
  this.tokens.name = name;
918
943
  this.tokens.extends = extendsToken;
919
944
  this.tokens.endInterface = endInterfaceToken;
920
- }
921
- get fields() {
922
- return this.body.filter(x => (0, reflection_1.isInterfaceFieldStatement)(x));
923
- }
924
- get methods() {
925
- return this.body.filter(x => (0, reflection_1.isInterfaceMethodStatement)(x));
945
+ this.range = (_a = util_1.util.createBoundingRange(this.tokens.interface, this.tokens.name, this.tokens.extends, this.parentInterfaceName, ...this.body, this.tokens.endInterface)) !== null && _a !== void 0 ? _a : creators_1.interpolatedRange;
946
+ for (let statement of this.body) {
947
+ if ((0, reflection_1.isInterfaceMethodStatement)(statement)) {
948
+ this.methods.push(statement);
949
+ this.memberMap[(_b = statement === null || statement === void 0 ? void 0 : statement.name) === null || _b === void 0 ? void 0 : _b.text.toLowerCase()] = statement;
950
+ }
951
+ else if ((0, reflection_1.isInterfaceFieldStatement)(statement)) {
952
+ this.fields.push(statement);
953
+ this.memberMap[(_c = statement === null || statement === void 0 ? void 0 : statement.tokens.name) === null || _c === void 0 ? void 0 : _c.text.toLowerCase()] = statement;
954
+ }
955
+ }
926
956
  }
927
957
  /**
928
958
  * The name of the interface WITH its leading namespace (if applicable)
929
959
  */
930
- get fullName() {
960
+ getName(parseMode) {
931
961
  var _a;
932
962
  const name = (_a = this.tokens.name) === null || _a === void 0 ? void 0 : _a.text;
933
963
  if (name) {
@@ -944,12 +974,49 @@ class InterfaceStatement extends Statement {
944
974
  return undefined;
945
975
  }
946
976
  }
977
+ buildSymbolTable(parentIface) {
978
+ var _a, _b;
979
+ this.memberTable.clear();
980
+ if (parentIface) {
981
+ this.memberTable.setParent(parentIface === null || parentIface === void 0 ? void 0 : parentIface.memberTable);
982
+ }
983
+ for (const statement of this.methods) {
984
+ const funcType = statement === null || statement === void 0 ? void 0 : statement.func.getFunctionType();
985
+ this.memberTable.addSymbol((_a = statement === null || statement === void 0 ? void 0 : statement.name) === null || _a === void 0 ? void 0 : _a.text, statement === null || statement === void 0 ? void 0 : statement.range, funcType);
986
+ }
987
+ for (const statement of this.fields) {
988
+ this.memberTable.addSymbol((_b = statement === null || statement === void 0 ? void 0 : statement.tokens.name) === null || _b === void 0 ? void 0 : _b.text, statement === null || statement === void 0 ? void 0 : statement.range, statement.getType());
989
+ }
990
+ }
991
+ hasParent() {
992
+ return !!this.parentInterfaceName;
993
+ }
994
+ getParentName() {
995
+ return !!this.parentInterfaceName;
996
+ }
947
997
  /**
948
- * The name of the interface (without the namespace prefix)
998
+ * Gets an array of possible parent interface names, taking into account the namespace this interface was created under
999
+ * @returns array of possible parent interface names
949
1000
  */
950
- get name() {
1001
+ getPossibleFullParentNames() {
951
1002
  var _a;
952
- return (_a = this.tokens.name) === null || _a === void 0 ? void 0 : _a.text;
1003
+ if (!this.hasParent()) {
1004
+ return [];
1005
+ }
1006
+ if (((_a = this.parentInterfaceName) === null || _a === void 0 ? void 0 : _a.getNameParts().length) > 1) {
1007
+ // The specified parent interface already has a dot, so it must already reference a namespace
1008
+ return [this.parentInterfaceName.getName()];
1009
+ }
1010
+ const names = [];
1011
+ if (this.namespaceName) {
1012
+ // We're under a namespace, so the full parent name MIGHT be with this namespace too
1013
+ names.push(this.namespaceName.getName() + '.' + this.parentInterfaceName.getName());
1014
+ }
1015
+ names.push(this.parentInterfaceName.getName());
1016
+ return names;
1017
+ }
1018
+ getThisBscType() {
1019
+ return new InterfaceType_1.InterfaceType(this.getName(Parser_1.ParseMode.BrighterScript), this.memberTable);
953
1020
  }
954
1021
  transpile(state) {
955
1022
  //interfaces should completely disappear at runtime
@@ -994,88 +1061,53 @@ class InterfaceStatement extends Statement {
994
1061
  }
995
1062
  exports.InterfaceStatement = InterfaceStatement;
996
1063
  class InterfaceFieldStatement extends Statement {
997
- constructor(nameToken, asToken, typeToken, type) {
1064
+ constructor(nameToken, asToken, type, namespaceName) {
1065
+ var _a;
998
1066
  super();
999
1067
  this.type = type;
1068
+ this.namespaceName = namespaceName;
1000
1069
  this.tokens = {};
1001
1070
  this.tokens.name = nameToken;
1002
1071
  this.tokens.as = asToken;
1003
- this.tokens.type = typeToken;
1072
+ this.range = (_a = util_1.util.createBoundingRange(this.tokens.name, this.tokens.as, this.type)) !== null && _a !== void 0 ? _a : creators_1.interpolatedRange;
1004
1073
  }
1005
1074
  transpile(state) {
1006
1075
  throw new Error('Method not implemented.');
1007
1076
  }
1008
- get range() {
1009
- var _a, _b;
1010
- return util_1.util.createRangeFromPositions(this.tokens.name.range.start, ((_b = (_a = this.tokens.type) !== null && _a !== void 0 ? _a : this.tokens.as) !== null && _b !== void 0 ? _b : this.tokens.name).range.end);
1077
+ getType() {
1078
+ var _a;
1079
+ return (_a = this.type) === null || _a === void 0 ? void 0 : _a.type;
1011
1080
  }
1012
1081
  get name() {
1013
- return this.tokens.name.text;
1082
+ return this.tokens.name;
1014
1083
  }
1015
1084
  walk(visitor, options) {
1016
1085
  //nothing to walk
1017
1086
  }
1018
1087
  getTypedef(state) {
1019
- var _a, _b, _c;
1088
+ var _a;
1020
1089
  const result = [];
1021
1090
  for (let annotation of (_a = this.annotations) !== null && _a !== void 0 ? _a : []) {
1022
1091
  result.push(...annotation.getTypedef(state), state.newline, state.indent());
1023
1092
  }
1024
1093
  result.push(this.tokens.name.text);
1025
- if (((_c = (_b = this.tokens.type) === null || _b === void 0 ? void 0 : _b.text) === null || _c === void 0 ? void 0 : _c.length) > 0) {
1026
- result.push(' as ', this.tokens.type.text);
1094
+ if (this.tokens.as && this.type) {
1095
+ result.push(' as ', ...this.type.transpile(state));
1027
1096
  }
1028
1097
  return result;
1029
1098
  }
1030
1099
  }
1031
1100
  exports.InterfaceFieldStatement = InterfaceFieldStatement;
1032
- class InterfaceMethodStatement extends Statement {
1033
- constructor(functionTypeToken, nameToken, leftParen, params, rightParen, asToken, returnTypeToken, returnType) {
1034
- super();
1035
- this.params = params;
1036
- this.returnType = returnType;
1037
- this.tokens = {};
1038
- this.tokens.functionType = functionTypeToken;
1039
- this.tokens.name = nameToken;
1040
- this.tokens.leftParen = leftParen;
1041
- this.tokens.rightParen = rightParen;
1042
- this.tokens.as = asToken;
1043
- this.tokens.returnType = returnTypeToken;
1044
- }
1101
+ class InterfaceMethodStatement extends FunctionStatement {
1045
1102
  transpile(state) {
1046
1103
  throw new Error('Method not implemented.');
1047
1104
  }
1048
- get range() {
1049
- var _a, _b, _c, _d, _e, _f, _g, _h;
1050
- return util_1.util.createRangeFromPositions(this.tokens.name.range.start, ((_h = (_g = (_f = (_c = (_b = (_a = this.tokens.returnType) !== null && _a !== void 0 ? _a : this.tokens.as) !== null && _b !== void 0 ? _b : this.tokens.rightParen) !== null && _c !== void 0 ? _c : (_d = this.params) === null || _d === void 0 ? void 0 : _d[((_e = this.params) === null || _e === void 0 ? void 0 : _e.length) - 1]) !== null && _f !== void 0 ? _f : this.tokens.leftParen) !== null && _g !== void 0 ? _g : this.tokens.name) !== null && _h !== void 0 ? _h : this.tokens.functionType).range.end);
1105
+ constructor(name, func) {
1106
+ super(name, func, undefined);
1051
1107
  }
1052
1108
  walk(visitor, options) {
1053
1109
  //nothing to walk
1054
1110
  }
1055
- getTypedef(state) {
1056
- var _a, _b, _c, _d, _e;
1057
- const result = [];
1058
- for (let annotation of (_a = this.annotations) !== null && _a !== void 0 ? _a : []) {
1059
- result.push(...annotation.getTypedef(state), state.newline, state.indent());
1060
- }
1061
- result.push(this.tokens.functionType.text, ' ', this.tokens.name.text, '(');
1062
- const params = (_b = this.params) !== null && _b !== void 0 ? _b : [];
1063
- for (let i = 0; i < params.length; i++) {
1064
- if (i > 0) {
1065
- result.push(', ');
1066
- }
1067
- const param = params[i];
1068
- result.push(param.name.text);
1069
- if (((_d = (_c = param.typeToken) === null || _c === void 0 ? void 0 : _c.text) === null || _d === void 0 ? void 0 : _d.length) > 0) {
1070
- result.push(' as ', param.typeToken.text);
1071
- }
1072
- }
1073
- result.push(')');
1074
- if (((_e = this.tokens.returnType) === null || _e === void 0 ? void 0 : _e.text.length) > 0) {
1075
- result.push(' as ', this.tokens.returnType.text);
1076
- }
1077
- return result;
1078
- }
1079
1111
  }
1080
1112
  exports.InterfaceMethodStatement = InterfaceMethodStatement;
1081
1113
  class ClassStatement extends Statement {
@@ -1084,7 +1116,7 @@ class ClassStatement extends Statement {
1084
1116
  * The name of the class (without namespace prefix)
1085
1117
  */
1086
1118
  name, body, end, extendsKeyword, parentClassName, namespaceName, currentSymbolTable) {
1087
- var _a, _b, _c;
1119
+ var _a, _b, _c, _d;
1088
1120
  super();
1089
1121
  this.classKeyword = classKeyword;
1090
1122
  this.name = name;
@@ -1101,15 +1133,15 @@ class ClassStatement extends Statement {
1101
1133
  this.fields = [];
1102
1134
  this.body = (_a = this.body) !== null && _a !== void 0 ? _a : [];
1103
1135
  this.symbolTable.setParent(currentSymbolTable);
1104
- this.range = util_1.util.createRangeFromPositions(this.classKeyword.range.start, this.end.range.end);
1136
+ this.range = (_b = util_1.util.createBoundingRange(this.classKeyword, this.name, this.extendsKeyword, this.parentClassName, ...this.body, this.end)) !== null && _b !== void 0 ? _b : creators_1.interpolatedRange;
1105
1137
  for (let statement of this.body) {
1106
1138
  if ((0, reflection_1.isClassMethodStatement)(statement)) {
1107
1139
  this.methods.push(statement);
1108
- this.memberMap[(_b = statement === null || statement === void 0 ? void 0 : statement.name) === null || _b === void 0 ? void 0 : _b.text.toLowerCase()] = statement;
1140
+ this.memberMap[(_c = statement === null || statement === void 0 ? void 0 : statement.name) === null || _c === void 0 ? void 0 : _c.text.toLowerCase()] = statement;
1109
1141
  }
1110
1142
  else if ((0, reflection_1.isClassFieldStatement)(statement)) {
1111
1143
  this.fields.push(statement);
1112
- this.memberMap[(_c = statement === null || statement === void 0 ? void 0 : statement.name) === null || _c === void 0 ? void 0 : _c.text.toLowerCase()] = statement;
1144
+ this.memberMap[(_d = statement === null || statement === void 0 ? void 0 : statement.name) === null || _d === void 0 ? void 0 : _d.text.toLowerCase()] = statement;
1113
1145
  }
1114
1146
  }
1115
1147
  }
@@ -1131,7 +1163,7 @@ class ClassStatement extends Statement {
1131
1163
  return undefined;
1132
1164
  }
1133
1165
  }
1134
- getCustomType() {
1166
+ getThisBscType() {
1135
1167
  return new CustomType_1.CustomType(this.getName(Parser_1.ParseMode.BrighterScript), this.memberTable);
1136
1168
  }
1137
1169
  getConstructorFunctionType() {
@@ -1145,9 +1177,9 @@ class ClassStatement extends Statement {
1145
1177
  buildSymbolTable(parentClass) {
1146
1178
  var _a, _b, _c, _d, _e;
1147
1179
  this.symbolTable.clear();
1148
- this.symbolTable.addSymbol('m', (_a = this.name) === null || _a === void 0 ? void 0 : _a.range, this.getCustomType());
1180
+ this.symbolTable.addSymbol('m', (_a = this.name) === null || _a === void 0 ? void 0 : _a.range, this.getThisBscType());
1149
1181
  this.memberTable.clear();
1150
- if (parentClass) {
1182
+ if ((0, reflection_1.isClassStatement)(parentClass)) {
1151
1183
  this.symbolTable.addSymbol('super', (_b = this.parentClassName) === null || _b === void 0 ? void 0 : _b.range, parentClass.getConstructorFunctionType());
1152
1184
  this.memberTable.setParent(parentClass === null || parentClass === void 0 ? void 0 : parentClass.memberTable);
1153
1185
  }
@@ -1172,6 +1204,7 @@ class ClassStatement extends Statement {
1172
1204
  }
1173
1205
  getTypedef(state) {
1174
1206
  var _a, _b;
1207
+ this.ensureConstructorFunctionExists();
1175
1208
  const result = [];
1176
1209
  for (let annotation of (_a = this.annotations) !== null && _a !== void 0 ? _a : []) {
1177
1210
  result.push(...annotation.getTypedef(state), state.newline, state.indent());
@@ -1213,7 +1246,7 @@ class ClassStatement extends Statement {
1213
1246
  }
1214
1247
  return myIndex - 1;
1215
1248
  }
1216
- hasParentClass() {
1249
+ hasParent() {
1217
1250
  return !!this.parentClassName;
1218
1251
  }
1219
1252
  /**
@@ -1222,7 +1255,7 @@ class ClassStatement extends Statement {
1222
1255
  */
1223
1256
  getPossibleFullParentNames() {
1224
1257
  var _a;
1225
- if (!this.hasParentClass()) {
1258
+ if (!this.hasParent()) {
1226
1259
  return [];
1227
1260
  }
1228
1261
  if (((_a = this.parentClassName) === null || _a === void 0 ? void 0 : _a.getNameParts().length) > 1) {
@@ -1275,14 +1308,16 @@ class ClassStatement extends Statement {
1275
1308
  }
1276
1309
  }
1277
1310
  getEmptyNewFunction() {
1278
- let stmt = Parser_1.Parser.parse(`
1279
- class UtilClass
1280
- sub new()
1281
- end sub
1282
- end class
1283
- `, { mode: Parser_1.ParseMode.BrighterScript }).statements[0].memberMap.new;
1284
- //TODO make locations point to 0,0 (might not matter?)
1285
- return stmt;
1311
+ return (0, creators_1.createClassMethodStatement)('new', TokenKind_1.TokenKind.Sub);
1312
+ }
1313
+ /**
1314
+ * Create an empty `new` function if class is missing it (simplifies transpile logic)
1315
+ */
1316
+ ensureConstructorFunctionExists() {
1317
+ if (!this.getConstructorFunction()) {
1318
+ this.memberMap.new = this.getEmptyNewFunction();
1319
+ this.body = [this.memberMap.new, ...this.body];
1320
+ }
1286
1321
  }
1287
1322
  /**
1288
1323
  * Determine if the specified field was declared in one of the ancestor classes
@@ -1303,6 +1338,7 @@ class ClassStatement extends Statement {
1303
1338
  */
1304
1339
  getTranspiledBuilder(state) {
1305
1340
  var _a;
1341
+ this.ensureConstructorFunctionExists();
1306
1342
  let result = [];
1307
1343
  result.push(`function ${this.getBuilderName(this.getName(Parser_1.ParseMode.BrightScript))}()\n`);
1308
1344
  state.blockDepth++;
@@ -1323,11 +1359,6 @@ class ClassStatement extends Statement {
1323
1359
  }
1324
1360
  result.push(state.newline, state.indent());
1325
1361
  let parentClassIndex = this.getParentClassIndex(state);
1326
- //create empty `new` function if class is missing it (simplifies transpile logic)
1327
- if (!this.getConstructorFunction()) {
1328
- this.memberMap.new = this.getEmptyNewFunction();
1329
- this.body = [this.memberMap.new, ...this.body];
1330
- }
1331
1362
  for (let statement of this.body) {
1332
1363
  //is field statement
1333
1364
  if ((0, reflection_1.isClassFieldStatement)(statement)) {
@@ -1412,11 +1443,19 @@ class ClassStatement extends Statement {
1412
1443
  exports.ClassStatement = ClassStatement;
1413
1444
  class ClassMethodStatement extends FunctionStatement {
1414
1445
  constructor(accessModifier, name, func, override) {
1415
- var _a;
1416
1446
  super(name, func, undefined);
1417
1447
  this.accessModifier = accessModifier;
1418
1448
  this.override = override;
1419
- this.range = util_1.util.createRangeFromPositions(((_a = this.accessModifier) !== null && _a !== void 0 ? _a : this.func).range.start, this.func.range.end);
1449
+ }
1450
+ get range() {
1451
+ return this.cacheRange();
1452
+ }
1453
+ cacheRange() {
1454
+ var _a, _b;
1455
+ if (!this._range) {
1456
+ this._range = (_b = util_1.util.createBoundingRange(this.accessModifier, this.override, (_a = this.func) !== null && _a !== void 0 ? _a : this.name)) !== null && _b !== void 0 ? _b : creators_1.interpolatedRange;
1457
+ }
1458
+ return this._range;
1420
1459
  }
1421
1460
  transpile(state) {
1422
1461
  if (this.name.text.toLowerCase() === 'new') {
@@ -1507,7 +1546,7 @@ class ClassMethodStatement extends FunctionStatement {
1507
1546
  * Inject field initializers at the top of the `new` function (after any present `super()` call)
1508
1547
  */
1509
1548
  injectFieldInitializersForConstructor(state) {
1510
- let startingIndex = state.classStatement.hasParentClass() ? 1 : 0;
1549
+ let startingIndex = state.classStatement.hasParent() ? 1 : 0;
1511
1550
  let newStatements = [];
1512
1551
  //insert the field initializers in order
1513
1552
  for (let field of state.classStatement.fields) {
@@ -1532,7 +1571,7 @@ class ClassMethodStatement extends FunctionStatement {
1532
1571
  exports.ClassMethodStatement = ClassMethodStatement;
1533
1572
  class ClassFieldStatement extends Statement {
1534
1573
  constructor(accessModifier, name, as, type, equal, initialValue, namespaceName) {
1535
- var _a, _b, _c, _d;
1574
+ var _a;
1536
1575
  super();
1537
1576
  this.accessModifier = accessModifier;
1538
1577
  this.name = name;
@@ -1541,7 +1580,7 @@ class ClassFieldStatement extends Statement {
1541
1580
  this.equal = equal;
1542
1581
  this.initialValue = initialValue;
1543
1582
  this.namespaceName = namespaceName;
1544
- this.range = util_1.util.createRangeFromPositions(((_a = this.accessModifier) !== null && _a !== void 0 ? _a : this.name).range.start, ((_d = (_c = (_b = this.initialValue) !== null && _b !== void 0 ? _b : this.type) !== null && _c !== void 0 ? _c : this.as) !== null && _d !== void 0 ? _d : this.name).range.end);
1583
+ this.range = (_a = util_1.util.createBoundingRange(this.accessModifier, this.name, this.as, this.type, this.equal, this.initialValue)) !== null && _a !== void 0 ? _a : creators_1.interpolatedRange;
1545
1584
  }
1546
1585
  /**
1547
1586
  * Derive a ValueKind from the type token, or the initial value.
@@ -1549,7 +1588,7 @@ class ClassFieldStatement extends Statement {
1549
1588
  */
1550
1589
  getType(parseMode = Parser_1.ParseMode.BrighterScript) {
1551
1590
  if (this.type) {
1552
- return util_1.util.tokenToBscType(this.type, parseMode === Parser_1.ParseMode.BrighterScript, this.namespaceName);
1591
+ return this.type.type;
1553
1592
  }
1554
1593
  else if ((0, reflection_1.isLiteralExpression)(this.initialValue)) {
1555
1594
  return this.initialValue.type;
@@ -1577,56 +1616,77 @@ class ClassFieldStatement extends Statement {
1577
1616
  return result;
1578
1617
  }
1579
1618
  walk(visitor, options) {
1580
- if (this.initialValue && options.walkMode & visitors_1.InternalWalkMode.walkExpressions) {
1619
+ if (options.walkMode & visitors_1.InternalWalkMode.walkExpressions) {
1620
+ (0, visitors_1.walk)(this, 'type', visitor, options);
1581
1621
  (0, visitors_1.walk)(this, 'initialValue', visitor, options);
1582
1622
  }
1583
1623
  }
1584
1624
  }
1585
1625
  exports.ClassFieldStatement = ClassFieldStatement;
1586
1626
  class TryCatchStatement extends Statement {
1587
- constructor(tryToken, tryBranch, catchToken, exceptionVariable, catchBranch, endTryToken) {
1627
+ constructor(tokens, tryBranch, catchStatement) {
1628
+ var _a;
1588
1629
  super();
1589
- this.tryToken = tryToken;
1630
+ this.tokens = tokens;
1590
1631
  this.tryBranch = tryBranch;
1591
- this.catchToken = catchToken;
1592
- this.exceptionVariable = exceptionVariable;
1593
- this.catchBranch = catchBranch;
1594
- this.endTryToken = endTryToken;
1595
- }
1596
- get range() {
1597
- var _a, _b, _c, _d, _e;
1598
- return util_1.util.createRangeFromPositions(this.tryToken.range.start, ((_e = (_d = (_c = (_b = (_a = this.endTryToken) !== null && _a !== void 0 ? _a : this.catchBranch) !== null && _b !== void 0 ? _b : this.exceptionVariable) !== null && _c !== void 0 ? _c : this.catchToken) !== null && _d !== void 0 ? _d : this.tryBranch) !== null && _e !== void 0 ? _e : this.tryToken).range.end);
1632
+ this.catchStatement = catchStatement;
1633
+ this.range = (_a = util_1.util.createBoundingRange(this.tokens.try, this.tryBranch, this.catchStatement, this.tokens.endTry)) !== null && _a !== void 0 ? _a : creators_1.interpolatedRange;
1599
1634
  }
1600
1635
  transpile(state) {
1636
+ var _a, _b;
1601
1637
  return [
1602
- state.transpileToken(this.tryToken),
1638
+ state.transpileToken(this.tokens.try),
1603
1639
  ...this.tryBranch.transpile(state),
1604
1640
  state.newline,
1605
1641
  state.indent(),
1606
- state.transpileToken(this.catchToken),
1607
- ' ',
1608
- state.transpileToken(this.exceptionVariable),
1609
- ...this.catchBranch.transpile(state),
1642
+ ...((_b = (_a = this.catchStatement) === null || _a === void 0 ? void 0 : _a.transpile(state)) !== null && _b !== void 0 ? _b : ['catch']),
1610
1643
  state.newline,
1611
1644
  state.indent(),
1612
- state.transpileToken(this.endTryToken)
1645
+ state.transpileToken(this.tokens.endTry)
1613
1646
  ];
1614
1647
  }
1615
1648
  walk(visitor, options) {
1616
1649
  if (this.tryBranch && options.walkMode & visitors_1.InternalWalkMode.walkStatements) {
1617
1650
  (0, visitors_1.walk)(this, 'tryBranch', visitor, options);
1618
- (0, visitors_1.walk)(this, 'catchBranch', visitor, options);
1651
+ (0, visitors_1.walk)(this, 'catchStatement', visitor, options);
1619
1652
  }
1620
1653
  }
1621
1654
  }
1622
1655
  exports.TryCatchStatement = TryCatchStatement;
1656
+ class CatchStatement extends Statement {
1657
+ constructor(tokens, exceptionVariable, catchBranch) {
1658
+ super();
1659
+ this.tokens = tokens;
1660
+ this.exceptionVariable = exceptionVariable;
1661
+ this.catchBranch = catchBranch;
1662
+ }
1663
+ get range() {
1664
+ var _a, _b;
1665
+ return util_1.util.createRangeFromPositions(this.tokens.catch.range.start, ((_b = (_a = this.catchBranch) !== null && _a !== void 0 ? _a : this.exceptionVariable) !== null && _b !== void 0 ? _b : this.tokens.catch).range.end);
1666
+ }
1667
+ transpile(state) {
1668
+ var _a, _b, _c, _d;
1669
+ return [
1670
+ state.transpileToken(this.tokens.catch),
1671
+ ' ',
1672
+ (_b = (_a = this.exceptionVariable) === null || _a === void 0 ? void 0 : _a.text) !== null && _b !== void 0 ? _b : 'e',
1673
+ ...((_d = (_c = this.catchBranch) === null || _c === void 0 ? void 0 : _c.transpile(state)) !== null && _d !== void 0 ? _d : [])
1674
+ ];
1675
+ }
1676
+ walk(visitor, options) {
1677
+ if (this.catchBranch && options.walkMode & visitors_1.InternalWalkMode.walkStatements) {
1678
+ (0, visitors_1.walk)(this, 'catchBranch', visitor, options);
1679
+ }
1680
+ }
1681
+ }
1682
+ exports.CatchStatement = CatchStatement;
1623
1683
  class ThrowStatement extends Statement {
1624
1684
  constructor(throwToken, expression) {
1625
1685
  var _a;
1626
1686
  super();
1627
1687
  this.throwToken = throwToken;
1628
1688
  this.expression = expression;
1629
- this.range = util_1.util.createRangeFromPositions(this.throwToken.range.start, ((_a = this.expression) !== null && _a !== void 0 ? _a : this.throwToken).range.end);
1689
+ this.range = (_a = util_1.util.createBoundingRange(this.throwToken, this.expression)) !== null && _a !== void 0 ? _a : creators_1.interpolatedRange;
1630
1690
  }
1631
1691
  transpile(state) {
1632
1692
  const result = [
@@ -1652,16 +1712,13 @@ class ThrowStatement extends Statement {
1652
1712
  exports.ThrowStatement = ThrowStatement;
1653
1713
  class EnumStatement extends Statement {
1654
1714
  constructor(tokens, body, namespaceName) {
1655
- var _a;
1715
+ var _a, _b;
1656
1716
  super();
1657
1717
  this.tokens = tokens;
1658
1718
  this.body = body;
1659
1719
  this.namespaceName = namespaceName;
1660
- this.body = (_a = this.body) !== null && _a !== void 0 ? _a : [];
1661
- }
1662
- get range() {
1663
- var _a, _b, _c;
1664
- return util_1.util.createRangeFromPositions((_a = this.tokens.enum.range.start) !== null && _a !== void 0 ? _a : vscode_languageserver_1.Position.create(0, 0), ((_c = (_b = this.tokens.endEnum) !== null && _b !== void 0 ? _b : this.tokens.name) !== null && _c !== void 0 ? _c : this.tokens.enum).range.end);
1720
+ this.range = (_a = util_1.util.createBoundingRange(this.tokens.enum, this.tokens.name, ...this.body, this.tokens.endEnum)) !== null && _a !== void 0 ? _a : creators_1.interpolatedRange;
1721
+ this.body = (_b = this.body) !== null && _b !== void 0 ? _b : [];
1665
1722
  }
1666
1723
  getMembers() {
1667
1724
  const result = [];
@@ -1767,9 +1824,11 @@ class EnumStatement extends Statement {
1767
1824
  exports.EnumStatement = EnumStatement;
1768
1825
  class EnumMemberStatement extends Statement {
1769
1826
  constructor(tokens, value) {
1827
+ var _a;
1770
1828
  super();
1771
1829
  this.tokens = tokens;
1772
1830
  this.value = value;
1831
+ this.range = (_a = util_1.util.createBoundingRange(this.tokens.name, this.tokens.equal, this.value)) !== null && _a !== void 0 ? _a : creators_1.interpolatedRange;
1773
1832
  }
1774
1833
  /**
1775
1834
  * The name of the member
@@ -1777,10 +1836,6 @@ class EnumMemberStatement extends Statement {
1777
1836
  get name() {
1778
1837
  return this.tokens.name.text;
1779
1838
  }
1780
- get range() {
1781
- var _a, _b, _c, _d, _e;
1782
- return util_1.util.createRangeFromPositions((_c = ((_b = (_a = this.tokens.name) !== null && _a !== void 0 ? _a : this.tokens.equal) !== null && _b !== void 0 ? _b : this.value).range.start) !== null && _c !== void 0 ? _c : vscode_languageserver_1.Position.create(0, 0), ((_e = (_d = this.value) !== null && _d !== void 0 ? _d : this.tokens.equal) !== null && _e !== void 0 ? _e : this.tokens.name).range.end);
1783
- }
1784
1839
  transpile(state) {
1785
1840
  return [];
1786
1841
  }