brighterscript 1.0.0-alpha.2 → 1.0.0-alpha.22

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 (388) hide show
  1. package/CHANGELOG.md +643 -253
  2. package/README.md +33 -9
  3. package/bsconfig.schema.json +22 -2
  4. package/dist/BsConfig.d.ts +9 -0
  5. package/dist/Cache.d.ts +5 -6
  6. package/dist/Cache.js +12 -11
  7. package/dist/Cache.js.map +1 -1
  8. package/dist/CodeActionUtil.d.ts +11 -2
  9. package/dist/CodeActionUtil.js +17 -3
  10. package/dist/CodeActionUtil.js.map +1 -1
  11. package/dist/CommentFlagProcessor.d.ts +4 -4
  12. package/dist/CommentFlagProcessor.js +5 -3
  13. package/dist/CommentFlagProcessor.js.map +1 -1
  14. package/dist/DependencyGraph.d.ts +2 -2
  15. package/dist/DependencyGraph.js +20 -7
  16. package/dist/DependencyGraph.js.map +1 -1
  17. package/dist/DiagnosticCollection.d.ts +3 -3
  18. package/dist/DiagnosticCollection.js +11 -11
  19. package/dist/DiagnosticCollection.js.map +1 -1
  20. package/dist/DiagnosticFilterer.js +5 -4
  21. package/dist/DiagnosticFilterer.js.map +1 -1
  22. package/dist/DiagnosticMessages.d.ts +59 -4
  23. package/dist/DiagnosticMessages.js +65 -7
  24. package/dist/DiagnosticMessages.js.map +1 -1
  25. package/dist/LanguageServer.d.ts +51 -39
  26. package/dist/LanguageServer.js +316 -232
  27. package/dist/LanguageServer.js.map +1 -1
  28. package/dist/Logger.d.ts +2 -0
  29. package/dist/Logger.js +10 -8
  30. package/dist/Logger.js.map +1 -1
  31. package/dist/PluginInterface.d.ts +7 -3
  32. package/dist/PluginInterface.js +9 -0
  33. package/dist/PluginInterface.js.map +1 -1
  34. package/dist/Program.d.ts +43 -25
  35. package/dist/Program.js +212 -95
  36. package/dist/Program.js.map +1 -1
  37. package/dist/ProgramBuilder.d.ts +4 -0
  38. package/dist/ProgramBuilder.js +36 -20
  39. package/dist/ProgramBuilder.js.map +1 -1
  40. package/dist/Scope.d.ts +126 -29
  41. package/dist/Scope.js +433 -156
  42. package/dist/Scope.js.map +1 -1
  43. package/dist/SemanticTokenUtils.d.ts +14 -0
  44. package/dist/SemanticTokenUtils.js +81 -0
  45. package/dist/SemanticTokenUtils.js.map +1 -0
  46. package/dist/SymbolTable.d.ts +10 -4
  47. package/dist/SymbolTable.js +55 -13
  48. package/dist/SymbolTable.js.map +1 -1
  49. package/dist/XmlScope.d.ts +7 -2
  50. package/dist/XmlScope.js +65 -27
  51. package/dist/XmlScope.js.map +1 -1
  52. package/dist/astUtils/AstEditor.d.ts +65 -0
  53. package/dist/astUtils/AstEditor.js +239 -0
  54. package/dist/astUtils/AstEditor.js.map +1 -0
  55. package/dist/{types/FunctionType.spec.d.ts → astUtils/AstEditor.spec.d.ts} +0 -0
  56. package/dist/astUtils/AstEditor.spec.js +254 -0
  57. package/dist/astUtils/AstEditor.spec.js.map +1 -0
  58. package/dist/astUtils/creators.d.ts +28 -6
  59. package/dist/astUtils/creators.js +137 -19
  60. package/dist/astUtils/creators.js.map +1 -1
  61. package/dist/astUtils/creators.spec.js +14 -4
  62. package/dist/astUtils/creators.spec.js.map +1 -1
  63. package/dist/astUtils/reflection.d.ts +32 -10
  64. package/dist/astUtils/reflection.js +82 -7
  65. package/dist/astUtils/reflection.js.map +1 -1
  66. package/dist/astUtils/reflection.spec.js +130 -119
  67. package/dist/astUtils/reflection.spec.js.map +1 -1
  68. package/dist/astUtils/stackedVisitor.js.map +1 -1
  69. package/dist/astUtils/stackedVisitor.spec.js +13 -13
  70. package/dist/astUtils/stackedVisitor.spec.js.map +1 -1
  71. package/dist/astUtils/visitors.d.ts +76 -51
  72. package/dist/astUtils/visitors.js +31 -11
  73. package/dist/astUtils/visitors.js.map +1 -1
  74. package/dist/astUtils/visitors.spec.js +126 -32
  75. package/dist/astUtils/visitors.spec.js.map +1 -1
  76. package/dist/astUtils/xml.d.ts +4 -3
  77. package/dist/astUtils/xml.js +8 -3
  78. package/dist/astUtils/xml.js.map +1 -1
  79. package/dist/bscPlugin/BscPlugin.d.ts +7 -1
  80. package/dist/bscPlugin/BscPlugin.js +28 -0
  81. package/dist/bscPlugin/BscPlugin.js.map +1 -1
  82. package/dist/bscPlugin/codeActions/CodeActionsProcessor.js +4 -4
  83. package/dist/bscPlugin/codeActions/CodeActionsProcessor.js.map +1 -1
  84. package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js +26 -26
  85. package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js.map +1 -1
  86. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.d.ts +9 -0
  87. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js +108 -0
  88. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js.map +1 -0
  89. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.d.ts +1 -0
  90. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js +130 -0
  91. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js.map +1 -0
  92. package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.d.ts +8 -0
  93. package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.js +52 -0
  94. package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.js.map +1 -0
  95. package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.d.ts +1 -0
  96. package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.js +32 -0
  97. package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.js.map +1 -0
  98. package/dist/bscPlugin/validation/BrsFileValidator.d.ts +9 -0
  99. package/dist/bscPlugin/validation/BrsFileValidator.js +66 -0
  100. package/dist/bscPlugin/validation/BrsFileValidator.js.map +1 -0
  101. package/dist/bscPlugin/validation/ScopeValidator.d.ts +29 -0
  102. package/dist/bscPlugin/validation/ScopeValidator.js +183 -0
  103. package/dist/bscPlugin/validation/ScopeValidator.js.map +1 -0
  104. package/dist/cli.js +10 -3
  105. package/dist/cli.js.map +1 -1
  106. package/dist/diagnosticUtils.d.ts +1 -0
  107. package/dist/diagnosticUtils.js +15 -8
  108. package/dist/diagnosticUtils.js.map +1 -1
  109. package/dist/examples/plugins/removePrint.js +12 -14
  110. package/dist/examples/plugins/removePrint.js.map +1 -1
  111. package/dist/files/BrsFile.Class.spec.js +717 -147
  112. package/dist/files/BrsFile.Class.spec.js.map +1 -1
  113. package/dist/files/BrsFile.d.ts +70 -30
  114. package/dist/files/BrsFile.js +719 -353
  115. package/dist/files/BrsFile.js.map +1 -1
  116. package/dist/files/BrsFile.spec.js +1238 -449
  117. package/dist/files/BrsFile.spec.js.map +1 -1
  118. package/dist/files/XmlFile.d.ts +6 -5
  119. package/dist/files/XmlFile.js +38 -30
  120. package/dist/files/XmlFile.js.map +1 -1
  121. package/dist/files/XmlFile.spec.js +302 -237
  122. package/dist/files/XmlFile.spec.js.map +1 -1
  123. package/dist/files/tests/imports.spec.js +44 -42
  124. package/dist/files/tests/imports.spec.js.map +1 -1
  125. package/dist/files/tests/optionalChaning.spec.d.ts +1 -0
  126. package/dist/files/tests/optionalChaning.spec.js +88 -0
  127. package/dist/files/tests/optionalChaning.spec.js.map +1 -0
  128. package/dist/globalCallables.d.ts +3 -1
  129. package/dist/globalCallables.js +424 -152
  130. package/dist/globalCallables.js.map +1 -1
  131. package/dist/index.d.ts +13 -3
  132. package/dist/index.js +28 -5
  133. package/dist/index.js.map +1 -1
  134. package/dist/interfaces.d.ts +133 -16
  135. package/dist/lexer/Lexer.d.ts +19 -1
  136. package/dist/lexer/Lexer.js +127 -21
  137. package/dist/lexer/Lexer.js.map +1 -1
  138. package/dist/lexer/Lexer.spec.js +657 -536
  139. package/dist/lexer/Lexer.spec.js.map +1 -1
  140. package/dist/lexer/Token.d.ts +2 -2
  141. package/dist/lexer/TokenKind.d.ts +13 -1
  142. package/dist/lexer/TokenKind.js +60 -3
  143. package/dist/lexer/TokenKind.js.map +1 -1
  144. package/dist/parser/BrsTranspileState.d.ts +9 -0
  145. package/dist/parser/BrsTranspileState.js +14 -0
  146. package/dist/parser/BrsTranspileState.js.map +1 -1
  147. package/dist/parser/Expression.d.ts +150 -34
  148. package/dist/parser/Expression.js +335 -165
  149. package/dist/parser/Expression.js.map +1 -1
  150. package/dist/parser/Parser.Class.spec.js +189 -89
  151. package/dist/parser/Parser.Class.spec.js.map +1 -1
  152. package/dist/parser/Parser.d.ts +153 -30
  153. package/dist/parser/Parser.js +1100 -503
  154. package/dist/parser/Parser.js.map +1 -1
  155. package/dist/parser/Parser.spec.js +687 -266
  156. package/dist/parser/Parser.spec.js.map +1 -1
  157. package/dist/parser/SGParser.d.ts +41 -4
  158. package/dist/parser/SGParser.js +186 -175
  159. package/dist/parser/SGParser.js.map +1 -1
  160. package/dist/parser/SGParser.spec.js +35 -22
  161. package/dist/parser/SGParser.spec.js.map +1 -1
  162. package/dist/parser/SGTypes.d.ts +206 -38
  163. package/dist/parser/SGTypes.js +470 -161
  164. package/dist/parser/SGTypes.js.map +1 -1
  165. package/dist/parser/SGTypes.spec.d.ts +1 -0
  166. package/dist/parser/SGTypes.spec.js +351 -0
  167. package/dist/parser/SGTypes.spec.js.map +1 -0
  168. package/dist/parser/Statement.d.ts +202 -48
  169. package/dist/parser/Statement.js +648 -193
  170. package/dist/parser/Statement.js.map +1 -1
  171. package/dist/parser/Statement.spec.js +11 -11
  172. package/dist/parser/Statement.spec.js.map +1 -1
  173. package/dist/parser/TranspileState.d.ts +1 -1
  174. package/dist/parser/TranspileState.js +15 -7
  175. package/dist/parser/TranspileState.js.map +1 -1
  176. package/dist/parser/tests/Parser.spec.d.ts +10 -9
  177. package/dist/parser/tests/Parser.spec.js +15 -11
  178. package/dist/parser/tests/Parser.spec.js.map +1 -1
  179. package/dist/parser/tests/controlFlow/For.spec.js +60 -60
  180. package/dist/parser/tests/controlFlow/For.spec.js.map +1 -1
  181. package/dist/parser/tests/controlFlow/ForEach.spec.js +40 -39
  182. package/dist/parser/tests/controlFlow/ForEach.spec.js.map +1 -1
  183. package/dist/parser/tests/controlFlow/If.spec.js +213 -194
  184. package/dist/parser/tests/controlFlow/If.spec.js.map +1 -1
  185. package/dist/parser/tests/controlFlow/While.spec.js +37 -37
  186. package/dist/parser/tests/controlFlow/While.spec.js.map +1 -1
  187. package/dist/parser/tests/expression/Additive.spec.js +30 -30
  188. package/dist/parser/tests/expression/Additive.spec.js.map +1 -1
  189. package/dist/parser/tests/expression/ArrayLiterals.spec.js +119 -119
  190. package/dist/parser/tests/expression/ArrayLiterals.spec.js.map +1 -1
  191. package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js +162 -138
  192. package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js.map +1 -1
  193. package/dist/parser/tests/expression/Boolean.spec.js +24 -24
  194. package/dist/parser/tests/expression/Boolean.spec.js.map +1 -1
  195. package/dist/parser/tests/expression/Call.spec.js +41 -40
  196. package/dist/parser/tests/expression/Call.spec.js.map +1 -1
  197. package/dist/parser/tests/expression/Exponential.spec.js +17 -17
  198. package/dist/parser/tests/expression/Exponential.spec.js.map +1 -1
  199. package/dist/parser/tests/expression/Function.spec.js +256 -256
  200. package/dist/parser/tests/expression/Function.spec.js.map +1 -1
  201. package/dist/parser/tests/expression/Indexing.spec.js +87 -87
  202. package/dist/parser/tests/expression/Indexing.spec.js.map +1 -1
  203. package/dist/parser/tests/expression/Multiplicative.spec.js +37 -37
  204. package/dist/parser/tests/expression/Multiplicative.spec.js.map +1 -1
  205. package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js +75 -63
  206. package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js.map +1 -1
  207. package/dist/parser/tests/expression/PrefixUnary.spec.js +41 -41
  208. package/dist/parser/tests/expression/PrefixUnary.spec.js.map +1 -1
  209. package/dist/parser/tests/expression/Primary.spec.js +41 -41
  210. package/dist/parser/tests/expression/Primary.spec.js.map +1 -1
  211. package/dist/parser/tests/expression/RegexLiteralExpression.spec.d.ts +1 -0
  212. package/dist/parser/tests/expression/RegexLiteralExpression.spec.js +171 -0
  213. package/dist/parser/tests/expression/RegexLiteralExpression.spec.js.map +1 -0
  214. package/dist/parser/tests/expression/Relational.spec.js +43 -43
  215. package/dist/parser/tests/expression/Relational.spec.js.map +1 -1
  216. package/dist/parser/tests/expression/SourceLiteralExpression.spec.js +9 -9
  217. package/dist/parser/tests/expression/SourceLiteralExpression.spec.js.map +1 -1
  218. package/dist/parser/tests/expression/TemplateStringExpression.spec.js +28 -28
  219. package/dist/parser/tests/expression/TemplateStringExpression.spec.js.map +1 -1
  220. package/dist/parser/tests/expression/TernaryExpression.spec.js +102 -102
  221. package/dist/parser/tests/expression/TernaryExpression.spec.js.map +1 -1
  222. package/dist/parser/tests/statement/AssignmentOperators.spec.js +36 -36
  223. package/dist/parser/tests/statement/AssignmentOperators.spec.js.map +1 -1
  224. package/dist/parser/tests/statement/Declaration.spec.js +44 -44
  225. package/dist/parser/tests/statement/Declaration.spec.js.map +1 -1
  226. package/dist/parser/tests/statement/Dim.spec.js +21 -21
  227. package/dist/parser/tests/statement/Dim.spec.js.map +1 -1
  228. package/dist/parser/tests/statement/Enum.spec.d.ts +1 -0
  229. package/dist/parser/tests/statement/Enum.spec.js +840 -0
  230. package/dist/parser/tests/statement/Enum.spec.js.map +1 -0
  231. package/dist/parser/tests/statement/For.spec.d.ts +1 -0
  232. package/dist/parser/tests/statement/For.spec.js +46 -0
  233. package/dist/parser/tests/statement/For.spec.js.map +1 -0
  234. package/dist/parser/tests/statement/ForEach.spec.d.ts +1 -0
  235. package/dist/parser/tests/statement/ForEach.spec.js +37 -0
  236. package/dist/parser/tests/statement/ForEach.spec.js.map +1 -0
  237. package/dist/parser/tests/statement/Function.spec.js +198 -197
  238. package/dist/parser/tests/statement/Function.spec.js.map +1 -1
  239. package/dist/parser/tests/statement/Goto.spec.js +15 -14
  240. package/dist/parser/tests/statement/Goto.spec.js.map +1 -1
  241. package/dist/parser/tests/statement/Increment.spec.js +50 -50
  242. package/dist/parser/tests/statement/Increment.spec.js.map +1 -1
  243. package/dist/parser/tests/statement/InterfaceStatement.spec.d.ts +1 -0
  244. package/dist/parser/tests/statement/InterfaceStatement.spec.js +254 -0
  245. package/dist/parser/tests/statement/InterfaceStatement.spec.js.map +1 -0
  246. package/dist/parser/tests/statement/LibraryStatement.spec.js +17 -17
  247. package/dist/parser/tests/statement/LibraryStatement.spec.js.map +1 -1
  248. package/dist/parser/tests/statement/Misc.spec.js +108 -106
  249. package/dist/parser/tests/statement/Misc.spec.js.map +1 -1
  250. package/dist/parser/tests/statement/PrintStatement.spec.js +40 -40
  251. package/dist/parser/tests/statement/PrintStatement.spec.js.map +1 -1
  252. package/dist/parser/tests/statement/ReturnStatement.spec.js +46 -46
  253. package/dist/parser/tests/statement/ReturnStatement.spec.js.map +1 -1
  254. package/dist/parser/tests/statement/Set.spec.js +83 -83
  255. package/dist/parser/tests/statement/Set.spec.js.map +1 -1
  256. package/dist/parser/tests/statement/Stop.spec.js +12 -11
  257. package/dist/parser/tests/statement/Stop.spec.js.map +1 -1
  258. package/dist/parser/tests/statement/Throw.spec.js +5 -5
  259. package/dist/parser/tests/statement/Throw.spec.js.map +1 -1
  260. package/dist/parser/tests/statement/TryCatch.spec.js +15 -13
  261. package/dist/parser/tests/statement/TryCatch.spec.js.map +1 -1
  262. package/dist/preprocessor/Chunk.d.ts +1 -1
  263. package/dist/preprocessor/Chunk.js.map +1 -1
  264. package/dist/preprocessor/Manifest.d.ts +5 -5
  265. package/dist/preprocessor/Manifest.js +14 -35
  266. package/dist/preprocessor/Manifest.js.map +1 -1
  267. package/dist/preprocessor/Manifest.spec.d.ts +1 -0
  268. package/dist/preprocessor/Manifest.spec.js +78 -103
  269. package/dist/preprocessor/Manifest.spec.js.map +1 -1
  270. package/dist/preprocessor/Preprocessor.d.ts +1 -1
  271. package/dist/preprocessor/Preprocessor.js +8 -8
  272. package/dist/preprocessor/Preprocessor.js.map +1 -1
  273. package/dist/preprocessor/Preprocessor.spec.js +49 -49
  274. package/dist/preprocessor/Preprocessor.spec.js.map +1 -1
  275. package/dist/preprocessor/PreprocessorParser.spec.js +72 -72
  276. package/dist/preprocessor/PreprocessorParser.spec.js.map +1 -1
  277. package/dist/roku-types/data.json +21891 -0
  278. package/dist/roku-types/index.d.ts +6776 -0
  279. package/dist/roku-types/index.js +11 -0
  280. package/dist/roku-types/index.js.map +1 -0
  281. package/dist/types/ArrayType.d.ts +8 -5
  282. package/dist/types/ArrayType.js +52 -12
  283. package/dist/types/ArrayType.js.map +1 -1
  284. package/dist/types/ArrayType.spec.js +72 -11
  285. package/dist/types/ArrayType.spec.js.map +1 -1
  286. package/dist/types/BooleanType.d.ts +4 -2
  287. package/dist/types/BooleanType.js +9 -4
  288. package/dist/types/BooleanType.js.map +1 -1
  289. package/dist/types/BooleanType.spec.js +5 -3
  290. package/dist/types/BooleanType.spec.js.map +1 -1
  291. package/dist/types/BscType.d.ts +20 -5
  292. package/dist/types/BscType.js +24 -0
  293. package/dist/types/BscType.js.map +1 -1
  294. package/dist/types/CustomType.d.ts +8 -6
  295. package/dist/types/CustomType.js +20 -11
  296. package/dist/types/CustomType.js.map +1 -1
  297. package/dist/types/DoubleType.d.ts +2 -0
  298. package/dist/types/DoubleType.js +14 -9
  299. package/dist/types/DoubleType.js.map +1 -1
  300. package/dist/types/DoubleType.spec.js +5 -3
  301. package/dist/types/DoubleType.spec.js.map +1 -1
  302. package/dist/types/DynamicType.d.ts +2 -0
  303. package/dist/types/DynamicType.js +6 -2
  304. package/dist/types/DynamicType.js.map +1 -1
  305. package/dist/types/DynamicType.spec.js +2 -2
  306. package/dist/types/DynamicType.spec.js.map +1 -1
  307. package/dist/types/EnumType.d.ts +22 -0
  308. package/dist/types/EnumType.js +55 -0
  309. package/dist/types/EnumType.js.map +1 -0
  310. package/dist/types/FloatType.d.ts +2 -0
  311. package/dist/types/FloatType.js +14 -9
  312. package/dist/types/FloatType.js.map +1 -1
  313. package/dist/types/FloatType.spec.js +4 -2
  314. package/dist/types/FloatType.spec.js.map +1 -1
  315. package/dist/types/FunctionType.d.ts +7 -31
  316. package/dist/types/FunctionType.js +11 -57
  317. package/dist/types/FunctionType.js.map +1 -1
  318. package/dist/types/IntegerType.d.ts +2 -0
  319. package/dist/types/IntegerType.js +14 -9
  320. package/dist/types/IntegerType.js.map +1 -1
  321. package/dist/types/IntegerType.spec.js +5 -3
  322. package/dist/types/IntegerType.spec.js.map +1 -1
  323. package/dist/types/InterfaceType.d.ts +13 -4
  324. package/dist/types/InterfaceType.js +48 -8
  325. package/dist/types/InterfaceType.js.map +1 -1
  326. package/dist/types/InterfaceType.spec.d.ts +1 -0
  327. package/dist/types/InterfaceType.spec.js +194 -0
  328. package/dist/types/InterfaceType.spec.js.map +1 -0
  329. package/dist/types/InvalidType.d.ts +4 -2
  330. package/dist/types/InvalidType.js +10 -5
  331. package/dist/types/InvalidType.js.map +1 -1
  332. package/dist/types/InvalidType.spec.js +4 -2
  333. package/dist/types/InvalidType.spec.js.map +1 -1
  334. package/dist/types/LazyType.d.ts +8 -7
  335. package/dist/types/LazyType.js +22 -10
  336. package/dist/types/LazyType.js.map +1 -1
  337. package/dist/types/LongIntegerType.d.ts +2 -0
  338. package/dist/types/LongIntegerType.js +14 -9
  339. package/dist/types/LongIntegerType.js.map +1 -1
  340. package/dist/types/LongIntegerType.spec.js +4 -2
  341. package/dist/types/LongIntegerType.spec.js.map +1 -1
  342. package/dist/types/ObjectType.d.ts +8 -4
  343. package/dist/types/ObjectType.js +9 -4
  344. package/dist/types/ObjectType.js.map +1 -1
  345. package/dist/types/ObjectType.spec.js +2 -2
  346. package/dist/types/ObjectType.spec.js.map +1 -1
  347. package/dist/types/StringType.d.ts +4 -2
  348. package/dist/types/StringType.js +9 -4
  349. package/dist/types/StringType.js.map +1 -1
  350. package/dist/types/StringType.spec.js +4 -2
  351. package/dist/types/StringType.spec.js.map +1 -1
  352. package/dist/types/TypedFunctionType.d.ts +28 -0
  353. package/dist/types/TypedFunctionType.js +88 -0
  354. package/dist/types/TypedFunctionType.js.map +1 -0
  355. package/dist/types/TypedFunctionType.spec.d.ts +1 -0
  356. package/dist/types/TypedFunctionType.spec.js +37 -0
  357. package/dist/types/TypedFunctionType.spec.js.map +1 -0
  358. package/dist/types/UninitializedType.js +3 -3
  359. package/dist/types/UninitializedType.js.map +1 -1
  360. package/dist/types/VoidType.d.ts +4 -2
  361. package/dist/types/VoidType.js +8 -4
  362. package/dist/types/VoidType.js.map +1 -1
  363. package/dist/types/VoidType.spec.js +2 -2
  364. package/dist/types/VoidType.spec.js.map +1 -1
  365. package/dist/types/helpers.d.ts +42 -0
  366. package/dist/types/helpers.js +118 -0
  367. package/dist/types/helpers.js.map +1 -0
  368. package/dist/util.d.ts +91 -21
  369. package/dist/util.js +364 -114
  370. package/dist/util.js.map +1 -1
  371. package/dist/validators/ClassValidator.d.ts +19 -2
  372. package/dist/validators/ClassValidator.js +164 -103
  373. package/dist/validators/ClassValidator.js.map +1 -1
  374. package/package.json +30 -19
  375. package/dist/astUtils/index.d.ts +0 -7
  376. package/dist/astUtils/index.js +0 -26
  377. package/dist/astUtils/index.js.map +0 -1
  378. package/dist/lexer/index.d.ts +0 -3
  379. package/dist/lexer/index.js +0 -17
  380. package/dist/lexer/index.js.map +0 -1
  381. package/dist/parser/index.d.ts +0 -3
  382. package/dist/parser/index.js +0 -16
  383. package/dist/parser/index.js.map +0 -1
  384. package/dist/preprocessor/index.d.ts +0 -3
  385. package/dist/preprocessor/index.js +0 -16
  386. package/dist/preprocessor/index.js.map +0 -1
  387. package/dist/types/FunctionType.spec.js +0 -23
  388. package/dist/types/FunctionType.spec.js.map +0 -1
