brighterscript 1.0.0-alpha.27 → 1.0.0-alpha.29

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 (168) hide show
  1. package/CHANGELOG.md +71 -0
  2. package/README.md +1 -1
  3. package/dist/AstValidationSegmenter.d.ts +12 -2
  4. package/dist/AstValidationSegmenter.js +74 -16
  5. package/dist/AstValidationSegmenter.js.map +1 -1
  6. package/dist/DependencyGraph.d.ts +4 -0
  7. package/dist/DependencyGraph.js +19 -0
  8. package/dist/DependencyGraph.js.map +1 -1
  9. package/dist/DiagnosticFilterer.d.ts +7 -4
  10. package/dist/DiagnosticFilterer.js +67 -37
  11. package/dist/DiagnosticFilterer.js.map +1 -1
  12. package/dist/DiagnosticMessages.d.ts +1 -1
  13. package/dist/PluginInterface.js +1 -1
  14. package/dist/PluginInterface.js.map +1 -1
  15. package/dist/Program.d.ts +19 -15
  16. package/dist/Program.js +153 -88
  17. package/dist/Program.js.map +1 -1
  18. package/dist/Scope.d.ts +27 -28
  19. package/dist/Scope.js +174 -361
  20. package/dist/Scope.js.map +1 -1
  21. package/dist/Stopwatch.d.ts +4 -0
  22. package/dist/Stopwatch.js +7 -0
  23. package/dist/Stopwatch.js.map +1 -1
  24. package/dist/SymbolTable.d.ts +2 -1
  25. package/dist/SymbolTable.js +26 -0
  26. package/dist/SymbolTable.js.map +1 -1
  27. package/dist/{SymbolTableFlag.js → SymbolTypeFlag.js} +1 -1
  28. package/dist/SymbolTypeFlag.js.map +1 -0
  29. package/dist/XmlScope.d.ts +0 -8
  30. package/dist/XmlScope.js +0 -77
  31. package/dist/XmlScope.js.map +1 -1
  32. package/dist/astUtils/CachedLookups.js +4 -8
  33. package/dist/astUtils/CachedLookups.js.map +1 -1
  34. package/dist/astUtils/creators.d.ts +1 -0
  35. package/dist/astUtils/creators.js +3 -2
  36. package/dist/astUtils/creators.js.map +1 -1
  37. package/dist/astUtils/creators.spec.js +0 -10
  38. package/dist/astUtils/creators.spec.js.map +1 -1
  39. package/dist/astUtils/reflection.d.ts +4 -4
  40. package/dist/astUtils/reflection.js +8 -7
  41. package/dist/astUtils/reflection.js.map +1 -1
  42. package/dist/astUtils/reflection.spec.js +10 -15
  43. package/dist/astUtils/reflection.spec.js.map +1 -1
  44. package/dist/astUtils/visitors.d.ts +1 -2
  45. package/dist/astUtils/visitors.js.map +1 -1
  46. package/dist/astUtils/visitors.spec.js +1 -5
  47. package/dist/astUtils/visitors.spec.js.map +1 -1
  48. package/dist/bscPlugin/BscPlugin.d.ts +3 -1
  49. package/dist/bscPlugin/BscPlugin.js +10 -0
  50. package/dist/bscPlugin/BscPlugin.js.map +1 -1
  51. package/dist/bscPlugin/SignatureHelpUtil.js +4 -3
  52. package/dist/bscPlugin/SignatureHelpUtil.js.map +1 -1
  53. package/dist/bscPlugin/completions/CompletionsProcessor.d.ts +1 -0
  54. package/dist/bscPlugin/completions/CompletionsProcessor.js +31 -11
  55. package/dist/bscPlugin/completions/CompletionsProcessor.js.map +1 -1
  56. package/dist/bscPlugin/completions/CompletionsProcessor.spec.js +39 -0
  57. package/dist/bscPlugin/completions/CompletionsProcessor.spec.js.map +1 -1
  58. package/dist/bscPlugin/hover/HoverProcessor.js +5 -5
  59. package/dist/bscPlugin/hover/HoverProcessor.js.map +1 -1
  60. package/dist/bscPlugin/hover/HoverProcessor.spec.js +51 -5
  61. package/dist/bscPlugin/hover/HoverProcessor.spec.js.map +1 -1
  62. package/dist/bscPlugin/references/ReferencesProvider.d.ts +12 -0
  63. package/dist/bscPlugin/references/ReferencesProvider.js +56 -0
  64. package/dist/bscPlugin/references/ReferencesProvider.js.map +1 -0
  65. package/dist/bscPlugin/references/ReferencesProvider.spec.d.ts +1 -0
  66. package/dist/bscPlugin/references/ReferencesProvider.spec.js +51 -0
  67. package/dist/bscPlugin/references/ReferencesProvider.spec.js.map +1 -0
  68. package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.js +1 -1
  69. package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.js.map +1 -1
  70. package/dist/bscPlugin/validation/BrsFileAfterValidatior.d.ts +7 -0
  71. package/dist/bscPlugin/validation/BrsFileAfterValidatior.js +18 -0
  72. package/dist/bscPlugin/validation/BrsFileAfterValidatior.js.map +1 -0
  73. package/dist/bscPlugin/validation/BrsFileValidator.d.ts +1 -0
  74. package/dist/bscPlugin/validation/BrsFileValidator.js +17 -10
  75. package/dist/bscPlugin/validation/BrsFileValidator.js.map +1 -1
  76. package/dist/bscPlugin/validation/ScopeValidator.d.ts +37 -1
  77. package/dist/bscPlugin/validation/ScopeValidator.js +434 -25
  78. package/dist/bscPlugin/validation/ScopeValidator.js.map +1 -1
  79. package/dist/bscPlugin/validation/ScopeValidator.spec.js +91 -4
  80. package/dist/bscPlugin/validation/ScopeValidator.spec.js.map +1 -1
  81. package/dist/files/BrsFile.Class.spec.js +11 -4
  82. package/dist/files/BrsFile.Class.spec.js.map +1 -1
  83. package/dist/files/BrsFile.d.ts +23 -5
  84. package/dist/files/BrsFile.js +189 -51
  85. package/dist/files/BrsFile.js.map +1 -1
  86. package/dist/files/BrsFile.spec.js +589 -97
  87. package/dist/files/BrsFile.spec.js.map +1 -1
  88. package/dist/files/BscFile.d.ts +2 -1
  89. package/dist/files/BscFile.js.map +1 -1
  90. package/dist/files/XmlFile.d.ts +2 -2
  91. package/dist/files/XmlFile.js +2 -2
  92. package/dist/files/XmlFile.js.map +1 -1
  93. package/dist/index.d.ts +1 -0
  94. package/dist/index.js +1 -0
  95. package/dist/index.js.map +1 -1
  96. package/dist/interfaces.d.ts +43 -4
  97. package/dist/interfaces.js.map +1 -1
  98. package/dist/lexer/Lexer.d.ts +9 -3
  99. package/dist/lexer/Lexer.js +36 -15
  100. package/dist/lexer/Lexer.js.map +1 -1
  101. package/dist/lexer/Lexer.spec.js +76 -38
  102. package/dist/lexer/Lexer.spec.js.map +1 -1
  103. package/dist/lexer/Token.js +1 -1
  104. package/dist/lexer/Token.js.map +1 -1
  105. package/dist/lexer/TokenKind.d.ts +1 -0
  106. package/dist/lexer/TokenKind.js +4 -1
  107. package/dist/lexer/TokenKind.js.map +1 -1
  108. package/dist/parser/AstNode.d.ts +1 -2
  109. package/dist/parser/AstNode.js +0 -1
  110. package/dist/parser/AstNode.js.map +1 -1
  111. package/dist/parser/BrsTranspileState.d.ts +1 -1
  112. package/dist/parser/Expression.d.ts +77 -47
  113. package/dist/parser/Expression.js +162 -88
  114. package/dist/parser/Expression.js.map +1 -1
  115. package/dist/parser/Parser.d.ts +7 -2
  116. package/dist/parser/Parser.js +40 -90
  117. package/dist/parser/Parser.js.map +1 -1
  118. package/dist/parser/Parser.spec.js +21 -44
  119. package/dist/parser/Parser.spec.js.map +1 -1
  120. package/dist/parser/SGTypes.js +5 -5
  121. package/dist/parser/SGTypes.js.map +1 -1
  122. package/dist/parser/Statement.d.ts +92 -84
  123. package/dist/parser/Statement.js +199 -133
  124. package/dist/parser/Statement.js.map +1 -1
  125. package/dist/parser/Statement.spec.js +0 -13
  126. package/dist/parser/Statement.spec.js.map +1 -1
  127. package/dist/parser/TranspileState.d.ts +17 -8
  128. package/dist/parser/TranspileState.js +67 -8
  129. package/dist/parser/TranspileState.js.map +1 -1
  130. package/dist/parser/tests/Parser.spec.d.ts +1 -1
  131. package/dist/parser/tests/Parser.spec.js +1 -2
  132. package/dist/parser/tests/Parser.spec.js.map +1 -1
  133. package/dist/parser/tests/controlFlow/If.spec.js +1 -1
  134. package/dist/parser/tests/controlFlow/If.spec.js.map +1 -1
  135. package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js +1 -3
  136. package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js.map +1 -1
  137. package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js +44 -0
  138. package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js.map +1 -1
  139. package/dist/parser/tests/expression/TemplateStringExpression.spec.js +6 -6
  140. package/dist/parser/tests/expression/TernaryExpression.spec.js +47 -0
  141. package/dist/parser/tests/expression/TernaryExpression.spec.js.map +1 -1
  142. package/dist/parser/tests/statement/ConstStatement.spec.js +2 -2
  143. package/dist/parser/tests/statement/InterfaceStatement.spec.js +8 -1
  144. package/dist/parser/tests/statement/InterfaceStatement.spec.js.map +1 -1
  145. package/dist/parser/tests/statement/Misc.spec.js +25 -5
  146. package/dist/parser/tests/statement/Misc.spec.js.map +1 -1
  147. package/dist/preprocessor/Chunk.js +1 -2
  148. package/dist/preprocessor/Chunk.js.map +1 -1
  149. package/dist/preprocessor/PreprocessorParser.js +2 -1
  150. package/dist/preprocessor/PreprocessorParser.js.map +1 -1
  151. package/dist/types/AssociativeArrayType.d.ts +3 -0
  152. package/dist/types/AssociativeArrayType.js +9 -0
  153. package/dist/types/AssociativeArrayType.js.map +1 -1
  154. package/dist/types/BscType.d.ts +1 -1
  155. package/dist/types/BscType.js +1 -0
  156. package/dist/types/BscType.js.map +1 -1
  157. package/dist/types/ComponentType.d.ts +1 -1
  158. package/dist/types/ReferenceType.d.ts +9 -1
  159. package/dist/types/ReferenceType.js +45 -1
  160. package/dist/types/ReferenceType.js.map +1 -1
  161. package/dist/types/ReferenceType.spec.js +15 -0
  162. package/dist/types/ReferenceType.spec.js.map +1 -1
  163. package/dist/util.d.ts +23 -9
  164. package/dist/util.js +115 -21
  165. package/dist/util.js.map +1 -1
  166. package/package.json +6 -3
  167. package/dist/SymbolTableFlag.js.map +0 -1
  168. /package/dist/{SymbolTableFlag.d.ts → SymbolTypeFlag.d.ts} +0 -0
