brighterscript 1.0.0-alpha.27 → 1.0.0-alpha.28

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 (147) hide show
  1. package/CHANGELOG.md +61 -0
  2. package/README.md +1 -1
  3. package/dist/AstValidationSegmenter.d.ts +1 -1
  4. package/dist/AstValidationSegmenter.js +2 -2
  5. package/dist/AstValidationSegmenter.js.map +1 -1
  6. package/dist/DiagnosticFilterer.d.ts +7 -4
  7. package/dist/DiagnosticFilterer.js +67 -37
  8. package/dist/DiagnosticFilterer.js.map +1 -1
  9. package/dist/DiagnosticMessages.d.ts +1 -1
  10. package/dist/PluginInterface.js +1 -1
  11. package/dist/PluginInterface.js.map +1 -1
  12. package/dist/Program.d.ts +1 -1
  13. package/dist/Program.js +10 -6
  14. package/dist/Program.js.map +1 -1
  15. package/dist/Scope.d.ts +6 -27
  16. package/dist/Scope.js +40 -298
  17. package/dist/Scope.js.map +1 -1
  18. package/dist/SymbolTable.d.ts +1 -1
  19. package/dist/{SymbolTableFlag.js → SymbolTypeFlag.js} +1 -1
  20. package/dist/SymbolTypeFlag.js.map +1 -0
  21. package/dist/XmlScope.d.ts +0 -8
  22. package/dist/XmlScope.js +0 -77
  23. package/dist/XmlScope.js.map +1 -1
  24. package/dist/astUtils/CachedLookups.js +4 -8
  25. package/dist/astUtils/CachedLookups.js.map +1 -1
  26. package/dist/astUtils/creators.d.ts +1 -0
  27. package/dist/astUtils/creators.js +3 -2
  28. package/dist/astUtils/creators.js.map +1 -1
  29. package/dist/astUtils/creators.spec.js +0 -10
  30. package/dist/astUtils/creators.spec.js.map +1 -1
  31. package/dist/astUtils/reflection.d.ts +1 -2
  32. package/dist/astUtils/reflection.js +3 -7
  33. package/dist/astUtils/reflection.js.map +1 -1
  34. package/dist/astUtils/reflection.spec.js +10 -15
  35. package/dist/astUtils/reflection.spec.js.map +1 -1
  36. package/dist/astUtils/visitors.d.ts +1 -2
  37. package/dist/astUtils/visitors.js.map +1 -1
  38. package/dist/astUtils/visitors.spec.js +1 -5
  39. package/dist/astUtils/visitors.spec.js.map +1 -1
  40. package/dist/bscPlugin/BscPlugin.d.ts +2 -1
  41. package/dist/bscPlugin/BscPlugin.js +4 -0
  42. package/dist/bscPlugin/BscPlugin.js.map +1 -1
  43. package/dist/bscPlugin/SignatureHelpUtil.js +4 -3
  44. package/dist/bscPlugin/SignatureHelpUtil.js.map +1 -1
  45. package/dist/bscPlugin/completions/CompletionsProcessor.d.ts +1 -0
  46. package/dist/bscPlugin/completions/CompletionsProcessor.js +26 -9
  47. package/dist/bscPlugin/completions/CompletionsProcessor.js.map +1 -1
  48. package/dist/bscPlugin/completions/CompletionsProcessor.spec.js +39 -0
  49. package/dist/bscPlugin/completions/CompletionsProcessor.spec.js.map +1 -1
  50. package/dist/bscPlugin/hover/HoverProcessor.js +5 -5
  51. package/dist/bscPlugin/hover/HoverProcessor.js.map +1 -1
  52. package/dist/bscPlugin/hover/HoverProcessor.spec.js +51 -5
  53. package/dist/bscPlugin/hover/HoverProcessor.spec.js.map +1 -1
  54. package/dist/bscPlugin/references/ReferencesProvider.d.ts +12 -0
  55. package/dist/bscPlugin/references/ReferencesProvider.js +56 -0
  56. package/dist/bscPlugin/references/ReferencesProvider.js.map +1 -0
  57. package/dist/bscPlugin/references/ReferencesProvider.spec.d.ts +1 -0
  58. package/dist/bscPlugin/references/ReferencesProvider.spec.js +51 -0
  59. package/dist/bscPlugin/references/ReferencesProvider.spec.js.map +1 -0
  60. package/dist/bscPlugin/validation/BrsFileValidator.js +1 -6
  61. package/dist/bscPlugin/validation/BrsFileValidator.js.map +1 -1
  62. package/dist/bscPlugin/validation/ScopeValidator.d.ts +28 -1
  63. package/dist/bscPlugin/validation/ScopeValidator.js +365 -7
  64. package/dist/bscPlugin/validation/ScopeValidator.js.map +1 -1
  65. package/dist/bscPlugin/validation/ScopeValidator.spec.js +89 -3
  66. package/dist/bscPlugin/validation/ScopeValidator.spec.js.map +1 -1
  67. package/dist/files/BrsFile.Class.spec.js +11 -4
  68. package/dist/files/BrsFile.Class.spec.js.map +1 -1
  69. package/dist/files/BrsFile.d.ts +12 -2
  70. package/dist/files/BrsFile.js +64 -38
  71. package/dist/files/BrsFile.js.map +1 -1
  72. package/dist/files/BrsFile.spec.js +373 -6
  73. package/dist/files/BrsFile.spec.js.map +1 -1
  74. package/dist/files/XmlFile.js +1 -1
  75. package/dist/files/XmlFile.js.map +1 -1
  76. package/dist/index.d.ts +1 -0
  77. package/dist/index.js +1 -0
  78. package/dist/index.js.map +1 -1
  79. package/dist/interfaces.d.ts +41 -3
  80. package/dist/interfaces.js.map +1 -1
  81. package/dist/lexer/Lexer.d.ts +9 -3
  82. package/dist/lexer/Lexer.js +36 -15
  83. package/dist/lexer/Lexer.js.map +1 -1
  84. package/dist/lexer/Lexer.spec.js +76 -38
  85. package/dist/lexer/Lexer.spec.js.map +1 -1
  86. package/dist/lexer/Token.js +1 -1
  87. package/dist/lexer/Token.js.map +1 -1
  88. package/dist/lexer/TokenKind.d.ts +1 -0
  89. package/dist/lexer/TokenKind.js +4 -1
  90. package/dist/lexer/TokenKind.js.map +1 -1
  91. package/dist/parser/AstNode.d.ts +1 -2
  92. package/dist/parser/AstNode.js +0 -1
  93. package/dist/parser/AstNode.js.map +1 -1
  94. package/dist/parser/BrsTranspileState.d.ts +1 -1
  95. package/dist/parser/Expression.d.ts +71 -47
  96. package/dist/parser/Expression.js +155 -87
  97. package/dist/parser/Expression.js.map +1 -1
  98. package/dist/parser/Parser.d.ts +7 -2
  99. package/dist/parser/Parser.js +40 -87
  100. package/dist/parser/Parser.js.map +1 -1
  101. package/dist/parser/Parser.spec.js +21 -44
  102. package/dist/parser/Parser.spec.js.map +1 -1
  103. package/dist/parser/SGTypes.js +5 -5
  104. package/dist/parser/SGTypes.js.map +1 -1
  105. package/dist/parser/Statement.d.ts +92 -84
  106. package/dist/parser/Statement.js +199 -133
  107. package/dist/parser/Statement.js.map +1 -1
  108. package/dist/parser/Statement.spec.js +0 -13
  109. package/dist/parser/Statement.spec.js.map +1 -1
  110. package/dist/parser/TranspileState.d.ts +17 -8
  111. package/dist/parser/TranspileState.js +64 -6
  112. package/dist/parser/TranspileState.js.map +1 -1
  113. package/dist/parser/tests/Parser.spec.d.ts +1 -1
  114. package/dist/parser/tests/Parser.spec.js +1 -2
  115. package/dist/parser/tests/Parser.spec.js.map +1 -1
  116. package/dist/parser/tests/controlFlow/If.spec.js +1 -1
  117. package/dist/parser/tests/controlFlow/If.spec.js.map +1 -1
  118. package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js +1 -3
  119. package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js.map +1 -1
  120. package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js +44 -0
  121. package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js.map +1 -1
  122. package/dist/parser/tests/expression/TemplateStringExpression.spec.js +6 -6
  123. package/dist/parser/tests/expression/TernaryExpression.spec.js +47 -0
  124. package/dist/parser/tests/expression/TernaryExpression.spec.js.map +1 -1
  125. package/dist/parser/tests/statement/ConstStatement.spec.js +2 -2
  126. package/dist/parser/tests/statement/InterfaceStatement.spec.js +8 -1
  127. package/dist/parser/tests/statement/InterfaceStatement.spec.js.map +1 -1
  128. package/dist/parser/tests/statement/Misc.spec.js +25 -5
  129. package/dist/parser/tests/statement/Misc.spec.js.map +1 -1
  130. package/dist/preprocessor/Chunk.js +1 -2
  131. package/dist/preprocessor/Chunk.js.map +1 -1
  132. package/dist/preprocessor/PreprocessorParser.js +2 -1
  133. package/dist/preprocessor/PreprocessorParser.js.map +1 -1
  134. package/dist/types/AssociativeArrayType.d.ts +3 -0
  135. package/dist/types/AssociativeArrayType.js +9 -0
  136. package/dist/types/AssociativeArrayType.js.map +1 -1
  137. package/dist/types/BscType.d.ts +1 -1
  138. package/dist/types/BscType.js +1 -0
  139. package/dist/types/BscType.js.map +1 -1
  140. package/dist/types/ComponentType.d.ts +1 -1
  141. package/dist/types/ReferenceType.d.ts +1 -1
  142. package/dist/util.d.ts +18 -8
  143. package/dist/util.js +96 -18
  144. package/dist/util.js.map +1 -1
  145. package/package.json +6 -3
  146. package/dist/SymbolTableFlag.js.map +0 -1
  147. /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,11 +122,14 @@ 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
