brighterscript 1.0.0-alpha.1 → 1.0.0-alpha.13

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 (316) hide show
  1. package/CHANGELOG.md +362 -248
  2. package/README.md +2 -2
  3. package/bsconfig.schema.json +1 -1
  4. package/dist/CodeActionUtil.d.ts +11 -2
  5. package/dist/CodeActionUtil.js +17 -3
  6. package/dist/CodeActionUtil.js.map +1 -1
  7. package/dist/CommentFlagProcessor.d.ts +4 -4
  8. package/dist/CommentFlagProcessor.js +5 -3
  9. package/dist/CommentFlagProcessor.js.map +1 -1
  10. package/dist/DependencyGraph.js.map +1 -1
  11. package/dist/DiagnosticCollection.js +2 -2
  12. package/dist/DiagnosticCollection.js.map +1 -1
  13. package/dist/DiagnosticFilterer.js +3 -3
  14. package/dist/DiagnosticFilterer.js.map +1 -1
  15. package/dist/DiagnosticMessages.d.ts +15 -5
  16. package/dist/DiagnosticMessages.js +19 -9
  17. package/dist/DiagnosticMessages.js.map +1 -1
  18. package/dist/LanguageServer.d.ts +11 -10
  19. package/dist/LanguageServer.js +87 -58
  20. package/dist/LanguageServer.js.map +1 -1
  21. package/dist/Logger.d.ts +2 -0
  22. package/dist/Logger.js +5 -3
  23. package/dist/Logger.js.map +1 -1
  24. package/dist/Program.d.ts +76 -46
  25. package/dist/Program.js +254 -180
  26. package/dist/Program.js.map +1 -1
  27. package/dist/ProgramBuilder.d.ts +7 -7
  28. package/dist/ProgramBuilder.js +37 -43
  29. package/dist/ProgramBuilder.js.map +1 -1
  30. package/dist/Scope.d.ts +33 -23
  31. package/dist/Scope.js +222 -147
  32. package/dist/Scope.js.map +1 -1
  33. package/dist/SemanticTokenUtils.d.ts +14 -0
  34. package/dist/SemanticTokenUtils.js +81 -0
  35. package/dist/SemanticTokenUtils.js.map +1 -0
  36. package/dist/SymbolTable.d.ts +9 -3
  37. package/dist/SymbolTable.js +40 -13
  38. package/dist/SymbolTable.js.map +1 -1
  39. package/dist/XmlScope.d.ts +7 -2
  40. package/dist/XmlScope.js +67 -29
  41. package/dist/XmlScope.js.map +1 -1
  42. package/dist/astUtils/AstEditor.d.ts +27 -0
  43. package/dist/astUtils/AstEditor.js +97 -0
  44. package/dist/astUtils/AstEditor.js.map +1 -0
  45. package/dist/astUtils/AstEditor.spec.d.ts +1 -0
  46. package/dist/astUtils/AstEditor.spec.js +133 -0
  47. package/dist/astUtils/AstEditor.spec.js.map +1 -0
  48. package/dist/astUtils/creators.d.ts +15 -1
  49. package/dist/astUtils/creators.js +39 -9
  50. package/dist/astUtils/creators.js.map +1 -1
  51. package/dist/astUtils/creators.spec.js +4 -4
  52. package/dist/astUtils/creators.spec.js.map +1 -1
  53. package/dist/astUtils/index.js +1 -1
  54. package/dist/astUtils/reflection.d.ts +20 -8
  55. package/dist/astUtils/reflection.js +42 -1
  56. package/dist/astUtils/reflection.js.map +1 -1
  57. package/dist/astUtils/reflection.spec.js +115 -115
  58. package/dist/astUtils/reflection.spec.js.map +1 -1
  59. package/dist/astUtils/stackedVisitor.js.map +1 -1
  60. package/dist/astUtils/stackedVisitor.spec.js +13 -13
  61. package/dist/astUtils/stackedVisitor.spec.js.map +1 -1
  62. package/dist/astUtils/visitors.js +1 -1
  63. package/dist/astUtils/visitors.js.map +1 -1
  64. package/dist/astUtils/visitors.spec.js +28 -28
  65. package/dist/astUtils/visitors.spec.js.map +1 -1
  66. package/dist/astUtils/xml.d.ts +4 -3
  67. package/dist/astUtils/xml.js +8 -3
  68. package/dist/astUtils/xml.js.map +1 -1
  69. package/dist/bscPlugin/BscPlugin.d.ts +2 -1
  70. package/dist/bscPlugin/BscPlugin.js +4 -0
  71. package/dist/bscPlugin/BscPlugin.js.map +1 -1
  72. package/dist/bscPlugin/codeActions/CodeActionsProcessor.js +5 -6
  73. package/dist/bscPlugin/codeActions/CodeActionsProcessor.js.map +1 -1
  74. package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js +30 -30
  75. package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js.map +1 -1
  76. package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.d.ts +7 -0
  77. package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.js +63 -0
  78. package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.js.map +1 -0
  79. package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.spec.d.ts +1 -0
  80. package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.spec.js +45 -0
  81. package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.spec.js.map +1 -0
  82. package/dist/diagnosticUtils.d.ts +1 -0
  83. package/dist/diagnosticUtils.js +14 -7
  84. package/dist/diagnosticUtils.js.map +1 -1
  85. package/dist/examples/plugins/removePrint.js +2 -2
  86. package/dist/examples/plugins/removePrint.js.map +1 -1
  87. package/dist/files/BrsFile.Class.spec.js +486 -71
  88. package/dist/files/BrsFile.Class.spec.js.map +1 -1
  89. package/dist/files/BrsFile.d.ts +48 -23
  90. package/dist/files/BrsFile.js +403 -233
  91. package/dist/files/BrsFile.js.map +1 -1
  92. package/dist/files/BrsFile.spec.js +367 -316
  93. package/dist/files/BrsFile.spec.js.map +1 -1
  94. package/dist/files/XmlFile.d.ts +13 -6
  95. package/dist/files/XmlFile.js +27 -21
  96. package/dist/files/XmlFile.js.map +1 -1
  97. package/dist/files/XmlFile.spec.js +274 -228
  98. package/dist/files/XmlFile.spec.js.map +1 -1
  99. package/dist/files/tests/imports.spec.js +49 -49
  100. package/dist/files/tests/imports.spec.js.map +1 -1
  101. package/dist/globalCallables.d.ts +3 -1
  102. package/dist/globalCallables.js +359 -87
  103. package/dist/globalCallables.js.map +1 -1
  104. package/dist/index.js +2 -1
  105. package/dist/index.js.map +1 -1
  106. package/dist/interfaces.d.ts +51 -14
  107. package/dist/lexer/Lexer.d.ts +14 -1
  108. package/dist/lexer/Lexer.js +91 -21
  109. package/dist/lexer/Lexer.js.map +1 -1
  110. package/dist/lexer/Lexer.spec.js +187 -132
  111. package/dist/lexer/Lexer.spec.js.map +1 -1
  112. package/dist/lexer/Token.d.ts +2 -2
  113. package/dist/lexer/TokenKind.d.ts +7 -1
  114. package/dist/lexer/TokenKind.js +51 -3
  115. package/dist/lexer/TokenKind.js.map +1 -1
  116. package/dist/lexer/index.js +2 -1
  117. package/dist/lexer/index.js.map +1 -1
  118. package/dist/parser/BrsTranspileState.d.ts +7 -0
  119. package/dist/parser/BrsTranspileState.js +10 -1
  120. package/dist/parser/BrsTranspileState.js.map +1 -1
  121. package/dist/parser/Expression.d.ts +23 -5
  122. package/dist/parser/Expression.js +124 -75
  123. package/dist/parser/Expression.js.map +1 -1
  124. package/dist/parser/Parser.Class.spec.js +159 -60
  125. package/dist/parser/Parser.Class.spec.js.map +1 -1
  126. package/dist/parser/Parser.d.ts +114 -26
  127. package/dist/parser/Parser.js +471 -126
  128. package/dist/parser/Parser.js.map +1 -1
  129. package/dist/parser/Parser.spec.js +396 -235
  130. package/dist/parser/Parser.spec.js.map +1 -1
  131. package/dist/parser/SGParser.d.ts +41 -4
  132. package/dist/parser/SGParser.js +186 -175
  133. package/dist/parser/SGParser.js.map +1 -1
  134. package/dist/parser/SGParser.spec.js +35 -22
  135. package/dist/parser/SGParser.spec.js.map +1 -1
  136. package/dist/parser/SGTypes.d.ts +206 -38
  137. package/dist/parser/SGTypes.js +470 -161
  138. package/dist/parser/SGTypes.js.map +1 -1
  139. package/dist/parser/SGTypes.spec.d.ts +1 -0
  140. package/dist/parser/SGTypes.spec.js +351 -0
  141. package/dist/parser/SGTypes.spec.js.map +1 -0
  142. package/dist/parser/Statement.d.ts +92 -18
  143. package/dist/parser/Statement.js +287 -58
  144. package/dist/parser/Statement.js.map +1 -1
  145. package/dist/parser/Statement.spec.js +11 -11
  146. package/dist/parser/Statement.spec.js.map +1 -1
  147. package/dist/parser/TranspileState.d.ts +1 -1
  148. package/dist/parser/TranspileState.js +15 -7
  149. package/dist/parser/TranspileState.js.map +1 -1
  150. package/dist/parser/index.js +1 -1
  151. package/dist/parser/tests/Parser.spec.d.ts +8 -7
  152. package/dist/parser/tests/Parser.spec.js +12 -8
  153. package/dist/parser/tests/Parser.spec.js.map +1 -1
  154. package/dist/parser/tests/controlFlow/For.spec.js +50 -50
  155. package/dist/parser/tests/controlFlow/For.spec.js.map +1 -1
  156. package/dist/parser/tests/controlFlow/ForEach.spec.js +31 -31
  157. package/dist/parser/tests/controlFlow/ForEach.spec.js.map +1 -1
  158. package/dist/parser/tests/controlFlow/If.spec.js +174 -156
  159. package/dist/parser/tests/controlFlow/If.spec.js.map +1 -1
  160. package/dist/parser/tests/controlFlow/While.spec.js +32 -32
  161. package/dist/parser/tests/controlFlow/While.spec.js.map +1 -1
  162. package/dist/parser/tests/expression/Additive.spec.js +21 -21
  163. package/dist/parser/tests/expression/Additive.spec.js.map +1 -1
  164. package/dist/parser/tests/expression/ArrayLiterals.spec.js +105 -105
  165. package/dist/parser/tests/expression/ArrayLiterals.spec.js.map +1 -1
  166. package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js +148 -124
  167. package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js.map +1 -1
  168. package/dist/parser/tests/expression/Boolean.spec.js +17 -17
  169. package/dist/parser/tests/expression/Boolean.spec.js.map +1 -1
  170. package/dist/parser/tests/expression/Call.spec.js +30 -30
  171. package/dist/parser/tests/expression/Call.spec.js.map +1 -1
  172. package/dist/parser/tests/expression/Exponential.spec.js +16 -16
  173. package/dist/parser/tests/expression/Exponential.spec.js.map +1 -1
  174. package/dist/parser/tests/expression/Function.spec.js +247 -247
  175. package/dist/parser/tests/expression/Function.spec.js.map +1 -1
  176. package/dist/parser/tests/expression/Indexing.spec.js +73 -73
  177. package/dist/parser/tests/expression/Indexing.spec.js.map +1 -1
  178. package/dist/parser/tests/expression/Multiplicative.spec.js +36 -36
  179. package/dist/parser/tests/expression/Multiplicative.spec.js.map +1 -1
  180. package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js +59 -47
  181. package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js.map +1 -1
  182. package/dist/parser/tests/expression/PrefixUnary.spec.js +35 -35
  183. package/dist/parser/tests/expression/PrefixUnary.spec.js.map +1 -1
  184. package/dist/parser/tests/expression/Primary.spec.js +26 -26
  185. package/dist/parser/tests/expression/Primary.spec.js.map +1 -1
  186. package/dist/parser/tests/expression/RegexLiteralExpression.spec.d.ts +1 -0
  187. package/dist/parser/tests/expression/RegexLiteralExpression.spec.js +170 -0
  188. package/dist/parser/tests/expression/RegexLiteralExpression.spec.js.map +1 -0
  189. package/dist/parser/tests/expression/Relational.spec.js +42 -42
  190. package/dist/parser/tests/expression/Relational.spec.js.map +1 -1
  191. package/dist/parser/tests/expression/SourceLiteralExpression.spec.js +8 -8
  192. package/dist/parser/tests/expression/SourceLiteralExpression.spec.js.map +1 -1
  193. package/dist/parser/tests/expression/TemplateStringExpression.spec.js +12 -12
  194. package/dist/parser/tests/expression/TemplateStringExpression.spec.js.map +1 -1
  195. package/dist/parser/tests/expression/TernaryExpression.spec.js +100 -100
  196. package/dist/parser/tests/expression/TernaryExpression.spec.js.map +1 -1
  197. package/dist/parser/tests/statement/AssignmentOperators.spec.js +35 -35
  198. package/dist/parser/tests/statement/AssignmentOperators.spec.js.map +1 -1
  199. package/dist/parser/tests/statement/Declaration.spec.js +39 -39
  200. package/dist/parser/tests/statement/Declaration.spec.js.map +1 -1
  201. package/dist/parser/tests/statement/Dim.spec.js +21 -21
  202. package/dist/parser/tests/statement/Dim.spec.js.map +1 -1
  203. package/dist/parser/tests/statement/Function.spec.js +192 -192
  204. package/dist/parser/tests/statement/Function.spec.js.map +1 -1
  205. package/dist/parser/tests/statement/Goto.spec.js +11 -11
  206. package/dist/parser/tests/statement/Goto.spec.js.map +1 -1
  207. package/dist/parser/tests/statement/Increment.spec.js +46 -46
  208. package/dist/parser/tests/statement/Increment.spec.js.map +1 -1
  209. package/dist/parser/tests/statement/InterfaceStatement.spec.d.ts +1 -0
  210. package/dist/parser/tests/statement/InterfaceStatement.spec.js +61 -0
  211. package/dist/parser/tests/statement/InterfaceStatement.spec.js.map +1 -0
  212. package/dist/parser/tests/statement/LibraryStatement.spec.js +10 -10
  213. package/dist/parser/tests/statement/LibraryStatement.spec.js.map +1 -1
  214. package/dist/parser/tests/statement/Misc.spec.js +37 -36
  215. package/dist/parser/tests/statement/Misc.spec.js.map +1 -1
  216. package/dist/parser/tests/statement/PrintStatement.spec.js +30 -30
  217. package/dist/parser/tests/statement/PrintStatement.spec.js.map +1 -1
  218. package/dist/parser/tests/statement/ReturnStatement.spec.js +43 -43
  219. package/dist/parser/tests/statement/ReturnStatement.spec.js.map +1 -1
  220. package/dist/parser/tests/statement/Set.spec.js +69 -69
  221. package/dist/parser/tests/statement/Set.spec.js.map +1 -1
  222. package/dist/parser/tests/statement/Stop.spec.js +9 -9
  223. package/dist/parser/tests/statement/Stop.spec.js.map +1 -1
  224. package/dist/parser/tests/statement/Throw.spec.js +5 -5
  225. package/dist/parser/tests/statement/Throw.spec.js.map +1 -1
  226. package/dist/parser/tests/statement/TryCatch.spec.js +13 -13
  227. package/dist/parser/tests/statement/TryCatch.spec.js.map +1 -1
  228. package/dist/preprocessor/Chunk.js.map +1 -1
  229. package/dist/preprocessor/Manifest.d.ts +1 -1
  230. package/dist/preprocessor/Preprocessor.js +1 -1
  231. package/dist/preprocessor/Preprocessor.js.map +1 -1
  232. package/dist/preprocessor/Preprocessor.spec.js +49 -49
  233. package/dist/preprocessor/Preprocessor.spec.js.map +1 -1
  234. package/dist/preprocessor/PreprocessorParser.spec.js +72 -72
  235. package/dist/preprocessor/PreprocessorParser.spec.js.map +1 -1
  236. package/dist/preprocessor/index.js +1 -1
  237. package/dist/types/ArrayType.js +5 -4
  238. package/dist/types/ArrayType.js.map +1 -1
  239. package/dist/types/ArrayType.spec.js +8 -8
  240. package/dist/types/ArrayType.spec.js.map +1 -1
  241. package/dist/types/BooleanType.js +3 -3
  242. package/dist/types/BooleanType.js.map +1 -1
  243. package/dist/types/BooleanType.spec.js +2 -2
  244. package/dist/types/BooleanType.spec.js.map +1 -1
  245. package/dist/types/BscType.d.ts +19 -5
  246. package/dist/types/BscType.js +9 -0
  247. package/dist/types/BscType.js.map +1 -1
  248. package/dist/types/CustomType.d.ts +8 -5
  249. package/dist/types/CustomType.js +17 -6
  250. package/dist/types/CustomType.js.map +1 -1
  251. package/dist/types/DoubleType.js +8 -8
  252. package/dist/types/DoubleType.js.map +1 -1
  253. package/dist/types/DoubleType.spec.js +2 -2
  254. package/dist/types/DoubleType.spec.js.map +1 -1
  255. package/dist/types/DynamicType.js +1 -1
  256. package/dist/types/DynamicType.js.map +1 -1
  257. package/dist/types/DynamicType.spec.js +2 -2
  258. package/dist/types/DynamicType.spec.js.map +1 -1
  259. package/dist/types/FloatType.d.ts +1 -1
  260. package/dist/types/FloatType.js +8 -8
  261. package/dist/types/FloatType.js.map +1 -1
  262. package/dist/types/FloatType.spec.js +2 -2
  263. package/dist/types/FloatType.spec.js.map +1 -1
  264. package/dist/types/FunctionType.d.ts +5 -11
  265. package/dist/types/FunctionType.js +24 -13
  266. package/dist/types/FunctionType.js.map +1 -1
  267. package/dist/types/FunctionType.spec.js +11 -5
  268. package/dist/types/FunctionType.spec.js.map +1 -1
  269. package/dist/types/IntegerType.d.ts +1 -1
  270. package/dist/types/IntegerType.js +8 -8
  271. package/dist/types/IntegerType.js.map +1 -1
  272. package/dist/types/IntegerType.spec.js +2 -2
  273. package/dist/types/IntegerType.spec.js.map +1 -1
  274. package/dist/types/InterfaceType.d.ts +8 -2
  275. package/dist/types/InterfaceType.js +42 -6
  276. package/dist/types/InterfaceType.js.map +1 -1
  277. package/dist/types/InterfaceType.spec.d.ts +1 -0
  278. package/dist/types/InterfaceType.spec.js +174 -0
  279. package/dist/types/InterfaceType.spec.js.map +1 -0
  280. package/dist/types/InvalidType.js +4 -4
  281. package/dist/types/InvalidType.js.map +1 -1
  282. package/dist/types/InvalidType.spec.js +2 -2
  283. package/dist/types/InvalidType.spec.js.map +1 -1
  284. package/dist/types/LazyType.d.ts +9 -7
  285. package/dist/types/LazyType.js +22 -10
  286. package/dist/types/LazyType.js.map +1 -1
  287. package/dist/types/LongIntegerType.d.ts +1 -1
  288. package/dist/types/LongIntegerType.js +8 -8
  289. package/dist/types/LongIntegerType.js.map +1 -1
  290. package/dist/types/LongIntegerType.spec.js +2 -2
  291. package/dist/types/LongIntegerType.spec.js.map +1 -1
  292. package/dist/types/ObjectType.d.ts +7 -4
  293. package/dist/types/ObjectType.js +6 -3
  294. package/dist/types/ObjectType.js.map +1 -1
  295. package/dist/types/ObjectType.spec.js +2 -2
  296. package/dist/types/ObjectType.spec.js.map +1 -1
  297. package/dist/types/StringType.js +3 -3
  298. package/dist/types/StringType.js.map +1 -1
  299. package/dist/types/StringType.spec.js +2 -2
  300. package/dist/types/StringType.spec.js.map +1 -1
  301. package/dist/types/UninitializedType.js +3 -3
  302. package/dist/types/UninitializedType.js.map +1 -1
  303. package/dist/types/VoidType.js +3 -3
  304. package/dist/types/VoidType.js.map +1 -1
  305. package/dist/types/VoidType.spec.js +2 -2
  306. package/dist/types/VoidType.spec.js.map +1 -1
  307. package/dist/types/helpers.d.ts +42 -0
  308. package/dist/types/helpers.js +113 -0
  309. package/dist/types/helpers.js.map +1 -0
  310. package/dist/util.d.ts +77 -17
  311. package/dist/util.js +247 -59
  312. package/dist/util.js.map +1 -1
  313. package/dist/validators/ClassValidator.d.ts +5 -1
  314. package/dist/validators/ClassValidator.js +59 -24
  315. package/dist/validators/ClassValidator.js.map +1 -1
  316. package/package.json +13 -13