@@ -11,7 +11,6 @@ const reflection_1 = require("../astUtils/reflection");
11
11
  const interfaces_1 = require("../interfaces");
12
12
  const VoidType_1 = require("../types/VoidType");
13
13
  const DynamicType_1 = require("../types/DynamicType");
14
- const TypedFunctionType_1 = require("../types/TypedFunctionType");
15
14
  const AstNode_1 = require("./AstNode");
16
15
  const SymbolTable_1 = require("../SymbolTable");
17
16
  const source_map_1 = require("source-map");
@@ -21,6 +20,8 @@ const UnionType_1 = require("../types/UnionType");
21
20
  const ArrayType_1 = require("../types/ArrayType");
22
21
  const AssociativeArrayType_1 = require("../types/AssociativeArrayType");
23
22
  const creators_1 = require("../astUtils/creators");
23
+ const types_1 = require("../types");
24
+ const FunctionType_1 = require("../types/FunctionType");
24
25
  class BinaryExpression extends AstNode_1.Expression {
25
26
  constructor(options) {
26
27
  super();
@@ -62,6 +63,9 @@ class BinaryExpression extends AstNode_1.Expression {
62
63
  }
63
64
  return DynamicType_1.DynamicType.instance;
64
65
  }
66
+ getLeadingTrivia() {
67
+ return this.left.getLeadingTrivia();
68
+ }
65
69
  }