135
  CallExpression.MaximumArguments = 32;
@@ -159,7 +166,7 @@ class FunctionExpression extends AstNode_1.Expression {
159
166
  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
167
  }
161
168
  transpile(state, name, includeBody = true) {
162
- var _a;
169
+ var _a, _b, _c;
163
170
  let results = [];
164
171
  //'function'|'sub'
165
172
  results.push(state.transpileToken(this.tokens.functionType, 'function'));
@@ -189,15 +196,16 @@ class FunctionExpression extends AstNode_1.Expression {
189
196
  //return type
190
197
  ...this.returnTypeExpression.transpile(state));
191
198
  }
199
+ let hasBody = false;
192
200
  if (includeBody) {
193
201
  state.lineage.unshift(this);
194
202
  let body = this.body.transpile(state);
203
+ hasBody = body.length > 0;
195
204
  state.lineage.shift();
196
205
  results.push(...body);
197
206
  }
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'}`));
207
+ 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;
208
+ results.push(...state.transpileEndBlockToken(lastLocatable, this.tokens.endFunctionType, `end ${(_c = this.tokens.functionType) !== null && _c !== void 0 ? _c : 'function'}`));
201
209
  return results;
202
210
  }
203
211
  getTypedef(state) {
@@ -252,7 +260,7 @@ class FunctionExpression extends AstNode_1.Expression {
252
260
  if (!returnType) {
253
261
  returnType = isSub ? VoidType_1.VoidType.instance : DynamicType_1.DynamicType.instance;
254
262
  }
255
- const resultType = new TypedFunctionType_1.TypedFunctionType(returnType);
263
+ const resultType = new types_1.TypedFunctionType(returnType);
256
264
  resultType.isSub = isSub;
257
265
  for (let param of this.parameters) {
258
266
  resultType.addParameter(param.tokens.name.text, param.getType(Object.assign(Object.assign({}, options), { typeChain: undefined })), !!param.defaultValue);
@@ -320,20 +328,19 @@ class FunctionParameterExpression extends AstNode_1.Expression {
320
328
  }
321
329
  getTypedef(state) {
322
330
  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
- ];
331
+ const results = [this.tokens.name.text];
332
+ if (this.defaultValue) {
333
+ results.push(' = ', ...this.defaultValue.transpile(state));
334
+ }
335
+ if (this.tokens.as) {
336
+ results.push(' as ');
337
+ // TODO: Is this conditional needed? Will typeToken always exist
338
+ // so long as `asToken` exists?
339
+ if (this.typeExpression) {
340
+ results.push(...((_b = (_a = this.typeExpression) === null || _a === void 0 ? void 0 : _a.getTypedef(state)) !== null && _b !== void 0 ? _b : ['']));
341
+ }
342
+ }
343
+ return results;
337
344
  }
338
345
  walk(visitor, options) {
339
346
  // eslint-disable-next-line no-bitwise
@@ -342,6 +349,10 @@ class FunctionParameterExpression extends AstNode_1.Expression {
342
349
  (0, visitors_2.walk)(this, 'typeExpression', visitor, options);
343
350
  }
344
351
  }
352
+ getLeadingTrivia() {
353
+ var _a;
354
+ return (_a = this.tokens.name.leadingTrivia) !== null && _a !== void 0 ? _a : [];
355
+ }
345
356
  }
346
357
  exports.FunctionParameterExpression = FunctionParameterExpression;
347
358
  class DottedGetExpression extends AstNode_1.Expression {
@@ -378,7 +389,11 @@ class DottedGetExpression extends AstNode_1.Expression {
378
389
  getType(options) {
379
390
  var _a, _b, _c, _d, _e, _f;
380
391
  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);
392
+ let result = objType === null || objType === void 0 ? void 0 : objType.getMemberType((_b = this.tokens.name) === null || _b === void 0 ? void 0 : _b.text, options);
393
+ if (util_1.default.isClassUsedAsFunction(result, this, options)) {
394
+ // treat this class constructor as a function
395
+ result = FunctionType_1.FunctionType.instance;
396
+ }
382
397
  (_c = options.typeChain) === null || _c === void 0 ? void 0 : _c.push(new interfaces_1.TypeChainEntry({
383
398
  name: (_d = this.tokens.name) === null || _d === void 0 ? void 0 : _d.text,
384
399
  type: result,
@@ -386,8 +401,10 @@ class DottedGetExpression extends AstNode_1.Expression {
386
401
  range: (_f = (_e = this.tokens.name) === null || _e === void 0 ? void 0 : _e.range) !== null && _f !== void 0 ? _f : this.range,
387
402
  kind: this.kind
388
403
  }));
389
- if (result || options.flags & 2 /* SymbolTypeFlag.typetime */) {
390
- // All types should be known at typetime
404
+ if (result ||
405
+ options.flags & 2 /* SymbolTypeFlag.typetime */ ||
406
+ ((0, reflection_1.isPrimitiveType)(objType) || (0, reflection_1.isCallableType)(objType))) {
407
+ // All types should be known at typeTime, or the obj is well known
391
408
  return result;
392
409
  }
393
410
  // It is possible at runtime that a value has been added dynamically to an object, or something
@@ -397,6 +414,9 @@ class DottedGetExpression extends AstNode_1.Expression {
397
414
  getName(parseMode) {
398
415
  return util_1.default.getAllDottedGetPartsAsString(this, parseMode);
399
416
  }
417
+ getLeadingTrivia() {
418
+ return this.obj.getLeadingTrivia();
419
+ }
400
420
  }
401
421
  exports.DottedGetExpression = DottedGetExpression;
402
422
  class XmlAttributeGetExpression extends AstNode_1.Expression {
@@ -419,6 +439,9 @@ class XmlAttributeGetExpression extends AstNode_1.Expression {
419
439
  (0, visitors_2.walk)(this, 'obj', visitor, options);
420
440
  }
421
441
  }
442
+ getLeadingTrivia() {
443
+ return this.obj.getLeadingTrivia();
444
+ }
422
445
  }
423
446
  exports.XmlAttributeGetExpression = XmlAttributeGetExpression;
424
447
  class IndexedGetExpression extends AstNode_1.Expression {
@@ -463,6 +486,9 @@ class IndexedGetExpression extends AstNode_1.Expression {
463
486
  }
464
487
  return super.getType(options);
465
488
  }
489
+ getLeadingTrivia() {
490
+ return this.obj.getLeadingTrivia();
491
+ }
466
492
  }
467
493
  exports.IndexedGetExpression = IndexedGetExpression;
468
494
  class GroupingExpression extends AstNode_1.Expression {
@@ -494,6 +520,10 @@ class GroupingExpression extends AstNode_1.Expression {
494
520
  getType(options) {
495
521
  return this.expression.getType(options);
496
522
  }
523
+ getLeadingTrivia() {
524
+ var _a, _b;
525
+ return (_b = (_a = this.tokens.leftParen) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
526
+ }
497
527
  }
498
528
  exports.GroupingExpression = GroupingExpression;
499
529
  class LiteralExpression extends AstNode_1.Expression {
@@ -527,12 +557,16 @@ class LiteralExpression extends AstNode_1.Expression {
527
557
  text = this.tokens.value.text;
528
558
  }
529
559
  return [
530
- state.sourceNode(this, text)
560
+ state.transpileToken(Object.assign(Object.assign({}, this.tokens.value), { text: text }))
531
561
  ];
532
562
  }
533
563
  walk(visitor, options) {
534
564
  //nothing to walk
535
565
  }
566
+ getLeadingTrivia() {
567
+ var _a;
568
+ return (_a = this.tokens.value.leadingTrivia) !== null && _a !== void 0 ? _a : [];
569
+ }
536
570
  }
537
571
  exports.LiteralExpression = LiteralExpression;
538
572
  /**
@@ -568,6 +602,7 @@ class ArrayLiteralExpression extends AstNode_1.Expression {
568
602
  this.range = util_1.default.createBoundingRange(this.tokens.open, ...this.elements, this.tokens.close);
569
603
  }
570
604
  transpile(state) {
605
+ var _a;
571
606
  let result = [];
572
607
  result.push(state.transpileToken(this.tokens.open, '['));
573
608
  let hasChildren = this.elements.length > 0;
@@ -575,32 +610,18 @@ class ArrayLiteralExpression extends AstNode_1.Expression {
575
610
  for (let i = 0; i < this.elements.length; i++) {
576
611
  let previousElement = this.elements[i - 1];
577
612
  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();
613
+ if (util_1.default.isLeadingCommentOnSameLine(previousElement !== null && previousElement !== void 0 ? previousElement : this.tokens.open, element)) {
614
+ result.push(' ');
589
615
  }
590
616
  else {
591
- result.push('\n');
592
- result.push(state.indent(), ...element.transpile(state));
617
+ result.push('\n', state.indent());
593
618
  }
619
+ result.push(...element.transpile(state));
594
620
  }
595
621
  state.blockDepth--;
596
622
  //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
- }
623
+ const lastLocatable = (_a = this.elements[this.elements.length - 1]) !== null && _a !== void 0 ? _a : this.tokens.open;
624
+ result.push(...state.transpileEndBlockToken(lastLocatable, this.tokens.close, ']', hasChildren));
604
625
  return result;
605
626
  }
606
627
  walk(visitor, options) {
@@ -609,9 +630,13 @@ class ArrayLiteralExpression extends AstNode_1.Expression {
609
630
  }
610
631
  }
611
632
  getType(options) {
612
- const innerTypes = this.elements.filter(x => !(0, reflection_1.isCommentStatement)(x)).map(expr => expr.getType(options));
633
+ const innerTypes = this.elements.map(expr => expr.getType(options));
613
634
  return new ArrayType_1.ArrayType(...innerTypes);
614
635
  }
636
+ getLeadingTrivia() {
637
+ var _a;
638
+ return (_a = this.tokens.open.leadingTrivia) !== null && _a !== void 0 ? _a : [];
639
+ }
615
640
  }
616
641
  exports.ArrayLiteralExpression = ArrayLiteralExpression;
617
642
  class AAMemberExpression extends AstNode_1.Expression {
@@ -636,6 +661,10 @@ class AAMemberExpression extends AstNode_1.Expression {
636
661
  getType(options) {
637
662
  return this.value.getType(options);
638
663
  }
664
+ getLeadingTrivia() {
665
+ var _a;
666
+ return (_a = this.tokens.key.leadingTrivia) !== null && _a !== void 0 ? _a : [];
667
+ }
639
668
  }
640
669
  exports.AAMemberExpression = AAMemberExpression;
641
670
  class AALiteralExpression extends AstNode_1.Expression {
@@ -650,12 +679,13 @@ class AALiteralExpression extends AstNode_1.Expression {
650
679
  this.range = util_1.default.createBoundingRange(this.tokens.open, ...this.elements, this.tokens.close);
651
680
  }
652
681
  transpile(state) {
682
+ var _a;
653
683
  let result = [];
654
684
  //open curly
655
685
  result.push(state.transpileToken(this.tokens.open, '{'));
656
686
  let hasChildren = this.elements.length > 0;
657
687
  //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))) {
688
+ if (hasChildren && !util_1.default.isLeadingCommentOnSameLine(this.tokens.open, this.elements[0])) {
659
689
  result.push('\n');
660
690
  }
661
691
  state.blockDepth++;
@@ -664,41 +694,29 @@ class AALiteralExpression extends AstNode_1.Expression {
664
694
  let previousElement = this.elements[i - 1];
665
695
  let nextElement = this.elements[i + 1];
666
696
  //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))) {
697
+ if (util_1.default.isLeadingCommentOnSameLine(this.tokens.open, element) ||
698
+ util_1.default.isLeadingCommentOnSameLine(previousElement, element)) {
669
699
  result.push(' ');
670
- //indent line
671
700
  }
672
701
  else {
702
+ //indent line
673
703
  result.push(state.indent());
674
704
  }
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
- }
705
+ //key
706
+ result.push(state.transpileToken(element.tokens.key));
707
+ //colon
708
+ result.push(state.transpileToken(element.tokens.colon, ':'), ' ');
709
+ //value
710
+ result.push(...element.value.transpile(state));
687
711
  //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) {
712
+ if (nextElement && !util_1.default.isLeadingCommentOnSameLine(element, nextElement)) {
689
713
  //add a newline between statements
690
- }
691
- else {
692
714
  result.push('\n');
693
715
  }
694
716
  }
695
717
  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, '}'));
718
+ const lastElement = (_a = this.elements[this.elements.length - 1]) !== null && _a !== void 0 ? _a : this.tokens.open;
719
+ result.push(...state.transpileEndBlockToken(lastElement, this.tokens.close, '}', hasChildren));
702
720
  return result;
703
721
  }
704
722
  walk(visitor, options) {
@@ -708,6 +726,7 @@ class AALiteralExpression extends AstNode_1.Expression {
708
726
  }
709
727
  getType(options) {
710
728
  const resultType = new AssociativeArrayType_1.AssociativeArrayType();
729
+ resultType.addBuiltInInterfaces();
711
730
  for (const element of this.elements) {
712
731
  if ((0, reflection_1.isAAMemberExpression)(element)) {
713
732
  resultType.addMember(element.tokens.key.text, { definingNode: element }, element.getType(options), 1 /* SymbolTypeFlag.runtime */);
@@ -715,6 +734,10 @@ class AALiteralExpression extends AstNode_1.Expression {
715
734
  }
716
735
  return resultType;
717
736
  }
737
+ getLeadingTrivia() {
738
+ var _a;
739
+ return (_a = this.tokens.open.leadingTrivia) !== null && _a !== void 0 ? _a : [];
740
+ }
718
741
  }
719
742
  exports.AALiteralExpression = AALiteralExpression;
720
743
  class UnaryExpression extends AstNode_1.Expression {
@@ -752,6 +775,10 @@ class UnaryExpression extends AstNode_1.Expression {
752
775
  getType(options) {
753
776
  return util_1.default.unaryOperatorResultType(this.tokens.operator, this.right.getType(options));
754
777
  }
778
+ getLeadingTrivia() {
779
+ var _a;
780
+ return (_a = this.tokens.operator.leadingTrivia) !== null && _a !== void 0 ? _a : [];
781
+ }
755
782
  }
756
783
  exports.UnaryExpression = UnaryExpression;
757
784
  class VariableExpression extends AstNode_1.Expression {
@@ -771,7 +798,7 @@ class VariableExpression extends AstNode_1.Expression {
771
798
  let result = [];
772
799
  const namespace = this.findAncestor(reflection_1.isNamespaceStatement);
773
800
  //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))) {
801
+ if (namespace && state.file.calleeIsKnownNamespaceFunction(this, namespace.getName(Parser_1.ParseMode.BrighterScript))) {
775
802
  result.push(state.sourceNode(this, [
776
803
  namespace.getName(Parser_1.ParseMode.BrightScript),
777
804
  '_',
@@ -794,10 +821,17 @@ class VariableExpression extends AstNode_1.Expression {
794
821
  if (!resultType) {
795
822
  const symbolTable = this.getSymbolTable();
796
823
  resultType = symbolTable === null || symbolTable === void 0 ? void 0 : symbolTable.getSymbolType(nameKey, Object.assign(Object.assign({}, options), { fullName: nameKey, tableProvider: () => this.getSymbolTable() }));
824
+ if (util_1.default.isClassUsedAsFunction(resultType, this, options)) {
825
+ resultType = FunctionType_1.FunctionType.instance;
826
+ }
797
827
  }
798
828
  (_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
829
  return resultType;
800
830
  }
831
+ getLeadingTrivia() {
832
+ var _a;
833
+ return (_a = this.tokens.name.leadingTrivia) !== null && _a !== void 0 ? _a : [];
834
+ }
801
835
  }
802
836
  exports.VariableExpression = VariableExpression;
803
837
  class SourceLiteralExpression extends AstNode_1.Expression {
@@ -828,7 +862,7 @@ class SourceLiteralExpression extends AstNode_1.Expression {
828
862
  return index;
829
863
  }
830
864
  getFunctionName(state, parseMode) {
831
- let func = state.file.getFunctionScopeAtPosition(this.tokens.value.range.start).func;
865
+ let func = this.findAncestor(reflection_1.isFunctionExpression);
832
866
  let nameParts = [];
833
867
  let parentFunction;
834
868
  while ((parentFunction = func.findAncestor(reflection_1.isFunctionExpression))) {
@@ -840,6 +874,19 @@ class SourceLiteralExpression extends AstNode_1.Expression {
840
874
  nameParts.unshift(func.functionStatement.getName(parseMode));
841
875
  return nameParts.join('$');
842
876
  }
877
+ /**
878
+ * Get the line number from our token or from the closest ancestor that has a range
879
+ */
880
+ getClosestLineNumber() {
881
+ let node = this;
882
+ while (node) {
883
+ if (node.range) {
884
+ return node.range.start.line + 1;
885
+ }
886
+ node = node.parent;
887
+ }
888
+ return -1;
889
+ }
843
890
  transpile(state) {
844
891
  let text;
845
892
  switch (this.tokens.value.kind) {
@@ -848,7 +895,8 @@ class SourceLiteralExpression extends AstNode_1.Expression {
848
895
  text = `"${pathUrl.substring(0, 4)}" + "${pathUrl.substring(4)}"`;
849
896
  break;
850
897
  case TokenKind_1.TokenKind.SourceLineNumLiteral:
851
- text = `${this.tokens.value.range.start.line + 1}`;
898
+ //TODO find first parent that has range, or default to -1
899
+ text = `${this.getClosestLineNumber()}`;
852
900
  break;
853
901
  case TokenKind_1.TokenKind.FunctionNameLiteral:
854
902
  text = `"${this.getFunctionName(state, Parser_1.ParseMode.BrightScript)}"`;
@@ -858,7 +906,8 @@ class SourceLiteralExpression extends AstNode_1.Expression {
858
906
  break;
859
907
  case TokenKind_1.TokenKind.SourceLocationLiteral:
860
908
  const locationUrl = fileUrl(state.srcPath);
861
- text = `"${locationUrl.substring(0, 4)}" + "${locationUrl.substring(4)}:${this.tokens.value.range.start.line + 1}"`;
909
+ //TODO find first parent that has range, or default to -1
910
+ text = `"${locationUrl.substring(0, 4)}" + "${locationUrl.substring(4)}:${this.getClosestLineNumber()}"`;
862
911
  break;
863
912
  case TokenKind_1.TokenKind.PkgPathLiteral:
864
913
  text = `"${util_1.default.sanitizePkgPath(state.file.pkgPath)}"`;
@@ -879,6 +928,10 @@ class SourceLiteralExpression extends AstNode_1.Expression {
879
928
  walk(visitor, options) {
880
929
  //nothing to walk
881
930
  }
931
+ getLeadingTrivia() {
932
+ var _a;
933
+ return (_a = this.tokens.value.leadingTrivia) !== null && _a !== void 0 ? _a : [];
934
+ }
882
935
  }
883
936
  exports.SourceLiteralExpression = SourceLiteralExpression;
884
937
  /**
@@ -928,6 +981,10 @@ class NewExpression extends AstNode_1.Expression {
928
981
  }
929
982
  return result;
930
983
  }
984
+ getLeadingTrivia() {
985
+ var _a;
986
+ return (_a = this.tokens.new.leadingTrivia) !== null && _a !== void 0 ? _a : [];
987
+ }
931
988
  }
932
989
  exports.NewExpression = NewExpression;
933
990
  class CallfuncExpression extends AstNode_1.Expression {
@@ -1008,6 +1065,9 @@ class CallfuncExpression extends AstNode_1.Expression {
1008
1065
  }
1009
1066
  return result;
1010
1067
  }
1068
+ getLeadingTrivia() {
1069
+ return this.callee.getLeadingTrivia();
1070
+ }
1011
1071
  }
1012
1072
  exports.CallfuncExpression = CallfuncExpression;
1013
1073
  /**
@@ -1183,8 +1243,8 @@ class AnnotationExpression extends AstNode_1.Expression {
1183
1243
  return this.call.args.map(e => expressionToValue(e, strict));
1184
1244
  }
1185
1245
  getLeadingTrivia() {
1186
- var _a;
1187
- return (_a = this.tokens.at) === null || _a === void 0 ? void 0 : _a.leadingTrivia;
1246
+ var _a, _b;
1247
+ return (_b = (_a = this.tokens.at) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
1188
1248
  }
1189
1249
  transpile(state) {
1190
1250
  return [];
@@ -1218,8 +1278,9 @@ class TernaryExpression extends AstNode_1.Expression {
1218
1278
  transpile(state) {
1219
1279
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
1220
1280
  let result = [];
1221
- let consequentInfo = util_1.default.getExpressionInfo(this.consequent);
1222
- let alternateInfo = util_1.default.getExpressionInfo(this.alternate);
1281
+ const file = state.file;
1282
+ let consequentInfo = util_1.default.getExpressionInfo(this.consequent, file);
1283
+ let alternateInfo = util_1.default.getExpressionInfo(this.alternate, file);
1223
1284
  //get all unique variable names used in the consequent and alternate, and sort them alphabetically so the output is consistent
1224
1285
  let allUniqueVarNames = [...new Set([...consequentInfo.uniqueVarNames, ...alternateInfo.uniqueVarNames])].sort();
1225
1286
  let mutatingExpressions = [
@@ -1230,9 +1291,9 @@ class TernaryExpression extends AstNode_1.Expression {
1230
1291
  result.push(state.sourceNode(this.tokens.questionMark,
1231
1292
  //write all the scope variables as parameters.
1232
1293
  //TODO handle when there are more than 31 parameters
1233
- `(function(__bsCondition, ${allUniqueVarNames.join(', ')})`), state.newline,
1294
+ `(function(${['__bsCondition', ...allUniqueVarNames].join(', ')})`), state.newline,
1234
1295
  //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(', ')})`));
1296
+ 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
1297
  state.blockDepth--;
1237
1298
  }
1238
1299
  else {
@@ -1247,6 +1308,9 @@ class TernaryExpression extends AstNode_1.Expression {
1247
1308
  (0, visitors_2.walk)(this, 'alternate', visitor, options);
1248
1309
  }
1249
1310
  }
1311
+ getLeadingTrivia() {
1312
+ return this.test.getLeadingTrivia();
1313
+ }
1250
1314
  }
1251
1315
  exports.TernaryExpression = TernaryExpression;
1252
1316
  class NullCoalescingExpression extends AstNode_1.Expression {
@@ -1262,8 +1326,8 @@ class NullCoalescingExpression extends AstNode_1.Expression {
1262
1326
  }
1263
1327
  transpile(state) {
1264
1328
  let result = [];
1265
- let consequentInfo = util_1.default.getExpressionInfo(this.consequent);
1266
- let alternateInfo = util_1.default.getExpressionInfo(this.alternate);
1329
+ let consequentInfo = util_1.default.getExpressionInfo(this.consequent, state.file);
1330
+ let alternateInfo = util_1.default.getExpressionInfo(this.alternate, state.file);
1267
1331
  //get all unique variable names used in the consequent and alternate, and sort them alphabetically so the output is consistent
1268
1332
  let allUniqueVarNames = [...new Set([...consequentInfo.uniqueVarNames, ...alternateInfo.uniqueVarNames])].sort();
1269
1333
  let hasMutatingExpression = [
@@ -1292,6 +1356,9 @@ class NullCoalescingExpression extends AstNode_1.Expression {
1292
1356
  (0, visitors_2.walk)(this, 'alternate', visitor, options);
1293
1357
  }
1294
1358
  }
1359
+ getLeadingTrivia() {
1360
+ return this.consequent.getLeadingTrivia();
1361
+ }
1295
1362
  }
1296
1363
  exports.NullCoalescingExpression = NullCoalescingExpression;
1297
1364
  class RegexLiteralExpression extends AstNode_1.Expression {
@@ -1333,6 +1400,10 @@ class RegexLiteralExpression extends AstNode_1.Expression {
1333
1400
  walk(visitor, options) {
1334
1401
  //nothing to walk
1335
1402
  }
1403
+ getLeadingTrivia() {
1404
+ var _a, _b;
1405
+ return (_b = (_a = this.tokens.regexLiteral) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
1406
+ }
1336
1407
  }
1337
1408
  exports.RegexLiteralExpression = RegexLiteralExpression;
1338
1409
  function expressionToValue(expr, strict) {
@@ -1354,14 +1425,11 @@ function expressionToValue(expr, strict) {
1354
1425
  }
1355
1426
  if ((0, reflection_1.isArrayLiteralExpression)(expr)) {
1356
1427
  return expr.elements
1357
- .filter(e => !(0, reflection_1.isCommentStatement)(e))
1358
1428
  .map(e => expressionToValue(e, strict));
1359
1429
  }
1360
1430
  if ((0, reflection_1.isAALiteralExpression)(expr)) {
1361
1431
  return expr.elements.reduce((acc, e) => {
1362
- if (!(0, reflection_1.isCommentStatement)(e)) {
1363
- acc[e.tokens.key.text] = expressionToValue(e.value, strict);
1364
- }
1432
+ acc[e.tokens.key.text] = expressionToValue(e.value, strict);
1365
1433
  return acc;
1366
1434
  }, {});
1367
1435
  }