@@ -11,16 +11,18 @@ 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`;
19
+ const stagingDir = (0, util_1.standardizePath) `${tmpPath}/staging`;
18
20
  let program;
19
- let testTranspile = testHelpers_spec_1.getTestTranspile(() => [program, rootDir]);
21
+ let testTranspile = (0, testHelpers_spec_1.getTestTranspile)(() => [program, rootDir]);
20
22
  beforeEach(() => {
21
23
  fsExtra.ensureDirSync(rootDir);
22
24
  fsExtra.emptyDirSync(tmpPath);
23
- program = new Program_1.Program({ rootDir: rootDir });
25
+ program = new Program_1.Program({ rootDir: rootDir, stagingFolderPath: stagingDir });
24
26
  });
25
27
  afterEach(() => {
26
28
  sinon.restore();
@@ -29,10 +31,10 @@ describe('BrsFile BrighterScript classes', () => {
29
31
  fsExtra.emptyDirSync(tmpPath);
30
32
  });
31
33
  function addFile(relativePath, text) {
32
- return program.addOrReplaceFile({ src: `${rootDir}/${relativePath}`, dest: relativePath }, text);
34
+ return program.setFile({ src: `${rootDir}/${relativePath}`, dest: relativePath }, text);
33
35
  }
34
36
  it('detects all classes after parse', () => {
35
- let file = program.addOrReplaceFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
37
+ let file = program.setFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
36
38
  class Animal
37
39
  end class
38
40
  class Duck
@@ -40,18 +42,17 @@ describe('BrsFile BrighterScript classes', () => {
40
42
 
41
43
  end class
42
44
  `);
