brighterscript 1.0.0-alpha.41 → 1.0.0-alpha.42

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 (210) hide show
  1. package/CHANGELOG.md +62 -2
  2. package/dist/AstValidationSegmenter.d.ts +3 -0
  3. package/dist/AstValidationSegmenter.js +62 -2
  4. package/dist/AstValidationSegmenter.js.map +1 -1
  5. package/dist/BsConfig.d.ts +7 -7
  6. package/dist/CrossScopeValidator.js +3 -3
  7. package/dist/CrossScopeValidator.js.map +1 -1
  8. package/dist/DiagnosticFilterer.d.ts +5 -1
  9. package/dist/DiagnosticFilterer.js +92 -33
  10. package/dist/DiagnosticFilterer.js.map +1 -1
  11. package/dist/DiagnosticManager.js +12 -9
  12. package/dist/DiagnosticManager.js.map +1 -1
  13. package/dist/DiagnosticMessages.d.ts +374 -225
  14. package/dist/DiagnosticMessages.js +641 -424
  15. package/dist/DiagnosticMessages.js.map +1 -1
  16. package/dist/DiagnosticSeverityAdjuster.js +4 -0
  17. package/dist/DiagnosticSeverityAdjuster.js.map +1 -1
  18. package/dist/LanguageServer.js +0 -7
  19. package/dist/LanguageServer.js.map +1 -1
  20. package/dist/PluginInterface.js +2 -0
  21. package/dist/PluginInterface.js.map +1 -1
  22. package/dist/Program.d.ts +22 -1
  23. package/dist/Program.js +206 -49
  24. package/dist/Program.js.map +1 -1
  25. package/dist/SymbolTable.d.ts +3 -0
  26. package/dist/SymbolTable.js +19 -1
  27. package/dist/SymbolTable.js.map +1 -1
  28. package/dist/XmlScope.js +3 -6
  29. package/dist/XmlScope.js.map +1 -1
  30. package/dist/astUtils/creators.d.ts +35 -3
  31. package/dist/astUtils/creators.js +52 -1
  32. package/dist/astUtils/creators.js.map +1 -1
  33. package/dist/astUtils/reflection.d.ts +4 -2
  34. package/dist/astUtils/reflection.js +12 -3
  35. package/dist/astUtils/reflection.js.map +1 -1
  36. package/dist/astUtils/visitors.d.ts +3 -2
  37. package/dist/astUtils/visitors.js +37 -14
  38. package/dist/astUtils/visitors.js.map +1 -1
  39. package/dist/astUtils/visitors.spec.js +172 -6
  40. package/dist/astUtils/visitors.spec.js.map +1 -1
  41. package/dist/bscPlugin/codeActions/CodeActionsProcessor.d.ts +0 -1
  42. package/dist/bscPlugin/codeActions/CodeActionsProcessor.js +0 -13
  43. package/dist/bscPlugin/codeActions/CodeActionsProcessor.js.map +1 -1
  44. package/dist/bscPlugin/completions/CompletionsProcessor.d.ts +2 -1
  45. package/dist/bscPlugin/completions/CompletionsProcessor.js +5 -5
  46. package/dist/bscPlugin/completions/CompletionsProcessor.js.map +1 -1
  47. package/dist/bscPlugin/completions/CompletionsProcessor.spec.js +106 -2
  48. package/dist/bscPlugin/completions/CompletionsProcessor.spec.js.map +1 -1
  49. package/dist/bscPlugin/hover/HoverProcessor.spec.js +51 -3
  50. package/dist/bscPlugin/hover/HoverProcessor.spec.js.map +1 -1
  51. package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.d.ts +1 -0
  52. package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.js +149 -0
  53. package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.js.map +1 -1
  54. package/dist/bscPlugin/validation/BrsFileValidator.js +15 -8
  55. package/dist/bscPlugin/validation/BrsFileValidator.js.map +1 -1
  56. package/dist/bscPlugin/validation/BrsFileValidator.spec.js +80 -9
  57. package/dist/bscPlugin/validation/BrsFileValidator.spec.js.map +1 -1
  58. package/dist/bscPlugin/validation/ScopeValidator.d.ts +7 -0
  59. package/dist/bscPlugin/validation/ScopeValidator.js +149 -79
  60. package/dist/bscPlugin/validation/ScopeValidator.js.map +1 -1
  61. package/dist/bscPlugin/validation/ScopeValidator.spec.js +1227 -27
  62. package/dist/bscPlugin/validation/ScopeValidator.spec.js.map +1 -1
  63. package/dist/bscPlugin/validation/XmlFileValidator.js +0 -8
  64. package/dist/bscPlugin/validation/XmlFileValidator.js.map +1 -1
  65. package/dist/diagnosticUtils.js +6 -5
  66. package/dist/diagnosticUtils.js.map +1 -1
  67. package/dist/files/BrsFile.Class.spec.js +87 -28
  68. package/dist/files/BrsFile.Class.spec.js.map +1 -1
  69. package/dist/files/BrsFile.d.ts +1 -0
  70. package/dist/files/BrsFile.js +20 -8
  71. package/dist/files/BrsFile.js.map +1 -1
  72. package/dist/files/BrsFile.spec.js +133 -34
  73. package/dist/files/BrsFile.spec.js.map +1 -1
  74. package/dist/files/XmlFile.js +2 -2
  75. package/dist/files/XmlFile.js.map +1 -1
  76. package/dist/files/XmlFile.spec.js +3 -20
  77. package/dist/files/XmlFile.spec.js.map +1 -1
  78. package/dist/globalCallables.js +1 -1
  79. package/dist/index.d.ts +8 -3
  80. package/dist/index.js +24 -16
  81. package/dist/index.js.map +1 -1
  82. package/dist/interfaces.d.ts +18 -0
  83. package/dist/interfaces.js.map +1 -1
  84. package/dist/lexer/Lexer.js +17 -11
  85. package/dist/lexer/Lexer.js.map +1 -1
  86. package/dist/lexer/Lexer.spec.js +21 -3
  87. package/dist/lexer/Lexer.spec.js.map +1 -1
  88. package/dist/lexer/TokenKind.d.ts +9 -0
  89. package/dist/lexer/TokenKind.js +11 -1
  90. package/dist/lexer/TokenKind.js.map +1 -1
  91. package/dist/parser/AstNode.d.ts +2 -1
  92. package/dist/parser/AstNode.js +3 -2
  93. package/dist/parser/AstNode.js.map +1 -1
  94. package/dist/parser/Expression.d.ts +22 -2
  95. package/dist/parser/Expression.js +76 -48
  96. package/dist/parser/Expression.js.map +1 -1
  97. package/dist/parser/Parser.Class.spec.js +3 -3
  98. package/dist/parser/Parser.Class.spec.js.map +1 -1
  99. package/dist/parser/Parser.js +73 -61
  100. package/dist/parser/Parser.js.map +1 -1
  101. package/dist/parser/Parser.spec.js +198 -15
  102. package/dist/parser/Parser.spec.js.map +1 -1
  103. package/dist/parser/SGParser.js +9 -9
  104. package/dist/parser/SGParser.js.map +1 -1
  105. package/dist/parser/SGParser.spec.js +3 -2
  106. package/dist/parser/SGParser.spec.js.map +1 -1
  107. package/dist/parser/Statement.d.ts +16 -18
  108. package/dist/parser/Statement.js +136 -82
  109. package/dist/parser/Statement.js.map +1 -1
  110. package/dist/parser/tests/controlFlow/If.spec.js +1 -1
  111. package/dist/parser/tests/controlFlow/If.spec.js.map +1 -1
  112. package/dist/parser/tests/expression/ArrayLiterals.spec.js +3 -3
  113. package/dist/parser/tests/expression/ArrayLiterals.spec.js.map +1 -1
  114. package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js +3 -3
  115. package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js.map +1 -1
  116. package/dist/parser/tests/expression/Call.spec.js +9 -9
  117. package/dist/parser/tests/expression/Call.spec.js.map +1 -1
  118. package/dist/parser/tests/expression/Indexing.spec.js +3 -3
  119. package/dist/parser/tests/expression/Indexing.spec.js.map +1 -1
  120. package/dist/parser/tests/expression/TemplateStringExpression.spec.js +1 -1
  121. package/dist/parser/tests/expression/TemplateStringExpression.spec.js.map +1 -1
  122. package/dist/parser/tests/expression/TernaryExpression.spec.js +353 -71
  123. package/dist/parser/tests/expression/TernaryExpression.spec.js.map +1 -1
  124. package/dist/parser/tests/statement/Dim.spec.js +10 -3
  125. package/dist/parser/tests/statement/Dim.spec.js.map +1 -1
  126. package/dist/parser/tests/statement/Enum.spec.js +2 -2
  127. package/dist/parser/tests/statement/Enum.spec.js.map +1 -1
  128. package/dist/parser/tests/statement/Increment.spec.js +3 -5
  129. package/dist/parser/tests/statement/Increment.spec.js.map +1 -1
  130. package/dist/parser/tests/statement/PrintStatement.spec.js +3 -3
  131. package/dist/parser/tests/statement/TryCatch.spec.js +1 -1
  132. package/dist/parser/tests/statement/TryCatch.spec.js.map +1 -1
  133. package/dist/roku-types/data.json +430 -235
  134. package/dist/roku-types/index.d.ts +30 -37
  135. package/dist/types/ArrayType.d.ts +2 -0
  136. package/dist/types/ArrayType.js +14 -4
  137. package/dist/types/ArrayType.js.map +1 -1
  138. package/dist/types/AssociativeArrayType.d.ts +1 -0
  139. package/dist/types/AssociativeArrayType.js +1 -0
  140. package/dist/types/AssociativeArrayType.js.map +1 -1
  141. package/dist/types/BaseFunctionType.d.ts +1 -0
  142. package/dist/types/BaseFunctionType.js +1 -0
  143. package/dist/types/BaseFunctionType.js.map +1 -1
  144. package/dist/types/BooleanType.d.ts +1 -0
  145. package/dist/types/BooleanType.js +1 -0
  146. package/dist/types/BooleanType.js.map +1 -1
  147. package/dist/types/BscType.d.ts +8 -1
  148. package/dist/types/BscType.js +12 -3
  149. package/dist/types/BscType.js.map +1 -1
  150. package/dist/types/BuiltInInterfaceAdder.js +10 -6
  151. package/dist/types/BuiltInInterfaceAdder.js.map +1 -1
  152. package/dist/types/ClassType.d.ts +1 -0
  153. package/dist/types/ClassType.js +5 -2
  154. package/dist/types/ClassType.js.map +1 -1
  155. package/dist/types/ComponentType.d.ts +11 -4
  156. package/dist/types/ComponentType.js +100 -8
  157. package/dist/types/ComponentType.js.map +1 -1
  158. package/dist/types/DoubleType.d.ts +2 -0
  159. package/dist/types/DoubleType.js +2 -0
  160. package/dist/types/DoubleType.js.map +1 -1
  161. package/dist/types/DynamicType.d.ts +1 -0
  162. package/dist/types/DynamicType.js +4 -0
  163. package/dist/types/DynamicType.js.map +1 -1
  164. package/dist/types/EnumType.d.ts +2 -0
  165. package/dist/types/EnumType.js +20 -2
  166. package/dist/types/EnumType.js.map +1 -1
  167. package/dist/types/FloatType.d.ts +2 -0
  168. package/dist/types/FloatType.js +2 -0
  169. package/dist/types/FloatType.js.map +1 -1
  170. package/dist/types/InheritableType.js +8 -0
  171. package/dist/types/InheritableType.js.map +1 -1
  172. package/dist/types/IntegerType.d.ts +2 -0
  173. package/dist/types/IntegerType.js +2 -0
  174. package/dist/types/IntegerType.js.map +1 -1
  175. package/dist/types/InterfaceType.js +4 -1
  176. package/dist/types/InterfaceType.js.map +1 -1
  177. package/dist/types/InvalidType.d.ts +2 -1
  178. package/dist/types/InvalidType.js +1 -0
  179. package/dist/types/InvalidType.js.map +1 -1
  180. package/dist/types/LongIntegerType.d.ts +2 -0
  181. package/dist/types/LongIntegerType.js +2 -0
  182. package/dist/types/LongIntegerType.js.map +1 -1
  183. package/dist/types/ObjectType.d.ts +1 -0
  184. package/dist/types/ObjectType.js +1 -0
  185. package/dist/types/ObjectType.js.map +1 -1
  186. package/dist/types/ReferenceType.d.ts +20 -2
  187. package/dist/types/ReferenceType.js +106 -5
  188. package/dist/types/ReferenceType.js.map +1 -1
  189. package/dist/types/StringType.d.ts +1 -0
  190. package/dist/types/StringType.js +1 -0
  191. package/dist/types/StringType.js.map +1 -1
  192. package/dist/types/TypedFunctionType.d.ts +1 -1
  193. package/dist/types/TypedFunctionType.js +8 -2
  194. package/dist/types/TypedFunctionType.js.map +1 -1
  195. package/dist/types/UninitializedType.d.ts +2 -0
  196. package/dist/types/UninitializedType.js +5 -6
  197. package/dist/types/UninitializedType.js.map +1 -1
  198. package/dist/types/UnionType.js +8 -2
  199. package/dist/types/UnionType.js.map +1 -1
  200. package/dist/types/VoidType.d.ts +4 -1
  201. package/dist/types/VoidType.js +5 -0
  202. package/dist/types/VoidType.js.map +1 -1
  203. package/dist/types/helpers.js +8 -1
  204. package/dist/types/helpers.js.map +1 -1
  205. package/dist/util.d.ts +15 -5
  206. package/dist/util.js +281 -14
  207. package/dist/util.js.map +1 -1
  208. package/dist/validators/ClassValidator.js +13 -5
  209. package/dist/validators/ClassValidator.js.map +1 -1
  210. package/package.json +2 -2