@@ -11,12 +11,13 @@ const util_1 = require("../util");
11
11
  const fsExtra = require("fs-extra");
12
12
  const BrsTranspileState_1 = require("../parser/BrsTranspileState");
13
13
  const assert_1 = require("assert");
14
+ const reflection_1 = require("../astUtils/reflection");
14
15
  let sinon = sinonImport.createSandbox();
15
16
  describe('BrsFile BrighterScript classes', () => {
16
- let tmpPath = util_1.standardizePath `${process.cwd()}/.tmp`;
17
- let rootDir = util_1.standardizePath `${tmpPath}/rootDir`;
17
+ let tmpPath = (0, util_1.standardizePath) `${process.cwd()}/.tmp`;
18
+ let rootDir = (0, util_1.standardizePath) `${tmpPath}/rootDir`;
18
19
  let program;
19
- let testTranspile = testHelpers_spec_1.getTestTranspile(() => [program, rootDir]);
20
+ let testTranspile = (0, testHelpers_spec_1.getTestTranspile)(() => [program, rootDir]);
20
21
  beforeEach(() => {
21
22
  fsExtra.ensureDirSync(rootDir);
22
23
  fsExtra.emptyDirSync(tmpPath);
@@ -29,10 +30,10 @@ describe('BrsFile BrighterScript classes', () => {
29
30
  fsExtra.emptyDirSync(tmpPath);
30
31
  });
31
32
  function addFile(relativePath, text) {
32
- return program.addOrReplaceFile({ src: `${rootDir}/${relativePath}`, dest: relativePath }, text);
33
+ return program.setFile({ src: `${rootDir}/${relativePath}`, dest: relativePath }, text);
33
34
  }
34
35
  it('detects all classes after parse', () => {
35
- let file = program.addOrReplaceFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
36
+ let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
36
37
  class Animal
37
38
  end class
38
39
  class Duck
@@ -40,10 +41,10 @@ describe('BrsFile BrighterScript classes', () => {
40
41
 
41
42
  end class
42
43
  `);
43
- chai_1.expect(file.parser.references.classStatements.map(x => x.getName(Parser_1.ParseMode.BrighterScript)).sort()).to.eql(['Animal', 'Duck']);
44
+ (0, chai_1.expect)(file.parser.references.classStatements.map(x => x.getName(Parser_1.ParseMode.BrighterScript)).sort()).to.eql(['Animal', 'Duck']);
44
45
  });
45
46
  it('does not cause errors with incomplete class statement', () => {
46
- program.addOrReplaceFile({ src: `${rootDir}/source/main.bs`, dest: 'source/main.bs' }, `
47
+ program.setFile({ src: `${rootDir}/source/main.bs`, dest: 'source/main.bs' }, `
47
48
  class
48
49
  `);
49
50
  program.validate();
@@ -51,7 +52,7 @@ describe('BrsFile BrighterScript classes', () => {
51
52
  });
52
53
  it('catches child class missing super call in constructor', () => {
53
54
  var _a;
54
- program.addOrReplaceFile({ src: `${rootDir}/source/main.bs`, dest: 'source/main.bs' }, `
55
+ program.setFile({ src: `${rootDir}/source/main.bs`, dest: 'source/main.bs' }, `
55
56
  class Person
56
57
  sub new()
57
58
  end sub
@@ -62,11 +63,11 @@ describe('BrsFile BrighterScript classes', () => {
62
63
  end class
63
64
  `);
64
65
  program.validate();
65
- chai_1.expect((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.classConstructorMissingSuperCall().message);
66
+ (0, chai_1.expect)((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.classConstructorMissingSuperCall().message);
66
67
  });
67
68
  it('access modifier is option for override', () => {
68
69
  var _a;
69
- let file = program.addOrReplaceFile({ src: `${rootDir}/source/main.bs`, dest: 'source/main.bs' }, `
70
+ let file = program.setFile({ src: `${rootDir}/source/main.bs`, dest: 'source/main.bs' }, `
70
71
  class Animal
71
72
  sub move()
72
73
  end sub
@@ -78,14 +79,14 @@ describe('BrsFile BrighterScript classes', () => {
78
79
  end class
79
80
  `);
80
81
  program.validate();
81
- chai_1.expect((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
82
+ (0, chai_1.expect)((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
82
83
  let duckClass = file.parser.references.classStatements.find(x => x.name.text.toLowerCase() === 'duck');
83
- chai_1.expect(duckClass).to.exist;
84
- chai_1.expect(duckClass.memberMap['move']).to.exist;
84
+ (0, chai_1.expect)(duckClass).to.exist;
85
+ (0, chai_1.expect)(duckClass.memberMap['move']).to.exist;
85
86
  });
86
87
  it('supports various namespace configurations', () => {
87
88
  var _a;
88
- program.addOrReplaceFile({ src: `${rootDir}/source/main.bs`, dest: 'source/main.bs' }, `
89
+ program.setFile({ src: `${rootDir}/source/main.bs`, dest: 'source/main.bs' }, `
89
90
  class Animal
90
91
  sub new()
91
92
  bigBird = new Birds.Bird()
@@ -105,12 +106,12 @@ describe('BrsFile BrighterScript classes', () => {
105
106
  end namespace
106
107
  `);
107
108
  program.validate();
108
- chai_1.expect((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
109
+ (0, chai_1.expect)((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
109
110
  });
110
111
  describe('super', () => {
111
112
  it('always requires super call in child constructor', () => {
112
113
  var _a;
113
- program.addOrReplaceFile('source/main.bs', `
114
+ program.setFile('source/main.bs', `
114
115
  class Bird
115
116
  end class
116
117
  class Duck extends Bird
@@ -119,11 +120,11 @@ describe('BrsFile BrighterScript classes', () => {
119
120
  end class
120
121
  `);
121
122
  program.validate();
122
- chai_1.expect((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).to.eql(DiagnosticMessages_1.DiagnosticMessages.classConstructorMissingSuperCall().message);
123
+ (0, chai_1.expect)((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).to.eql(DiagnosticMessages_1.DiagnosticMessages.classConstructorMissingSuperCall().message);
123
124
  });
124
125
  it('requires super call in child when parent has own `new` method', () => {
125
126
  var _a;
126
- program.addOrReplaceFile('source/main.bs', `
127
+ program.setFile('source/main.bs', `
127
128
  class Bird
128
129
  sub new()
129
130
  end sub
@@ -134,11 +135,11 @@ describe('BrsFile BrighterScript classes', () => {
134
135
  end class
135
136
  `);
136
137
  program.validate();
137
- chai_1.expect((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).to.eql(DiagnosticMessages_1.DiagnosticMessages.classConstructorMissingSuperCall().message);
138
+ (0, chai_1.expect)((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).to.eql(DiagnosticMessages_1.DiagnosticMessages.classConstructorMissingSuperCall().message);
138
139
  });
139
140
  it('allows non-`m` expressions and statements before the super call', () => {
140
141
  var _a;
141
- program.addOrReplaceFile('source/main.bs', `
142
+ program.setFile('source/main.bs', `
142
143
  class Bird
143
144
  sub new(name)
144
145
  end sub
@@ -153,10 +154,10 @@ describe('BrsFile BrighterScript classes', () => {
153
154
  end class
154
155
  `);
155
156
  program.validate();
156
- chai_1.expect((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).to.be.undefined;
157
+ (0, chai_1.expect)((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).to.be.undefined;
157
158
  });
158
159
  it('allows non-`m` expressions and statements before the super call', () => {
159
- program.addOrReplaceFile('source/main.bs', `
160
+ program.setFile('source/main.bs', `
160
161
  class Bird
161
162
  sub new(name)
162
163
  end sub
@@ -164,12 +165,12 @@ describe('BrsFile BrighterScript classes', () => {
164
165
  class Duck extends Bird
165
166
  sub new()
166
167
  m.name = m.name + "Duck"
167
- super()
168
+ super(m.name)
168
169
  end sub
169
170
  end class
170
171
  `);
171
172
  program.validate();
172
- chai_1.expect(program.getDiagnostics().map(x => ({ message: x.message, range: x.range }))).to.eql([{
173
+ (0, chai_1.expect)(program.getDiagnostics().map(x => ({ message: x.message, range: x.range }))).to.eql([{
173
174
  message: DiagnosticMessages_1.DiagnosticMessages.classConstructorIllegalUseOfMBeforeSuperCall().message,
174
175
  range: vscode_languageserver_1.Range.create(7, 24, 7, 25)
175
176
  }, {
@@ -357,6 +358,9 @@ describe('BrsFile BrighterScript classes', () => {
357
358
  class Animal
358
359
  sub new(name as string)
359
360
  end sub
361
+
362
+ sub DoSomething()
363
+ end sub
360
364
  end class
361
365
 
362
366
  class Duck extends Animal
@@ -370,6 +374,8 @@ describe('BrsFile BrighterScript classes', () => {
370
374
  instance = {}
371
375
  instance.new = sub(name as string)
372
376
  end sub
377
+ instance.DoSomething = sub()
378
+ end sub
373
379
  return instance
374
380
  end function
375
381
  function Animal(name as string)
@@ -661,7 +667,7 @@ describe('BrsFile BrighterScript classes', () => {
661
667
  });
662
668
  it('detects using `new` keyword on non-classes', () => {
663
669
  var _a;
664
- program.addOrReplaceFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
670
+ program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
665
671
  sub quack()
666
672
  end sub
667
673
  sub main()
@@ -669,11 +675,11 @@ describe('BrsFile BrighterScript classes', () => {
669
675
  end sub
670
676
  `);
671
677
  program.validate();
672
- chai_1.expect((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.expressionIsNotConstructable('sub').message);
678
+ (0, chai_1.expect)((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.expressionIsNotConstructable('sub').message);
673
679
  });
674
680
  it('detects missing call to super', () => {
675
681
  var _a;
676
- program.addOrReplaceFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
682
+ program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
677
683
  class Animal
678
684
  sub new()
679
685
  end sub
@@ -684,11 +690,11 @@ describe('BrsFile BrighterScript classes', () => {
684
690
  end class
685
691
  `);
686
692
  program.validate();
687
- chai_1.expect((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.classConstructorMissingSuperCall().message);
693
+ (0, chai_1.expect)((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.classConstructorMissingSuperCall().message);
688
694
  });
689
695
  it.skip('detects calls to unknown m methods', () => {
690
696
  var _a;
691
- program.addOrReplaceFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
697
+ program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
692
698
  class Animal
693
699
  sub new()
694
700
  m.methodThatDoesNotExist()
@@ -696,10 +702,10 @@ describe('BrsFile BrighterScript classes', () => {
696
702
  end class
697
703
  `);
698
704
  program.validate();
699
- chai_1.expect((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.methodDoesNotExistOnType('methodThatDoesNotExist', 'Animal'));
705
+ (0, chai_1.expect)((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.methodDoesNotExistOnType('methodThatDoesNotExist', 'Animal'));
700
706
  });
701
707
  it('detects duplicate member names', () => {
702
- program.addOrReplaceFile({ src: `${rootDir}/source/main.bs`, dest: 'source/main.bs' }, `
708
+ program.setFile({ src: `${rootDir}/source/main.bs`, dest: 'source/main.bs' }, `
703
709
  class Animal
704
710
  public name
705
711
  public name
@@ -721,10 +727,10 @@ describe('BrsFile BrighterScript classes', () => {
721
727
  severity: vscode_languageserver_1.DiagnosticSeverity.Error
722
728
  };
723
729
  });
724
- chai_1.expect(diagnostics).to.eql([Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.duplicateIdentifier('name')), { range: vscode_languageserver_1.Range.create(3, 23, 3, 27) }), Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.duplicateIdentifier('name')), { range: vscode_languageserver_1.Range.create(4, 27, 4, 31) }), Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.duplicateIdentifier('age')), { range: vscode_languageserver_1.Range.create(8, 27, 8, 30) }), Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.duplicateIdentifier('age')), { range: vscode_languageserver_1.Range.create(10, 23, 10, 26) })]);
730
+ (0, chai_1.expect)(diagnostics).to.eql([Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.duplicateIdentifier('name')), { range: vscode_languageserver_1.Range.create(3, 23, 3, 27) }), Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.duplicateIdentifier('name')), { range: vscode_languageserver_1.Range.create(4, 27, 4, 31) }), Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.duplicateIdentifier('age')), { range: vscode_languageserver_1.Range.create(8, 27, 8, 30) }), Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.duplicateIdentifier('age')), { range: vscode_languageserver_1.Range.create(10, 23, 10, 26) })]);
725
731
  });
726
732
  it('detects mismatched member type in child class', () => {
727
- program.addOrReplaceFile({ src: `${rootDir}/source/main.bs`, dest: 'source/main.bs' }, `
733
+ program.setFile({ src: `${rootDir}/source/main.bs`, dest: 'source/main.bs' }, `
728
734
  class Animal
729
735
  public name
730
736
  end class
@@ -735,10 +741,10 @@ describe('BrsFile BrighterScript classes', () => {
735
741
  end class
736
742
  `);
737
743
  program.validate();
738
- chai_1.expect(program.getDiagnostics().map(x => x.message).sort()[0]).to.eql(DiagnosticMessages_1.DiagnosticMessages.classChildMemberDifferentMemberTypeThanAncestor('method', 'field', 'Animal').message);
744
+ (0, chai_1.expect)(program.getDiagnostics().map(x => x.message).sort()[0]).to.eql(DiagnosticMessages_1.DiagnosticMessages.classChildMemberDifferentMemberTypeThanAncestor('method', 'field', 'Animal').message);
739
745
  });
740
- it('detects overridden property name in child class', () => {
741
- program.addOrReplaceFile({ src: `${rootDir}/source/main.bs`, dest: 'source/main.bs' }, `
746
+ it('allows untyped overridden field in child class', () => {
747
+ program.setFile({ src: `${rootDir}/source/main.bs`, dest: 'source/main.bs' }, `
742
748
  class Animal
743
749
  public name
744
750
  end class
@@ -747,13 +753,43 @@ describe('BrsFile BrighterScript classes', () => {
747
753
  end class
748
754
  `);
749
755
  program.validate();
750
- let diagnostics = program.getDiagnostics().map(x => x.message);
751
- chai_1.expect(diagnostics).to.eql([
752
- DiagnosticMessages_1.DiagnosticMessages.memberAlreadyExistsInParentClass('field', 'Animal').message
756
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(program);
757
+ });
758
+ it('allows overridden property name in child class', () => {
759
+ program.setFile('source/main.bs', `
760
+ class Bird
761
+ public name = "bird"
762
+ end class
763
+ class Duck extends Bird
764
+ public name = "duck"
765
+ end class
766
+ `);
767
+ program.validate();
768
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(program);
769
+ });
770
+ it('flags incompatible child field type changes', () => {
771
+ program.setFile('source/main.bs', `
772
+ class Bird
773
+ public age = 12
774
+ public name = "bird"
775
+ public owner as Person
776
+ end class
777
+ class Duck extends Bird
778
+ public age = 12.2 'should be integer but is float
779
+ public name = 12 'should be string but is integer
780
+ public owner as string
781
+ end class
782
+ `);
783
+ program.validate();
784
+ (0, chai_1.expect)(program.getDiagnostics().map(x => x.message).sort()).to.eql([
785
+ DiagnosticMessages_1.DiagnosticMessages.cannotFindType('Person').message,
786
+ DiagnosticMessages_1.DiagnosticMessages.childFieldTypeNotAssignableToBaseProperty('Duck', 'Bird', 'age', 'float', 'integer').message,
787
+ DiagnosticMessages_1.DiagnosticMessages.childFieldTypeNotAssignableToBaseProperty('Duck', 'Bird', 'name', 'integer', 'string').message,
788
+ DiagnosticMessages_1.DiagnosticMessages.childFieldTypeNotAssignableToBaseProperty('Duck', 'Bird', 'owner', 'string', 'Person').message
753
789
  ]);
754
790
  });
755
791
  it('detects overridden methods without override keyword', () => {
756
- program.addOrReplaceFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
792
+ program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
757
793
  class Animal
758
794
  sub speak()
759
795
  end sub
@@ -764,21 +800,67 @@ describe('BrsFile BrighterScript classes', () => {
764
800
  end class
765
801
  `);
766
802
  program.validate();
767
- chai_1.expect(program.getDiagnostics()[0]).to.exist.and.to.include(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.missingOverrideKeyword('Animal')));
803
+ (0, chai_1.expect)(program.getDiagnostics()[0]).to.exist.and.to.include(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.missingOverrideKeyword('Animal')));
804
+ });
805
+ it('detects overridden methods with different visibility', () => {
806
+ program.setFile({ src: `${rootDir}/source/main.bs`, dest: 'source/main.bs' }, `
807
+ class Animal
808
+ sub speakInPublic()
809
+ end sub
810
+ protected sub speakWithFriends()
811
+ end sub
812
+ private sub speakWithFamily()
813
+ end sub
814
+ end class
815
+ class Duck extends Animal
816
+ private override sub speakInPublic()
817
+ end sub
818
+ public override sub speakWithFriends()
819
+ end sub
820
+ override sub speakWithFamily()
821
+ end sub
822
+ end class
823
+ `);
824
+ program.validate();
825
+ (0, chai_1.expect)(program.getDiagnostics()[0]).to.exist.and.to.include(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.mismatchedOverriddenMemberVisibility('Duck', 'speakInPublic', 'private', 'public', 'Animal')));
826
+ (0, chai_1.expect)(program.getDiagnostics()[1]).to.exist.and.to.include(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.mismatchedOverriddenMemberVisibility('Duck', 'speakWithFriends', 'public', 'protected', 'Animal')));
827
+ (0, chai_1.expect)(program.getDiagnostics()[2]).to.exist.and.to.include(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.mismatchedOverriddenMemberVisibility('Duck', 'speakWithFamily', 'public', 'private', 'Animal')));
828
+ });
829
+ it('allows overridden methods with matching visibility', () => {
830
+ program.setFile({ src: `${rootDir}/source/main.bs`, dest: 'source/main.bs' }, `
831
+ class Animal
832
+ sub speakInPublic()
833
+ end sub
834
+ protected sub speakWithFriends()
835
+ end sub
836
+ private sub speakWithFamily()
837
+ end sub
838
+ end class
839
+ class Duck extends Animal
840
+ override sub speakInPublic()
841
+ end sub
842
+ protected override sub speakWithFriends()
843
+ end sub
844
+ private override sub speakWithFamily()
845
+ end sub
846
+ end class
847
+ `);
848
+ program.validate();
849
+ (0, chai_1.expect)(program.getDiagnostics()).to.be.empty;
768
850
  });
769
851
  it('detects extending unknown parent class', () => {
770
- program.addOrReplaceFile('source/main.brs', `
852
+ program.setFile('source/main.brs', `
771
853
  class Duck extends Animal
772
854
  sub speak()
773
855
  end sub
774
856
  end class
775
857
  `);
776
858
  program.validate();
777
- chai_1.expect(program.getDiagnostics()[0]).to.exist.and.to.deep.include(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.classCouldNotBeFound('Animal', 'source')), { range: vscode_languageserver_1.Range.create(1, 31, 1, 37) }));
859
+ (0, chai_1.expect)(program.getDiagnostics()[0]).to.exist.and.to.deep.include(Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.classCouldNotBeFound('Animal', 'source')), { range: vscode_languageserver_1.Range.create(1, 31, 1, 37) }));
778
860
  });
779
861
  it('catches newable class without namespace name', () => {
780
862
  var _a;
781
- program.addOrReplaceFile('source/main.bs', `
863
+ program.setFile('source/main.bs', `
782
864
  namespace NameA.NameB
783
865
  class Duck
784
866
  end class
@@ -789,11 +871,11 @@ describe('BrsFile BrighterScript classes', () => {
789
871
  end sub
790
872
  `);
791
873
  program.validate();
792
- chai_1.expect((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.classCouldNotBeFound('Duck', 'source').message);
874
+ (0, chai_1.expect)((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.classCouldNotBeFound('Duck', 'source').message);
793
875
  });
794
876
  it('supports newable class namespace inference', () => {
795
877
  var _a;
796
- program.addOrReplaceFile({ src: `${rootDir}/source/main.bs`, dest: 'source/main.bs' }, `
878
+ program.setFile({ src: `${rootDir}/source/main.bs`, dest: 'source/main.bs' }, `
797
879
  namespace NameA.NameB
798
880
  class Duck
799
881
  end class
@@ -803,11 +885,11 @@ describe('BrsFile BrighterScript classes', () => {
803
885
  end namespace
804
886
  `);
805
887
  program.validate();
806
- chai_1.expect((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
888
+ (0, chai_1.expect)((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
807
889
  });
808
890
  it('catches extending unknown namespaced class', () => {
809
891
  var _a;
810
- program.addOrReplaceFile({ src: `${rootDir}/source/main.bs`, dest: 'source/main.bs' }, `
892
+ program.setFile({ src: `${rootDir}/source/main.bs`, dest: 'source/main.bs' }, `
811
893
  namespace NameA.NameB
812
894
  class Animal
813
895
  end class
@@ -816,11 +898,11 @@ describe('BrsFile BrighterScript classes', () => {
816
898
  end namespace
817
899
  `);
818
900
  program.validate();
819
- chai_1.expect((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.classCouldNotBeFound('NameA.NameB.Animal1', 'source').message);
901
+ (0, chai_1.expect)((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.classCouldNotBeFound('NameA.NameB.Animal1', 'source').message);
820
902
  });
821
903
  it('supports omitting namespace prefix for items in same namespace', () => {
822
904
  var _a;
823
- program.addOrReplaceFile({ src: `${rootDir}/source/main.bs`, dest: 'source/main.bs' }, `
905
+ program.setFile({ src: `${rootDir}/source/main.bs`, dest: 'source/main.bs' }, `
824
906
  namespace NameA.NameB
825
907
  class Animal
826
908
  end class
@@ -829,21 +911,21 @@ describe('BrsFile BrighterScript classes', () => {
829
911
  end namespace
830
912
  `);
831
913
  program.validate();
832
- chai_1.expect((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
914
+ (0, chai_1.expect)((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
833
915
  });
834
916
  it('catches duplicate root-level class declarations', () => {
835
917
  var _a;
836
- program.addOrReplaceFile({ src: `${rootDir}/source/main.bs`, dest: 'source/main.bs' }, `
918
+ program.setFile({ src: `${rootDir}/source/main.bs`, dest: 'source/main.bs' }, `
837
919
  class Animal
838
920
  end class
839
921
  class Animal
840
922
  `);
841
923
  program.validate();
842
- chai_1.expect((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.duplicateClassDeclaration('source', 'Animal').message);
924
+ (0, chai_1.expect)((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.duplicateClassDeclaration('source', 'Animal').message);
843
925
  });
844
926
  it('catches duplicate namespace-level class declarations', () => {
845
927
  var _a;
846
- program.addOrReplaceFile({ src: `${rootDir}/source/main.bs`, dest: 'source/main.bs' }, `
928
+ program.setFile({ src: `${rootDir}/source/main.bs`, dest: 'source/main.bs' }, `
847
929
  namespace NameA.NameB
848
930
  class Animal
849
931
  end class
@@ -851,11 +933,11 @@ describe('BrsFile BrighterScript classes', () => {
851
933
  end namespace
852
934
  `);
853
935
  program.validate();
854
- chai_1.expect((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.duplicateClassDeclaration('source', 'NameA.NameB.Animal').message);
936
+ (0, chai_1.expect)((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.duplicateClassDeclaration('source', 'NameA.NameB.Animal').message);
855
937
  });
856
938
  it('catches namespaced class name which is the same as a global class', () => {
857
939
  var _a;
858
- program.addOrReplaceFile({ src: `${rootDir}/source/main.bs`, dest: 'source/main.bs' }, `
940
+ program.setFile({ src: `${rootDir}/source/main.bs`, dest: 'source/main.bs' }, `
859
941
  namespace NameA.NameB
860
942
  class Animal
861
943
  end class
@@ -864,33 +946,33 @@ describe('BrsFile BrighterScript classes', () => {
864
946
  end class
865
947
  `);
866
948
  program.validate();
867
- chai_1.expect((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.namespacedClassCannotShareNamewithNonNamespacedClass('Animal').message);
949
+ (0, chai_1.expect)((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.namespacedClassCannotShareNamewithNonNamespacedClass('Animal').message);
868
950
  });
869
951
  it('catches class with same name as function', () => {
870
952
  var _a;
871
- program.addOrReplaceFile('source/main.bs', `
953
+ program.setFile('source/main.bs', `
872
954
  class Animal
873
955
  end class
874
956
  sub Animal()
875
957
  end sub
876
958
  `);
877
959
  program.validate();
878
- chai_1.expect((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.functionCannotHaveSameNameAsClass('Animal').message);
960
+ (0, chai_1.expect)((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.functionCannotHaveSameNameAsClass('Animal').message);
879
961
  });
880
962
  it('catches class with same name (but different case) as function', () => {
881
963
  var _a;
882
- program.addOrReplaceFile('source/main.bs', `
964
+ program.setFile('source/main.bs', `
883
965
  class ANIMAL
884
966
  end class
885
967
  sub animal()
886
968
  end sub
887
969
  `);
888
970
  program.validate();
889
- chai_1.expect((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.functionCannotHaveSameNameAsClass('animal').message);
971
+ (0, chai_1.expect)((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.functionCannotHaveSameNameAsClass('animal').message);
890
972
  });
891
973
  it('catches variable with same name as class', () => {
892
974
  var _a;
893
- program.addOrReplaceFile('source/main.bs', `
975
+ program.setFile('source/main.bs', `
894
976
  class Animal
895
977
  end class
896
978
  sub main()
@@ -898,10 +980,10 @@ describe('BrsFile BrighterScript classes', () => {
898
980
  end sub
899
981
  `);
900
982
  program.validate();
901
- chai_1.expect((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.localVarSameNameAsClass('Animal').message);
983
+ (0, chai_1.expect)((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.localVarSameNameAsClass('Animal').message);
902
984
  });
903
985
  it('allows extending classes with more than one dot in the filename', () => {
904
- program.addOrReplaceFile('source/testclass.bs', `
986
+ program.setFile('source/testclass.bs', `
905
987
  class Foo
906
988
  end class
907
989
 
@@ -911,14 +993,14 @@ describe('BrsFile BrighterScript classes', () => {
911
993
  end sub
912
994
  end class
913
995
  `);
914
- program.addOrReplaceFile('source/testclass_no_testdot.bs', `
996
+ program.setFile('source/testclass_no_testdot.bs', `
915
997
  class BarNoDot extends Foo
916
998
  sub new()
917
999
  super()
918
1000
  end sub
919
1001
  end class
920
1002
  `);
921
- program.addOrReplaceFile('source/testclass.dot.bs', `
1003
+ program.setFile('source/testclass.dot.bs', `
922
1004
  class BarDot extends Foo
923
1005
  sub new()
924
1006
  super()
@@ -926,10 +1008,10 @@ describe('BrsFile BrighterScript classes', () => {
926
1008
  end class
927
1009
  `);
928
1010
  program.validate();
929
- testHelpers_spec_1.expectZeroDiagnostics(program);
1011
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(program);
930
1012
  });
931
1013
  it('computes correct super index for grandchild class', () => {
932
- program.addOrReplaceFile('source/main.bs', `
1014
+ program.setFile('source/main.bs', `
933
1015
  sub Main()
934
1016
  c = new App.ClassC()
935
1017
  end sub
@@ -967,7 +1049,7 @@ describe('BrsFile BrighterScript classes', () => {
967
1049
  `, 'trim', 'source/App.ClassC.bs');
968
1050
  });
969
1051
  it('computes correct super index for namespaced child class and global parent class', () => {
970
- program.addOrReplaceFile('source/ClassA.bs', `
1052
+ program.setFile('source/ClassA.bs', `
971
1053
  class ClassA
972
1054
  end class
973
1055
  `);
@@ -993,13 +1075,346 @@ describe('BrsFile BrighterScript classes', () => {
993
1075
  `, 'trim', 'source/App.ClassB.bs');
994
1076
  });
995
1077
  it('does not crash when parent class is missing', () => {
996
- const file = program.addOrReplaceFile('source/ClassB.bs', `
1078
+ const file = program.setFile('source/ClassB.bs', `
997
1079
  class ClassB extends ClassA
998
1080
  end class
999
1081
  `);
1000
- assert_1.doesNotThrow(() => {
1082
+ (0, assert_1.doesNotThrow)(() => {
1001
1083
  file.parser.references.classStatements[0].getParentClassIndex(new BrsTranspileState_1.BrsTranspileState(file));
1002
1084
  });
1003
1085
  });
1086
+ describe('getHover', () => {
1087
+ const animalClassCode = `
1088
+ class Animal
1089
+ kind as string
1090
+ isHungry as boolean
1091
+
1092
+ sub new(kind as string)
1093
+ m.kind = kind
1094
+ m.isHungry = true ' born hungry
1095
+ end sub
1096
+
1097
+ sub eat(foodAmount as integer)
1098
+ if foodAmount > 100
1099
+ m.isHungry = false
1100
+ end if
1101
+ end sub
1102
+
1103
+ sub sleep()
1104
+ m.isHungry = false
1105
+ end sub
1106
+
1107
+ end class
1108
+
1109
+ class Dog extends Animal
1110
+ breed as string
1111
+ sub new(breed as string)
1112
+ super("Dog")
1113
+ m.breed = breed
1114
+ end sub
1115
+
1116
+ sub snooze()
1117
+ m.sleep()
1118
+ end sub
1119
+ end class
1120
+
1121
+ class DogHouse
1122
+ puppy as Dog
1123
+ sub new(pup as Dog)
1124
+ m.puppy = pup
1125
+ end sub
1126
+ end class
1127
+
1128
+ sub main()
1129
+ snoopy = new Dog("Beagle")
1130
+ biplane = new DogHouse(snoopy)
1131
+ print snoopy.kind ' Dog
1132
+ print snoopy.breed ' Beagle
1133
+ print snoopy.isHungry ' true
1134
+ feedAnimal(biplane.puppy)
1135
+ print snoopy.isHungry ' false
1136
+ end sub
1137
+
1138
+ sub feedAnimal(beast as Animal)
1139
+ beast.eat(100)
1140
+ end sub
1141
+ `;
1142
+ it('correctly parses the file', () => {
1143
+ program.setFile('source/animal.bs', animalClassCode);
1144
+ program.validate();
1145
+ (0, chai_1.expect)(program.getDiagnostics().length).to.equal(0);
1146
+ });
1147
+ it('gets the correct text for m', () => {
1148
+ let animalCode = program.setFile('source/animal.bs', animalClassCode);
1149
+ program.validate();
1150
+ let hover = animalCode.getHover(vscode_languageserver_1.Position.create(6, 17));
1151
+ (0, chai_1.expect)(hover).to.exist;
1152
+ (0, chai_1.expect)(hover.contents).to.equal('m as Animal');
1153
+ hover = animalCode.getHover(vscode_languageserver_1.Position.create(26, 17));
1154
+ (0, chai_1.expect)(hover).to.exist;
1155
+ (0, chai_1.expect)(hover.contents).to.equal('m as Dog');
1156
+ });
1157
+ it('gets the correct text for m.field', () => {
1158
+ let animalCode = program.setFile('source/animal.bs', animalClassCode);
1159
+ program.validate();
1160
+ let hover = animalCode.getHover(vscode_languageserver_1.Position.create(6, 19));
1161
+ (0, chai_1.expect)(hover).to.exist;
1162
+ (0, chai_1.expect)(hover.contents).to.equal('Animal.kind as string');
1163
+ hover = animalCode.getHover(vscode_languageserver_1.Position.create(26, 19));
1164
+ (0, chai_1.expect)(hover).to.exist;
1165
+ (0, chai_1.expect)(hover.contents).to.equal('Dog.breed as string');
1166
+ });
1167
+ it('gets the correct text for m.method', () => {
1168
+ let animalCode = program.setFile('source/animal.bs', animalClassCode);
1169
+ program.validate();
1170
+ let hover = animalCode.getHover(vscode_languageserver_1.Position.create(30, 21));
1171
+ (0, chai_1.expect)(hover).to.exist;
1172
+ (0, chai_1.expect)(hover.contents).to.equal('sub Animal.sleep() as void');
1173
+ });
1174
+ it('gets the correct text for obj.field', () => {
1175
+ let animalCode = program.setFile('source/animal.brs', animalClassCode);
1176
+ program.validate();
1177
+ let hover = animalCode.getHover(vscode_languageserver_1.Position.create(46, 29));
1178
+ (0, chai_1.expect)(hover).to.exist;
1179
+ //TODO TYPES: This should probably say 'Animal.isHungry ...' because that field is defined in Animal
1180
+ (0, chai_1.expect)(hover.contents).to.equal('Dog.isHungry as boolean');
1181
+ });
1182
+ it('gets the correct text for obj.method', () => {
1183
+ let animalCode = program.setFile('source/animal.bs', animalClassCode);
1184
+ program.validate();
1185
+ let hover = animalCode.getHover(vscode_languageserver_1.Position.create(52, 21));
1186
+ (0, chai_1.expect)(hover).to.exist;
1187
+ (0, chai_1.expect)(hover.contents).to.equal('sub Animal.eat(foodAmount as integer) as void');
1188
+ });
1189
+ });
1190
+ describe('getHover class members', () => {
1191
+ const testCode = `
1192
+ class Foo
1193
+ sub new(name as string)
1194
+ end sub
1195
+ end class
1196
+
1197
+ class Bar
1198
+ sub doSomething()
1199
+ myFoo = new Foo()
1200
+ end sub
1201
+
1202
+ function getInt() as integer
1203
+ return 1
1204
+ end function
1205
+ end class
1206
+
1207
+ class Buz
1208
+ myInt as integer
1209
+ sub new(i as integer)
1210
+ myInt = i
1211
+ end sub
1212
+ end class
1213
+
1214
+ class Bee extends Buz
1215
+ sub new(i as integer)
1216
+ super(i)
1217
+ end sub
1218
+
1219
+ sub varSameNameAsMember()
1220
+ myInt = 4567
1221
+ print myInt ' should not print m.myInt
1222
+ end sub
1223
+ end class`;
1224
+ it('correctly parses the file', () => {
1225
+ program.setFile('source/fooBar.bs', testCode);
1226
+ program.validate();
1227
+ (0, chai_1.expect)(program.getDiagnostics().length).to.equal(0);
1228
+ });
1229
+ it('gets the correct text for new Class()', () => {
1230
+ let file = program.setFile('source/fooBar.bs', testCode);
1231
+ program.validate();
1232
+ let hover = file.getHover(vscode_languageserver_1.Position.create(8, 34)); // new Foo("hello")
1233
+ (0, chai_1.expect)(hover).to.exist;
1234
+ (0, chai_1.expect)(hover.contents).to.equal('new Foo(name as string)');
1235
+ });
1236
+ it('gets the correct text for created object', () => {
1237
+ let file = program.setFile('source/fooBar.bs', testCode);
1238
+ program.validate();
1239
+ let hover = file.getHover(vscode_languageserver_1.Position.create(8, 23)); // myFoo
1240
+ (0, chai_1.expect)(hover).to.exist;
1241
+ (0, chai_1.expect)(hover.contents).to.equal('myFoo as Foo');
1242
+ });
1243
+ it('gets the correct text for class declaration', () => {
1244
+ let file = program.setFile('source/fooBar.bs', testCode);
1245
+ program.validate();
1246
+ let hover = file.getHover(vscode_languageserver_1.Position.create(6, 21)); // class Bar
1247
+ (0, chai_1.expect)(hover).to.exist;
1248
+ (0, chai_1.expect)(hover.contents).to.equal('class Bar');
1249
+ });
1250
+ it('gets the correct text for class method declaration', () => {
1251
+ let file = program.setFile('source/fooBar.bs', testCode);
1252
+ program.validate();
1253
+ let hover = file.getHover(vscode_languageserver_1.Position.create(11, 29)); // getInt
1254
+ (0, chai_1.expect)(hover).to.exist;
1255
+ (0, chai_1.expect)(hover.contents).to.equal('function Bar.getInt() as integer');
1256
+ });
1257
+ it('gets the correct text for class field declaration', () => {
1258
+ let file = program.setFile('source/fooBar.bs', testCode);
1259
+ program.validate();
1260
+ let hover = file.getHover(vscode_languageserver_1.Position.create(17, 20)); // myInt
1261
+ (0, chai_1.expect)(hover).to.exist;
1262
+ (0, chai_1.expect)(hover.contents).to.equal('Buz.myInt as integer');
1263
+ });
1264
+ it('gets the correct text for super() call', () => {
1265
+ let file = program.setFile('source/fooBar.bs', testCode);
1266
+ program.validate();
1267
+ let hover = file.getHover(vscode_languageserver_1.Position.create(25, 23)); // super() in Bee.new
1268
+ (0, chai_1.expect)(hover).to.exist;
1269
+ (0, chai_1.expect)(hover.contents).to.equal('new Buz(i as integer)');
1270
+ });
1271
+ it('gets the correct text for variable with same name as a member', () => {
1272
+ let file = program.setFile('source/fooBar.bs', testCode);
1273
+ program.validate();
1274
+ let hover = file.getHover(vscode_languageserver_1.Position.create(29, 23)); // myInt in Bee.varSameNameAsMember
1275
+ (0, chai_1.expect)(hover).to.exist;
1276
+ (0, chai_1.expect)(hover.contents).to.equal('myInt as integer');
1277
+ });
1278
+ });
1279
+ describe('getSymbolTypeFromToken', () => {
1280
+ const testClassCode = `
1281
+ class KlassA
1282
+ function getInt() as integer
1283
+ return 1
1284
+ end function
1285
+
1286
+ sub printInt(i as integer)
1287
+ print i
1288
+ end sub
1289
+ end class
1290
+
1291
+ class KlassB
1292
+
1293
+ function getA() as KlassA
1294
+ return new KlassA()
1295
+ end function
1296
+ end class
1297
+
1298
+ class KlassC
1299
+ public b as KlassB
1300
+
1301
+ sub new()
1302
+ m.b = new KlassB()
1303
+ end sub
1304
+ end class
1305
+
1306
+ sub main()
1307
+ c = new KlassC()
1308
+ a = c.b.getA()
1309
+ num = c.b.getA().getInt()
1310
+ c.b.getA().printInt(num)
1311
+ end sub
1312
+ `;
1313
+ it('correctly parses the file', () => {
1314
+ program.setFile('source/klassTest.bs', testClassCode);
1315
+ program.validate();
1316
+ (0, chai_1.expect)(program.getDiagnostics().length).to.equal(0);
1317
+ });
1318
+ describe('finding tokens', () => {
1319
+ let klassCode;
1320
+ let mainScope;
1321
+ beforeEach(() => {
1322
+ klassCode = program.setFile('source/klassTest.bs', testClassCode);
1323
+ const scopes = program.getScopesForFile(klassCode);
1324
+ (0, chai_1.expect)(scopes.length).to.eql(1);
1325
+ mainScope = scopes[0];
1326
+ mainScope.linkSymbolTable();
1327
+ });
1328
+ afterEach(() => {
1329
+ mainScope.unlinkSymbolTable();
1330
+ });
1331
+ it('gets correct class for m', () => {
1332
+ var _a;
1333
+ const position = vscode_languageserver_1.Position.create(22, 17); // 'm' from m.b = new KlassB()
1334
+ const token = klassCode.parser.getTokenAt(position);
1335
+ (0, chai_1.expect)(token.text).to.equal('m');
1336
+ const func = klassCode.getFunctionExpressionAtPosition(position);
1337
+ let klass = (_a = klassCode.getClassFromToken(token, func, mainScope)) === null || _a === void 0 ? void 0 : _a.item;
1338
+ (0, chai_1.expect)(klass).to.exist;
1339
+ (0, chai_1.expect)(klass.getName(Parser_1.ParseMode.BrighterScript)).to.equal('KlassC');
1340
+ });
1341
+ it('gets correct class for fieldMember', () => {
1342
+ var _a;
1343
+ const position = vscode_languageserver_1.Position.create(22, 19); // 'b' from m.b = new KlassB()
1344
+ const token = klassCode.parser.getTokenAt(position);
1345
+ (0, chai_1.expect)(token.text).to.equal('b');
1346
+ const func = klassCode.getFunctionExpressionAtPosition(position);
1347
+ let klass = (_a = klassCode.getClassFromToken(token, func, mainScope)) === null || _a === void 0 ? void 0 : _a.item;
1348
+ (0, chai_1.expect)(klass).to.exist;
1349
+ (0, chai_1.expect)(klass.getName(Parser_1.ParseMode.BrighterScript)).to.equal('KlassB');
1350
+ });
1351
+ it('gets correct class for variable', () => {
1352
+ var _a;
1353
+ const position = vscode_languageserver_1.Position.create(28, 17); // 'c' from c.b.getA().getInt()
1354
+ const token = klassCode.parser.getTokenAt(position);
1355
+ (0, chai_1.expect)(token.text).to.equal('c');
1356
+ const func = klassCode.getFunctionExpressionAtPosition(position);
1357
+ let klass = (_a = klassCode.getClassFromToken(token, func, mainScope)) === null || _a === void 0 ? void 0 : _a.item;
1358
+ (0, chai_1.expect)(klass).to.exist;
1359
+ (0, chai_1.expect)(klass.getName(Parser_1.ParseMode.BrighterScript)).to.equal('KlassC');
1360
+ });
1361
+ it('gets correct class for variable field', () => {
1362
+ var _a;
1363
+ const position = vscode_languageserver_1.Position.create(28, 19); // 'b' from c.b.getA()
1364
+ const token = klassCode.parser.getTokenAt(position);
1365
+ (0, chai_1.expect)(token.text).to.equal('b');
1366
+ const func = klassCode.getFunctionExpressionAtPosition(position);
1367
+ let klass = (_a = klassCode.getClassFromToken(token, func, mainScope)) === null || _a === void 0 ? void 0 : _a.item;
1368
+ (0, chai_1.expect)(klass).to.exist;
1369
+ (0, chai_1.expect)(klass.getName(Parser_1.ParseMode.BrighterScript)).to.equal('KlassB');
1370
+ });
1371
+ it('gets type and return class for variable function field', () => {
1372
+ const position = vscode_languageserver_1.Position.create(28, 23); // 'getA' from c.b.getA()
1373
+ const token = klassCode.parser.getTokenAt(position);
1374
+ (0, chai_1.expect)(token.text).to.equal('getA');
1375
+ const func = klassCode.getFunctionExpressionAtPosition(position);
1376
+ let { type, symbolContainer } = klassCode.getSymbolTypeFromToken(token, func, mainScope);
1377
+ (0, chai_1.expect)(type).to.exist;
1378
+ (0, chai_1.expect)((0, reflection_1.isFunctionType)(type)).to.be.true;
1379
+ (0, chai_1.expect)(symbolContainer).to.exist;
1380
+ (0, chai_1.expect)((0, reflection_1.isCustomType)(symbolContainer)).to.be.true;
1381
+ (0, chai_1.expect)(symbolContainer.name).to.equal('KlassA');
1382
+ });
1383
+ it('gets type and class for field from return value of function', () => {
1384
+ const position = vscode_languageserver_1.Position.create(29, 30); // 'getInt' from c.b.getA().getInt()
1385
+ const token = klassCode.parser.getTokenAt(position);
1386
+ (0, chai_1.expect)(token.text).to.equal('getInt');
1387
+ const func = klassCode.getFunctionExpressionAtPosition(position);
1388
+ let { type, symbolContainer } = klassCode.getSymbolTypeFromToken(token, func, mainScope);
1389
+ (0, chai_1.expect)(type).to.exist;
1390
+ (0, chai_1.expect)((0, reflection_1.isFunctionType)(type)).to.be.true;
1391
+ (0, chai_1.expect)(symbolContainer).to.be.undefined; // getInt() returns integer - no class reference at this point
1392
+ });
1393
+ });
1394
+ });
1395
+ it('does not crash when child has field with same name as sub in parent', () => {
1396
+ program.setFile('source/main.bs', `
1397
+ class Parent
1398
+ public function helloWorld()
1399
+ end function
1400
+ end class
1401
+ class Child extends Parent
1402
+ public helloWorld as string
1403
+ end class
1404
+ `);
1405
+ program.validate();
1406
+ });
1407
+ it('does not crash when child has method with same name as field in parent', () => {
1408
+ program.setFile('source/main.bs', `
1409
+ class Parent
1410
+ public helloWorld as string
1411
+ end class
1412
+ class Child extends Parent
1413
+ public function helloWorld()
1414
+ end function
1415
+ end class
1416
+ `);
1417
+ program.validate();
1418
+ });
1004
1419
  });
1005
1420
  //# sourceMappingURL=BrsFile.Class.spec.js.map