66
70
  exports.BinaryExpression = BinaryExpression;
67
71
  class CallExpression extends AstNode_1.Expression {
@@ -118,14 +122,23 @@ class CallExpression extends AstNode_1.Expression {
118
122
  if ((0, reflection_1.isCallableType)(calleeType) && (!(0, reflection_1.isReferenceType)(calleeType.returnType) || ((_a = calleeType.returnType) === null || _a === void 0 ? void 0 : _a.isResolvable()))) {
119
123
  return calleeType.returnType;
120
124
  }
121
- if (!(0, reflection_1.isReferenceType)(calleeType) && ((_b = calleeType.returnType) === null || _b === void 0 ? void 0 : _b.isResolvable())) {
125
+ if (!(0, reflection_1.isReferenceType)(calleeType) && ((_b = calleeType === null || calleeType === void 0 ? void 0 : calleeType.returnType) === null || _b === void 0 ? void 0 : _b.isResolvable())) {
122
126
  return calleeType.returnType;
123
127
  }
124
128
  return new ReferenceType_1.TypePropertyReferenceType(calleeType, 'returnType');
125
129
  }
130
+ getLeadingTrivia() {
131
+ return this.callee.getLeadingTrivia();
132
+ }
126
133
  }
127
134
  exports.CallExpression = CallExpression;
128
- CallExpression.MaximumArguments = 32;
135
+ /**
136
+ * Number of parameters that can be defined on a function
137
+ *
138
+ * Prior to Roku OS 11.5, this was 32
139
+ * As of Roku OS 11.5, this is 63
140
+ */
141
+ CallExpression.MaximumArguments = 63;
129
142
  class FunctionExpression extends AstNode_1.Expression {
130
143
  constructor(options) {
131
144
  var _a;
@@ -159,7 +172,7 @@ class FunctionExpression extends AstNode_1.Expression {
159
172
  return util_1.default.createBoundingRange(this.tokens.functionType, this.tokens.leftParen, ...this.parameters, this.tokens.rightParen, this.tokens.as, this.returnTypeExpression, this.tokens.endFunctionType);
160
173
  }
161
174
  transpile(state, name, includeBody = true) {
162
- var _a;
175
+ var _a, _b, _c;
163
176
  let results = [];
164
177
  //'function'|'sub'
165
178
  results.push(state.transpileToken(this.tokens.functionType, 'function'));
@@ -189,15 +202,16 @@ class FunctionExpression extends AstNode_1.Expression {
189
202
  //return type
190
203
  ...this.returnTypeExpression.transpile(state));
191
204
  }
205
+ let hasBody = false;
192
206
  if (includeBody) {
193
207
  state.lineage.unshift(this);
194
208
  let body = this.body.transpile(state);
209
+ hasBody = body.length > 0;
195
210
  state.lineage.shift();
196
211
  results.push(...body);
197
212
  }
198
- results.push('\n');
199
- //'end sub'|'end function'
200
- results.push(state.indent(), state.transpileToken(this.tokens.endFunctionType, `end ${(_a = this.tokens.functionType) !== null && _a !== void 0 ? _a : 'function'}`));
213
+ const lastLocatable = hasBody ? this.body : (_b = (_a = this.returnTypeExpression) !== null && _a !== void 0 ? _a : this.tokens.leftParen) !== null && _b !== void 0 ? _b : this.tokens.functionType;
214
+ results.push(...state.transpileEndBlockToken(lastLocatable, this.tokens.endFunctionType, `end ${(_c = this.tokens.functionType) !== null && _c !== void 0 ? _c : 'function'}`));
201
215
  return results;
202
216
  }
203
217
  getTypedef(state) {
@@ -252,7 +266,7 @@ class FunctionExpression extends AstNode_1.Expression {
252
266
  if (!returnType) {
253
267
  returnType = isSub ? VoidType_1.VoidType.instance : DynamicType_1.DynamicType.instance;
254
268
  }
255
- const resultType = new TypedFunctionType_1.TypedFunctionType(returnType);
269
+ const resultType = new types_1.TypedFunctionType(returnType);
256
270
  resultType.isSub = isSub;
257
271
  for (let param of this.parameters) {
258
272
  resultType.addParameter(param.tokens.name.text, param.getType(Object.assign(Object.assign({}, options), { typeChain: undefined })), !!param.defaultValue);
@@ -320,20 +334,19 @@ class FunctionParameterExpression extends AstNode_1.Expression {
320
334
  }
321
335
  getTypedef(state) {
322
336
  var _a, _b;
323
- return [
324
- //name
325
- this.tokens.name.text,
326
- //default value
327
- ...(this.defaultValue ? [
328
- ' = ',
329
- ...this.defaultValue.transpile(state)
330
- ] : []),
331
- //type declaration
332
- ...(this.typeExpression ? [
333
- ' as ',
334
- ...((_b = (_a = this.typeExpression) === null || _a === void 0 ? void 0 : _a.getTypedef(state)) !== null && _b !== void 0 ? _b : [''])
335
- ] : [])
336
- ];
337
+ const results = [this.tokens.name.text];
338
+ if (this.defaultValue) {
339
+ results.push(' = ', ...this.defaultValue.transpile(state));
340
+ }
341
+ if (this.tokens.as) {
342
+ results.push(' as ');
343
+ // TODO: Is this conditional needed? Will typeToken always exist
344
+ // so long as `asToken` exists?
345
+ if (this.typeExpression) {
346
+ results.push(...((_b = (_a = this.typeExpression) === null || _a === void 0 ? void 0 : _a.getTypedef(state)) !== null && _b !== void 0 ? _b : ['']));
347
+ }
348
+ }
349
+ return results;
337
350
  }
338
351
  walk(visitor, options) {
339
352
  // eslint-disable-next-line no-bitwise
@@ -342,6 +355,10 @@ class FunctionParameterExpression extends AstNode_1.Expression {
342
355
  (0, visitors_2.walk)(this, 'typeExpression', visitor, options);
343
356
  }
344
357
  }
358
+ getLeadingTrivia() {
359
+ var _a;
360
+ return (_a = this.tokens.name.leadingTrivia) !== null && _a !== void 0 ? _a : [];
361
+ }
345
362
  }
346
363
  exports.FunctionParameterExpression = FunctionParameterExpression;
347
364
  class DottedGetExpression extends AstNode_1.Expression {
@@ -378,7 +395,11 @@ class DottedGetExpression extends AstNode_1.Expression {
378
395
  getType(options) {
379
396
  var _a, _b, _c, _d, _e, _f;
380
397
  const objType = (_a = this.obj) === null || _a === void 0 ? void 0 : _a.getType(options);
381
- const result = objType === null || objType === void 0 ? void 0 : objType.getMemberType((_b = this.tokens.name) === null || _b === void 0 ? void 0 : _b.text, options);
398
+ let result = objType === null || objType === void 0 ? void 0 : objType.getMemberType((_b = this.tokens.name) === null || _b === void 0 ? void 0 : _b.text, options);
399
+ if (util_1.default.isClassUsedAsFunction(result, this, options)) {
400
+ // treat this class constructor as a function
401
+ result = FunctionType_1.FunctionType.instance;
402
+ }
382
403
  (_c = options.typeChain) === null || _c === void 0 ? void 0 : _c.push(new interfaces_1.TypeChainEntry({
383
404
  name: (_d = this.tokens.name) === null || _d === void 0 ? void 0 : _d.text,
384
405
  type: result,
@@ -386,8 +407,10 @@ class DottedGetExpression extends AstNode_1.Expression {
386
407
  range: (_f = (_e = this.tokens.name) === null || _e === void 0 ? void 0 : _e.range) !== null && _f !== void 0 ? _f : this.range,
387
408
  kind: this.kind
388
409
  }));
389
- if (result || options.flags & 2 /* SymbolTypeFlag.typetime */) {
390
- // All types should be known at typetime
410
+ if (result ||
411
+ options.flags & 2 /* SymbolTypeFlag.typetime */ ||
412
+ ((0, reflection_1.isPrimitiveType)(objType) || (0, reflection_1.isCallableType)(objType))) {
413
+ // All types should be known at typeTime, or the obj is well known
391
414
  return result;
392
415
  }
393
416
  // It is possible at runtime that a value has been added dynamically to an object, or something
@@ -397,6 +420,9 @@ class DottedGetExpression extends AstNode_1.Expression {
397
420
  getName(parseMode) {
398
421
  return util_1.default.getAllDottedGetPartsAsString(this, parseMode);
399
422
  }
423
+ getLeadingTrivia() {
424
+ return this.obj.getLeadingTrivia();
425
+ }
400
426
  }
401
427
  exports.DottedGetExpression = DottedGetExpression;
402
428
  class XmlAttributeGetExpression extends AstNode_1.Expression {
@@ -419,6 +445,9 @@ class XmlAttributeGetExpression extends AstNode_1.Expression {
419
445
  (0, visitors_2.walk)(this, 'obj', visitor, options);
420
446
  }
421
447
  }
448
+ getLeadingTrivia() {
449
+ return this.obj.getLeadingTrivia();
450
+ }
422
451
  }
423
452
  exports.XmlAttributeGetExpression = XmlAttributeGetExpression;
424
453
  class IndexedGetExpression extends AstNode_1.Expression {
@@ -463,6 +492,9 @@ class IndexedGetExpression extends AstNode_1.Expression {
463
492
  }
464
493
  return super.getType(options);
465
494
  }
495
+ getLeadingTrivia() {
496
+ return this.obj.getLeadingTrivia();
497
+ }
466
498
  }
467
499
  exports.IndexedGetExpression = IndexedGetExpression;
468
500
  class GroupingExpression extends AstNode_1.Expression {
@@ -494,6 +526,10 @@ class GroupingExpression extends AstNode_1.Expression {
494
526
  getType(options) {
495
527
  return this.expression.getType(options);
496
528
  }
529
+ getLeadingTrivia() {
530
+ var _a, _b;
531
+ return (_b = (_a = this.tokens.leftParen) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
532
+ }
497
533
  }
498
534
  exports.GroupingExpression = GroupingExpression;
499
535
  class LiteralExpression extends AstNode_1.Expression {
@@ -527,12 +563,16 @@ class LiteralExpression extends AstNode_1.Expression {
527
563
  text = this.tokens.value.text;
528
564
  }
529
565
  return [
530
- state.sourceNode(this, text)
566
+ state.transpileToken(Object.assign(Object.assign({}, this.tokens.value), { text: text }))
531
567
  ];
532
568
  }
533
569
  walk(visitor, options) {
534
570
  //nothing to walk
535
571
  }
572
+ getLeadingTrivia() {
573
+ var _a;
574
+ return (_a = this.tokens.value.leadingTrivia) !== null && _a !== void 0 ? _a : [];
575
+ }
536
576
  }
537
577
  exports.LiteralExpression = LiteralExpression;
538
578
  /**
@@ -568,6 +608,7 @@ class ArrayLiteralExpression extends AstNode_1.Expression {
568
608
  this.range = util_1.default.createBoundingRange(this.tokens.open, ...this.elements, this.tokens.close);
569
609
  }
570
610
  transpile(state) {
611
+ var _a;
571
612
  let result = [];
572
613
  result.push(state.transpileToken(this.tokens.open, '['));
573
614
  let hasChildren = this.elements.length > 0;
@@ -575,32 +616,18 @@ class ArrayLiteralExpression extends AstNode_1.Expression {
575
616
  for (let i = 0; i < this.elements.length; i++) {
576
617
  let previousElement = this.elements[i - 1];
577
618
  let element = this.elements[i];
578
- if ((0, reflection_1.isCommentStatement)(element)) {
579
- //if the comment is on the same line as opening square or previous statement, don't add newline
580
- if (util_1.default.linesTouch(this.tokens.open, element) || util_1.default.linesTouch(previousElement, element)) {
581
- result.push(' ');
582
- }
583
- else {
584
- result.push('\n', state.indent());
585
- }
586
- state.lineage.unshift(this);
587
- result.push(element.transpile(state));
588
- state.lineage.shift();
619
+ if (util_1.default.isLeadingCommentOnSameLine(previousElement !== null && previousElement !== void 0 ? previousElement : this.tokens.open, element)) {
620
+ result.push(' ');
589
621
  }
590
622
  else {
591
- result.push('\n');
592
- result.push(state.indent(), ...element.transpile(state));
623
+ result.push('\n', state.indent());
593
624
  }
625
+ result.push(...element.transpile(state));
594
626
  }
595
627
  state.blockDepth--;
596
628
  //add a newline between open and close if there are elements
597
- if (hasChildren) {
598
- result.push('\n');
599
- result.push(state.indent());
600
- }
601
- if (this.tokens.close) {
602
- result.push(state.transpileToken(this.tokens.close));
603
- }
629
+ const lastLocatable = (_a = this.elements[this.elements.length - 1]) !== null && _a !== void 0 ? _a : this.tokens.open;
630
+ result.push(...state.transpileEndBlockToken(lastLocatable, this.tokens.close, ']', hasChildren));
604
631
  return result;
605
632
  }
606
633
  walk(visitor, options) {
@@ -609,9 +636,13 @@ class ArrayLiteralExpression extends AstNode_1.Expression {
609
636
  }
610
637
  }
611
638
  getType(options) {
612
- const innerTypes = this.elements.filter(x => !(0, reflection_1.isCommentStatement)(x)).map(expr => expr.getType(options));
639
+ const innerTypes = this.elements.map(expr => expr.getType(options));
613
640
  return new ArrayType_1.ArrayType(...innerTypes);
614
641
  }
642
+ getLeadingTrivia() {
643
+ var _a;
644
+ return (_a = this.tokens.open.leadingTrivia) !== null && _a !== void 0 ? _a : [];
645
+ }
615
646
  }
616
647
  exports.ArrayLiteralExpression = ArrayLiteralExpression;
617
648
  class AAMemberExpression extends AstNode_1.Expression {
@@ -636,6 +667,10 @@ class AAMemberExpression extends AstNode_1.Expression {
636
667
  getType(options) {
637
668
  return this.value.getType(options);
638
669
  }
670
+ getLeadingTrivia() {
671
+ var _a;
672
+ return (_a = this.tokens.key.leadingTrivia) !== null && _a !== void 0 ? _a : [];
673
+ }
639
674
  }
640
675
  exports.AAMemberExpression = AAMemberExpression;
641
676
  class AALiteralExpression extends AstNode_1.Expression {
@@ -650,12 +685,13 @@ class AALiteralExpression extends AstNode_1.Expression {
650
685
  this.range = util_1.default.createBoundingRange(this.tokens.open, ...this.elements, this.tokens.close);
651
686
  }
652
687
  transpile(state) {
688
+ var _a;
653
689
  let result = [];
654
690
  //open curly
655
691
  result.push(state.transpileToken(this.tokens.open, '{'));
656
692
  let hasChildren = this.elements.length > 0;
657
693
  //add newline if the object has children and the first child isn't a comment starting on the same line as opening curly
658
- if (hasChildren && ((0, reflection_1.isCommentStatement)(this.elements[0]) === false || !util_1.default.linesTouch(this.elements[0], this.tokens.open))) {
694
+ if (hasChildren && !util_1.default.isLeadingCommentOnSameLine(this.tokens.open, this.elements[0])) {
659
695
  result.push('\n');
660
696
  }
661
697
  state.blockDepth++;
@@ -664,41 +700,29 @@ class AALiteralExpression extends AstNode_1.Expression {
664
700
  let previousElement = this.elements[i - 1];
665
701
  let nextElement = this.elements[i + 1];
666
702
  //don't indent if comment is same-line
667
- if ((0, reflection_1.isCommentStatement)(element) &&
668
- (util_1.default.linesTouch(this.tokens.open, element) || util_1.default.linesTouch(previousElement, element))) {
703
+ if (util_1.default.isLeadingCommentOnSameLine(this.tokens.open, element) ||
704
+ util_1.default.isLeadingCommentOnSameLine(previousElement, element)) {
669
705
  result.push(' ');
670
- //indent line
671
706
  }
672
707
  else {
708
+ //indent line
673
709
  result.push(state.indent());
674
710
  }
675
- //render comments
676
- if ((0, reflection_1.isCommentStatement)(element)) {
677
- result.push(...element.transpile(state));
678
- }
679
- else {
680
- //key
681
- result.push(state.transpileToken(element.tokens.key));
682
- //colon
683
- result.push(state.transpileToken(element.tokens.colon, ':'), ' ');
684
- //value
685
- result.push(...element.value.transpile(state));
686
- }
711
+ //key
712
+ result.push(state.transpileToken(element.tokens.key));
713
+ //colon
714
+ result.push(state.transpileToken(element.tokens.colon, ':'), ' ');
715
+ //value
716
+ result.push(...element.value.transpile(state));
687
717
  //if next element is a same-line comment, skip the newline
688
- if (nextElement && (0, reflection_1.isCommentStatement)(nextElement) && nextElement.range.start.line === element.range.start.line) {
718
+ if (nextElement && !util_1.default.isLeadingCommentOnSameLine(element, nextElement)) {
689
719
  //add a newline between statements
690
- }
691
- else {
692
720
  result.push('\n');
693
721
  }
694
722
  }
695
723
  state.blockDepth--;
696
- //only indent the closing curly if we have children
697
- if (hasChildren) {
698
- result.push(state.indent());
699
- }
700
- //close curly
701
- result.push(state.transpileToken(this.tokens.close, '}'));
724
+ const lastElement = (_a = this.elements[this.elements.length - 1]) !== null && _a !== void 0 ? _a : this.tokens.open;
725
+ result.push(...state.transpileEndBlockToken(lastElement, this.tokens.close, '}', hasChildren));
702
726
  return result;
703
727
  }
704
728
  walk(visitor, options) {
@@ -708,6 +732,7 @@ class AALiteralExpression extends AstNode_1.Expression {
708
732
  }
709
733
  getType(options) {
710
734
  const resultType = new AssociativeArrayType_1.AssociativeArrayType();
735
+ resultType.addBuiltInInterfaces();
711
736
  for (const element of this.elements) {
712
737
  if ((0, reflection_1.isAAMemberExpression)(element)) {
713
738
  resultType.addMember(element.tokens.key.text, { definingNode: element }, element.getType(options), 1 /* SymbolTypeFlag.runtime */);
@@ -715,6 +740,10 @@ class AALiteralExpression extends AstNode_1.Expression {
715
740
  }
716
741
  return resultType;
717
742
  }
743
+ getLeadingTrivia() {
744
+ var _a;
745
+ return (_a = this.tokens.open.leadingTrivia) !== null && _a !== void 0 ? _a : [];
746
+ }
718
747
  }
719
748
  exports.AALiteralExpression = AALiteralExpression;
720
749
  class UnaryExpression extends AstNode_1.Expression {
@@ -752,6 +781,10 @@ class UnaryExpression extends AstNode_1.Expression {
752
781
  getType(options) {
753
782
  return util_1.default.unaryOperatorResultType(this.tokens.operator, this.right.getType(options));
754
783
  }
784
+ getLeadingTrivia() {
785
+ var _a;
786
+ return (_a = this.tokens.operator.leadingTrivia) !== null && _a !== void 0 ? _a : [];
787
+ }
755
788
  }
756
789
  exports.UnaryExpression = UnaryExpression;
757
790
  class VariableExpression extends AstNode_1.Expression {
@@ -771,7 +804,7 @@ class VariableExpression extends AstNode_1.Expression {
771
804
  let result = [];
772
805
  const namespace = this.findAncestor(reflection_1.isNamespaceStatement);
773
806
  //if the callee is the name of a known namespace function
774
- if (state.file.calleeIsKnownNamespaceFunction(this, namespace === null || namespace === void 0 ? void 0 : namespace.getName(Parser_1.ParseMode.BrighterScript))) {
807
+ if (namespace && state.file.calleeIsKnownNamespaceFunction(this, namespace.getName(Parser_1.ParseMode.BrighterScript))) {
775
808
  result.push(state.sourceNode(this, [
776
809
  namespace.getName(Parser_1.ParseMode.BrightScript),
777
810
  '_',
@@ -794,10 +827,17 @@ class VariableExpression extends AstNode_1.Expression {
794
827
  if (!resultType) {
795
828
  const symbolTable = this.getSymbolTable();
796
829
  resultType = symbolTable === null || symbolTable === void 0 ? void 0 : symbolTable.getSymbolType(nameKey, Object.assign(Object.assign({}, options), { fullName: nameKey, tableProvider: () => this.getSymbolTable() }));
830
+ if (util_1.default.isClassUsedAsFunction(resultType, this, options)) {
831
+ resultType = FunctionType_1.FunctionType.instance;
832
+ }
797
833
  }
798
834
  (_a = options.typeChain) === null || _a === void 0 ? void 0 : _a.push(new interfaces_1.TypeChainEntry({ name: nameKey, type: resultType, data: options.data, range: this.range, kind: this.kind }));
799
835
  return resultType;
800
836
  }
837
+ getLeadingTrivia() {
838
+ var _a;
839
+ return (_a = this.tokens.name.leadingTrivia) !== null && _a !== void 0 ? _a : [];
840
+ }
801
841
  }
802
842
  exports.VariableExpression = VariableExpression;
803
843
  class SourceLiteralExpression extends AstNode_1.Expression {
@@ -828,7 +868,7 @@ class SourceLiteralExpression extends AstNode_1.Expression {
828
868
  return index;
829
869
  }
830
870
  getFunctionName(state, parseMode) {
831
- let func = state.file.getFunctionScopeAtPosition(this.tokens.value.range.start).func;
871
+ let func = this.findAncestor(reflection_1.isFunctionExpression);
832
872
  let nameParts = [];
833
873
  let parentFunction;
834
874
  while ((parentFunction = func.findAncestor(reflection_1.isFunctionExpression))) {
@@ -840,6 +880,19 @@ class SourceLiteralExpression extends AstNode_1.Expression {
840
880
  nameParts.unshift(func.functionStatement.getName(parseMode));
841
881
  return nameParts.join('$');
842
882
  }
883
+ /**
884
+ * Get the line number from our token or from the closest ancestor that has a range
885
+ */
886
+ getClosestLineNumber() {
887
+ let node = this;
888
+ while (node) {
889
+ if (node.range) {
890
+ return node.range.start.line + 1;
891
+ }
892
+ node = node.parent;
893
+ }
894
+ return -1;
895
+ }
843
896
  transpile(state) {
844
897
  let text;
845
898
  switch (this.tokens.value.kind) {
@@ -848,7 +901,8 @@ class SourceLiteralExpression extends AstNode_1.Expression {
848
901
  text = `"${pathUrl.substring(0, 4)}" + "${pathUrl.substring(4)}"`;
849
902
  break;
850
903
  case TokenKind_1.TokenKind.SourceLineNumLiteral:
851
- text = `${this.tokens.value.range.start.line + 1}`;
904
+ //TODO find first parent that has range, or default to -1
905
+ text = `${this.getClosestLineNumber()}`;
852
906
  break;
853
907
  case TokenKind_1.TokenKind.FunctionNameLiteral:
854
908
  text = `"${this.getFunctionName(state, Parser_1.ParseMode.BrightScript)}"`;
@@ -858,7 +912,8 @@ class SourceLiteralExpression extends AstNode_1.Expression {
858
912
  break;
859
913
  case TokenKind_1.TokenKind.SourceLocationLiteral:
860
914
  const locationUrl = fileUrl(state.srcPath);
861
- text = `"${locationUrl.substring(0, 4)}" + "${locationUrl.substring(4)}:${this.tokens.value.range.start.line + 1}"`;
915
+ //TODO find first parent that has range, or default to -1
916
+ text = `"${locationUrl.substring(0, 4)}" + "${locationUrl.substring(4)}:${this.getClosestLineNumber()}"`;
862
917
  break;
863
918
  case TokenKind_1.TokenKind.PkgPathLiteral:
864
919
  text = `"${util_1.default.sanitizePkgPath(state.file.pkgPath)}"`;
@@ -879,6 +934,10 @@ class SourceLiteralExpression extends AstNode_1.Expression {
879
934
  walk(visitor, options) {
880
935
  //nothing to walk
881
936
  }
937
+ getLeadingTrivia() {
938
+ var _a;
939
+ return (_a = this.tokens.value.leadingTrivia) !== null && _a !== void 0 ? _a : [];
940
+ }
882
941
  }
883
942
  exports.SourceLiteralExpression = SourceLiteralExpression;
884
943
  /**
@@ -928,6 +987,10 @@ class NewExpression extends AstNode_1.Expression {
928
987
  }
929
988
  return result;
930
989
  }
990
+ getLeadingTrivia() {
991
+ var _a;
992
+ return (_a = this.tokens.new.leadingTrivia) !== null && _a !== void 0 ? _a : [];
993
+ }
931
994
  }
932
995
  exports.NewExpression = NewExpression;
933
996
  class CallfuncExpression extends AstNode_1.Expression {
@@ -1008,6 +1071,9 @@ class CallfuncExpression extends AstNode_1.Expression {
1008
1071
  }
1009
1072
  return result;
1010
1073
  }
1074
+ getLeadingTrivia() {
1075
+ return this.callee.getLeadingTrivia();
1076
+ }
1011
1077
  }
1012
1078
  exports.CallfuncExpression = CallfuncExpression;
1013
1079
  /**
@@ -1183,8 +1249,8 @@ class AnnotationExpression extends AstNode_1.Expression {
1183
1249
  return this.call.args.map(e => expressionToValue(e, strict));
1184
1250
  }
1185
1251
  getLeadingTrivia() {
1186
- var _a;
1187
- return (_a = this.tokens.at) === null || _a === void 0 ? void 0 : _a.leadingTrivia;
1252
+ var _a, _b;
1253
+ return (_b = (_a = this.tokens.at) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
1188
1254
  }
1189
1255
  transpile(state) {
1190
1256
  return [];
@@ -1218,8 +1284,9 @@ class TernaryExpression extends AstNode_1.Expression {
1218
1284
  transpile(state) {
1219
1285
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
1220
1286
  let result = [];
1221
- let consequentInfo = util_1.default.getExpressionInfo(this.consequent);
1222
- let alternateInfo = util_1.default.getExpressionInfo(this.alternate);
1287
+ const file = state.file;
1288
+ let consequentInfo = util_1.default.getExpressionInfo(this.consequent, file);
1289
+ let alternateInfo = util_1.default.getExpressionInfo(this.alternate, file);
1223
1290
  //get all unique variable names used in the consequent and alternate, and sort them alphabetically so the output is consistent
1224
1291
  let allUniqueVarNames = [...new Set([...consequentInfo.uniqueVarNames, ...alternateInfo.uniqueVarNames])].sort();
1225
1292
  let mutatingExpressions = [
@@ -1230,9 +1297,9 @@ class TernaryExpression extends AstNode_1.Expression {
1230
1297
  result.push(state.sourceNode(this.tokens.questionMark,
1231
1298
  //write all the scope variables as parameters.
1232
1299
  //TODO handle when there are more than 31 parameters
1233
- `(function(__bsCondition, ${allUniqueVarNames.join(', ')})`), state.newline,
1300
+ `(function(${['__bsCondition', ...allUniqueVarNames].join(', ')})`), state.newline,
1234
1301
  //double indent so our `end function` line is still indented one at the end
1235
- state.indent(2), state.sourceNode(this.test, `if __bsCondition then`), state.newline, state.indent(1), state.sourceNode((_a = this.consequent) !== null && _a !== void 0 ? _a : this.tokens.questionMark, 'return '), ...(_c = (_b = this.consequent) === null || _b === void 0 ? void 0 : _b.transpile(state)) !== null && _c !== void 0 ? _c : [state.sourceNode(this.tokens.questionMark, 'invalid')], state.newline, state.indent(-1), state.sourceNode((_d = this.consequent) !== null && _d !== void 0 ? _d : this.tokens.questionMark, 'else'), state.newline, state.indent(1), state.sourceNode((_e = this.consequent) !== null && _e !== void 0 ? _e : this.tokens.questionMark, 'return '), ...(_g = (_f = this.alternate) === null || _f === void 0 ? void 0 : _f.transpile(state)) !== null && _g !== void 0 ? _g : [state.sourceNode((_h = this.consequent) !== null && _h !== void 0 ? _h : this.tokens.questionMark, 'invalid')], state.newline, state.indent(-1), state.sourceNode(this.tokens.questionMark, 'end if'), state.newline, state.indent(-1), state.sourceNode(this.tokens.questionMark, 'end function)('), ...this.test.transpile(state), state.sourceNode(this.tokens.questionMark, `, ${allUniqueVarNames.join(', ')})`));
1302
+ state.indent(2), state.sourceNode(this.test, `if __bsCondition then`), state.newline, state.indent(1), state.sourceNode((_a = this.consequent) !== null && _a !== void 0 ? _a : this.tokens.questionMark, 'return '), ...(_c = (_b = this.consequent) === null || _b === void 0 ? void 0 : _b.transpile(state)) !== null && _c !== void 0 ? _c : [state.sourceNode(this.tokens.questionMark, 'invalid')], state.newline, state.indent(-1), state.sourceNode((_d = this.consequent) !== null && _d !== void 0 ? _d : this.tokens.questionMark, 'else'), state.newline, state.indent(1), state.sourceNode((_e = this.consequent) !== null && _e !== void 0 ? _e : this.tokens.questionMark, 'return '), ...(_g = (_f = this.alternate) === null || _f === void 0 ? void 0 : _f.transpile(state)) !== null && _g !== void 0 ? _g : [state.sourceNode((_h = this.consequent) !== null && _h !== void 0 ? _h : this.tokens.questionMark, 'invalid')], state.newline, state.indent(-1), state.sourceNode(this.tokens.questionMark, 'end if'), state.newline, state.indent(-1), state.sourceNode(this.tokens.questionMark, 'end function)('), ...this.test.transpile(state), state.sourceNode(this.tokens.questionMark, `${['', ...allUniqueVarNames].join(', ')})`));
1236
1303
  state.blockDepth--;
1237
1304
  }
1238
1305
  else {
@@ -1247,6 +1314,9 @@ class TernaryExpression extends AstNode_1.Expression {
1247
1314
  (0, visitors_2.walk)(this, 'alternate', visitor, options);
1248
1315
  }
1249
1316
  }
1317
+ getLeadingTrivia() {
1318
+ return this.test.getLeadingTrivia();
1319
+ }
1250
1320
  }
1251
1321
  exports.TernaryExpression = TernaryExpression;
1252
1322
  class NullCoalescingExpression extends AstNode_1.Expression {
@@ -1262,8 +1332,8 @@ class NullCoalescingExpression extends AstNode_1.Expression {
1262
1332
  }
1263
1333
  transpile(state) {
1264
1334
  let result = [];
1265
- let consequentInfo = util_1.default.getExpressionInfo(this.consequent);
1266
- let alternateInfo = util_1.default.getExpressionInfo(this.alternate);
1335
+ let consequentInfo = util_1.default.getExpressionInfo(this.consequent, state.file);
1336
+ let alternateInfo = util_1.default.getExpressionInfo(this.alternate, state.file);
1267
1337
  //get all unique variable names used in the consequent and alternate, and sort them alphabetically so the output is consistent
1268
1338
  let allUniqueVarNames = [...new Set([...consequentInfo.uniqueVarNames, ...alternateInfo.uniqueVarNames])].sort();
1269
1339
  let hasMutatingExpression = [
@@ -1292,6 +1362,9 @@ class NullCoalescingExpression extends AstNode_1.Expression {
1292
1362
  (0, visitors_2.walk)(this, 'alternate', visitor, options);
1293
1363
  }
1294
1364
  }
1365
+ getLeadingTrivia() {
1366
+ return this.consequent.getLeadingTrivia();
1367
+ }
1295
1368
  }
1296
1369
  exports.NullCoalescingExpression = NullCoalescingExpression;
1297
1370
  class RegexLiteralExpression extends AstNode_1.Expression {
@@ -1333,6 +1406,10 @@ class RegexLiteralExpression extends AstNode_1.Expression {
1333
1406
  walk(visitor, options) {
1334
1407
  //nothing to walk
1335
1408
  }
1409
+ getLeadingTrivia() {
1410
+ var _a, _b;
1411
+ return (_b = (_a = this.tokens.regexLiteral) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
1412
+ }
1336
1413
  }
1337
1414
  exports.RegexLiteralExpression = RegexLiteralExpression;
1338
1415
  function expressionToValue(expr, strict) {
@@ -1354,14 +1431,11 @@ function expressionToValue(expr, strict) {
1354
1431
  }
1355
1432
  if ((0, reflection_1.isArrayLiteralExpression)(expr)) {
1356
1433
  return expr.elements
1357
- .filter(e => !(0, reflection_1.isCommentStatement)(e))
1358
1434
  .map(e => expressionToValue(e, strict));
1359
1435
  }
1360
1436
  if ((0, reflection_1.isAALiteralExpression)(expr)) {
1361
1437
  return expr.elements.reduce((acc, e) => {
1362
- if (!(0, reflection_1.isCommentStatement)(e)) {
1363
- acc[e.tokens.key.text] = expressionToValue(e.value, strict);
1364
- }
1438
+ acc[e.tokens.key.text] = expressionToValue(e.value, strict);
1365
1439
  return acc;
1366
1440
  }, {});
1367
1441
  }