43
- chai_1.expect(file.parser.references.classStatements.map(x => x.getName(Parser_1.ParseMode.BrighterScript)).sort()).to.eql(['Animal', 'Duck']);
45
+ (0, chai_1.expect)(file.parser.references.classStatements.map(x => x.getName(Parser_1.ParseMode.BrighterScript)).sort()).to.eql(['Animal', 'Duck']);
44
46
  });
45
47
  it('does not cause errors with incomplete class statement', () => {
46
- program.addOrReplaceFile({ src: `${rootDir}/source/main.bs`, dest: 'source/main.bs' }, `
48
+ program.setFile({ src: `${rootDir}/source/main.bs`, dest: 'source/main.bs' }, `
47
49
  class
48
50
  `);
49
51
  program.validate();
50
52
  //if no exception was thrown, this test passes
51
53
  });
52
54
  it('catches child class missing super call in constructor', () => {
53
- 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,12 @@ 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, testHelpers_spec_1.expectDiagnostics)(program, [
67
+ DiagnosticMessages_1.DiagnosticMessages.classConstructorMissingSuperCall()
68
+ ]);
66
69
  });
67
70
  it('access modifier is option for override', () => {
68
- var _a;
69
- let file = program.addOrReplaceFile({ src: `${rootDir}/source/main.bs`, dest: 'source/main.bs' }, `
71
+ let file = program.setFile({ src: `${rootDir}/source/main.bs`, dest: 'source/main.bs' }, `
70
72
  class Animal
71
73
  sub move()
72
74
  end sub
@@ -78,14 +80,13 @@ describe('BrsFile BrighterScript classes', () => {
78
80
  end class
79
81
  `);
80
82
  program.validate();
81
- chai_1.expect((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
83
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(program);
82
84
  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;
85
+ (0, chai_1.expect)(duckClass).to.exist;
86
+ (0, chai_1.expect)(duckClass.memberMap['move']).to.exist;
85
87
  });
86
88
  it('supports various namespace configurations', () => {
87
- 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,11 @@ 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, testHelpers_spec_1.expectZeroDiagnostics)(program);
109
110
  });
110
111
  describe('super', () => {
111
112
  it('always requires super call in child constructor', () => {
112
- var _a;
113
- program.addOrReplaceFile('source/main.bs', `
113
+ program.setFile('source/main.bs', `
114
114
  class Bird
115
115
  end class
116
116
  class Duck extends Bird
@@ -119,11 +119,12 @@ describe('BrsFile BrighterScript classes', () => {
119
119
  end class
120
120
  `);
121
121
  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);
122
+ (0, testHelpers_spec_1.expectDiagnostics)(program, [
123
+ DiagnosticMessages_1.DiagnosticMessages.classConstructorMissingSuperCall()
124
+ ]);
123
125
  });
124
126
  it('requires super call in child when parent has own `new` method', () => {
125
- 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,12 @@ 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, testHelpers_spec_1.expectDiagnostics)(program, [
139
+ DiagnosticMessages_1.DiagnosticMessages.classConstructorMissingSuperCall()
140
+ ]);
138
141
  });
139
142
  it('allows non-`m` expressions and statements before the super call', () => {
140
- var _a;
141
- program.addOrReplaceFile('source/main.bs', `
143
+ program.setFile('source/main.bs', `
142
144
  class Bird
143
145
  sub new(name)
144
146
  end sub
@@ -153,10 +155,10 @@ describe('BrsFile BrighterScript classes', () => {
153
155
  end class
154
156
  `);
155
157
  program.validate();
156
- chai_1.expect((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).to.be.undefined;
158
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(program);
157
159
  });
158
160
  it('allows non-`m` expressions and statements before the super call', () => {
159
- program.addOrReplaceFile('source/main.bs', `
161
+ program.setFile('source/main.bs', `
160
162
  class Bird
161
163
  sub new(name)
162
164
  end sub
@@ -164,21 +166,30 @@ describe('BrsFile BrighterScript classes', () => {
164
166
  class Duck extends Bird
165
167
  sub new()
166
168
  m.name = m.name + "Duck"
167
- super()
169
+ super(m.name)
168
170
  end sub
169
171
  end class
170
172
  `);
171
173
  program.validate();
172
- chai_1.expect(program.getDiagnostics().map(x => ({ message: x.message, range: x.range }))).to.eql([{
173
- message: DiagnosticMessages_1.DiagnosticMessages.classConstructorIllegalUseOfMBeforeSuperCall().message,
174
- range: vscode_languageserver_1.Range.create(7, 24, 7, 25)
175
- }, {
176
- message: DiagnosticMessages_1.DiagnosticMessages.classConstructorIllegalUseOfMBeforeSuperCall().message,
177
- range: vscode_languageserver_1.Range.create(7, 33, 7, 34)
178
- }]);
174
+ (0, testHelpers_spec_1.expectDiagnostics)(program, [Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.classConstructorIllegalUseOfMBeforeSuperCall()), { range: vscode_languageserver_1.Range.create(7, 24, 7, 25) }), Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.classConstructorIllegalUseOfMBeforeSuperCall()), { range: vscode_languageserver_1.Range.create(7, 33, 7, 34) })]);
179
175
  });
180
176
  });
181
177
  describe('transpile', () => {
178
+ it('does not mess with AST when injecting `super()` call', async () => {
179
+ const file = program.setFile('source/classes.bs', `
180
+ class Parent
181
+ end class
182
+
183
+ class Child extends parent
184
+ sub new()
185
+ super()
186
+ end sub
187
+ end class
188
+ `);
189
+ (0, chai_1.expect)(file.ast.statements[1].body[0].func.body.statements[0].expression.callee.name.text).to.eql('super');
190
+ await program.transpile([], stagingDir);
191
+ (0, chai_1.expect)(file.ast.statements[1].body[0].func.body.statements[0].expression.callee.name.text).to.eql('super');
192
+ });
182
193
  it('follows correct sequence for property initializers', () => {
183
194
  testTranspile(`
184
195
  class Animal
@@ -357,6 +368,9 @@ describe('BrsFile BrighterScript classes', () => {
357
368
  class Animal
358
369
  sub new(name as string)
359
370
  end sub
371
+
372
+ sub DoSomething()
373
+ end sub
360
374
  end class
361
375
 
362
376
  class Duck extends Animal
@@ -370,6 +384,8 @@ describe('BrsFile BrighterScript classes', () => {
370
384
  instance = {}
371
385
  instance.new = sub(name as string)
372
386
  end sub
387
+ instance.DoSomething = sub()
388
+ end sub
373
389
  return instance
374
390
  end function
375
391
  function Animal(name as string)
@@ -435,7 +451,7 @@ describe('BrsFile BrighterScript classes', () => {
435
451
  instance.super0_sayHello = instance.sayHello
436
452
  instance.sayHello = function(text)
437
453
  text = "The duck says " + text
438
- if text <> invalid then
454
+ if text <> invalid
439
455
  m.super0_sayHello(text)
440
456
  end if
441
457
  end function
@@ -501,6 +517,71 @@ describe('BrsFile BrighterScript classes', () => {
501
517
  end sub
502
518
  `, undefined, 'source/main.bs');
503
519
  });
520
+ it('calls super ', () => {
521
+ const { file } = testTranspile(`
522
+ class Parent
523
+ sub new()
524
+ end sub
525
+ end class
526
+ class Child extends Parent
527
+ sub new()
528
+ end sub
529
+ end class
530
+ `, `
531
+ function __Parent_builder()
532
+ instance = {}
533
+ instance.new = sub()
534
+ end sub
535
+ return instance
536
+ end function
537
+ function Parent()
538
+ instance = __Parent_builder()
539
+ instance.new()
540
+ return instance
541
+ end function
542
+ function __Child_builder()
543
+ instance = __Parent_builder()
544
+ instance.super0_new = instance.new
545
+ instance.new = sub()
546
+ m.super0_new()
547
+ end sub
548
+ return instance
549
+ end function
550
+ function Child()
551
+ instance = __Child_builder()
552
+ instance.new()
553
+ return instance
554
+ end function
555
+ `, undefined, undefined, false);
556
+ //the AST should not be permanently modified
557
+ const constructor = file.ast.statements[0].body[0];
558
+ (0, chai_1.expect)(constructor.func.body.statements).to.be.lengthOf(0);
559
+ });
560
+ it('adds field initializers', () => {
561
+ const { file } = testTranspile(`
562
+ class Person
563
+ sub new()
564
+ end sub
565
+ name = "Bob"
566
+ end class
567
+ `, `
568
+ function __Person_builder()
569
+ instance = {}
570
+ instance.new = sub()
571
+ m.name = "Bob"
572
+ end sub
573
+ return instance
574
+ end function
575
+ function Person()
576
+ instance = __Person_builder()
577
+ instance.new()
578
+ return instance
579
+ end function
580
+ `);
581
+ //the AST should not be permanently modified
582
+ const constructor = file.ast.statements[0].body[0];
583
+ (0, chai_1.expect)(constructor.func.body.statements).to.be.lengthOf(0);
584
+ });
504
585
  it('does not screw up local variable references', () => {
505
586
  testTranspile(`
506
587
  class Animal
@@ -660,8 +741,7 @@ describe('BrsFile BrighterScript classes', () => {
660
741
  });
661
742
  });
662
743
  it('detects using `new` keyword on non-classes', () => {
663
- var _a;
664
- program.addOrReplaceFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
744
+ program.setFile({ src: `${rootDir}/source/main.bs`, dest: 'source/main.brs' }, `
665
745
  sub quack()
666
746
  end sub
667
747
  sub main()
@@ -669,37 +749,41 @@ describe('BrsFile BrighterScript classes', () => {
669
749
  end sub
670
750
  `);
671
751
  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);
752
+ (0, testHelpers_spec_1.expectDiagnostics)(program, [
753
+ DiagnosticMessages_1.DiagnosticMessages.expressionIsNotConstructable('sub')
754
+ ]);
673
755
  });
674
756
  it('detects missing call to super', () => {
675
- var _a;
676
- program.addOrReplaceFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
757
+ program.setFile({ src: `${rootDir}/source/main.bs`, dest: 'source/main.brs' }, `
677
758
  class Animal
678
- sub new()
759
+ sub new ()
679
760
  end sub
680
761
  end class
681
762
  class Duck extends Animal
682
- sub new()
763
+ sub new ()
683
764
  end sub
684
765
  end class
685
766
  `);
686
767
  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);
768
+ (0, testHelpers_spec_1.expectDiagnostics)(program, [
769
+ DiagnosticMessages_1.DiagnosticMessages.classConstructorMissingSuperCall()
770
+ ]);
688
771
  });
689
772
  it.skip('detects calls to unknown m methods', () => {
690
- var _a;
691
- program.addOrReplaceFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
773
+ program.setFile('source/main.brs', `
692
774
  class Animal
693
- sub new()
775
+ sub new ()
694
776
  m.methodThatDoesNotExist()
695
777
  end sub
696
778
  end class
697
779
  `);
698
780
  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'));
781
+ (0, testHelpers_spec_1.expectDiagnostics)(program, [
782
+ DiagnosticMessages_1.DiagnosticMessages.methodDoesNotExistOnType('methodThatDoesNotExist', 'Animal')
783
+ ]);
700
784
  });
701
785
  it('detects duplicate member names', () => {
702
- program.addOrReplaceFile({ src: `${rootDir}/source/main.bs`, dest: 'source/main.bs' }, `
786
+ program.setFile('source/main.bs', `
703
787
  class Animal
704
788
  public name
705
789
  public name
@@ -713,32 +797,26 @@ describe('BrsFile BrighterScript classes', () => {
713
797
  end class
714
798
  `);
715
799
  program.validate();
716
- let diagnostics = program.getDiagnostics().map(x => {
717
- return {
718
- code: x.code,
719
- message: x.message,
720
- range: x.range,
721
- severity: vscode_languageserver_1.DiagnosticSeverity.Error
722
- };
723
- });
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) })]);
800
+ (0, testHelpers_spec_1.expectDiagnostics)(program, [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
801
  });
726
802
  it('detects mismatched member type in child class', () => {
727
- program.addOrReplaceFile({ src: `${rootDir}/source/main.bs`, dest: 'source/main.bs' }, `
803
+ program.setFile('source/main.bs', `
728
804
  class Animal
729
805
  public name
730
806
  end class
731
807
  class Duck extends Animal
732
- public function name()
808
+ public override function name()
733
809
  return "Donald"
734
810
  end function
735
811
  end class
736
812
  `);
737
813
  program.validate();
738
- chai_1.expect(program.getDiagnostics().map(x => x.message).sort()[0]).to.eql(DiagnosticMessages_1.DiagnosticMessages.classChildMemberDifferentMemberTypeThanAncestor('method', 'field', 'Animal').message);
814
+ (0, testHelpers_spec_1.expectDiagnostics)(program, [
815
+ DiagnosticMessages_1.DiagnosticMessages.classChildMemberDifferentMemberTypeThanAncestor('method', 'field', 'Animal')
816
+ ]);
739
817
  });
740
818
  it('allows untyped overridden field in child class', () => {
741
- program.addOrReplaceFile({ src: `${rootDir}/source/main.bs`, dest: 'source/main.bs' }, `
819
+ program.setFile('source/main.bs', `
742
820
  class Animal
743
821
  public name
744
822
  end class
@@ -747,10 +825,10 @@ describe('BrsFile BrighterScript classes', () => {
747
825
  end class
748
826
  `);
749
827
  program.validate();
750
- testHelpers_spec_1.expectZeroDiagnostics(program);
828
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(program);
751
829
  });
752
830
  it('allows overridden property name in child class', () => {
753
- program.addOrReplaceFile('source/main.bs', `
831
+ program.setFile('source/main.bs', `
754
832
  class Bird
755
833
  public name = "bird"
756
834
  end class
@@ -759,10 +837,10 @@ describe('BrsFile BrighterScript classes', () => {
759
837
  end class
760
838
  `);
761
839
  program.validate();
762
- testHelpers_spec_1.expectZeroDiagnostics(program);
840
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(program);
763
841
  });
764
842
  it('flags incompatible child field type changes', () => {
765
- program.addOrReplaceFile('source/main.bs', `
843
+ program.setFile('source/main.bs', `
766
844
  class Bird
767
845
  public age = 12
768
846
  public name = "bird"
@@ -775,15 +853,15 @@ describe('BrsFile BrighterScript classes', () => {
775
853
  end class
776
854
  `);
777
855
  program.validate();
778
- chai_1.expect(program.getDiagnostics().map(x => x.message).sort()).to.eql([
779
- DiagnosticMessages_1.DiagnosticMessages.cannotFindType('Person').message,
780
- DiagnosticMessages_1.DiagnosticMessages.childFieldTypeNotAssignableToBaseProperty('Duck', 'Bird', 'age', 'float', 'integer').message,
781
- DiagnosticMessages_1.DiagnosticMessages.childFieldTypeNotAssignableToBaseProperty('Duck', 'Bird', 'name', 'integer', 'string').message,
782
- DiagnosticMessages_1.DiagnosticMessages.childFieldTypeNotAssignableToBaseProperty('Duck', 'Bird', 'owner', 'string', 'Person').message
856
+ (0, testHelpers_spec_1.expectDiagnostics)(program, [
857
+ DiagnosticMessages_1.DiagnosticMessages.cannotFindType('Person'),
858
+ DiagnosticMessages_1.DiagnosticMessages.childFieldTypeNotAssignableToBaseProperty('Duck', 'Bird', 'age', 'float', 'integer'),
859
+ DiagnosticMessages_1.DiagnosticMessages.childFieldTypeNotAssignableToBaseProperty('Duck', 'Bird', 'name', 'integer', 'string'),
860
+ DiagnosticMessages_1.DiagnosticMessages.childFieldTypeNotAssignableToBaseProperty('Duck', 'Bird', 'owner', 'string', 'Person')
783
861
  ]);
784
862
  });
785
863
  it('detects overridden methods without override keyword', () => {
786
- program.addOrReplaceFile({ src: `${rootDir}/source/main.brs`, dest: 'source/main.brs' }, `
864
+ program.setFile('source/main.bs', `
787
865
  class Animal
788
866
  sub speak()
789
867
  end sub
@@ -794,10 +872,12 @@ describe('BrsFile BrighterScript classes', () => {
794
872
  end class
795
873
  `);
796
874
  program.validate();
797
- chai_1.expect(program.getDiagnostics()[0]).to.exist.and.to.include(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.missingOverrideKeyword('Animal')));
875
+ (0, testHelpers_spec_1.expectDiagnostics)(program, [
876
+ DiagnosticMessages_1.DiagnosticMessages.missingOverrideKeyword('Animal')
877
+ ]);
798
878
  });
799
879
  it('detects overridden methods with different visibility', () => {
800
- program.addOrReplaceFile({ src: `${rootDir}/source/main.bs`, dest: 'source/main.bs' }, `
880
+ program.setFile('source/main.bs', `
801
881
  class Animal
802
882
  sub speakInPublic()
803
883
  end sub
@@ -816,12 +896,14 @@ describe('BrsFile BrighterScript classes', () => {
816
896
  end class
817
897
  `);
818
898
  program.validate();
819
- chai_1.expect(program.getDiagnostics()[0]).to.exist.and.to.include(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.mismatchedOverriddenMemberVisibility('Duck', 'speakInPublic', 'private', 'public', 'Animal')));
820
- chai_1.expect(program.getDiagnostics()[1]).to.exist.and.to.include(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.mismatchedOverriddenMemberVisibility('Duck', 'speakWithFriends', 'public', 'protected', 'Animal')));
821
- chai_1.expect(program.getDiagnostics()[2]).to.exist.and.to.include(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.mismatchedOverriddenMemberVisibility('Duck', 'speakWithFamily', 'public', 'private', 'Animal')));
899
+ (0, testHelpers_spec_1.expectDiagnostics)(program, [
900
+ DiagnosticMessages_1.DiagnosticMessages.mismatchedOverriddenMemberVisibility('Duck', 'speakInPublic', 'private', 'public', 'Animal'),
901
+ DiagnosticMessages_1.DiagnosticMessages.mismatchedOverriddenMemberVisibility('Duck', 'speakWithFriends', 'public', 'protected', 'Animal'),
902
+ DiagnosticMessages_1.DiagnosticMessages.mismatchedOverriddenMemberVisibility('Duck', 'speakWithFamily', 'public', 'private', 'Animal')
903
+ ]);
822
904
  });
823
905
  it('allows overridden methods with matching visibility', () => {
824
- program.addOrReplaceFile({ src: `${rootDir}/source/main.bs`, dest: 'source/main.bs' }, `
906
+ program.setFile('source/main.bs', `
825
907
  class Animal
826
908
  sub speakInPublic()
827
909
  end sub
@@ -840,50 +922,123 @@ describe('BrsFile BrighterScript classes', () => {
840
922
  end class
841
923
  `);
842
924
  program.validate();
843
- chai_1.expect(program.getDiagnostics()).to.be.empty;
925
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(program);
844
926
  });
845
- it('detects extending unknown parent class', () => {
846
- program.addOrReplaceFile('source/main.brs', `
847
- class Duck extends Animal
848
- sub speak()
849
- end sub
850
- end class
851
- `);
852
- program.validate();
853
- 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) }));
927
+ describe('detects unknown parent class', () => {
928
+ it('non-namespaced parent from outside namespace', () => {
929
+ program.setFile('source/main.bs', `
930
+ class Duck extends Animal
931
+ sub speak()
932
+ end sub
933
+ end class
934
+
935
+ namespace Vertibrates
936
+ class Animal
937
+ end class
938
+ end namespace
939
+ `);
940
+ program.validate();
941
+ (0, testHelpers_spec_1.expectDiagnostics)(program, [Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.classCouldNotBeFound('Animal', 'source')), { range: vscode_languageserver_1.Range.create(1, 35, 1, 41) })]);
942
+ });
943
+ it('non-namespaced parent from within namespace', () => {
944
+ program.setFile('source/main.bs', `
945
+ namespace Vertibrates
946
+ class Duck extends Animal
947
+ sub speak()
948
+ end sub
949
+ end class
950
+ end namespace
951
+ `);
952
+ program.validate();
953
+ (0, testHelpers_spec_1.expectDiagnostics)(program, [
954
+ DiagnosticMessages_1.DiagnosticMessages.classCouldNotBeFound('Animal', 'source')
955
+ ]);
956
+ });
957
+ it('non-namespaced name from outside namespace alongside existing namespace', () => {
958
+ program.setFile('source/main.bs', `
959
+ namespace Vertibrates
960
+ class Animal
961
+ end class
962
+ end namespace
963
+
964
+ class Duck extends Animal
965
+ sub speak()
966
+ end sub
967
+ end class
968
+ `);
969
+ program.validate();
970
+ (0, testHelpers_spec_1.expectDiagnostics)(program, [
971
+ DiagnosticMessages_1.DiagnosticMessages.classCouldNotBeFound('Animal', 'source')
972
+ ]);
973
+ });
974
+ it('namespaced parent class from outside namespace', () => {
975
+ program.setFile('source/vertibrates.bs', `
976
+ namespace Vertibrates
977
+ class Bird
978
+ end class
979
+ end namespace
980
+ `);
981
+ program.setFile('source/Duck.bs', `
982
+ class Duck extends Vertibrates.GroundedBird
983
+ sub speak()
984
+ end sub
985
+ end class
986
+ `);
987
+ program.validate();
988
+ //TODO replace this with `expectDiagnostics` once we fix the duplicate diagnostic one-per-file for missing base classes issue
989
+ (0, chai_1.expect)(program.getDiagnostics()[0].message).to.eql(DiagnosticMessages_1.DiagnosticMessages.classCouldNotBeFound('Vertibrates.GroundedBird', 'source').message);
990
+ });
991
+ it('namespaced parent class from inside namespace', () => {
992
+ program.setFile('source/vertibrates.bs', `
993
+ namespace Vertibrates
994
+ class Bird
995
+ end class
996
+ end namespace
997
+ `);
998
+ program.setFile('source/Duck.bs', `
999
+ namespace Birdies
1000
+ class Duck extends Vertibrates.GroundedBird
1001
+ sub speak()
1002
+ end sub
1003
+ end class
1004
+ end namespace
1005
+ `);
1006
+ program.validate();
1007
+ //TODO replace this with `expectDiagnostics` once we fix the duplicate diagnostic one-per-file for missing base classes issue
1008
+ (0, chai_1.expect)(program.getDiagnostics()[0].message).to.eql(DiagnosticMessages_1.DiagnosticMessages.classCouldNotBeFound('Vertibrates.GroundedBird', 'source').message);
1009
+ });
854
1010
  });
855
1011
  it('catches newable class without namespace name', () => {
856
- var _a;
857
- program.addOrReplaceFile('source/main.bs', `
1012
+ program.setFile('source/main.bs', `
858
1013
  namespace NameA.NameB
859
1014
  class Duck
860
1015
  end class
861
- end namespace
1016
+ end namespace
862
1017
  sub main()
863
1018
  ' this should be an error because the proper name is NameA.NameB.Duck"
864
1019
  d = new Duck()
865
1020
  end sub
866
- `);
1021
+ `);
867
1022
  program.validate();
868
- chai_1.expect((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.classCouldNotBeFound('Duck', 'source').message);
1023
+ (0, testHelpers_spec_1.expectDiagnostics)(program, [
1024
+ DiagnosticMessages_1.DiagnosticMessages.classCouldNotBeFound('Duck', 'source')
1025
+ ]);
869
1026
  });
870
1027
  it('supports newable class namespace inference', () => {
871
- var _a;
872
- program.addOrReplaceFile({ src: `${rootDir}/source/main.bs`, dest: 'source/main.bs' }, `
1028
+ program.setFile('source/main.bs', `
873
1029
  namespace NameA.NameB
874
1030
  class Duck
875
1031
  end class
876
- sub main()
1032
+ sub main()
877
1033
  d = new Duck()
878
1034
  end sub
879
1035
  end namespace
880
- `);
1036
+ `);
881
1037
  program.validate();
882
- chai_1.expect((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
1038
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(program);
883
1039
  });
884
1040
  it('catches extending unknown namespaced class', () => {
885
- var _a;
886
- program.addOrReplaceFile({ src: `${rootDir}/source/main.bs`, dest: 'source/main.bs' }, `
1041
+ program.setFile('source/main.bs', `
887
1042
  namespace NameA.NameB
888
1043
  class Animal
889
1044
  end class
@@ -892,120 +1047,129 @@ describe('BrsFile BrighterScript classes', () => {
892
1047
  end namespace
893
1048
  `);
894
1049
  program.validate();
895
- 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);
1050
+ (0, testHelpers_spec_1.expectDiagnostics)(program, [
1051
+ DiagnosticMessages_1.DiagnosticMessages.classCouldNotBeFound('NameA.NameB.Animal1', 'source')
1052
+ ]);
896
1053
  });
897
1054
  it('supports omitting namespace prefix for items in same namespace', () => {
898
- var _a;
899
- program.addOrReplaceFile({ src: `${rootDir}/source/main.bs`, dest: 'source/main.bs' }, `
1055
+ program.setFile('source/main.bs', `
900
1056
  namespace NameA.NameB
901
1057
  class Animal
902
1058
  end class
903
1059
  class Duck extends Animal
904
1060
  end class
905
- end namespace
906
- `);
1061
+ end namespace
1062
+ `);
907
1063
  program.validate();
908
- chai_1.expect((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
1064
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(program);
909
1065
  });
910
1066
  it('catches duplicate root-level class declarations', () => {
911
- var _a;
912
- program.addOrReplaceFile({ src: `${rootDir}/source/main.bs`, dest: 'source/main.bs' }, `
1067
+ program.setFile('source/main.bs', `
913
1068
  class Animal
914
1069
  end class
915
1070
  class Animal
1071
+ end class
916
1072
  `);
917
1073
  program.validate();
918
- chai_1.expect((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.duplicateClassDeclaration('source', 'Animal').message);
1074
+ (0, testHelpers_spec_1.expectDiagnostics)(program, [
1075
+ DiagnosticMessages_1.DiagnosticMessages.duplicateClassDeclaration('source', 'Animal')
1076
+ ]);
919
1077
  });
920
1078
  it('catches duplicate namespace-level class declarations', () => {
921
- var _a;
922
- program.addOrReplaceFile({ src: `${rootDir}/source/main.bs`, dest: 'source/main.bs' }, `
1079
+ program.setFile('source/main.bs', `
923
1080
  namespace NameA.NameB
924
1081
  class Animal
925
1082
  end class
926
1083
  class Animal
1084
+ end class
927
1085
  end namespace
928
1086
  `);
929
1087
  program.validate();
930
- 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);
1088
+ (0, testHelpers_spec_1.expectDiagnostics)(program, [
1089
+ DiagnosticMessages_1.DiagnosticMessages.duplicateClassDeclaration('source', 'NameA.NameB.Animal')
1090
+ ]);
931
1091
  });
932
1092
  it('catches namespaced class name which is the same as a global class', () => {
933
- var _a;
934
- program.addOrReplaceFile({ src: `${rootDir}/source/main.bs`, dest: 'source/main.bs' }, `
1093
+ program.setFile('source/main.bs', `
935
1094
  namespace NameA.NameB
936
1095
  class Animal
937
1096
  end class
938
- end namespace
1097
+ end namespace
939
1098
  class Animal
940
1099
  end class
941
1100
  `);
942
1101
  program.validate();
943
- chai_1.expect((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.namespacedClassCannotShareNamewithNonNamespacedClass('Animal').message);
1102
+ (0, testHelpers_spec_1.expectDiagnostics)(program, [
1103
+ DiagnosticMessages_1.DiagnosticMessages.namespacedClassCannotShareNamewithNonNamespacedClass('Animal').message
1104
+ ]);
944
1105
  });
945
1106
  it('catches class with same name as function', () => {
946
- var _a;
947
- program.addOrReplaceFile('source/main.bs', `
1107
+ program.setFile('source/main.bs', `
948
1108
  class Animal
949
1109
  end class
950
- sub Animal()
1110
+ sub Animal()
951
1111
  end sub
952
- `);
1112
+ `);
953
1113
  program.validate();
954
- chai_1.expect((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.functionCannotHaveSameNameAsClass('Animal').message);
1114
+ (0, testHelpers_spec_1.expectDiagnostics)(program, [
1115
+ DiagnosticMessages_1.DiagnosticMessages.functionCannotHaveSameNameAsClass('Animal').message
1116
+ ]);
955
1117
  });
956
1118
  it('catches class with same name (but different case) as function', () => {
957
- var _a;
958
- program.addOrReplaceFile('source/main.bs', `
1119
+ program.setFile('source/main.bs', `
959
1120
  class ANIMAL
960
1121
  end class
961
- sub animal()
1122
+ sub animal()
962
1123
  end sub
963
- `);
1124
+ `);
964
1125
  program.validate();
965
- chai_1.expect((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.functionCannotHaveSameNameAsClass('animal').message);
1126
+ (0, testHelpers_spec_1.expectDiagnostics)(program, [
1127
+ DiagnosticMessages_1.DiagnosticMessages.functionCannotHaveSameNameAsClass('animal').message
1128
+ ]);
966
1129
  });
967
1130
  it('catches variable with same name as class', () => {
968
- var _a;
969
- program.addOrReplaceFile('source/main.bs', `
1131
+ program.setFile('source/main.bs', `
970
1132
  class Animal
971
1133
  end class
972
- sub main()
1134
+ sub main()
973
1135
  animal = new Animal()
974
1136
  end sub
975
- `);
1137
+ `);
976
1138
  program.validate();
977
- chai_1.expect((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.localVarSameNameAsClass('Animal').message);
1139
+ (0, testHelpers_spec_1.expectDiagnostics)(program, [
1140
+ DiagnosticMessages_1.DiagnosticMessages.localVarSameNameAsClass('Animal').message
1141
+ ]);
978
1142
  });
979
1143
  it('allows extending classes with more than one dot in the filename', () => {
980
- program.addOrReplaceFile('source/testclass.bs', `
1144
+ program.setFile('source/testclass.bs', `
981
1145
  class Foo
982
1146
  end class
983
1147
 
984
1148
  class Bar extends Foo
985
- sub new()
1149
+ sub new ()
986
1150
  super()
987
1151
  end sub
988
1152
  end class
989
1153
  `);
990
- program.addOrReplaceFile('source/testclass_no_testdot.bs', `
1154
+ program.setFile('source/testclass_no_testdot.bs', `
991
1155
  class BarNoDot extends Foo
992
- sub new()
1156
+ sub new ()
993
1157
  super()
994
1158
  end sub
995
1159
  end class
996
1160
  `);
997
- program.addOrReplaceFile('source/testclass.dot.bs', `
1161
+ program.setFile('source/testclass.dot.bs', `
998
1162
  class BarDot extends Foo
999
- sub new()
1163
+ sub new ()
1000
1164
  super()
1001
1165
  end sub
1002
1166
  end class
1003
1167
  `);
1004
1168
  program.validate();
1005
- testHelpers_spec_1.expectZeroDiagnostics(program);
1169
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(program);
1006
1170
  });
1007
1171
  it('computes correct super index for grandchild class', () => {
1008
- program.addOrReplaceFile('source/main.bs', `
1172
+ program.setFile('source/main.bs', `
1009
1173
  sub Main()
1010
1174
  c = new App.ClassC()
1011
1175
  end sub
@@ -1021,7 +1185,7 @@ describe('BrsFile BrighterScript classes', () => {
1021
1185
  testTranspile(`
1022
1186
  namespace App
1023
1187
  class ClassC extends ClassB
1024
- sub new()
1188
+ sub new ()
1025
1189
  super()
1026
1190
  end sub
1027
1191
  end class
@@ -1043,7 +1207,7 @@ describe('BrsFile BrighterScript classes', () => {
1043
1207
  `, 'trim', 'source/App.ClassC.bs');
1044
1208
  });
1045
1209
  it('computes correct super index for namespaced child class and global parent class', () => {
1046
- program.addOrReplaceFile('source/ClassA.bs', `
1210
+ program.setFile('source/ClassA.bs', `
1047
1211
  class ClassA
1048
1212
  end class
1049
1213
  `);
@@ -1052,7 +1216,7 @@ describe('BrsFile BrighterScript classes', () => {
1052
1216
  class ClassB extends ClassA
1053
1217
  end class
1054
1218
  end namespace
1055
- `, `
1219
+ `, `
1056
1220
  function __App_ClassB_builder()
1057
1221
  instance = __ClassA_builder()
1058
1222
  instance.super0_new = instance.new
@@ -1069,13 +1233,419 @@ describe('BrsFile BrighterScript classes', () => {
1069
1233
  `, 'trim', 'source/App.ClassB.bs');
1070
1234
  });
1071
1235
  it('does not crash when parent class is missing', () => {
1072
- const file = program.addOrReplaceFile('source/ClassB.bs', `
1236
+ const file = program.setFile('source/ClassB.bs', `
1073
1237
  class ClassB extends ClassA
1074
1238
  end class
1075
1239
  `);
1076
- assert_1.doesNotThrow(() => {
1077
- file.parser.references.classStatements[0].getParentClassIndex(new BrsTranspileState_1.BrsTranspileState(file));
1240
+ (0, assert_1.doesNotThrow)(() => {
1241
+ file.parser.references.classStatements[0]['getParentClassIndex'](new BrsTranspileState_1.BrsTranspileState(file));
1242
+ });
1243
+ });
1244
+ describe('getHover', () => {
1245
+ const animalClassCode = `
1246
+ class Animal
1247
+ kind as string
1248
+ isHungry as boolean
1249
+
1250
+ sub new (kind as string)
1251
+ m.kind = kind
1252
+ m.isHungry = true ' born hungry
1253
+ end sub
1254
+
1255
+ sub eat(foodAmount as integer)
1256
+ if foodAmount > 100
1257
+ m.isHungry = false
1258
+ end if
1259
+ end sub
1260
+
1261
+ sub sleep()
1262
+ m.isHungry = false
1263
+ end sub
1264
+
1265
+ end class
1266
+
1267
+ class Dog extends Animal
1268
+ breed as string
1269
+ sub new (breed as string)
1270
+ super("Dog")
1271
+ m.breed = breed
1272
+ end sub
1273
+
1274
+ sub snooze()
1275
+ m.sleep()
1276
+ end sub
1277
+ end class
1278
+
1279
+ class DogHouse
1280
+ puppy as Dog
1281
+ sub new (pup as Dog)
1282
+ m.puppy = pup
1283
+ end sub
1284
+ end class
1285
+
1286
+ sub main()
1287
+ snoopy = new Dog("Beagle")
1288
+ biplane = new DogHouse(snoopy)
1289
+ print snoopy.kind ' Dog
1290
+ print snoopy.breed ' Beagle
1291
+ print snoopy.isHungry ' true
1292
+ feedAnimal(biplane.puppy)
1293
+ print snoopy.isHungry ' false
1294
+ end sub
1295
+
1296
+ sub feedAnimal(beast as Animal)
1297
+ beast.eat(100)
1298
+ end sub
1299
+ `;
1300
+ it('correctly parses the file', () => {
1301
+ program.setFile('source/animal.bs', animalClassCode);
1302
+ program.validate();
1303
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(program);
1304
+ });
1305
+ it('gets the correct text for m', () => {
1306
+ let animalCode = program.setFile('source/animal.bs', animalClassCode);
1307
+ program.validate();
1308
+ let hover = animalCode.getHover(vscode_languageserver_1.Position.create(6, 21));
1309
+ (0, chai_1.expect)(hover === null || hover === void 0 ? void 0 : hover.contents).to.equal([
1310
+ '```brightscript',
1311
+ 'm as Animal',
1312
+ '```'
1313
+ ].join('\n'));
1314
+ hover = animalCode.getHover(vscode_languageserver_1.Position.create(26, 20));
1315
+ (0, chai_1.expect)(hover === null || hover === void 0 ? void 0 : hover.contents).to.equal([
1316
+ '```brightscript',
1317
+ 'm as Dog',
1318
+ '```'
1319
+ ].join('\n'));
1320
+ });
1321
+ it('gets the correct text for m.field', () => {
1322
+ let animalCode = program.setFile('source/animal.bs', animalClassCode);
1323
+ program.validate();
1324
+ let hover = animalCode.getHover(vscode_languageserver_1.Position.create(6, 26));
1325
+ (0, chai_1.expect)(hover === null || hover === void 0 ? void 0 : hover.contents).to.equal([
1326
+ '```brightscript',
1327
+ 'Animal.kind as string',
1328
+ '```'
1329
+ ].join('\n'));
1330
+ hover = animalCode.getHover(vscode_languageserver_1.Position.create(26, 25));
1331
+ (0, chai_1.expect)(hover === null || hover === void 0 ? void 0 : hover.contents).to.equal([
1332
+ '```brightscript',
1333
+ 'Dog.breed as string',
1334
+ '```'
1335
+ ].join('\n'));
1336
+ });
1337
+ it('gets the correct text for m.method', () => {
1338
+ let animalCode = program.setFile('source/animal.bs', animalClassCode);
1339
+ program.validate();
1340
+ let hover = animalCode.getHover(vscode_languageserver_1.Position.create(30, 25));
1341
+ (0, chai_1.expect)(hover === null || hover === void 0 ? void 0 : hover.contents).to.equal([
1342
+ '```brightscript',
1343
+ 'sub Animal.sleep() as void',
1344
+ '```'
1345
+ ].join('\n'));
1346
+ });
1347
+ it('gets the correct text for obj.field', () => {
1348
+ let animalCode = program.setFile('source/animal.brs', animalClassCode);
1349
+ program.validate();
1350
+ let hover = animalCode.getHover(vscode_languageserver_1.Position.create(46, 33));
1351
+ (0, chai_1.expect)(hover).to.exist;
1352
+ //TODO TYPES: This should probably say 'Animal.isHungry ...' because that field is defined in Animal
1353
+ (0, chai_1.expect)(hover === null || hover === void 0 ? void 0 : hover.contents).to.equal([
1354
+ '```brightscript',
1355
+ 'Dog.isHungry as boolean',
1356
+ '```'
1357
+ ].join('\n'));
1358
+ });
1359
+ it('gets the correct text for obj.method', () => {
1360
+ let animalCode = program.setFile('source/animal.bs', `
1361
+ sub feedAnimal(beast as Animal)
1362
+ beast.eat(100)
1363
+ end sub
1364
+ class Animal
1365
+ sub eat(foodAmount as integer)
1366
+ end sub
1367
+ end class
1368
+ `);
1369
+ program.validate();
1370
+ let hover = animalCode.getHover(vscode_languageserver_1.Position.create(2, 29));
1371
+ (0, chai_1.expect)(hover === null || hover === void 0 ? void 0 : hover.contents).to.equal([
1372
+ '```brightscript',
1373
+ 'sub Animal.eat(foodAmount as integer) as void',
1374
+ '```'
1375
+ ].join('\n'));
1376
+ });
1377
+ });
1378
+ describe('getHover class members', () => {
1379
+ const testCode = `
1380
+ class Foo
1381
+ sub new (name as string)
1382
+ end sub
1383
+ end class
1384
+
1385
+ class Bar
1386
+ sub doSomething()
1387
+ myFoo = new Foo()
1388
+ end sub
1389
+
1390
+ function getInt() as integer
1391
+ return 1
1392
+ end function
1393
+ end class
1394
+
1395
+ class Buz
1396
+ myInt as integer
1397
+ sub new (i as integer)
1398
+ myInt = i
1399
+ end sub
1400
+ end class
1401
+
1402
+ class Bee extends Buz
1403
+ sub new (i as integer)
1404
+ super(i)
1405
+ end sub
1406
+
1407
+ sub varSameNameAsMember()
1408
+ myInt = 4567
1409
+ print myInt ' should not print m.myInt
1410
+ end sub
1411
+ end class`;
1412
+ it('correctly parses the file', () => {
1413
+ program.setFile('source/fooBar.bs', testCode);
1414
+ program.validate();
1415
+ (0, chai_1.expect)(program.getDiagnostics().length).to.equal(0);
1416
+ });
1417
+ it('gets the correct text for new Class()', () => {
1418
+ let file = program.setFile('source/fooBar.bs', testCode);
1419
+ program.validate();
1420
+ let hover = file.getHover(vscode_languageserver_1.Position.create(8, 34)); // new Foo("hello")
1421
+ (0, chai_1.expect)(hover === null || hover === void 0 ? void 0 : hover.contents).to.equal([
1422
+ '```brightscript',
1423
+ 'new Foo(name as string)',
1424
+ '```'
1425
+ ].join('\n'));
1426
+ });
1427
+ it('gets the correct text for created object', () => {
1428
+ let file = program.setFile('source/fooBar.bs', testCode);
1429
+ program.validate();
1430
+ let hover = file.getHover(vscode_languageserver_1.Position.create(8, 23)); // myFoo
1431
+ (0, chai_1.expect)(hover === null || hover === void 0 ? void 0 : hover.contents).to.equal([
1432
+ '```brightscript',
1433
+ 'myFoo as Foo',
1434
+ '```'
1435
+ ].join('\n'));
1436
+ });
1437
+ it('gets the correct text for class declaration', () => {
1438
+ let file = program.setFile('source/fooBar.bs', testCode);
1439
+ program.validate();
1440
+ let hover = file.getHover(vscode_languageserver_1.Position.create(6, 21)); // class Bar
1441
+ (0, chai_1.expect)(hover === null || hover === void 0 ? void 0 : hover.contents).to.equal([
1442
+ '```brightscript',
1443
+ 'class Bar',
1444
+ '```'
1445
+ ].join('\n'));
1446
+ });
1447
+ it('gets the correct text for class method declaration', () => {
1448
+ let file = program.setFile('source/fooBar.bs', testCode);
1449
+ program.validate();
1450
+ let hover = file.getHover(vscode_languageserver_1.Position.create(11, 29)); // getInt
1451
+ (0, chai_1.expect)(hover === null || hover === void 0 ? void 0 : hover.contents).to.equal([
1452
+ '```brightscript',
1453
+ 'function Bar.getInt() as integer',
1454
+ '```'
1455
+ ].join('\n'));
1456
+ });
1457
+ it('gets the correct text for class field declaration', () => {
1458
+ let file = program.setFile('source/fooBar.bs', testCode);
1459
+ program.validate();
1460
+ let hover = file.getHover(vscode_languageserver_1.Position.create(17, 20)); // myInt
1461
+ (0, chai_1.expect)(hover === null || hover === void 0 ? void 0 : hover.contents).to.equal([
1462
+ '```brightscript',
1463
+ 'Buz.myInt as integer',
1464
+ '```'
1465
+ ].join('\n'));
1466
+ });
1467
+ it('gets the correct text for super() call', () => {
1468
+ let file = program.setFile('source/fooBar.bs', testCode);
1469
+ program.validate();
1470
+ let hover = file.getHover(vscode_languageserver_1.Position.create(25, 23)); // super() in Bee.new
1471
+ (0, chai_1.expect)(hover === null || hover === void 0 ? void 0 : hover.contents).to.equal([
1472
+ '```brightscript',
1473
+ 'new Buz(i as integer)',
1474
+ '```'
1475
+ ].join('\n'));
1476
+ });
1477
+ it('gets the correct text for variable with same name as a member', () => {
1478
+ let file = program.setFile('source/fooBar.bs', testCode);
1479
+ program.validate();
1480
+ let hover = file.getHover(vscode_languageserver_1.Position.create(29, 23)); // myInt in Bee.varSameNameAsMember
1481
+ (0, chai_1.expect)(hover === null || hover === void 0 ? void 0 : hover.contents).to.equal([
1482
+ '```brightscript',
1483
+ 'myInt as integer',
1484
+ '```'
1485
+ ].join('\n'));
1486
+ });
1487
+ });
1488
+ describe('getSymbolTypeFromToken', () => {
1489
+ const testClassCode = `
1490
+ sub main()
1491
+ c = new KlassC()
1492
+ a = c.b.getA()
1493
+ num = c.b.getA().getInt()
1494
+ c.b.getA().printInt(num)
1495
+ end sub
1496
+ class KlassA
1497
+ function getInt() as integer
1498
+ return 1
1499
+ end function
1500
+
1501
+ sub printInt(i as integer)
1502
+ print i
1503
+ end sub
1504
+ end class
1505
+
1506
+ class KlassB
1507
+
1508
+ function getA() as KlassA
1509
+ return new KlassA()
1510
+ end function
1511
+ end class
1512
+
1513
+ class KlassC
1514
+ public b as KlassB
1515
+
1516
+ sub new ()
1517
+ m.b = new KlassB()
1518
+ end sub
1519
+ end class
1520
+ `;
1521
+ it('correctly parses the file', () => {
1522
+ program.setFile('source/klassTest.bs', testClassCode);
1523
+ program.validate();
1524
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(program);
1525
+ });
1526
+ describe('finding tokens', () => {
1527
+ let klassCode;
1528
+ let mainScope;
1529
+ beforeEach(() => {
1530
+ klassCode = program.setFile('source/klassTest.bs', testClassCode);
1531
+ const scopes = program.getScopesForFile(klassCode);
1532
+ (0, chai_1.expect)(scopes.length).to.eql(1);
1533
+ mainScope = scopes[0];
1534
+ mainScope.linkSymbolTable();
1535
+ });
1536
+ afterEach(() => {
1537
+ mainScope.unlinkSymbolTable();
1538
+ });
1539
+ it('gets correct class for m', () => {
1540
+ var _a;
1541
+ const position = vscode_languageserver_1.Position.create(28, 20); // 'm' from m.b = new KlassB()
1542
+ const token = klassCode.parser.getTokenAt(position);
1543
+ (0, chai_1.expect)(token.text).to.equal('m');
1544
+ const func = klassCode.getFunctionExpressionAtPosition(position);
1545
+ let klass = (_a = klassCode.getClassFromToken(token, func, mainScope)) === null || _a === void 0 ? void 0 : _a.item;
1546
+ (0, chai_1.expect)(klass).to.exist;
1547
+ (0, chai_1.expect)(klass.getName(Parser_1.ParseMode.BrighterScript)).to.equal('KlassC');
1548
+ });
1549
+ it('gets correct class for fieldMember', () => {
1550
+ var _a;
1551
+ const position = vscode_languageserver_1.Position.create(28, 23); // 'b' from m.b = new KlassB()
1552
+ const token = klassCode.parser.getTokenAt(position);
1553
+ (0, chai_1.expect)(token.text).to.equal('b');
1554
+ const func = klassCode.getFunctionExpressionAtPosition(position);
1555
+ let klass = (_a = klassCode.getClassFromToken(token, func, mainScope)) === null || _a === void 0 ? void 0 : _a.item;
1556
+ (0, chai_1.expect)(klass).to.exist;
1557
+ (0, chai_1.expect)(klass.getName(Parser_1.ParseMode.BrighterScript)).to.equal('KlassB');
1558
+ });
1559
+ it('gets correct class for variable', () => {
1560
+ var _a;
1561
+ const position = vscode_languageserver_1.Position.create(4, 22); // 'c' from c.b.getA().getInt()
1562
+ const token = klassCode.parser.getTokenAt(position);
1563
+ (0, chai_1.expect)(token.text).to.equal('c');
1564
+ const func = klassCode.getFunctionExpressionAtPosition(position);
1565
+ let klass = (_a = klassCode.getClassFromToken(token, func, mainScope)) === null || _a === void 0 ? void 0 : _a.item;
1566
+ (0, chai_1.expect)(klass).to.exist;
1567
+ (0, chai_1.expect)(klass.getName(Parser_1.ParseMode.BrighterScript)).to.equal('KlassC');
1568
+ });
1569
+ it('gets correct class for variable field', () => {
1570
+ var _a;
1571
+ const position = vscode_languageserver_1.Position.create(3, 23); // 'b' from c.b.getA()
1572
+ const token = klassCode.parser.getTokenAt(position);
1573
+ (0, chai_1.expect)(token.text).to.equal('b');
1574
+ const func = klassCode.getFunctionExpressionAtPosition(position);
1575
+ let klass = (_a = klassCode.getClassFromToken(token, func, mainScope)) === null || _a === void 0 ? void 0 : _a.item;
1576
+ (0, chai_1.expect)(klass).to.exist;
1577
+ (0, chai_1.expect)(klass.getName(Parser_1.ParseMode.BrighterScript)).to.equal('KlassB');
1578
+ });
1579
+ it('gets type and return class for variable function field', () => {
1580
+ const position = vscode_languageserver_1.Position.create(3, 28); // 'getA' from c.b.getA()
1581
+ const token = klassCode.parser.getTokenAt(position);
1582
+ (0, chai_1.expect)(token.text).to.equal('getA');
1583
+ const func = klassCode.getFunctionExpressionAtPosition(position);
1584
+ let { type, symbolContainer } = klassCode.getSymbolTypeFromToken(token, func, mainScope);
1585
+ (0, chai_1.expect)((0, reflection_1.isTypedFunctionType)(type)).to.be.true;
1586
+ (0, chai_1.expect)((0, reflection_1.isCustomType)(symbolContainer)).to.be.true;
1587
+ (0, chai_1.expect)(symbolContainer.name).to.equal('KlassA');
1588
+ });
1589
+ it('gets type and class for field from return value of function', () => {
1590
+ const position = vscode_languageserver_1.Position.create(4, 37); // 'getInt' from c.b.getA().getInt()
1591
+ const token = klassCode.parser.getTokenAt(position);
1592
+ (0, chai_1.expect)(token.text).to.equal('getInt');
1593
+ const func = klassCode.getFunctionExpressionAtPosition(position);
1594
+ let { type, symbolContainer } = klassCode.getSymbolTypeFromToken(token, func, mainScope);
1595
+ (0, chai_1.expect)(type).to.exist;
1596
+ (0, chai_1.expect)((0, reflection_1.isTypedFunctionType)(type)).to.be.true;
1597
+ (0, chai_1.expect)(symbolContainer).to.be.undefined; // getInt() returns integer - no class reference at this point
1598
+ });
1078
1599
  });
1079
1600
  });
1601
+ it('does not crash when child has field with same name as sub in parent', () => {
1602
+ program.setFile('source/main.bs', `
1603
+ class Parent
1604
+ public function helloWorld()
1605
+ end function
1606
+ end class
1607
+ class Child extends Parent
1608
+ public helloWorld as string
1609
+ end class
1610
+ `);
1611
+ program.validate();
1612
+ });
1613
+ it('does not crash when child has method with same name as field in parent', () => {
1614
+ program.setFile('source/main.bs', `
1615
+ class Parent
1616
+ public helloWorld as string
1617
+ end class
1618
+ class Child extends Parent
1619
+ public function helloWorld()
1620
+ end function
1621
+ end class
1622
+ `);
1623
+ program.validate();
1624
+ });
1625
+ it.skip('detects calling class constructors with too many parameters', () => {
1626
+ program.setFile('source/main.bs', `
1627
+ class Parameterless
1628
+ sub new ()
1629
+ end sub
1630
+ end class
1631
+
1632
+ class OneParam
1633
+ sub new (param1)
1634
+ end sub
1635
+ end class
1636
+
1637
+ sub main()
1638
+ c1 = new Parameterless(1)
1639
+ c2 = new OneParam(1, 2)
1640
+ c2 = new OneParam()
1641
+ end sub
1642
+ `);
1643
+ program.validate();
1644
+ (0, testHelpers_spec_1.expectDiagnostics)(program, [
1645
+ DiagnosticMessages_1.DiagnosticMessages.mismatchArgumentCount(0, 1),
1646
+ DiagnosticMessages_1.DiagnosticMessages.mismatchArgumentCount(1, 2),
1647
+ DiagnosticMessages_1.DiagnosticMessages.mismatchArgumentCount(1, 0)
1648
+ ]);
1649
+ });
1080
1650
  });
1081
1651
  //# sourceMappingURL=BrsFile.Class.spec.js.map