@@ -16,6 +16,7 @@ const util_1 = require("../util");
16
16
  const testHelpers_spec_1 = require("../testHelpers.spec");
17
17
  const Parser_1 = require("../parser/Parser");
18
18
  const Statement_1 = require("../parser/Statement");
19
+ const Statement_2 = require("../parser/Statement");
19
20
  const creators_1 = require("../astUtils/creators");
20
21
  const fsExtra = require("fs-extra");
21
22
  const undent_1 = require("undent");
@@ -23,6 +24,8 @@ const testHelpers_spec_2 = require("../testHelpers.spec");
23
24
  const types_1 = require("../types");
24
25
  const fileUrl = require("file-url");
25
26
  const reflection_1 = require("../astUtils/reflection");
27
+ const Expression_1 = require("../parser/Expression");
28
+ const logger_1 = require("@rokucommunity/logger");
26
29
  let sinon = sinonImport.createSandbox();
27
30
  describe('BrsFile', () => {
28
31
  let program;
@@ -156,6 +159,38 @@ describe('BrsFile', () => {
156
159
  program.validate();
157
160
  (0, testHelpers_spec_1.expectDiagnostics)(program, [DiagnosticMessages_1.DiagnosticMessages.itemCannotBeUsedAsVariable('enum').message]);
158
161
  });
162
+ it('does not crazy during validation with unique binary operator', () => {
163
+ //monitor the logging system, if we detect an error, this test fails
164
+ const spy = sinon.spy(logger_1.Logger.prototype, 'error');
165
+ const file = program.setFile('source/main.bs', `
166
+ namespace date
167
+ function timeElapsedInDay()
168
+ time = 1
169
+ if true then
170
+ time = getInteger()
171
+ end if
172
+ clockSeconds = getInteger() + 1
173
+ assumedMidnight = time - clockSeconds
174
+ offset = assumedMidnight - 1
175
+ end function
176
+
177
+ function getInteger()
178
+ return 1
179
+ end function
180
+ end namespace
181
+
182
+ `);
183
+ program.validate();
184
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(program);
185
+ (0, chai_config_spec_1.expect)(spy.getCalls().map(x => { var _a, _b; return (_b = (_a = x.args) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.toString(); }).filter(x => x === null || x === void 0 ? void 0 : x.includes('Error when calling plugin'))).to.eql([]);
186
+ // Check the result type too
187
+ const sourceScope = program.getScopeByName('source');
188
+ sourceScope.linkSymbolTable();
189
+ const timeElapsedFunc = file.ast.findChild(reflection_1.isFunctionExpression);
190
+ const symbolTable = timeElapsedFunc.body.getSymbolTable();
191
+ const offsetType = symbolTable.getSymbolType('offset', { flags: 1 /* SymbolTypeFlag.runtime */ });
192
+ (0, testHelpers_spec_1.expectTypeToBe)(offsetType, IntegerType_1.IntegerType);
193
+ });
159
194
  it('supports the third parameter in CreateObject', () => {
160
195
  program.setFile('source/main.brs', `
161
196
  sub main()
@@ -191,7 +226,7 @@ describe('BrsFile', () => {
191
226
  it('computes new import statements after clearing parser references', () => {
192
227
  const file = program.setFile('source/main.bs', ``);
193
228
  (0, chai_config_spec_1.expect)(file.ownScriptImports).to.be.empty;
194
- file.parser.ast.statements.push(new Statement_1.ImportStatement({
229
+ file.parser.ast.statements.push(new Statement_2.ImportStatement({
195
230
  import: (0, creators_1.createToken)(TokenKind_1.TokenKind.Import),
196
231
  path: (0, creators_1.createToken)(TokenKind_1.TokenKind.StringLiteral, 'pkg:/source/lib.brs')
197
232
  }));
@@ -373,6 +408,17 @@ describe('BrsFile', () => {
373
408
  program.validate();
374
409
  (0, testHelpers_spec_1.expectDiagnostics)(program, [Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.unknownDiagnosticCode(123456)), { location: util_1.default.createLocationFromFileRange(file, vscode_languageserver_1.Range.create(2, 53, 2, 59)) }), Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.unknownDiagnosticCode(999999)), { location: util_1.default.createLocationFromFileRange(file, vscode_languageserver_1.Range.create(2, 60, 2, 66)) })]);
375
410
  });
411
+ it('recognizes diagnostic names', () => {
412
+ let file = program.setFile({ src: `${testHelpers_spec_2.rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
413
+ sub Main()
414
+ 'bs:disable-next-line: cannot-find-name
415
+ name = unknown
416
+ end sub
417
+ `);
418
+ (0, chai_config_spec_1.expect)(file.commentFlags[0]).to.exist;
419
+ program.validate();
420
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(program);
421
+ });
376
422
  });
377
423
  describe('bs:disable-line', () => {
378
424
  it('works for all', () => {
@@ -646,7 +692,7 @@ describe('BrsFile', () => {
646
692
  `);
647
693
  program.validate();
648
694
  (0, testHelpers_spec_1.expectDiagnostics)(program, [
649
- DiagnosticMessages_1.DiagnosticMessages.referencedConstDoesNotExist()
695
+ DiagnosticMessages_1.DiagnosticMessages.hashConstDoesNotExist()
650
696
  ]);
651
697
  });
652
698
  it('detects syntax error in #if not', () => {
@@ -659,7 +705,7 @@ describe('BrsFile', () => {
659
705
  `);
660
706
  program.validate();
661
707
  (0, testHelpers_spec_1.expectDiagnostics)(program, [
662
- DiagnosticMessages_1.DiagnosticMessages.referencedConstDoesNotExist()
708
+ DiagnosticMessages_1.DiagnosticMessages.hashConstDoesNotExist()
663
709
  ]);
664
710
  });
665
711
  it('detects syntax error in #const', () => {
@@ -682,7 +728,7 @@ describe('BrsFile', () => {
682
728
  end sub
683
729
  `);
684
730
  (0, testHelpers_spec_1.expectDiagnostics)(program, [
685
- DiagnosticMessages_1.DiagnosticMessages.constNameCannotBeReservedWord()
731
+ DiagnosticMessages_1.DiagnosticMessages.cannotUseReservedWordAsIdentifier('function')
686
732
  ]);
687
733
  });
688
734
  it('detects syntax error in #const', () => {
@@ -1063,7 +1109,7 @@ describe('BrsFile', () => {
1063
1109
  `);
1064
1110
  program.validate();
1065
1111
  (0, testHelpers_spec_1.expectDiagnostics)(program, [
1066
- DiagnosticMessages_1.DiagnosticMessages.statementMustBeDeclaredAtTopOfFile('import')
1112
+ DiagnosticMessages_1.DiagnosticMessages.unexpectedStatementLocation('import', 'at the top of the file')
1067
1113
  ]);
1068
1114
  });
1069
1115
  it('supports library imports', () => {
@@ -1080,7 +1126,7 @@ describe('BrsFile', () => {
1080
1126
  `);
1081
1127
  program.validate();
1082
1128
  (0, testHelpers_spec_1.expectDiagnostics)(program, [
1083
- DiagnosticMessages_1.DiagnosticMessages.statementMustBeDeclaredAtTopOfFile('library')
1129
+ DiagnosticMessages_1.DiagnosticMessages.unexpectedStatementLocation('library', 'at the top of the file')
1084
1130
  ]);
1085
1131
  });
1086
1132
  it('adds error for library statements inside of function body', () => {
@@ -1091,7 +1137,7 @@ describe('BrsFile', () => {
1091
1137
  `);
1092
1138
  program.validate();
1093
1139
  (0, testHelpers_spec_1.expectDiagnostics)(program, [
1094
- DiagnosticMessages_1.DiagnosticMessages.statementMustBeDeclaredAtTopOfFile('library')
1140
+ DiagnosticMessages_1.DiagnosticMessages.unexpectedStatementLocation('library', 'at the top of the file')
1095
1141
  ]);
1096
1142
  });
1097
1143
  it('supports colons as separators in associative array properties', () => {
@@ -1191,10 +1237,10 @@ describe('BrsFile', () => {
1191
1237
  end function
1192
1238
  `);
1193
1239
  (0, testHelpers_spec_1.expectDiagnostics)(file.parser.diagnostics, [
1194
- DiagnosticMessages_1.DiagnosticMessages.expectedRightParenAfterFunctionCallArguments(),
1240
+ DiagnosticMessages_1.DiagnosticMessages.unmatchedLeftToken('(', 'function call arguments'),
1195
1241
  DiagnosticMessages_1.DiagnosticMessages.expectedNewlineOrColon(),
1196
1242
  DiagnosticMessages_1.DiagnosticMessages.unexpectedToken('end function'),
1197
- DiagnosticMessages_1.DiagnosticMessages.expectedRightParenAfterFunctionCallArguments(),
1243
+ DiagnosticMessages_1.DiagnosticMessages.unmatchedLeftToken('(', 'function call arguments'),
1198
1244
  DiagnosticMessages_1.DiagnosticMessages.expectedNewlineOrColon()
1199
1245
  ]);
1200
1246
  });
@@ -1668,8 +1714,8 @@ describe('BrsFile', () => {
1668
1714
  print PKG_PATH
1669
1715
  print LINE_NUM
1670
1716
  print new Person()
1671
- m@.someCallfunc()
1672
- m@.someCallfunc(1, 2)
1717
+ m.node@.someCallfunc()
1718
+ m.node@.someCallfunc(1, 2)
1673
1719
  print tag\`stuff\${LINE_NUM}\${LINE_NUM}\`
1674
1720
  print 1 = 1 ? 1 : 2
1675
1721
  print 1 = 1 ? m.one : m.two
@@ -1722,8 +1768,8 @@ describe('BrsFile', () => {
1722
1768
  print "pkg:/source/main.brs"
1723
1769
  print LINE_NUM
1724
1770
  print Person()
1725
- m.callfunc("someCallfunc")
1726
- m.callfunc("someCallfunc", 1, 2)
1771
+ m.node.callfunc("someCallfunc")
1772
+ m.node.callfunc("someCallfunc", 1, 2)
1727
1773
  print tag(["stuff", "", ""], [LINE_NUM, LINE_NUM])
1728
1774
  print bslib_ternary(1 = 1, 1, 2)
1729
1775
  print (function(__bsCondition, m)
@@ -1801,6 +1847,51 @@ describe('BrsFile', () => {
1801
1847
  const result = file.transpile();
1802
1848
  (0, chai_config_spec_1.expect)((0, testHelpers_spec_1.trimMap)((0, undent_1.default)(result.code))).to.eql((0, undent_1.default)(expected));
1803
1849
  }
1850
+ it('transpiles call expression when paren tokens are missing', async () => {
1851
+ const file = program.setFile('source/main.bs', `
1852
+ sub main()
1853
+ end sub
1854
+ `);
1855
+ const body = file.ast.findChild(reflection_1.isBlock);
1856
+ body.statements.push(new Expression_1.CallExpression({
1857
+ callee: new Expression_1.LiteralExpression({ value: (0, creators_1.createIdentifier)('lcase') }),
1858
+ args: [(0, creators_1.createStringLiteral)('HELLO')]
1859
+ }));
1860
+ await testTranspile(file, `
1861
+ sub main()
1862
+ lcase("HELLO")
1863
+ end sub
1864
+ `, undefined, undefined, false);
1865
+ });
1866
+ it('transpiles print expression when print token is missing', async () => {
1867
+ const file = program.setFile('source/main.bs', `
1868
+ sub main()
1869
+ end sub
1870
+ `);
1871
+ const body = file.ast.findChild(reflection_1.isBlock);
1872
+ body.statements.push(new Statement_2.PrintStatement({
1873
+ expressions: [(0, creators_1.createStringLiteral)('HELLO')]
1874
+ }));
1875
+ await testTranspile(file, `
1876
+ sub main()
1877
+ print "HELLO"
1878
+ end sub
1879
+ `, undefined, undefined, false);
1880
+ });
1881
+ it('transpiles function expression when paren tokens are missing', async () => {
1882
+ const file = program.setFile('source/main.bs', `
1883
+ `);
1884
+ file.ast.statements.push(new Statement_1.FunctionStatement({
1885
+ func: new Expression_1.FunctionExpression({
1886
+ body: new Statement_1.Block({ statements: [] })
1887
+ }),
1888
+ name: (0, creators_1.createIdentifier)('main')
1889
+ }));
1890
+ await testTranspile(file, `
1891
+ function main()
1892
+ end function
1893
+ `, undefined, undefined, false);
1894
+ });
1804
1895
  });
1805
1896
  it('transpilies libpkg:/ paths when encountered', async () => {
1806
1897
  program.setFile('source/lib.bs', `
@@ -3731,10 +3822,10 @@ describe('BrsFile', () => {
3731
3822
  });
3732
3823
  describe('callfunc operator', () => {
3733
3824
  describe('transpile', () => {
3734
- it('does not produce diagnostics', () => {
3825
+ it('does not produce diagnostics on plain roSGNode', () => {
3735
3826
  program.setFile('source/main.bs', `
3736
3827
  sub test()
3737
- someNode = createObject("roSGNode", "Rectangle")
3828
+ someNode = createObject("roSGNode", "Node")
3738
3829
  someNode@.someFunction({test: "value"})
3739
3830
  end sub
3740
3831
  `);
@@ -3744,15 +3835,13 @@ describe('BrsFile', () => {
3744
3835
  it('sets invalid on empty callfunc with legacyCallfuncHandling=true', async () => {
3745
3836
  program.options.legacyCallfuncHandling = true;
3746
3837
  await testTranspile(`
3747
- sub main()
3748
- node = invalid
3838
+ sub main(node)
3749
3839
  node@.doSomething()
3750
3840
  m.top.node@.doSomething()
3751
3841
  m.top.node@.doSomething(1)
3752
3842
  end sub
3753
3843
  `, `
3754
- sub main()
3755
- node = invalid
3844
+ sub main(node)
3756
3845
  node.callfunc("doSomething", invalid)
3757
3846
  m.top.node.callfunc("doSomething", invalid)
3758
3847
  m.top.node.callfunc("doSomething", 1)
@@ -3761,15 +3850,13 @@ describe('BrsFile', () => {
3761
3850
  });
3762
3851
  it('empty callfunc allowed by default', async () => {
3763
3852
  await testTranspile(`
3764
- sub main()
3765
- node = invalid
3853
+ sub main(node)
3766
3854
  node@.doSomething()
3767
3855
  m.top.node@.doSomething()
3768
3856
  m.top.node@.doSomething(1)
3769
3857
  end sub
3770
3858
  `, `
3771
- sub main()
3772
- node = invalid
3859
+ sub main(node)
3773
3860
  node.callfunc("doSomething")
3774
3861
  m.top.node.callfunc("doSomething")
3775
3862
  m.top.node.callfunc("doSomething", 1)
@@ -3778,13 +3865,11 @@ describe('BrsFile', () => {
3778
3865
  });
3779
3866
  it('includes original arguments', async () => {
3780
3867
  await testTranspile(`
3781
- sub main()
3782
- node = invalid
3868
+ sub main(node)
3783
3869
  node@.doSomething(1, true, m.top.someVal)
3784
3870
  end sub
3785
3871
  `, `
3786
- sub main()
3787
- node = invalid
3872
+ sub main(node)
3788
3873
  node.callfunc("doSomething", 1, true, m.top.someVal)
3789
3874
  end sub
3790
3875
  `);
@@ -3933,9 +4018,11 @@ describe('BrsFile', () => {
3933
4018
  });
3934
4019
  });
3935
4020
  describe('getTypedef', () => {
3936
- function testTypedef(original, expected) {
3937
- let file = program.setFile('source/main.brs', original);
4021
+ function testTypedef(original, expected, mode = Parser_1.ParseMode.BrighterScript) {
4022
+ const ext = mode === Parser_1.ParseMode.BrighterScript ? 'bs' : 'brs';
4023
+ let file = program.setFile(`source/main.${ext}`, original);
3938
4024
  program.validate();
4025
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(program);
3939
4026
  (0, chai_config_spec_1.expect)(file.getTypedef().trimEnd()).to.eql(expected);
3940
4027
  }
3941
4028
  it('includes namespace on extend class names', () => {
@@ -4008,6 +4095,7 @@ describe('BrsFile', () => {
4008
4095
  `);
4009
4096
  });
4010
4097
  it('includes import statements', () => {
4098
+ program.setFile('source/lib.brs', ``);
4011
4099
  testTypedef(`
4012
4100
  import "pkg:/source/lib.brs"
4013
4101
  `, (0, testHelpers_spec_1.trim) `
@@ -4103,6 +4191,7 @@ describe('BrsFile', () => {
4103
4191
  it('includes class inheritance', () => {
4104
4192
  testTypedef(`
4105
4193
  class Human
4194
+ name
4106
4195
  sub new(name as string)
4107
4196
  m.name = name
4108
4197
  end sub
@@ -4114,6 +4203,7 @@ describe('BrsFile', () => {
4114
4203
  end class
4115
4204
  `, (0, testHelpers_spec_1.trim) `
4116
4205
  class Human
4206
+ public name as dynamic
4117
4207
  sub new(name as string)
4118
4208
  end sub
4119
4209
  end class
@@ -4186,6 +4276,7 @@ describe('BrsFile', () => {
4186
4276
  testTypedef(`
4187
4277
  namespace NameA
4188
4278
  class Human
4279
+ name
4189
4280
  sub new(name as string)
4190
4281
  m.name = name
4191
4282
  end sub
@@ -4201,6 +4292,7 @@ describe('BrsFile', () => {
4201
4292
  `, (0, testHelpers_spec_1.trim) `
4202
4293
  namespace NameA
4203
4294
  class Human
4295
+ public name as dynamic
4204
4296
  sub new(name as string)
4205
4297
  end sub
4206
4298
  end class
@@ -4420,7 +4512,7 @@ describe('BrsFile', () => {
4420
4512
  end function
4421
4513
  `);
4422
4514
  program.validate();
4423
- (0, testHelpers_spec_1.expectDiagnostics)(program, [Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.mismatchedEndCallableKeyword('function', 'sub')), { location: util_1.default.createLocationFromFileRange(file, util_1.default.createRange(2, 12, 2, 19)) }), Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.mismatchedEndCallableKeyword('sub', 'function')), { location: util_1.default.createLocationFromFileRange(file, util_1.default.createRange(4, 12, 4, 24)) })]);
4515
+ (0, testHelpers_spec_1.expectDiagnostics)(program, [Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.closingKeywordMismatch('function', 'sub')), { location: util_1.default.createLocationFromFileRange(file, util_1.default.createRange(2, 12, 2, 19)) }), Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.closingKeywordMismatch('sub', 'function')), { location: util_1.default.createLocationFromFileRange(file, util_1.default.createRange(4, 12, 4, 24)) })]);
4424
4516
  });
4425
4517
  describe('requiredSymbols', () => {
4426
4518
  it('should be empty for a simple file', () => {
@@ -4616,14 +4708,21 @@ describe('BrsFile', () => {
4616
4708
  end class
4617
4709
  `);
4618
4710
  validateFile(mainFile);
4619
- (0, chai_config_spec_1.expect)(mainFile.requiredSymbols.length).to.eq(5);
4711
+ // 'DataKind' is there twice:
4712
+ // - when used as a type
4713
+ // - when DataObject.kind is used
4714
+ (0, chai_config_spec_1.expect)(mainFile.requiredSymbols.length).to.eq(6);
4620
4715
  const requiredTypeChains = mainFile.requiredSymbols.map(x => x.typeChain.map(tc => tc.name).join('.'));
4621
- (0, chai_config_spec_1.expect)(requiredTypeChains).to.have.same.members([
4622
- 'DataKind', 'SubData', 'BaseData', 'DataProcessor', 'ProcessedData'
4716
+ (0, chai_config_spec_1.expect)(Array.from(requiredTypeChains)).to.have.same.members([
4717
+ 'DataKind', 'DataKind', 'SubData', 'BaseData', 'DataProcessor', 'ProcessedData'
4623
4718
  ]);
4624
4719
  const requiredSymbolsFlags = mainFile.requiredSymbols.map(x => x.flags);
4625
4720
  (0, chai_config_spec_1.expect)(requiredSymbolsFlags).to.have.same.members([
4626
- 2 /* SymbolTypeFlag.typetime */, 2 /* SymbolTypeFlag.typetime */, 2 /* SymbolTypeFlag.typetime */, 2 /* SymbolTypeFlag.typetime */, 2 /* SymbolTypeFlag.typetime */
4721
+ 2 /* SymbolTypeFlag.typetime */, 2 /* SymbolTypeFlag.typetime */, 2 /* SymbolTypeFlag.typetime */, 2 /* SymbolTypeFlag.typetime */, 2 /* SymbolTypeFlag.typetime */, 2 /* SymbolTypeFlag.typetime */
4722
+ ]);
4723
+ const requiredSymbolsEndFlags = mainFile.requiredSymbols.map(x => x.endChainFlags);
4724
+ (0, chai_config_spec_1.expect)(requiredSymbolsEndFlags).to.have.same.members([
4725
+ 2 /* SymbolTypeFlag.typetime */, 1 /* SymbolTypeFlag.runtime */, 2 /* SymbolTypeFlag.typetime */, 2 /* SymbolTypeFlag.typetime */, 2 /* SymbolTypeFlag.typetime */, 2 /* SymbolTypeFlag.typetime */
4627
4726
  ]);
4628
4727
  });
4629
4728
  it('includes namespace details', () => {