brighterscript 0.66.0-alpha.9 → 0.67.0

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 (472) hide show
  1. package/CHANGELOG.md +116 -73
  2. package/README.md +14 -418
  3. package/dist/BsConfig.d.ts +25 -2
  4. package/dist/Cache.js +3 -3
  5. package/dist/Cache.js.map +1 -1
  6. package/dist/CodeActionUtil.d.ts +3 -3
  7. package/dist/CodeActionUtil.js.map +1 -1
  8. package/dist/CommentFlagProcessor.d.ts +3 -4
  9. package/dist/CommentFlagProcessor.js +4 -3
  10. package/dist/CommentFlagProcessor.js.map +1 -1
  11. package/dist/DependencyGraph.js +8 -8
  12. package/dist/DependencyGraph.js.map +1 -1
  13. package/dist/DiagnosticFilterer.d.ts +8 -4
  14. package/dist/DiagnosticFilterer.js +71 -38
  15. package/dist/DiagnosticFilterer.js.map +1 -1
  16. package/dist/DiagnosticMessages.d.ts +15 -36
  17. package/dist/DiagnosticMessages.js +15 -61
  18. package/dist/DiagnosticMessages.js.map +1 -1
  19. package/dist/DiagnosticSeverityAdjuster.js +3 -0
  20. package/dist/DiagnosticSeverityAdjuster.js.map +1 -1
  21. package/dist/FunctionScope.d.ts +2 -3
  22. package/dist/FunctionScope.js +0 -3
  23. package/dist/FunctionScope.js.map +1 -1
  24. package/dist/LanguageServer.d.ts +1 -2
  25. package/dist/LanguageServer.js +29 -35
  26. package/dist/LanguageServer.js.map +1 -1
  27. package/dist/Logger.d.ts +5 -9
  28. package/dist/Logger.js +18 -22
  29. package/dist/Logger.js.map +1 -1
  30. package/dist/PluginInterface.d.ts +13 -15
  31. package/dist/PluginInterface.js +16 -70
  32. package/dist/PluginInterface.js.map +1 -1
  33. package/dist/Program.d.ts +105 -138
  34. package/dist/Program.js +479 -702
  35. package/dist/Program.js.map +1 -1
  36. package/dist/ProgramBuilder.d.ts +8 -19
  37. package/dist/ProgramBuilder.js +82 -87
  38. package/dist/ProgramBuilder.js.map +1 -1
  39. package/dist/Scope.d.ts +56 -46
  40. package/dist/Scope.js +281 -217
  41. package/dist/Scope.js.map +1 -1
  42. package/dist/Stopwatch.js +1 -1
  43. package/dist/Stopwatch.js.map +1 -1
  44. package/dist/SymbolTable.d.ts +12 -68
  45. package/dist/SymbolTable.js +28 -213
  46. package/dist/SymbolTable.js.map +1 -1
  47. package/dist/XmlScope.d.ts +5 -7
  48. package/dist/XmlScope.js +36 -76
  49. package/dist/XmlScope.js.map +1 -1
  50. package/dist/astUtils/{Editor.d.ts → AstEditor.d.ts} +1 -6
  51. package/dist/astUtils/{Editor.js → AstEditor.js} +3 -9
  52. package/dist/astUtils/AstEditor.js.map +1 -0
  53. package/dist/astUtils/{Editor.spec.js → AstEditor.spec.js} +6 -10
  54. package/dist/astUtils/AstEditor.spec.js.map +1 -0
  55. package/dist/astUtils/creators.d.ts +8 -19
  56. package/dist/astUtils/creators.js +22 -54
  57. package/dist/astUtils/creators.js.map +1 -1
  58. package/dist/astUtils/creators.spec.js +0 -10
  59. package/dist/astUtils/creators.spec.js.map +1 -1
  60. package/dist/astUtils/reflection.d.ts +45 -81
  61. package/dist/astUtils/reflection.js +157 -220
  62. package/dist/astUtils/reflection.js.map +1 -1
  63. package/dist/astUtils/reflection.spec.js +19 -96
  64. package/dist/astUtils/reflection.spec.js.map +1 -1
  65. package/dist/astUtils/stackedVisitor.spec.js.map +1 -1
  66. package/dist/astUtils/visitors.d.ts +14 -18
  67. package/dist/astUtils/visitors.js +9 -22
  68. package/dist/astUtils/visitors.js.map +1 -1
  69. package/dist/astUtils/visitors.spec.js +9 -62
  70. package/dist/astUtils/visitors.spec.js.map +1 -1
  71. package/dist/astUtils/xml.d.ts +9 -9
  72. package/dist/astUtils/xml.js +6 -6
  73. package/dist/astUtils/xml.js.map +1 -1
  74. package/dist/bscPlugin/BscPlugin.d.ts +8 -11
  75. package/dist/bscPlugin/BscPlugin.js +21 -29
  76. package/dist/bscPlugin/BscPlugin.js.map +1 -1
  77. package/dist/bscPlugin/CallExpressionInfo.d.ts +6 -5
  78. package/dist/bscPlugin/CallExpressionInfo.js +2 -2
  79. package/dist/bscPlugin/CallExpressionInfo.js.map +1 -1
  80. package/dist/bscPlugin/codeActions/CodeActionsProcessor.js +11 -11
  81. package/dist/bscPlugin/codeActions/CodeActionsProcessor.js.map +1 -1
  82. package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js +4 -4
  83. package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js.map +1 -1
  84. package/dist/bscPlugin/completions/CompletionsProcessor.d.ts +1 -49
  85. package/dist/bscPlugin/completions/CompletionsProcessor.js +23 -424
  86. package/dist/bscPlugin/completions/CompletionsProcessor.js.map +1 -1
  87. package/dist/bscPlugin/definition/DefinitionProvider.d.ts +13 -0
  88. package/dist/bscPlugin/definition/DefinitionProvider.js +200 -0
  89. package/dist/bscPlugin/definition/DefinitionProvider.js.map +1 -0
  90. package/dist/bscPlugin/definition/DefinitionProvider.spec.js +87 -0
  91. package/dist/bscPlugin/definition/DefinitionProvider.spec.js.map +1 -0
  92. package/dist/bscPlugin/hover/HoverProcessor.d.ts +3 -7
  93. package/dist/bscPlugin/hover/HoverProcessor.js +88 -128
  94. package/dist/bscPlugin/hover/HoverProcessor.js.map +1 -1
  95. package/dist/bscPlugin/hover/HoverProcessor.spec.js +24 -336
  96. package/dist/bscPlugin/hover/HoverProcessor.spec.js.map +1 -1
  97. package/dist/bscPlugin/references/ReferencesProvider.d.ts +12 -0
  98. package/dist/bscPlugin/references/ReferencesProvider.js +56 -0
  99. package/dist/bscPlugin/references/ReferencesProvider.js.map +1 -0
  100. package/dist/bscPlugin/references/ReferencesProvider.spec.js +51 -0
  101. package/dist/bscPlugin/references/ReferencesProvider.spec.js.map +1 -0
  102. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.d.ts +0 -1
  103. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js +5 -49
  104. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js.map +1 -1
  105. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js +0 -22
  106. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js.map +1 -1
  107. package/dist/bscPlugin/symbols/DocumentSymbolProcessor.d.ts +7 -0
  108. package/dist/bscPlugin/symbols/DocumentSymbolProcessor.js +22 -0
  109. package/dist/bscPlugin/symbols/DocumentSymbolProcessor.js.map +1 -0
  110. package/dist/bscPlugin/symbols/DocumentSymbolProcessor.spec.js +290 -0
  111. package/dist/bscPlugin/symbols/DocumentSymbolProcessor.spec.js.map +1 -0
  112. package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.d.ts +7 -0
  113. package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.js +26 -0
  114. package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.js.map +1 -0
  115. package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.spec.js +245 -0
  116. package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.spec.js.map +1 -0
  117. package/dist/bscPlugin/symbols/symbolUtils.d.ts +5 -0
  118. package/dist/bscPlugin/symbols/symbolUtils.js +140 -0
  119. package/dist/bscPlugin/symbols/symbolUtils.js.map +1 -0
  120. package/dist/bscPlugin/transpile/{BrsFileTranspileProcessor.d.ts → BrsFilePreTranspileProcessor.d.ts} +2 -4
  121. package/dist/bscPlugin/transpile/{BrsFileTranspileProcessor.js → BrsFilePreTranspileProcessor.js} +15 -36
  122. package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.js.map +1 -0
  123. package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.js +46 -0
  124. package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.js.map +1 -0
  125. package/dist/bscPlugin/validation/BrsFileValidator.d.ts +1 -0
  126. package/dist/bscPlugin/validation/BrsFileValidator.js +30 -41
  127. package/dist/bscPlugin/validation/BrsFileValidator.js.map +1 -1
  128. package/dist/bscPlugin/validation/BrsFileValidator.spec.js +2 -2
  129. package/dist/bscPlugin/validation/BrsFileValidator.spec.js.map +1 -1
  130. package/dist/bscPlugin/validation/ProgramValidator.d.ts +3 -3
  131. package/dist/bscPlugin/validation/ProgramValidator.js +6 -6
  132. package/dist/bscPlugin/validation/ProgramValidator.js.map +1 -1
  133. package/dist/bscPlugin/validation/ScopeValidator.d.ts +6 -28
  134. package/dist/bscPlugin/validation/ScopeValidator.js +166 -387
  135. package/dist/bscPlugin/validation/ScopeValidator.js.map +1 -1
  136. package/dist/bscPlugin/validation/XmlFileValidator.js +9 -9
  137. package/dist/bscPlugin/validation/XmlFileValidator.js.map +1 -1
  138. package/dist/diagnosticUtils.d.ts +2 -3
  139. package/dist/diagnosticUtils.js +5 -5
  140. package/dist/diagnosticUtils.js.map +1 -1
  141. package/dist/examples/plugins/removePrint.js +1 -1
  142. package/dist/examples/plugins/removePrint.js.map +1 -1
  143. package/dist/files/BrsFile.Class.spec.js +143 -114
  144. package/dist/files/BrsFile.Class.spec.js.map +1 -1
  145. package/dist/files/BrsFile.d.ts +61 -83
  146. package/dist/files/BrsFile.js +552 -607
  147. package/dist/files/BrsFile.js.map +1 -1
  148. package/dist/files/BrsFile.spec.js +1365 -1201
  149. package/dist/files/BrsFile.spec.js.map +1 -1
  150. package/dist/files/XmlFile.d.ts +28 -56
  151. package/dist/files/XmlFile.js +103 -89
  152. package/dist/files/XmlFile.js.map +1 -1
  153. package/dist/files/XmlFile.spec.js +179 -122
  154. package/dist/files/XmlFile.spec.js.map +1 -1
  155. package/dist/files/tests/imports.spec.js +19 -29
  156. package/dist/files/tests/imports.spec.js.map +1 -1
  157. package/dist/files/tests/optionalChaning.spec.js +14 -14
  158. package/dist/files/tests/optionalChaning.spec.js.map +1 -1
  159. package/dist/globalCallables.js +83 -88
  160. package/dist/globalCallables.js.map +1 -1
  161. package/dist/index.d.ts +1 -9
  162. package/dist/index.js +1 -9
  163. package/dist/index.js.map +1 -1
  164. package/dist/interfaces.d.ts +173 -423
  165. package/dist/interfaces.js +0 -24
  166. package/dist/interfaces.js.map +1 -1
  167. package/dist/lexer/Lexer.d.ts +9 -15
  168. package/dist/lexer/Lexer.js +35 -46
  169. package/dist/lexer/Lexer.js.map +1 -1
  170. package/dist/lexer/Lexer.spec.js +48 -40
  171. package/dist/lexer/Lexer.spec.js.map +1 -1
  172. package/dist/lexer/Token.d.ts +1 -5
  173. package/dist/lexer/Token.js +1 -1
  174. package/dist/lexer/Token.js.map +1 -1
  175. package/dist/lexer/TokenKind.d.ts +0 -6
  176. package/dist/lexer/TokenKind.js +2 -14
  177. package/dist/lexer/TokenKind.js.map +1 -1
  178. package/dist/logging.d.ts +9 -0
  179. package/dist/logging.js +16 -0
  180. package/dist/logging.js.map +1 -0
  181. package/dist/parser/AstNode.d.ts +6 -90
  182. package/dist/parser/AstNode.js +5 -96
  183. package/dist/parser/AstNode.js.map +1 -1
  184. package/dist/parser/AstNode.spec.js.map +1 -1
  185. package/dist/parser/BrsTranspileState.d.ts +3 -4
  186. package/dist/parser/BrsTranspileState.js +2 -3
  187. package/dist/parser/BrsTranspileState.js.map +1 -1
  188. package/dist/parser/Expression.d.ts +114 -137
  189. package/dist/parser/Expression.js +244 -373
  190. package/dist/parser/Expression.js.map +1 -1
  191. package/dist/parser/Parser.Class.spec.js +19 -46
  192. package/dist/parser/Parser.Class.spec.js.map +1 -1
  193. package/dist/parser/Parser.d.ts +18 -14
  194. package/dist/parser/Parser.js +196 -175
  195. package/dist/parser/Parser.js.map +1 -1
  196. package/dist/parser/Parser.spec.d.ts +0 -2
  197. package/dist/parser/Parser.spec.js +10 -674
  198. package/dist/parser/Parser.spec.js.map +1 -1
  199. package/dist/parser/SGParser.d.ts +6 -44
  200. package/dist/parser/SGParser.js +198 -194
  201. package/dist/parser/SGParser.js.map +1 -1
  202. package/dist/parser/SGParser.spec.js +11 -14
  203. package/dist/parser/SGParser.spec.js.map +1 -1
  204. package/dist/parser/SGTypes.d.ts +52 -280
  205. package/dist/parser/SGTypes.js +185 -562
  206. package/dist/parser/SGTypes.js.map +1 -1
  207. package/dist/parser/Statement.d.ts +140 -172
  208. package/dist/parser/Statement.js +201 -337
  209. package/dist/parser/Statement.js.map +1 -1
  210. package/dist/parser/Statement.spec.js.map +1 -1
  211. package/dist/parser/TranspileState.d.ts +3 -2
  212. package/dist/parser/TranspileState.js +8 -10
  213. package/dist/parser/TranspileState.js.map +1 -1
  214. package/dist/parser/tests/Parser.spec.js +3 -5
  215. package/dist/parser/tests/Parser.spec.js.map +1 -1
  216. package/dist/parser/tests/controlFlow/For.spec.js +8 -16
  217. package/dist/parser/tests/controlFlow/For.spec.js.map +1 -1
  218. package/dist/parser/tests/controlFlow/ForEach.spec.js +6 -12
  219. package/dist/parser/tests/controlFlow/ForEach.spec.js.map +1 -1
  220. package/dist/parser/tests/controlFlow/While.spec.js +4 -8
  221. package/dist/parser/tests/controlFlow/While.spec.js.map +1 -1
  222. package/dist/parser/tests/expression/Call.spec.js +4 -4
  223. package/dist/parser/tests/expression/Call.spec.js.map +1 -1
  224. package/dist/parser/tests/expression/Indexing.spec.js +25 -0
  225. package/dist/parser/tests/expression/Indexing.spec.js.map +1 -1
  226. package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js +73 -29
  227. package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js.map +1 -1
  228. package/dist/parser/tests/expression/RegexLiteralExpression.spec.js +10 -10
  229. package/dist/parser/tests/expression/RegexLiteralExpression.spec.js.map +1 -1
  230. package/dist/parser/tests/expression/SourceLiteralExpression.spec.js +24 -24
  231. package/dist/parser/tests/expression/SourceLiteralExpression.spec.js.map +1 -1
  232. package/dist/parser/tests/expression/TemplateStringExpression.spec.js +47 -35
  233. package/dist/parser/tests/expression/TemplateStringExpression.spec.js.map +1 -1
  234. package/dist/parser/tests/expression/TernaryExpression.spec.js +83 -36
  235. package/dist/parser/tests/expression/TernaryExpression.spec.js.map +1 -1
  236. package/dist/parser/tests/expression/UnaryExpression.spec.js +2 -2
  237. package/dist/parser/tests/expression/UnaryExpression.spec.js.map +1 -1
  238. package/dist/parser/tests/statement/ConstStatement.spec.js +26 -27
  239. package/dist/parser/tests/statement/ConstStatement.spec.js.map +1 -1
  240. package/dist/parser/tests/statement/Continue.spec.js +2 -2
  241. package/dist/parser/tests/statement/Continue.spec.js.map +1 -1
  242. package/dist/parser/tests/statement/Dim.spec.js.map +1 -1
  243. package/dist/parser/tests/statement/Enum.spec.js +393 -90
  244. package/dist/parser/tests/statement/Enum.spec.js.map +1 -1
  245. package/dist/parser/tests/statement/For.spec.js +6 -6
  246. package/dist/parser/tests/statement/For.spec.js.map +1 -1
  247. package/dist/parser/tests/statement/ForEach.spec.js +4 -4
  248. package/dist/parser/tests/statement/ForEach.spec.js.map +1 -1
  249. package/dist/parser/tests/statement/Function.spec.js +1 -1
  250. package/dist/parser/tests/statement/Function.spec.js.map +1 -1
  251. package/dist/parser/tests/statement/InterfaceStatement.spec.js +18 -18
  252. package/dist/parser/tests/statement/InterfaceStatement.spec.js.map +1 -1
  253. package/dist/parser/tests/statement/Misc.spec.js.map +1 -1
  254. package/dist/parser/tests/statement/PrintStatement.spec.js +13 -16
  255. package/dist/parser/tests/statement/PrintStatement.spec.js.map +1 -1
  256. package/dist/parser/tests/statement/ReturnStatement.spec.js +3 -5
  257. package/dist/parser/tests/statement/ReturnStatement.spec.js.map +1 -1
  258. package/dist/parser/tests/statement/Set.spec.js +13 -26
  259. package/dist/parser/tests/statement/Set.spec.js.map +1 -1
  260. package/dist/parser/tests/statement/Throw.spec.js.map +1 -1
  261. package/dist/parser/tests/statement/TryCatch.spec.js.map +1 -1
  262. package/dist/preprocessor/Chunk.js +1 -2
  263. package/dist/preprocessor/Chunk.js.map +1 -1
  264. package/dist/preprocessor/Preprocessor.d.ts +3 -4
  265. package/dist/preprocessor/Preprocessor.js +3 -3
  266. package/dist/preprocessor/Preprocessor.js.map +1 -1
  267. package/dist/preprocessor/PreprocessorParser.js +8 -1
  268. package/dist/preprocessor/PreprocessorParser.js.map +1 -1
  269. package/dist/roku-types/data.json +293 -243
  270. package/dist/roku-types/index.d.ts +38 -17
  271. package/dist/types/ArrayType.d.ts +4 -9
  272. package/dist/types/ArrayType.js +24 -72
  273. package/dist/types/ArrayType.js.map +1 -1
  274. package/dist/types/ArrayType.spec.js +10 -39
  275. package/dist/types/ArrayType.spec.js.map +1 -1
  276. package/dist/types/BooleanType.d.ts +4 -8
  277. package/dist/types/BooleanType.js +8 -19
  278. package/dist/types/BooleanType.js.map +1 -1
  279. package/dist/types/BooleanType.spec.js +3 -9
  280. package/dist/types/BooleanType.spec.js.map +1 -1
  281. package/dist/types/BscType.d.ts +2 -29
  282. package/dist/types/BscType.js +0 -113
  283. package/dist/types/BscType.js.map +1 -1
  284. package/dist/types/CustomType.d.ts +9 -0
  285. package/dist/types/CustomType.js +32 -0
  286. package/dist/types/CustomType.js.map +1 -0
  287. package/dist/types/DoubleType.d.ts +4 -8
  288. package/dist/types/DoubleType.js +20 -23
  289. package/dist/types/DoubleType.js.map +1 -1
  290. package/dist/types/DoubleType.spec.js +3 -11
  291. package/dist/types/DoubleType.spec.js.map +1 -1
  292. package/dist/types/DynamicType.d.ts +3 -9
  293. package/dist/types/DynamicType.js +2 -18
  294. package/dist/types/DynamicType.js.map +1 -1
  295. package/dist/types/DynamicType.spec.js +4 -15
  296. package/dist/types/DynamicType.spec.js.map +1 -1
  297. package/dist/types/FloatType.d.ts +4 -8
  298. package/dist/types/FloatType.js +20 -23
  299. package/dist/types/FloatType.js.map +1 -1
  300. package/dist/types/FloatType.spec.js +3 -3
  301. package/dist/types/FloatType.spec.js.map +1 -1
  302. package/dist/types/FunctionType.d.ts +20 -10
  303. package/dist/types/FunctionType.js +52 -27
  304. package/dist/types/FunctionType.js.map +1 -1
  305. package/dist/types/FunctionType.spec.js +23 -0
  306. package/dist/types/FunctionType.spec.js.map +1 -0
  307. package/dist/types/IntegerType.d.ts +4 -8
  308. package/dist/types/IntegerType.js +20 -23
  309. package/dist/types/IntegerType.js.map +1 -1
  310. package/dist/types/IntegerType.spec.js +3 -7
  311. package/dist/types/IntegerType.spec.js.map +1 -1
  312. package/dist/types/InterfaceType.d.ts +10 -12
  313. package/dist/types/InterfaceType.js +48 -23
  314. package/dist/types/InterfaceType.js.map +1 -1
  315. package/dist/types/InterfaceType.spec.js +45 -82
  316. package/dist/types/InterfaceType.spec.js.map +1 -1
  317. package/dist/types/InvalidType.d.ts +4 -7
  318. package/dist/types/InvalidType.js +8 -18
  319. package/dist/types/InvalidType.js.map +1 -1
  320. package/dist/types/InvalidType.spec.js +3 -7
  321. package/dist/types/InvalidType.spec.js.map +1 -1
  322. package/dist/types/LongIntegerType.d.ts +4 -8
  323. package/dist/types/LongIntegerType.js +20 -23
  324. package/dist/types/LongIntegerType.js.map +1 -1
  325. package/dist/types/LongIntegerType.spec.js +3 -9
  326. package/dist/types/LongIntegerType.spec.js.map +1 -1
  327. package/dist/types/ObjectType.d.ts +4 -8
  328. package/dist/types/ObjectType.js +7 -21
  329. package/dist/types/ObjectType.js.map +1 -1
  330. package/dist/types/ObjectType.spec.js +2 -2
  331. package/dist/types/ObjectType.spec.js.map +1 -1
  332. package/dist/types/StringType.d.ts +4 -11
  333. package/dist/types/StringType.js +8 -23
  334. package/dist/types/StringType.js.map +1 -1
  335. package/dist/types/StringType.spec.js +2 -2
  336. package/dist/types/StringType.spec.js.map +1 -1
  337. package/dist/types/UninitializedType.d.ts +3 -7
  338. package/dist/types/UninitializedType.js +3 -14
  339. package/dist/types/UninitializedType.js.map +1 -1
  340. package/dist/types/VoidType.d.ts +4 -8
  341. package/dist/types/VoidType.js +8 -18
  342. package/dist/types/VoidType.js.map +1 -1
  343. package/dist/types/VoidType.spec.js +2 -2
  344. package/dist/types/VoidType.spec.js.map +1 -1
  345. package/dist/util.d.ts +43 -104
  346. package/dist/util.js +243 -640
  347. package/dist/util.js.map +1 -1
  348. package/dist/validators/ClassValidator.d.ts +6 -1
  349. package/dist/validators/ClassValidator.js +61 -20
  350. package/dist/validators/ClassValidator.js.map +1 -1
  351. package/package.json +13 -11
  352. package/dist/ActionPipeline.d.ts +0 -10
  353. package/dist/ActionPipeline.js +0 -40
  354. package/dist/ActionPipeline.js.map +0 -1
  355. package/dist/AstValidationSegmenter.d.ts +0 -25
  356. package/dist/AstValidationSegmenter.js +0 -150
  357. package/dist/AstValidationSegmenter.js.map +0 -1
  358. package/dist/CacheVerifier.d.ts +0 -7
  359. package/dist/CacheVerifier.js +0 -20
  360. package/dist/CacheVerifier.js.map +0 -1
  361. package/dist/astUtils/Editor.js.map +0 -1
  362. package/dist/astUtils/Editor.spec.js.map +0 -1
  363. package/dist/bscPlugin/FileWriter.d.ts +0 -6
  364. package/dist/bscPlugin/FileWriter.js +0 -24
  365. package/dist/bscPlugin/FileWriter.js.map +0 -1
  366. package/dist/bscPlugin/completions/CompletionsProcessor.spec.js +0 -1658
  367. package/dist/bscPlugin/completions/CompletionsProcessor.spec.js.map +0 -1
  368. package/dist/bscPlugin/fileProviders/FileProvider.d.ts +0 -9
  369. package/dist/bscPlugin/fileProviders/FileProvider.js +0 -51
  370. package/dist/bscPlugin/fileProviders/FileProvider.js.map +0 -1
  371. package/dist/bscPlugin/serialize/BslibInjector.spec.js +0 -19
  372. package/dist/bscPlugin/serialize/BslibInjector.spec.js.map +0 -1
  373. package/dist/bscPlugin/serialize/BslibManager.d.ts +0 -9
  374. package/dist/bscPlugin/serialize/BslibManager.js +0 -40
  375. package/dist/bscPlugin/serialize/BslibManager.js.map +0 -1
  376. package/dist/bscPlugin/serialize/FileSerializer.d.ts +0 -9
  377. package/dist/bscPlugin/serialize/FileSerializer.js +0 -72
  378. package/dist/bscPlugin/serialize/FileSerializer.js.map +0 -1
  379. package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.js.map +0 -1
  380. package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.spec.js +0 -41
  381. package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.spec.js.map +0 -1
  382. package/dist/bscPlugin/transpile/XmlFilePreTranspileProcessor.d.ts +0 -11
  383. package/dist/bscPlugin/transpile/XmlFilePreTranspileProcessor.js +0 -53
  384. package/dist/bscPlugin/transpile/XmlFilePreTranspileProcessor.js.map +0 -1
  385. package/dist/bscPlugin/validation/ScopeValidator.spec.js +0 -2004
  386. package/dist/bscPlugin/validation/ScopeValidator.spec.js.map +0 -1
  387. package/dist/files/AssetFile.d.ts +0 -26
  388. package/dist/files/AssetFile.js +0 -26
  389. package/dist/files/AssetFile.js.map +0 -1
  390. package/dist/files/Factory.d.ts +0 -25
  391. package/dist/files/Factory.js +0 -22
  392. package/dist/files/Factory.js.map +0 -1
  393. package/dist/files/File.d.ts +0 -106
  394. package/dist/files/File.js +0 -16
  395. package/dist/files/File.js.map +0 -1
  396. package/dist/files/LazyFileData.d.ts +0 -20
  397. package/dist/files/LazyFileData.js +0 -54
  398. package/dist/files/LazyFileData.js.map +0 -1
  399. package/dist/files/LazyFileData.spec.js +0 -27
  400. package/dist/files/LazyFileData.spec.js.map +0 -1
  401. package/dist/parser/tests/expression/TypeExpression.spec.js +0 -127
  402. package/dist/parser/tests/expression/TypeExpression.spec.js.map +0 -1
  403. package/dist/types/AssociativeArrayType.d.ts +0 -11
  404. package/dist/types/AssociativeArrayType.js +0 -52
  405. package/dist/types/AssociativeArrayType.js.map +0 -1
  406. package/dist/types/BaseFunctionType.d.ts +0 -9
  407. package/dist/types/BaseFunctionType.js +0 -25
  408. package/dist/types/BaseFunctionType.js.map +0 -1
  409. package/dist/types/BscTypeKind.d.ts +0 -25
  410. package/dist/types/BscTypeKind.js +0 -30
  411. package/dist/types/BscTypeKind.js.map +0 -1
  412. package/dist/types/BuiltInInterfaceAdder.d.ts +0 -23
  413. package/dist/types/BuiltInInterfaceAdder.js +0 -160
  414. package/dist/types/BuiltInInterfaceAdder.js.map +0 -1
  415. package/dist/types/BuiltInInterfaceAdder.spec.d.ts +0 -1
  416. package/dist/types/BuiltInInterfaceAdder.spec.js +0 -116
  417. package/dist/types/BuiltInInterfaceAdder.spec.js.map +0 -1
  418. package/dist/types/ClassType.d.ts +0 -17
  419. package/dist/types/ClassType.js +0 -58
  420. package/dist/types/ClassType.js.map +0 -1
  421. package/dist/types/ClassType.spec.d.ts +0 -1
  422. package/dist/types/ClassType.spec.js +0 -77
  423. package/dist/types/ClassType.spec.js.map +0 -1
  424. package/dist/types/ComponentType.d.ts +0 -26
  425. package/dist/types/ComponentType.js +0 -83
  426. package/dist/types/ComponentType.js.map +0 -1
  427. package/dist/types/EnumType.d.ts +0 -40
  428. package/dist/types/EnumType.js +0 -81
  429. package/dist/types/EnumType.js.map +0 -1
  430. package/dist/types/EnumType.spec.d.ts +0 -1
  431. package/dist/types/EnumType.spec.js +0 -33
  432. package/dist/types/EnumType.spec.js.map +0 -1
  433. package/dist/types/InheritableType.d.ts +0 -28
  434. package/dist/types/InheritableType.js +0 -152
  435. package/dist/types/InheritableType.js.map +0 -1
  436. package/dist/types/NamespaceType.d.ts +0 -12
  437. package/dist/types/NamespaceType.js +0 -28
  438. package/dist/types/NamespaceType.js.map +0 -1
  439. package/dist/types/ReferenceType.d.ts +0 -63
  440. package/dist/types/ReferenceType.js +0 -423
  441. package/dist/types/ReferenceType.js.map +0 -1
  442. package/dist/types/ReferenceType.spec.d.ts +0 -1
  443. package/dist/types/ReferenceType.spec.js +0 -137
  444. package/dist/types/ReferenceType.spec.js.map +0 -1
  445. package/dist/types/TypedFunctionType.d.ts +0 -33
  446. package/dist/types/TypedFunctionType.js +0 -106
  447. package/dist/types/TypedFunctionType.js.map +0 -1
  448. package/dist/types/TypedFunctionType.spec.d.ts +0 -1
  449. package/dist/types/TypedFunctionType.spec.js +0 -122
  450. package/dist/types/TypedFunctionType.spec.js.map +0 -1
  451. package/dist/types/UnionType.d.ts +0 -20
  452. package/dist/types/UnionType.js +0 -123
  453. package/dist/types/UnionType.js.map +0 -1
  454. package/dist/types/UnionType.spec.d.ts +0 -1
  455. package/dist/types/UnionType.spec.js +0 -130
  456. package/dist/types/UnionType.spec.js.map +0 -1
  457. package/dist/types/helper.spec.d.ts +0 -1
  458. package/dist/types/helper.spec.js +0 -145
  459. package/dist/types/helper.spec.js.map +0 -1
  460. package/dist/types/helpers.d.ts +0 -24
  461. package/dist/types/helpers.js +0 -178
  462. package/dist/types/helpers.js.map +0 -1
  463. package/dist/types/index.d.ts +0 -22
  464. package/dist/types/index.js +0 -39
  465. package/dist/types/index.js.map +0 -1
  466. /package/dist/astUtils/{Editor.spec.d.ts → AstEditor.spec.d.ts} +0 -0
  467. /package/dist/bscPlugin/{completions/CompletionsProcessor.spec.d.ts → definition/DefinitionProvider.spec.d.ts} +0 -0
  468. /package/dist/bscPlugin/{serialize/BslibInjector.spec.d.ts → references/ReferencesProvider.spec.d.ts} +0 -0
  469. /package/dist/bscPlugin/{transpile/BrsFileTranspileProcessor.spec.d.ts → symbols/DocumentSymbolProcessor.spec.d.ts} +0 -0
  470. /package/dist/bscPlugin/{validation/ScopeValidator.spec.d.ts → symbols/WorkspaceSymbolProcessor.spec.d.ts} +0 -0
  471. /package/dist/{files/LazyFileData.spec.d.ts → bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.d.ts} +0 -0
  472. /package/dist/{parser/tests/expression/TypeExpression.spec.d.ts → types/FunctionType.spec.d.ts} +0 -0
@@ -6,7 +6,7 @@ const vscode_languageserver_1 = require("vscode-languageserver");
6
6
  const Program_1 = require("../Program");
7
7
  const BooleanType_1 = require("../types/BooleanType");
8
8
  const DynamicType_1 = require("../types/DynamicType");
9
- const TypedFunctionType_1 = require("../types/TypedFunctionType");
9
+ const FunctionType_1 = require("../types/FunctionType");
10
10
  const IntegerType_1 = require("../types/IntegerType");
11
11
  const StringType_1 = require("../types/StringType");
12
12
  const BrsFile_1 = require("./BrsFile");
@@ -15,16 +15,17 @@ const Lexer_1 = require("../lexer/Lexer");
15
15
  const TokenKind_1 = require("../lexer/TokenKind");
16
16
  const DiagnosticMessages_1 = require("../DiagnosticMessages");
17
17
  const util_1 = require("../util");
18
+ const PluginInterface_1 = require("../PluginInterface");
18
19
  const testHelpers_spec_1 = require("../testHelpers.spec");
19
20
  const Parser_1 = require("../parser/Parser");
21
+ const logging_1 = require("../logging");
20
22
  const Statement_1 = require("../parser/Statement");
21
23
  const creators_1 = require("../astUtils/creators");
22
24
  const fsExtra = require("fs-extra");
23
25
  const vscode_uri_1 = require("vscode-uri");
24
26
  const undent_1 = require("undent");
25
27
  const testHelpers_spec_2 = require("../testHelpers.spec");
26
- const SymbolTable_1 = require("../SymbolTable");
27
- const types_1 = require("../types");
28
+ const fileUrl = require("file-url");
28
29
  let sinon = sinonImport.createSandbox();
29
30
  describe('BrsFile', () => {
30
31
  let program;
@@ -36,41 +37,12 @@ describe('BrsFile', () => {
36
37
  beforeEach(() => {
37
38
  fsExtra.emptyDirSync(testHelpers_spec_2.tempDir);
38
39
  program = new Program_1.Program({ rootDir: testHelpers_spec_2.rootDir, sourceMap: true });
39
- file = new BrsFile_1.BrsFile({
40
- srcPath: srcPath,
41
- destPath: destPath,
42
- program: program
43
- });
40
+ file = new BrsFile_1.BrsFile(srcPath, destPath, program);
44
41
  });
45
42
  afterEach(() => {
46
43
  sinon.restore();
47
44
  program.dispose();
48
45
  });
49
- describe('constructor', () => {
50
- it('calculates correct paths when no pkgPath specified', () => {
51
- (0, chai_config_spec_1.expect)(new BrsFile_1.BrsFile({
52
- srcPath: (0, util_1.standardizePath) `${testHelpers_spec_2.rootDir}/source/main.bs`,
53
- destPath: (0, util_1.standardizePath) `source/main.bs`,
54
- program: program
55
- })).to.include({
56
- srcPath: (0, util_1.standardizePath) `${testHelpers_spec_2.rootDir}/source/main.bs`,
57
- destPath: (0, util_1.standardizePath) `source/main.bs`,
58
- pkgPath: (0, util_1.standardizePath) `source/main.brs`
59
- });
60
- });
61
- it('uses supplied pkgPath', () => {
62
- (0, chai_config_spec_1.expect)(new BrsFile_1.BrsFile({
63
- srcPath: (0, util_1.standardizePath) `${testHelpers_spec_2.rootDir}/source/main.bs`,
64
- destPath: (0, util_1.standardizePath) `source/main.bs`,
65
- pkgPath: (0, util_1.standardizePath) `source/main.transpiled.brs`,
66
- program: program
67
- })).to.include({
68
- srcPath: (0, util_1.standardizePath) `${testHelpers_spec_2.rootDir}/source/main.bs`,
69
- destPath: (0, util_1.standardizePath) `source/main.bs`,
70
- pkgPath: (0, util_1.standardizePath) `source/main.transpiled.brs`
71
- });
72
- });
73
- });
74
46
  describe('allowBrighterScriptInBrightScript', () => {
75
47
  it('is false by default', () => {
76
48
  program.setFile('source/main.brs', `
@@ -127,29 +99,6 @@ describe('BrsFile', () => {
127
99
  program.validate();
128
100
  (0, testHelpers_spec_1.expectZeroDiagnostics)(program);
129
101
  });
130
- it('flags enums used as variables', () => {
131
- program.setFile('source/main.bs', `
132
- enum Foo
133
- bar
134
- baz
135
- end enum
136
-
137
- sub main()
138
- print getFooValue()
139
- print getFoo()
140
- end sub
141
-
142
- function getFoo() as Foo
143
- return Foo ' Error - cannot return an enum, just an enum value
144
- end function
145
-
146
- function getFooValue() as Foo
147
- return Foo.bar
148
- end function
149
- `);
150
- program.validate();
151
- (0, testHelpers_spec_1.expectDiagnostics)(program, [DiagnosticMessages_1.DiagnosticMessages.itemCannotBeUsedAsVariable('enum').message]);
152
- });
153
102
  it('supports the third parameter in CreateObject', () => {
154
103
  program.setFile('source/main.brs', `
155
104
  sub main()
@@ -170,17 +119,9 @@ describe('BrsFile', () => {
170
119
  });
171
120
  it('sets needsTranspiled to true for .bs files', () => {
172
121
  //BrightScript
173
- (0, chai_config_spec_1.expect)(new BrsFile_1.BrsFile({
174
- srcPath: `${testHelpers_spec_2.rootDir}/source/main.brs`,
175
- destPath: 'source/main.brs',
176
- program: program
177
- })['needsTranspiled']).to.be.false;
122
+ (0, chai_config_spec_1.expect)(new BrsFile_1.BrsFile(`${testHelpers_spec_2.rootDir}/source/main.brs`, 'source/main.brs', program).needsTranspiled).to.be.false;
178
123
  //BrighterScript
179
- (0, chai_config_spec_1.expect)(new BrsFile_1.BrsFile({
180
- srcPath: `${testHelpers_spec_2.rootDir}/source/main.bs`,
181
- destPath: 'source/main.bs',
182
- program: program
183
- })['needsTranspiled']).to.be.true;
124
+ (0, chai_config_spec_1.expect)(new BrsFile_1.BrsFile(`${testHelpers_spec_2.rootDir}/source/main.bs`, 'source/main.bs', program).needsTranspiled).to.be.true;
184
125
  });
185
126
  it('computes new import statements after clearing parser references', () => {
186
127
  const file = program.setFile('source/main.bs', ``);
@@ -199,6 +140,75 @@ describe('BrsFile', () => {
199
140
  file.addDiagnostics(expected);
200
141
  (0, testHelpers_spec_1.expectDiagnostics)(file, expected);
201
142
  });
143
+ describe('getPartialVariableName', () => {
144
+ let entry = {
145
+ src: `${testHelpers_spec_2.rootDir}/source/lib.brs`,
146
+ dest: `source/lib.brs`
147
+ };
148
+ it('creates proper tokens', () => {
149
+ file = program.setFile(entry, `call(ModuleA.ModuleB.ModuleC.`);
150
+ (0, chai_config_spec_1.expect)(file['getPartialVariableName'](file.parser.tokens[7])).to.equal('ModuleA.ModuleB.ModuleC.');
151
+ (0, chai_config_spec_1.expect)(file['getPartialVariableName'](file.parser.tokens[6])).to.equal('ModuleA.ModuleB.ModuleC');
152
+ (0, chai_config_spec_1.expect)(file['getPartialVariableName'](file.parser.tokens[5])).to.equal('ModuleA.ModuleB.');
153
+ (0, chai_config_spec_1.expect)(file['getPartialVariableName'](file.parser.tokens[4])).to.equal('ModuleA.ModuleB');
154
+ (0, chai_config_spec_1.expect)(file['getPartialVariableName'](file.parser.tokens[3])).to.equal('ModuleA.');
155
+ (0, chai_config_spec_1.expect)(file['getPartialVariableName'](file.parser.tokens[2])).to.equal('ModuleA');
156
+ });
157
+ });
158
+ describe('canBePruned', () => {
159
+ it('returns false is target file has contains a function statement', () => {
160
+ program.setFile('source/main.brs', `
161
+ sub main()
162
+ print \`pkg:\`
163
+ end sub
164
+ `);
165
+ const file = program.getFile('source/main.brs');
166
+ (0, chai_config_spec_1.expect)(file.canBePruned).to.be.false;
167
+ });
168
+ it('returns false if target file contains a class statement', () => {
169
+ program.setFile('source/main.brs', `
170
+ class Animal
171
+ public name as string
172
+ end class
173
+ `);
174
+ const file = program.getFile('source/main.brs');
175
+ (0, chai_config_spec_1.expect)(file.canBePruned).to.be.false;
176
+ });
177
+ it('returns false if target file contains a class statement', () => {
178
+ program.setFile('source/main.brs', `
179
+ namespace Vertibrates.Birds
180
+ function GetDucks()
181
+ end function
182
+ end namespace
183
+ `);
184
+ const file = program.getFile('source/main.brs');
185
+ (0, chai_config_spec_1.expect)(file.canBePruned).to.be.false;
186
+ });
187
+ it('returns true if target file contains only enum', () => {
188
+ program.setFile('source/main.brs', `
189
+ enum Direction
190
+ up
191
+ down
192
+ left
193
+ right
194
+ end enum
195
+ `);
196
+ const file = program.getFile('source/main.brs');
197
+ (0, chai_config_spec_1.expect)(file.canBePruned).to.be.true;
198
+ });
199
+ it('returns true if target file is empty', () => {
200
+ program.setFile('source/main.brs', '');
201
+ const file = program.getFile('source/main.brs');
202
+ (0, chai_config_spec_1.expect)(file.canBePruned).to.be.true;
203
+ });
204
+ it('returns true if target file only has comments', () => {
205
+ program.setFile('source/main.brs', `
206
+ ' this is an interesting comment
207
+ `);
208
+ const file = program.getFile('source/main.brs');
209
+ (0, chai_config_spec_1.expect)(file.canBePruned).to.be.true;
210
+ });
211
+ });
202
212
  describe('getScopesForFile', () => {
203
213
  it('finds the scope for the file', () => {
204
214
  var _a;
@@ -206,6 +216,238 @@ describe('BrsFile', () => {
206
216
  (0, chai_config_spec_1.expect)((_a = program.getScopesForFile(file)[0]) === null || _a === void 0 ? void 0 : _a.name).to.equal('source');
207
217
  });
208
218
  });
219
+ describe('getCompletions', () => {
220
+ it('does not crash for callfunc on a function call', () => {
221
+ const file = program.setFile('source/main.brs', `
222
+ sub main()
223
+ getManager()@.
224
+ end sub
225
+ `);
226
+ (0, chai_config_spec_1.expect)(() => {
227
+ program.getCompletions(file.srcPath, util_1.default.createPosition(2, 34));
228
+ }).not.to.throw;
229
+ });
230
+ it('suggests pkg paths in strings that match that criteria', () => {
231
+ program.setFile('source/main.brs', `
232
+ sub main()
233
+ print "pkg:"
234
+ end sub
235
+ `);
236
+ const result = program.getCompletions(`${testHelpers_spec_2.rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(2, 31));
237
+ const names = result.map(x => x.label);
238
+ (0, chai_config_spec_1.expect)(names.sort()).to.eql([
239
+ 'pkg:/source/main.brs'
240
+ ]);
241
+ });
242
+ it('suggests libpkg paths in strings that match that criteria', () => {
243
+ program.setFile('source/main.brs', `
244
+ sub main()
245
+ print "libpkg:"
246
+ end sub
247
+ `);
248
+ const result = program.getCompletions(`${testHelpers_spec_2.rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(2, 31));
249
+ const names = result.map(x => x.label);
250
+ (0, chai_config_spec_1.expect)(names.sort()).to.eql([
251
+ 'libpkg:/source/main.brs'
252
+ ]);
253
+ });
254
+ it('suggests pkg paths in template strings', () => {
255
+ program.setFile('source/main.brs', `
256
+ sub main()
257
+ print \`pkg:\`
258
+ end sub
259
+ `);
260
+ const result = program.getCompletions(`${testHelpers_spec_2.rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(2, 31));
261
+ const names = result.map(x => x.label);
262
+ (0, chai_config_spec_1.expect)(names.sort()).to.eql([
263
+ 'pkg:/source/main.brs'
264
+ ]);
265
+ });
266
+ it('waits for the file to be processed before collecting completions', () => {
267
+ //eslint-disable-next-line @typescript-eslint/no-floating-promises
268
+ program.setFile('source/main.brs', `
269
+ sub Main()
270
+ print "hello"
271
+ Say
272
+ end sub
273
+
274
+ sub SayHello()
275
+ end sub
276
+ `);
277
+ let result = program.getCompletions(`${testHelpers_spec_2.rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(3, 23));
278
+ let names = result.map(x => x.label);
279
+ (0, chai_config_spec_1.expect)(names).to.includes('Main');
280
+ (0, chai_config_spec_1.expect)(names).to.includes('SayHello');
281
+ });
282
+ it('includes every type of item at base level', () => {
283
+ program.setFile('source/main.bs', `
284
+ sub main()
285
+ print
286
+ end sub
287
+ sub speak()
288
+ end sub
289
+ namespace stuff
290
+ end namespace
291
+ class Person
292
+ end class
293
+ enum Direction
294
+ end enum
295
+ `);
296
+ (0, testHelpers_spec_1.expectCompletionsIncludes)(program.getCompletions('source/main.bs', util_1.default.createPosition(2, 26)), [{
297
+ label: 'main',
298
+ kind: vscode_languageserver_1.CompletionItemKind.Function
299
+ }, {
300
+ label: 'speak',
301
+ kind: vscode_languageserver_1.CompletionItemKind.Function
302
+ }, {
303
+ label: 'stuff',
304
+ kind: vscode_languageserver_1.CompletionItemKind.Module
305
+ }, {
306
+ label: 'Person',
307
+ kind: vscode_languageserver_1.CompletionItemKind.Class
308
+ }, {
309
+ label: 'Direction',
310
+ kind: vscode_languageserver_1.CompletionItemKind.Enum
311
+ }]);
312
+ });
313
+ describe('namespaces', () => {
314
+ it('gets full namespace completions at any point through the leading identifier', () => {
315
+ program.setFile('source/main.bs', `
316
+ sub main()
317
+ foo.bar
318
+ end sub
319
+
320
+ namespace foo.bar
321
+ end namespace
322
+
323
+ class Person
324
+ end class
325
+ `);
326
+ const result = program.getCompletions(`${testHelpers_spec_2.rootDir}/source/main.bs`, vscode_languageserver_1.Position.create(2, 24)).map(x => x.label);
327
+ (0, chai_config_spec_1.expect)(result).includes('main');
328
+ (0, chai_config_spec_1.expect)(result).includes('foo');
329
+ (0, chai_config_spec_1.expect)(result).includes('Person');
330
+ });
331
+ it('gets namespace completions', () => {
332
+ program.setFile('source/main.bs', `
333
+ namespace foo.bar
334
+ function sayHello()
335
+ end function
336
+ end namespace
337
+
338
+ sub Main()
339
+ print "hello"
340
+ foo.ba
341
+ foo.bar.
342
+ end sub
343
+ `);
344
+ let result = program.getCompletions(`${testHelpers_spec_2.rootDir}/source/main.bs`, vscode_languageserver_1.Position.create(8, 30));
345
+ let names = result.map(x => x.label);
346
+ (0, chai_config_spec_1.expect)(names).to.includes('bar');
347
+ result = program.getCompletions(`${testHelpers_spec_2.rootDir}/source/main.bs`, vscode_languageserver_1.Position.create(9, 32));
348
+ names = result.map(x => x.label);
349
+ (0, chai_config_spec_1.expect)(names).to.includes('sayHello');
350
+ });
351
+ });
352
+ it('always includes `m`', () => {
353
+ //eslint-disable-next-line @typescript-eslint/no-floating-promises
354
+ program.setFile('source/main.brs', `
355
+ sub Main()
356
+
357
+ end sub
358
+ `);
359
+ let result = program.getCompletions(`${testHelpers_spec_2.rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(2, 23));
360
+ let names = result.map(x => x.label);
361
+ (0, chai_config_spec_1.expect)(names).to.contain('m');
362
+ });
363
+ it('does not fail for missing previousToken', () => {
364
+ //add a single character to the file, and get completions after it
365
+ program.setFile('source/main.brs', `i`);
366
+ (0, chai_config_spec_1.expect)(() => {
367
+ program.getCompletions(`${testHelpers_spec_2.rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(0, 1)).map(x => x.label);
368
+ }).not.to.throw;
369
+ });
370
+ it('includes all keywords`', () => {
371
+ //eslint-disable-next-line @typescript-eslint/no-floating-promises
372
+ program.setFile('source/main.brs', `
373
+ sub Main()
374
+
375
+ end sub
376
+ `);
377
+ let keywords = Object.keys(TokenKind_1.Keywords).filter(x => !x.includes(' '));
378
+ //inside the function
379
+ let result = program.getCompletions(`${testHelpers_spec_2.rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(2, 23));
380
+ let names = result.map(x => x.label);
381
+ for (let keyword of keywords) {
382
+ (0, chai_config_spec_1.expect)(names).to.include(keyword);
383
+ }
384
+ //outside the function
385
+ result = program.getCompletions(`${testHelpers_spec_2.rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(4, 8));
386
+ names = result.map(x => x.label);
387
+ for (let keyword of keywords) {
388
+ (0, chai_config_spec_1.expect)(names).to.include(keyword);
389
+ }
390
+ });
391
+ it('does not provide completions within a comment', () => {
392
+ //eslint-disable-next-line @typescript-eslint/no-floating-promises
393
+ program.setFile('source/main.brs', `
394
+ sub Main()
395
+ 'some comment
396
+ end sub
397
+ `);
398
+ //inside the function
399
+ let result = program.getCompletions(`${testHelpers_spec_2.rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(2, 33));
400
+ (0, chai_config_spec_1.expect)(result).to.be.lengthOf(0);
401
+ });
402
+ it('does not provide duplicate entries for variables', () => {
403
+ //eslint-disable-next-line @typescript-eslint/no-floating-promises
404
+ program.setFile('source/main.brs', `
405
+ sub Main()
406
+ name = "bob"
407
+ age = 12
408
+ name = "john"
409
+ end sub
410
+ `);
411
+ let result = program.getCompletions(`${testHelpers_spec_2.rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(3, 23));
412
+ let count = result.reduce((total, x) => {
413
+ return x.label === 'name' ? total + 1 : total;
414
+ }, 0);
415
+ (0, chai_config_spec_1.expect)(count).to.equal(1);
416
+ });
417
+ it('does not include `as` and `string` text options when used in function params', () => {
418
+ //eslint-disable-next-line @typescript-eslint/no-floating-promises
419
+ program.setFile('source/main.brs', `
420
+ sub Main(name as string)
421
+
422
+ end sub
423
+ `);
424
+ let result = program.getCompletions(`${testHelpers_spec_2.rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(2, 23));
425
+ (0, chai_config_spec_1.expect)(result.filter(x => x.kind === vscode_languageserver_1.CompletionItemKind.Text)).not.to.contain('as');
426
+ (0, chai_config_spec_1.expect)(result.filter(x => x.kind === vscode_languageserver_1.CompletionItemKind.Text)).not.to.contain('string');
427
+ });
428
+ it('does not provide intellisense results when inside a comment', () => {
429
+ //eslint-disable-next-line @typescript-eslint/no-floating-promises
430
+ program.setFile('source/main.brs', `
431
+ sub Main(name as string)
432
+ 'this is a comment
433
+ end sub
434
+ `);
435
+ let results = program.getCompletions(`${testHelpers_spec_2.rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(2, 30));
436
+ (0, chai_config_spec_1.expect)(results).to.be.empty;
437
+ });
438
+ it('does provide intellisence for labels only after a goto keyword', () => {
439
+ var _a;
440
+ //eslint-disable-next-line @typescript-eslint/no-floating-promises
441
+ program.setFile('source/main.brs', `
442
+ sub Main(name as string)
443
+ something:
444
+ goto \nend sub
445
+ `);
446
+ let results = program.getCompletions(`${testHelpers_spec_2.rootDir}/source/main.brs`, vscode_languageserver_1.Position.create(3, 25));
447
+ (0, chai_config_spec_1.expect)(results.length).to.equal(1);
448
+ (0, chai_config_spec_1.expect)((_a = results[0]) === null || _a === void 0 ? void 0 : _a.label).to.equal('something');
449
+ });
450
+ });
209
451
  describe('comment flags', () => {
210
452
  describe('bs:disable-next-line', () => {
211
453
  it('disables critical diagnostic issues', () => {
@@ -288,12 +530,12 @@ describe('BrsFile', () => {
288
530
  something = true 'bs:disable-line: LINT1005
289
531
  end sub
290
532
  `);
291
- file.diagnostics.push({
292
- code: 'LINT1005',
293
- file: file,
294
- message: 'Something is not right',
295
- range: util_1.default.createRange(2, 16, 2, 26)
296
- });
533
+ file.addDiagnostics([{
534
+ code: 'LINT1005',
535
+ file: file,
536
+ message: 'Something is not right',
537
+ range: util_1.default.createRange(2, 16, 2, 26)
538
+ }]);
297
539
  const scope = program.getScopesForFile(file)[0];
298
540
  (0, testHelpers_spec_1.expectZeroDiagnostics)(scope);
299
541
  });
@@ -435,6 +677,27 @@ describe('BrsFile', () => {
435
677
  (0, testHelpers_spec_1.expectZeroDiagnostics)(file);
436
678
  });
437
679
  describe('conditional compile', () => {
680
+ it('supports whitespace-separated directives', () => {
681
+ const file = program.setFile('source/main.bs', `
682
+ sub main()
683
+ #\t const thing=true
684
+ #\t if thing
685
+ print "if"
686
+ #\t elseif false
687
+ print "elseif"
688
+ #\t error crash
689
+ #\t else
690
+ print "else"
691
+ #\t endif
692
+ end sub
693
+ `);
694
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(program);
695
+ testTranspile(file.fileContents, `
696
+ sub main()
697
+ print "if"
698
+ end sub
699
+ `);
700
+ });
438
701
  it('supports case-insensitive bs_const variables', () => {
439
702
  fsExtra.outputFileSync(`${testHelpers_spec_2.rootDir}/manifest`, (0, undent_1.default) `
440
703
  bs_const=SomeKey=true
@@ -801,7 +1064,6 @@ describe('BrsFile', () => {
801
1064
  file.parse(`
802
1065
  sub Main()
803
1066
  doWork = function(callback as function)
804
- callback()
805
1067
  end function
806
1068
  end sub
807
1069
  `);
@@ -978,11 +1240,7 @@ describe('BrsFile', () => {
978
1240
  `);
979
1241
  });
980
1242
  it('finds line and column numbers for functions', () => {
981
- let file = new BrsFile_1.BrsFile({
982
- srcPath: 'absolute_path/file.brs',
983
- destPath: 'relative_path/file.brs',
984
- program: program
985
- });
1243
+ let file = new BrsFile_1.BrsFile('absolute_path/file.brs', 'relative_path/file.brs', program);
986
1244
  file.parse(`
987
1245
  function DoA()
988
1246
  print "A"
@@ -998,11 +1256,7 @@ describe('BrsFile', () => {
998
1256
  (0, chai_config_spec_1.expect)(file.callables[1].nameRange).to.eql(vscode_languageserver_1.Range.create(5, 26, 5, 29));
999
1257
  });
1000
1258
  it('throws an error if the file has already been parsed', () => {
1001
- let file = new BrsFile_1.BrsFile({
1002
- srcPath: 'abspath',
1003
- destPath: 'relpath',
1004
- program: program
1005
- });
1259
+ let file = new BrsFile_1.BrsFile('abspath', 'relpath', program);
1006
1260
  file.parse(`'a comment`);
1007
1261
  try {
1008
1262
  file.parse(`'a new comment`);
@@ -1013,11 +1267,7 @@ describe('BrsFile', () => {
1013
1267
  }
1014
1268
  });
1015
1269
  it('finds and registers duplicate callables', () => {
1016
- let file = new BrsFile_1.BrsFile({
1017
- srcPath: 'absolute_path/file.brs',
1018
- destPath: 'relative_path/file.brs',
1019
- program: program
1020
- });
1270
+ let file = new BrsFile_1.BrsFile('absolute_path/file.brs', 'relative_path/file.brs', program);
1021
1271
  file.parse(`
1022
1272
  function DoA()
1023
1273
  print "A"
@@ -1034,11 +1284,7 @@ describe('BrsFile', () => {
1034
1284
  (0, chai_config_spec_1.expect)(file.callables[1].nameRange.start.line).to.equal(5);
1035
1285
  });
1036
1286
  it('finds function call line and column numbers', () => {
1037
- let file = new BrsFile_1.BrsFile({
1038
- srcPath: 'absolute_path/file.brs',
1039
- destPath: 'relative_path/file.brs',
1040
- program: program
1041
- });
1287
+ let file = new BrsFile_1.BrsFile('absolute_path/file.brs', 'relative_path/file.brs', program);
1042
1288
  file.parse(`
1043
1289
  function DoA()
1044
1290
  DoB("a")
@@ -1054,11 +1300,7 @@ describe('BrsFile', () => {
1054
1300
  (0, chai_config_spec_1.expect)(file.functionCalls[1].nameRange).to.eql(vscode_languageserver_1.Range.create(5, 20, 5, 23));
1055
1301
  });
1056
1302
  it('finds function calls that are unfinished', () => {
1057
- let file = new BrsFile_1.BrsFile({
1058
- srcPath: 'absolute_path/file.brs',
1059
- destPath: 'relative_path/file.brs',
1060
- program: program
1061
- });
1303
+ let file = new BrsFile_1.BrsFile('absolute_path/file.brs', 'relative_path/file.brs', program);
1062
1304
  file.parse(`
1063
1305
  function DoA()
1064
1306
  DoB("a"
@@ -1081,11 +1323,7 @@ describe('BrsFile', () => {
1081
1323
  (0, chai_config_spec_1.expect)(file.functionCalls[1].nameRange).to.eql(vscode_languageserver_1.Range.create(5, 20, 5, 23));
1082
1324
  });
1083
1325
  it('sanitizes brs errors', () => {
1084
- let file = new BrsFile_1.BrsFile({
1085
- srcPath: 'absolute_path/file.brs',
1086
- destPath: 'relative_path/file.brs',
1087
- program: program
1088
- });
1326
+ let file = new BrsFile_1.BrsFile('absolute_path/file.brs', 'relative_path/file.brs', program);
1089
1327
  file.parse(`
1090
1328
  function DoSomething
1091
1329
  end function
@@ -1095,11 +1333,7 @@ describe('BrsFile', () => {
1095
1333
  (0, chai_config_spec_1.expect)(file.getDiagnostics()[0].range.start.line).to.equal(1);
1096
1334
  });
1097
1335
  it('supports using the `next` keyword in a for loop', () => {
1098
- let file = new BrsFile_1.BrsFile({
1099
- srcPath: 'absolute_path/file.brs',
1100
- destPath: 'relative_path/file.brs',
1101
- program: program
1102
- });
1336
+ let file = new BrsFile_1.BrsFile('absolute_path/file.brs', 'relative_path/file.brs', program);
1103
1337
  file.parse(`
1104
1338
  sub countit()
1105
1339
  for each num in [1,2,3]
@@ -1111,11 +1345,7 @@ describe('BrsFile', () => {
1111
1345
  });
1112
1346
  //test is not working yet, but will be enabled when brs supports this syntax
1113
1347
  it('supports assigning functions to objects', () => {
1114
- let file = new BrsFile_1.BrsFile({
1115
- srcPath: 'absolute_path/file.brs',
1116
- destPath: 'relative_path/file.brs',
1117
- program: program
1118
- });
1348
+ let file = new BrsFile_1.BrsFile('absolute_path/file.brs', 'relative_path/file.brs', program);
1119
1349
  file.parse(`
1120
1350
  function main()
1121
1351
  o = CreateObject("roAssociativeArray")
@@ -1126,28 +1356,10 @@ describe('BrsFile', () => {
1126
1356
  `);
1127
1357
  (0, testHelpers_spec_1.expectZeroDiagnostics)(file);
1128
1358
  });
1129
- it('supports parameter types in functions in AA literals', () => {
1130
- program.setFile('source/main.brs', `
1131
- sub main()
1132
- aa = {
1133
- name: "test"
1134
- addInts: function(a as integer, b as integer) as integer
1135
- return a + b
1136
- end function
1137
- }
1138
- end sub
1139
- `);
1140
- program.validate();
1141
- (0, testHelpers_spec_1.expectZeroDiagnostics)(program);
1142
- });
1143
1359
  });
1144
1360
  describe('findCallables', () => {
1145
1361
  it('finds range', () => {
1146
- let file = new BrsFile_1.BrsFile({
1147
- srcPath: 'absolute_path/file.brs',
1148
- destPath: 'relative_path/file.brs',
1149
- program: program
1150
- });
1362
+ let file = new BrsFile_1.BrsFile('absolute_path/file.brs', 'relative_path/file.brs', program);
1151
1363
  file.parse(`
1152
1364
  sub Sum()
1153
1365
  print "hello world"
@@ -1157,11 +1369,7 @@ describe('BrsFile', () => {
1157
1369
  (0, chai_config_spec_1.expect)(callable.range).to.eql(vscode_languageserver_1.Range.create(1, 16, 3, 23));
1158
1370
  });
1159
1371
  it('finds correct body range even with inner function', () => {
1160
- let file = new BrsFile_1.BrsFile({
1161
- srcPath: 'absolute_path/file.brs',
1162
- destPath: 'relative_path/file.brs',
1163
- program: program
1164
- });
1372
+ let file = new BrsFile_1.BrsFile('absolute_path/file.brs', 'relative_path/file.brs', program);
1165
1373
  file.parse(`
1166
1374
  sub Sum()
1167
1375
  sayHi = sub()
@@ -1174,11 +1382,7 @@ describe('BrsFile', () => {
1174
1382
  (0, chai_config_spec_1.expect)(callable.range).to.eql(vscode_languageserver_1.Range.create(1, 16, 6, 23));
1175
1383
  });
1176
1384
  it('finds callable parameters', () => {
1177
- let file = new BrsFile_1.BrsFile({
1178
- srcPath: 'absolute_path/file.brs',
1179
- destPath: 'relative_path/file.brs',
1180
- program: program
1181
- });
1385
+ let file = new BrsFile_1.BrsFile('absolute_path/file.brs', 'relative_path/file.brs', program);
1182
1386
  file.parse(`
1183
1387
  function Sum(a, b, c)
1184
1388
 
@@ -1205,11 +1409,7 @@ describe('BrsFile', () => {
1205
1409
  (0, chai_config_spec_1.expect)(callable.params[2].type).instanceof(DynamicType_1.DynamicType);
1206
1410
  });
1207
1411
  it('finds optional parameters', () => {
1208
- let file = new BrsFile_1.BrsFile({
1209
- srcPath: 'absolute_path/file.brs',
1210
- destPath: 'relative_path/file.brs',
1211
- program: program
1212
- });
1412
+ let file = new BrsFile_1.BrsFile('absolute_path/file.brs', 'relative_path/file.brs', program);
1213
1413
  file.parse(`
1214
1414
  function Sum(a=2)
1215
1415
 
@@ -1221,14 +1421,10 @@ describe('BrsFile', () => {
1221
1421
  isOptional: true,
1222
1422
  isRestArgument: false
1223
1423
  });
1224
- (0, chai_config_spec_1.expect)(callable.params[0].type).instanceof(IntegerType_1.IntegerType);
1424
+ (0, chai_config_spec_1.expect)(callable.params[0].type).instanceof(DynamicType_1.DynamicType);
1225
1425
  });
1226
1426
  it('finds parameter types', () => {
1227
- let file = new BrsFile_1.BrsFile({
1228
- srcPath: 'absolute_path/file.brs',
1229
- destPath: 'relative_path/file.brs',
1230
- program: program
1231
- });
1427
+ let file = new BrsFile_1.BrsFile('absolute_path/file.brs', 'relative_path/file.brs', program);
1232
1428
  file.parse(`
1233
1429
  function Sum(a, b as integer, c as string)
1234
1430
 
@@ -1257,11 +1453,7 @@ describe('BrsFile', () => {
1257
1453
  });
1258
1454
  describe('findCallableInvocations', () => {
1259
1455
  it('finds arguments with literal values', () => {
1260
- let file = new BrsFile_1.BrsFile({
1261
- srcPath: 'absolute_path/file.brs',
1262
- destPath: 'relative_path/file.brs',
1263
- program: program
1264
- });
1456
+ let file = new BrsFile_1.BrsFile('absolute_path/file.brs', 'relative_path/file.brs', program);
1265
1457
  file.parse(`
1266
1458
  function Sum()
1267
1459
  DoSomething("name", 12, true)
@@ -1273,15 +1465,15 @@ describe('BrsFile', () => {
1273
1465
  return { type: arg.type, range: arg.range, text: arg.text };
1274
1466
  });
1275
1467
  (0, chai_config_spec_1.expect)(argsMap).to.eql([{
1276
- type: StringType_1.StringType.instance,
1468
+ type: new StringType_1.StringType(),
1277
1469
  range: util_1.default.createRange(2, 32, 2, 38),
1278
1470
  text: '"name"'
1279
1471
  }, {
1280
- type: IntegerType_1.IntegerType.instance,
1472
+ type: new IntegerType_1.IntegerType(),
1281
1473
  range: util_1.default.createRange(2, 40, 2, 42),
1282
1474
  text: '12'
1283
1475
  }, {
1284
- type: BooleanType_1.BooleanType.instance,
1476
+ type: new BooleanType_1.BooleanType(),
1285
1477
  range: util_1.default.createRange(2, 44, 2, 48),
1286
1478
  text: 'true'
1287
1479
  }]);
@@ -1296,15 +1488,11 @@ describe('BrsFile', () => {
1296
1488
  `);
1297
1489
  program.validate();
1298
1490
  (0, testHelpers_spec_1.expectDiagnostics)(program, [
1299
- DiagnosticMessages_1.DiagnosticMessages.cannotFindName('DoesNotExist')
1491
+ DiagnosticMessages_1.DiagnosticMessages.cannotFindFunction('DoesNotExist')
1300
1492
  ]);
1301
1493
  });
1302
1494
  it('finds arguments with variable values', () => {
1303
- let file = new BrsFile_1.BrsFile({
1304
- srcPath: 'absolute_path/file.brs',
1305
- destPath: 'relative_path/file.brs',
1306
- program: program
1307
- });
1495
+ let file = new BrsFile_1.BrsFile('absolute_path/file.brs', 'relative_path/file.brs', program);
1308
1496
  file.parse(`
1309
1497
  function Sum()
1310
1498
  count = 1
@@ -1331,11 +1519,7 @@ describe('BrsFile', () => {
1331
1519
  describe('findCallables', () => {
1332
1520
  //this test is to help with code coverage
1333
1521
  it('skips top-level statements', () => {
1334
- let file = new BrsFile_1.BrsFile({
1335
- srcPath: 'absolute',
1336
- destPath: 'relative',
1337
- program: program
1338
- });
1522
+ let file = new BrsFile_1.BrsFile('absolute', 'relative', program);
1339
1523
  file.parse('name = "Bob"');
1340
1524
  (0, chai_config_spec_1.expect)(file.callables.length).to.equal(0);
1341
1525
  });
@@ -1407,19 +1591,19 @@ describe('BrsFile', () => {
1407
1591
  lineIndex: 2,
1408
1592
  name: 'sayHi'
1409
1593
  });
1410
- (0, chai_config_spec_1.expect)(file.functionScopes[0].variableDeclarations[0].getType()).instanceof(TypedFunctionType_1.TypedFunctionType);
1594
+ (0, chai_config_spec_1.expect)(file.functionScopes[0].variableDeclarations[0].type).instanceof(FunctionType_1.FunctionType);
1411
1595
  (0, chai_config_spec_1.expect)(file.functionScopes[1].variableDeclarations).to.be.length(1);
1412
1596
  (0, chai_config_spec_1.expect)(file.functionScopes[1].variableDeclarations[0]).to.deep.include({
1413
1597
  lineIndex: 3,
1414
1598
  name: 'age'
1415
1599
  });
1416
- (0, chai_config_spec_1.expect)(file.functionScopes[1].variableDeclarations[0].getType()).instanceof(IntegerType_1.IntegerType);
1600
+ (0, chai_config_spec_1.expect)(file.functionScopes[1].variableDeclarations[0].type).instanceof(IntegerType_1.IntegerType);
1417
1601
  (0, chai_config_spec_1.expect)(file.functionScopes[2].variableDeclarations).to.be.length(1);
1418
1602
  (0, chai_config_spec_1.expect)(file.functionScopes[2].variableDeclarations[0]).to.deep.include({
1419
1603
  lineIndex: 7,
1420
1604
  name: 'name'
1421
1605
  });
1422
- (0, chai_config_spec_1.expect)(file.functionScopes[2].variableDeclarations[0].getType()).instanceof(StringType_1.StringType);
1606
+ (0, chai_config_spec_1.expect)(file.functionScopes[2].variableDeclarations[0].type).instanceof(StringType_1.StringType);
1423
1607
  });
1424
1608
  it('finds variable declarations inside of if statements', () => {
1425
1609
  file.parse(`
@@ -1443,31 +1627,26 @@ describe('BrsFile', () => {
1443
1627
  return "bob"
1444
1628
  end function
1445
1629
  `);
1446
- // Types are only guaranteed after validation
1447
- program.validate();
1448
- (0, testHelpers_spec_1.expectZeroDiagnostics)(program);
1449
1630
  (0, chai_config_spec_1.expect)(file.functionScopes[0].variableDeclarations).to.be.length(1);
1450
1631
  (0, chai_config_spec_1.expect)(file.functionScopes[0].variableDeclarations[0]).to.deep.include({
1451
1632
  lineIndex: 2,
1452
1633
  name: 'myName'
1453
1634
  });
1454
- (0, testHelpers_spec_1.expectTypeToBe)(file.functionScopes[0].variableDeclarations[0].getType(), StringType_1.StringType);
1635
+ (0, chai_config_spec_1.expect)(file.functionScopes[0].variableDeclarations[0].type).instanceof(StringType_1.StringType);
1455
1636
  });
1456
1637
  it('finds variable type from other variable', () => {
1457
- let file = program.setFile('source/main.brs', `
1638
+ file.parse(`
1458
1639
  sub Main()
1459
1640
  name = "bob"
1460
1641
  nameCopy = name
1461
1642
  end sub
1462
1643
  `);
1463
- // Types are only guaranteed after validation
1464
- program.validate();
1465
1644
  (0, chai_config_spec_1.expect)(file.functionScopes[0].variableDeclarations).to.be.length(2);
1466
1645
  (0, chai_config_spec_1.expect)(file.functionScopes[0].variableDeclarations[1]).to.deep.include({
1467
1646
  lineIndex: 3,
1468
1647
  name: 'nameCopy'
1469
1648
  });
1470
- (0, testHelpers_spec_1.expectTypeToBe)(file.functionScopes[0].variableDeclarations[1].getType(), StringType_1.StringType);
1649
+ (0, chai_config_spec_1.expect)(file.functionScopes[0].variableDeclarations[1].type).instanceof(StringType_1.StringType);
1471
1650
  });
1472
1651
  it('sets proper range for functions', () => {
1473
1652
  file.parse(`
@@ -1490,7 +1669,7 @@ describe('BrsFile', () => {
1490
1669
  end if
1491
1670
  end sub
1492
1671
  `);
1493
- (0, testHelpers_spec_1.expectZeroDiagnostics)(mainFile);
1672
+ (0, chai_config_spec_1.expect)(mainFile.getDiagnostics()).to.be.lengthOf(0);
1494
1673
  mainFile = program.setFile('source/main.brs', `
1495
1674
  sub Main()
1496
1675
  if true Then
@@ -1498,7 +1677,7 @@ describe('BrsFile', () => {
1498
1677
  end if
1499
1678
  end sub
1500
1679
  `);
1501
- (0, testHelpers_spec_1.expectZeroDiagnostics)(mainFile);
1680
+ (0, chai_config_spec_1.expect)(mainFile.getDiagnostics()).to.be.lengthOf(0);
1502
1681
  mainFile = program.setFile('source/main.brs', `
1503
1682
  sub Main()
1504
1683
  if true THEN
@@ -1506,80 +1685,589 @@ describe('BrsFile', () => {
1506
1685
  end if
1507
1686
  end sub
1508
1687
  `);
1509
- (0, testHelpers_spec_1.expectZeroDiagnostics)(mainFile);
1510
- });
1511
- it('does not throw when encountering incomplete import statement', () => {
1512
- program.setFile('source/main.brs', `
1513
- import
1514
- sub main()
1515
- end sub
1516
- `);
1517
- program.validate();
1518
- //this test will throw an exception if something went wrong
1688
+ (0, chai_config_spec_1.expect)(mainFile.getDiagnostics()).to.be.lengthOf(0);
1519
1689
  });
1520
- describe('transpile', () => {
1521
- it('excludes trailing commas in array literals', async () => {
1522
- await testTranspile(`
1523
- sub main()
1524
- arr = [
1525
- 1,
1526
- 2,
1527
- 3
1528
- ]
1529
- obj = {
1530
- one: 1,
1531
- two: 2,
1532
- three: 3
1533
- }
1534
- end sub
1535
- `, `
1536
- sub main()
1537
- arr = [
1538
- 1
1539
- 2
1540
- 3
1541
- ]
1542
- obj = {
1543
- one: 1
1544
- two: 2
1545
- three: 3
1546
- }
1690
+ describe('getHover', () => {
1691
+ it('works for param types', () => {
1692
+ let file = program.setFile('source/main.brs', `
1693
+ sub DoSomething(name as string)
1694
+ name = 1
1695
+ sayMyName = function(name as string)
1696
+ end function
1547
1697
  end sub
1548
1698
  `);
1699
+ //hover over the `name = 1` line
1700
+ let hover = program.getHover(file.srcPath, vscode_languageserver_1.Position.create(2, 24))[0];
1701
+ (0, chai_config_spec_1.expect)(hover).to.exist;
1702
+ (0, chai_config_spec_1.expect)(hover.range).to.eql(vscode_languageserver_1.Range.create(2, 20, 2, 24));
1703
+ //hover over the `name` parameter declaration
1704
+ hover = program.getHover(file.srcPath, vscode_languageserver_1.Position.create(1, 34))[0];
1705
+ (0, chai_config_spec_1.expect)(hover).to.exist;
1706
+ (0, chai_config_spec_1.expect)(hover.range).to.eql(vscode_languageserver_1.Range.create(1, 32, 1, 36));
1549
1707
  });
1550
- it('transpiles if statement keywords as provided', async () => {
1551
- const code = `
1552
- sub main()
1553
- If True Then
1554
- Print True
1555
- Else If True Then
1556
- print True
1557
- Else If False Then
1558
- Print False
1559
- Else
1560
- Print False
1561
- End If
1708
+ //ignore this for now...it's not a huge deal
1709
+ it('does not match on keywords or data types', () => {
1710
+ let file = program.setFile('source/main.brs', `
1711
+ sub Main(name as string)
1562
1712
  end sub
1563
- `;
1564
- await testTranspile(code);
1565
- await testTranspile(code.toLowerCase());
1566
- await testTranspile(code.toUpperCase());
1567
- });
1568
- it('does not transpile `then` tokens', async () => {
1569
- await testTranspile(`
1570
- sub main()
1571
- if true
1572
- print true
1573
- else if true
1574
- print false
1575
- end if
1713
+ sub as()
1576
1714
  end sub
1577
1715
  `);
1716
+ //hover over the `as`
1717
+ (0, chai_config_spec_1.expect)(program.getHover(file.srcPath, vscode_languageserver_1.Position.create(1, 31))).to.be.empty;
1718
+ //hover over the `string`
1719
+ (0, chai_config_spec_1.expect)(program.getHover(file.srcPath, vscode_languageserver_1.Position.create(1, 36))).to.be.empty;
1578
1720
  });
1579
- it('honors spacing between multi-word tokens', async () => {
1580
- await testTranspile(`
1581
- sub main()
1582
- if true
1721
+ it('finds declared function', () => {
1722
+ let file = program.setFile('source/main.brs', `
1723
+ function Main(count = 1)
1724
+ firstName = "bob"
1725
+ age = 21
1726
+ shoeSize = 10
1727
+ end function
1728
+ `);
1729
+ let hover = program.getHover(file.srcPath, vscode_languageserver_1.Position.create(1, 28))[0];
1730
+ (0, chai_config_spec_1.expect)(hover).to.exist;
1731
+ (0, chai_config_spec_1.expect)(hover.range).to.eql(vscode_languageserver_1.Range.create(1, 25, 1, 29));
1732
+ (0, chai_config_spec_1.expect)(hover.contents).to.equal([
1733
+ '```brightscript',
1734
+ 'function Main(count? as dynamic) as dynamic',
1735
+ '```'
1736
+ ].join('\n'));
1737
+ });
1738
+ it('finds declared namespace function', () => {
1739
+ let file = program.setFile('source/main.brs', `
1740
+ namespace mySpace
1741
+ function Main(count = 1)
1742
+ firstName = "bob"
1743
+ age = 21
1744
+ shoeSize = 10
1745
+ end function
1746
+ end namespace
1747
+ `);
1748
+ let hover = program.getHover(file.srcPath, vscode_languageserver_1.Position.create(2, 28))[0];
1749
+ (0, chai_config_spec_1.expect)(hover).to.exist;
1750
+ (0, chai_config_spec_1.expect)(hover.range).to.eql(vscode_languageserver_1.Range.create(2, 25, 2, 29));
1751
+ (0, chai_config_spec_1.expect)(hover.contents).to.equal([
1752
+ '```brightscript',
1753
+ 'function Main(count? as dynamic) as dynamic',
1754
+ '```'
1755
+ ].join('\n'));
1756
+ });
1757
+ it('finds variable function hover in same scope', () => {
1758
+ let file = program.setFile('source/main.brs', `
1759
+ sub Main()
1760
+ sayMyName = sub(name as string)
1761
+ end sub
1762
+
1763
+ sayMyName()
1764
+ end sub
1765
+ `);
1766
+ let hover = program.getHover(file.srcPath, vscode_languageserver_1.Position.create(5, 24))[0];
1767
+ (0, chai_config_spec_1.expect)(hover.range).to.eql(vscode_languageserver_1.Range.create(5, 20, 5, 29));
1768
+ (0, chai_config_spec_1.expect)(hover.contents).to.equal([
1769
+ '```brightscript',
1770
+ 'sub sayMyName(name as string) as void',
1771
+ '```'
1772
+ ].join('\n'));
1773
+ });
1774
+ it('does not crash when hovering on built-in functions', () => {
1775
+ let file = program.setFile('source/main.brs', `
1776
+ function doUcase(text)
1777
+ return ucase(text)
1778
+ end function
1779
+ `);
1780
+ (0, chai_config_spec_1.expect)(program.getHover(file.srcPath, vscode_languageserver_1.Position.create(2, 30))[0].contents).to.equal([
1781
+ '```brightscript',
1782
+ 'function UCase(s as string) as string',
1783
+ '```'
1784
+ ].join('\n'));
1785
+ });
1786
+ it('does not crash when hovering on object method call', () => {
1787
+ let file = program.setFile('source/main.brs', `
1788
+ function getInstr(url, text)
1789
+ return url.instr(text)
1790
+ end function
1791
+ `);
1792
+ (0, chai_config_spec_1.expect)(program.getHover(file.srcPath, vscode_languageserver_1.Position.create(2, 35))[0].contents).to.equal([
1793
+ '```brightscript',
1794
+ //TODO this really shouldn't be returning the global function, but it does...so make sure it doesn't crash right now.
1795
+ 'function Instr(start as integer, text as string, substring as string) as integer',
1796
+ '```'
1797
+ ].join('\n'));
1798
+ });
1799
+ it('finds function hover in file scope', () => {
1800
+ let file = program.setFile('source/main.brs', `
1801
+ sub Main()
1802
+ sayMyName()
1803
+ end sub
1804
+
1805
+ sub sayMyName()
1806
+
1807
+ end sub
1808
+ `);
1809
+ let hover = program.getHover(file.srcPath, vscode_languageserver_1.Position.create(2, 25))[0];
1810
+ (0, chai_config_spec_1.expect)(hover.range).to.eql(vscode_languageserver_1.Range.create(2, 20, 2, 29));
1811
+ (0, chai_config_spec_1.expect)(hover.contents).to.equal([
1812
+ '```brightscript',
1813
+ 'sub sayMyName() as void',
1814
+ '```'
1815
+ ].join('\n'));
1816
+ });
1817
+ it('finds namespace function hover in file scope', () => {
1818
+ let file = program.setFile('source/main.brs', `
1819
+ namespace mySpace
1820
+ sub Main()
1821
+ sayMyName()
1822
+ end sub
1823
+
1824
+ sub sayMyName()
1825
+
1826
+ end sub
1827
+ end namespace
1828
+ `);
1829
+ let hover = program.getHover(file.srcPath, vscode_languageserver_1.Position.create(3, 25))[0];
1830
+ (0, chai_config_spec_1.expect)(hover.range).to.eql(vscode_languageserver_1.Range.create(3, 20, 3, 29));
1831
+ (0, chai_config_spec_1.expect)(hover.contents).to.equal([
1832
+ '```brightscript',
1833
+ 'sub sayMyName() as void',
1834
+ '```'
1835
+ ].join('\n'));
1836
+ });
1837
+ it('finds function hover in scope', () => {
1838
+ let rootDir = process.cwd();
1839
+ program = new Program_1.Program({
1840
+ rootDir: rootDir
1841
+ });
1842
+ let mainFile = program.setFile('source/main.brs', `
1843
+ sub Main()
1844
+ sayMyName()
1845
+ end sub
1846
+ `);
1847
+ program.setFile('source/lib.brs', `
1848
+ sub sayMyName(name as string)
1849
+
1850
+ end sub
1851
+ `);
1852
+ let hover = program.getHover(mainFile.srcPath, vscode_languageserver_1.Position.create(2, 25))[0];
1853
+ (0, chai_config_spec_1.expect)(hover).to.exist;
1854
+ (0, chai_config_spec_1.expect)(hover.range).to.eql(vscode_languageserver_1.Range.create(2, 20, 2, 29));
1855
+ (0, chai_config_spec_1.expect)(hover.contents).to.equal([
1856
+ '```brightscript',
1857
+ 'sub sayMyName(name as string) as void',
1858
+ '```'
1859
+ ].join('\n'));
1860
+ });
1861
+ it('finds namespace function hover in scope', () => {
1862
+ let rootDir = process.cwd();
1863
+ program = new Program_1.Program({
1864
+ rootDir: rootDir
1865
+ });
1866
+ let mainFile = program.setFile('source/main.brs', `
1867
+ sub Main()
1868
+ mySpace.sayMyName()
1869
+ end sub
1870
+ `);
1871
+ program.setFile('source/lib.brs', `
1872
+ namespace mySpace
1873
+ sub sayMyName(name as string)
1874
+ end sub
1875
+ end namespace
1876
+ `);
1877
+ let hover = program.getHover(mainFile.srcPath, vscode_languageserver_1.Position.create(2, 34))[0];
1878
+ (0, chai_config_spec_1.expect)(hover).to.exist;
1879
+ (0, chai_config_spec_1.expect)(hover.range).to.eql(vscode_languageserver_1.Range.create(2, 28, 2, 37));
1880
+ (0, chai_config_spec_1.expect)(hover.contents).to.equal([
1881
+ '```brightscript',
1882
+ 'sub sayMyName(name as string) as void',
1883
+ '```'
1884
+ ].join('\n'));
1885
+ });
1886
+ it('includes markdown comments in hover.', () => {
1887
+ let rootDir = process.cwd();
1888
+ program = new Program_1.Program({
1889
+ rootDir: rootDir
1890
+ });
1891
+ const file = program.setFile('source/lib.brs', `
1892
+ '
1893
+ ' The main function
1894
+ '
1895
+ sub main()
1896
+ writeToLog("hello")
1897
+ end sub
1898
+
1899
+ '
1900
+ ' Prints a message to the log.
1901
+ ' Works with *markdown* **content**
1902
+ '
1903
+ sub writeToLog(message as string)
1904
+ print message
1905
+ end sub
1906
+ `);
1907
+ //hover over log("hello")
1908
+ (0, chai_config_spec_1.expect)(program.getHover(file.srcPath, vscode_languageserver_1.Position.create(5, 22))[0].contents).to.equal([
1909
+ '```brightscript',
1910
+ 'sub writeToLog(message as string) as void',
1911
+ '```',
1912
+ '***',
1913
+ '',
1914
+ ' Prints a message to the log.',
1915
+ ' Works with *markdown* **content**',
1916
+ ''
1917
+ ].join('\n'));
1918
+ //hover over sub ma|in()
1919
+ (0, chai_config_spec_1.expect)((0, testHelpers_spec_1.trim)(program.getHover(file.srcPath, vscode_languageserver_1.Position.create(4, 22))[0].contents.toString())).to.equal((0, testHelpers_spec_1.trim) `
1920
+ \`\`\`brightscript
1921
+ sub main() as void
1922
+ \`\`\`
1923
+ ***
1924
+
1925
+ The main function
1926
+ `);
1927
+ });
1928
+ it('handles mixed case `then` partions of conditionals', () => {
1929
+ let mainFile = program.setFile('source/main.brs', `
1930
+ sub Main()
1931
+ if true then
1932
+ print "works"
1933
+ end if
1934
+ end sub
1935
+ `);
1936
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(mainFile);
1937
+ mainFile = program.setFile('source/main.brs', `
1938
+ sub Main()
1939
+ if true Then
1940
+ print "works"
1941
+ end if
1942
+ end sub
1943
+ `);
1944
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(mainFile);
1945
+ mainFile = program.setFile('source/main.brs', `
1946
+ sub Main()
1947
+ if true THEN
1948
+ print "works"
1949
+ end if
1950
+ end sub
1951
+ `);
1952
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(mainFile);
1953
+ });
1954
+ });
1955
+ it('does not throw when encountering incomplete import statement', () => {
1956
+ program.setFile('source/main.brs', `
1957
+ import
1958
+ sub main()
1959
+ end sub
1960
+ `);
1961
+ program.validate();
1962
+ //this test will throw an exception if something went wrong
1963
+ });
1964
+ describe('transpile', () => {
1965
+ describe('null tokens', () => {
1966
+ it('succeeds when token locations are omitted', () => {
1967
+ doTest(`
1968
+ library "something" 'comment before func
1969
+ sub main(arg0, arg1 as string, arg2 = invalid)
1970
+ 'comment
1971
+ aa = {
1972
+ 'comment
1973
+ one: 1
1974
+ "two": 2
1975
+ }
1976
+ arr = [
1977
+ 'comment
1978
+ 1
1979
+ 'comment
1980
+ 2
1981
+ ]
1982
+ val = +3
1983
+ print "hello"
1984
+ 'comment after print
1985
+ num = 1
1986
+ num++
1987
+ num += 2
1988
+ num = +num
1989
+ test(num)
1990
+ for i = 0 to 10 step 1
1991
+ exit for
1992
+ end for
1993
+ while true
1994
+ exit while
1995
+ end while
1996
+ if true then
1997
+ print 1
1998
+ else if true
1999
+ print 1
2000
+ else
2001
+ print 1
2002
+ end if
2003
+ dim thing[1, 2]
2004
+ label1:
2005
+ goto label1
2006
+ end
2007
+ stop
2008
+ stuff = [
2009
+ 1
2010
+ 2
2011
+ 3
2012
+ ]
2013
+ for each item in stuff
2014
+ print item
2015
+ end for
2016
+ m.thing = 1
2017
+ m.thing += 1
2018
+ m[1] = 1
2019
+ m[1] += 1
2020
+ m[1, 2] = 2
2021
+ try
2022
+ print m.b.c
2023
+ catch e
2024
+ print e
2025
+ end try
2026
+ throw "crash"
2027
+ for i = 0 to 10
2028
+ continue
2029
+ end for
2030
+ print m@name
2031
+ print (1 + 2)
2032
+ end sub
2033
+
2034
+ sub test(p1)
2035
+ return p1
2036
+ end sub
2037
+ `);
2038
+ });
2039
+ it('works for bs content', () => {
2040
+ program.setFile('source/lib.bs', ``);
2041
+ doTest(`
2042
+ import "pkg:/source/lib.bs"
2043
+ @annotation()
2044
+ sub test()
2045
+ two = 2
2046
+ print \`1\${two}\${3}\n\`
2047
+ print (1 as integer)
2048
+ print SOURCE_LINE_NUM
2049
+ print FUNCTION_NAME
2050
+ print SOURCE_FUNCTION_NAME
2051
+ print PKG_LOCATION
2052
+ print PKG_PATH
2053
+ print LINE_NUM
2054
+ print new Person()
2055
+ m@.someCallfunc()
2056
+ m@.someCallfunc(1, 2)
2057
+ print tag\`stuff\${LINE_NUM}\${LINE_NUM}\`
2058
+ print 1 = 1 ? 1 : 2
2059
+ print 1 = 1 ? m.one : m.two
2060
+ print 1 ?? 2
2061
+ print m.one ?? m.two
2062
+ print /123/gi
2063
+ end sub
2064
+ function tag(param1, param2)
2065
+ end function
2066
+ const a = 1
2067
+ namespace alpha
2068
+ function beta()
2069
+ throw "An error has occurred"
2070
+ end function
2071
+ function charlie()
2072
+ end function
2073
+ end namespace
2074
+ sub test()
2075
+ ' alpha.charlie()
2076
+ end sub
2077
+
2078
+ enum Direction
2079
+ up = "up"
2080
+ end enum
2081
+
2082
+ class Person
2083
+ name as string
2084
+ sub new()
2085
+ print m.name
2086
+ end sub
2087
+
2088
+ sub test()
2089
+ end sub
2090
+ end class
2091
+
2092
+ interface Beta
2093
+ name as string
2094
+ end interface
2095
+ `, `
2096
+ 'import "pkg:/source/lib.bs"
2097
+
2098
+ sub test()
2099
+ two = 2
2100
+ print ("1" + bslib_toString(two) + bslib_toString(3) + chr(10))
2101
+ print 1
2102
+ print -1
2103
+ print "test"
2104
+ print "test"
2105
+ print "pkg:/source/main.brs:" + str(LINE_NUM)
2106
+ print "pkg:/source/main.brs"
2107
+ print LINE_NUM
2108
+ print Person()
2109
+ m.callfunc("someCallfunc", invalid)
2110
+ m.callfunc("someCallfunc", 1, 2)
2111
+ print tag(["stuff", "", ""], [LINE_NUM, LINE_NUM])
2112
+ print bslib_ternary(1 = 1, 1, 2)
2113
+ print (function(__bsCondition, m)
2114
+ if __bsCondition then
2115
+ return m.one
2116
+ else
2117
+ return m.two
2118
+ end if
2119
+ end function)(1 = 1, m)
2120
+ print bslib_coalesce(1, 2)
2121
+ print (function(m)
2122
+ __bsConsequent = m.one
2123
+ if __bsConsequent <> invalid then
2124
+ return __bsConsequent
2125
+ else
2126
+ return m.two
2127
+ end if
2128
+ end function)(m)
2129
+ print CreateObject("roRegex", "123", "gi")
2130
+ end sub
2131
+
2132
+ function tag(param1, param2)
2133
+ end function
2134
+
2135
+ function alpha_beta()
2136
+ throw "An error has occurred"
2137
+ end function
2138
+
2139
+ function alpha_charlie()
2140
+ end function
2141
+
2142
+ sub test()
2143
+ ' alpha.charlie()
2144
+ end sub
2145
+
2146
+ function __Person_builder()
2147
+ instance = {}
2148
+ instance.new = sub()
2149
+ m.name = invalid
2150
+ print m.name
2151
+ end sub
2152
+ instance.test = sub()
2153
+ end sub
2154
+ return instance
2155
+ end function
2156
+ function Person()
2157
+ instance = __Person_builder()
2158
+ instance.new()
2159
+ return instance
2160
+ end function
2161
+ `);
2162
+ });
2163
+ it('handles source literals properly', () => {
2164
+ const pathUrl = fileUrl(testHelpers_spec_2.rootDir);
2165
+ let text = `"${pathUrl.substring(0, 4)}" + "${pathUrl.substring(4)}`;
2166
+ doTest(`
2167
+ sub test()
2168
+ print SOURCE_FILE_PATH
2169
+ print SOURCE_LOCATION
2170
+ end sub
2171
+ `, `
2172
+ sub test()
2173
+ print ${text}/source/main.bs"
2174
+ print ${text}/source/main.bs:-1"
2175
+ end sub
2176
+ `);
2177
+ });
2178
+ function doTest(source, expected = source) {
2179
+ const file = program.setFile('source/main.bs', '');
2180
+ //override the parser with our locationless parser
2181
+ file['_parser'] = Parser_1.Parser.parse(source, { mode: Parser_1.ParseMode.BrighterScript, trackLocations: false });
2182
+ program.getScopesForFile(file).forEach(x => x['cache'].clear());
2183
+ program.validate();
2184
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(program);
2185
+ const result = file.transpile();
2186
+ (0, chai_config_spec_1.expect)((0, testHelpers_spec_1.trimMap)((0, undent_1.default)(result.code))).to.eql((0, undent_1.default)(expected));
2187
+ }
2188
+ });
2189
+ it('transpilies libpkg:/ paths when encountered', () => {
2190
+ program.setFile('source/lib.bs', `
2191
+ import "libpkg:/source/numbers.bs"
2192
+ `);
2193
+ program.setFile('source/numbers.bs', `
2194
+ sub test()
2195
+ end sub
2196
+ `);
2197
+ testTranspile(`
2198
+ <component name="TestButton" extends="Group">
2199
+ <script type="text/brightscript" uri="libpkg:/source/lib.bs"/>
2200
+ </component>
2201
+ `, `
2202
+ <component name="TestButton" extends="Group">
2203
+ <script type="text/brightscript" uri="libpkg:/source/lib.brs" />
2204
+ <script type="text/brightscript" uri="pkg:/source/numbers.brs" />
2205
+ <script type="text/brightscript" uri="pkg:/source/bslib.brs" />
2206
+ </component>
2207
+ `, undefined, 'components/TestButton.xml');
2208
+ });
2209
+ it('excludes trailing commas in array literals', () => {
2210
+ testTranspile(`
2211
+ sub main()
2212
+ arr = [
2213
+ 1,
2214
+ 2,
2215
+ 3
2216
+ ]
2217
+ obj = {
2218
+ one: 1,
2219
+ two: 2,
2220
+ three: 3
2221
+ }
2222
+ end sub
2223
+ `, `
2224
+ sub main()
2225
+ arr = [
2226
+ 1
2227
+ 2
2228
+ 3
2229
+ ]
2230
+ obj = {
2231
+ one: 1
2232
+ two: 2
2233
+ three: 3
2234
+ }
2235
+ end sub
2236
+ `);
2237
+ });
2238
+ it('transpiles if statement keywords as provided', () => {
2239
+ const code = `
2240
+ sub main()
2241
+ If True Then
2242
+ Print True
2243
+ Else If True Then
2244
+ print True
2245
+ Else If False Then
2246
+ Print False
2247
+ Else
2248
+ Print False
2249
+ End If
2250
+ end sub
2251
+ `;
2252
+ testTranspile(code);
2253
+ testTranspile(code.toLowerCase());
2254
+ testTranspile(code.toUpperCase());
2255
+ });
2256
+ it('does not transpile `then` tokens', () => {
2257
+ testTranspile(`
2258
+ sub main()
2259
+ if true
2260
+ print true
2261
+ else if true
2262
+ print false
2263
+ end if
2264
+ end sub
2265
+ `);
2266
+ });
2267
+ it('honors spacing between multi-word tokens', () => {
2268
+ testTranspile(`
2269
+ sub main()
2270
+ if true
1583
2271
  print true
1584
2272
  elseif true
1585
2273
  print false
@@ -1587,39 +2275,39 @@ describe('BrsFile', () => {
1587
2275
  end sub
1588
2276
  `);
1589
2277
  });
1590
- it('handles when only some of the statements have `then`', async () => {
1591
- await testTranspile(`
2278
+ it('handles when only some of the statements have `then`', () => {
2279
+ testTranspile(`
1592
2280
  sub main()
1593
2281
  if true
1594
2282
  else if true then
1595
2283
  else if true
1596
2284
  else if true then
1597
2285
  if true then
1598
- return
2286
+ return true
1599
2287
  end if
1600
2288
  end if
1601
2289
  end sub
1602
2290
  `);
1603
2291
  });
1604
- it('retains casing of parameter types', async () => {
1605
- async function test(type) {
1606
- await testTranspile(`
2292
+ it('retains casing of parameter types', () => {
2293
+ function test(type) {
2294
+ testTranspile(`
1607
2295
  sub one(a as ${type}, b as ${type.toUpperCase()}, c as ${type.toLowerCase()})
1608
2296
  end sub
1609
2297
  `);
1610
2298
  }
1611
- await test('Boolean');
1612
- await test('Double');
1613
- await test('Dynamic');
1614
- await test('Float');
1615
- await test('Integer');
1616
- await test('LongInteger');
1617
- await test('Object');
1618
- await test('String');
1619
- });
1620
- it('retains casing of return types', async () => {
1621
- async function test(type) {
1622
- await testTranspile(`
2299
+ test('Boolean');
2300
+ test('Double');
2301
+ test('Dynamic');
2302
+ test('Float');
2303
+ test('Integer');
2304
+ test('LongInteger');
2305
+ test('Object');
2306
+ test('String');
2307
+ });
2308
+ it('retains casing of return types', () => {
2309
+ function test(type) {
2310
+ testTranspile(`
1623
2311
  sub one() as ${type}
1624
2312
  end sub
1625
2313
 
@@ -1630,19 +2318,19 @@ describe('BrsFile', () => {
1630
2318
  end sub
1631
2319
  `);
1632
2320
  }
1633
- await test('Boolean');
1634
- await test('Double');
1635
- await test('Dynamic');
1636
- await test('Float');
1637
- await test('Integer');
1638
- await test('LongInteger');
1639
- await test('Object');
1640
- await test('String');
1641
- await test('Void');
1642
- });
1643
- it('retains casing of literal types', async () => {
1644
- async function test(type) {
1645
- await testTranspile(`
2321
+ test('Boolean');
2322
+ test('Double');
2323
+ test('Dynamic');
2324
+ test('Float');
2325
+ test('Integer');
2326
+ test('LongInteger');
2327
+ test('Object');
2328
+ test('String');
2329
+ test('Void');
2330
+ });
2331
+ it('retains casing of literal types', () => {
2332
+ function test(type) {
2333
+ testTranspile(`
1646
2334
  sub main()
1647
2335
  thing = ${type}
1648
2336
  thing = ${type.toLowerCase()}
@@ -1650,13 +2338,13 @@ describe('BrsFile', () => {
1650
2338
  end sub
1651
2339
  `);
1652
2340
  }
1653
- await test('Invalid');
1654
- await test('True');
1655
- await test('False');
2341
+ test('Invalid');
2342
+ test('True');
2343
+ test('False');
1656
2344
  });
1657
2345
  describe('throwStatement', () => {
1658
- it('transpiles properly', async () => {
1659
- await testTranspile(`
2346
+ it('transpiles properly', () => {
2347
+ testTranspile(`
1660
2348
  sub main()
1661
2349
  try
1662
2350
  throw "some message"
@@ -1667,8 +2355,8 @@ describe('BrsFile', () => {
1667
2355
  });
1668
2356
  });
1669
2357
  describe('try/catch', () => {
1670
- it('transpiles properly', async () => {
1671
- await testTranspile(`
2358
+ it('transpiles properly', () => {
2359
+ testTranspile(`
1672
2360
  sub main()
1673
2361
  try
1674
2362
  print m.b.c
@@ -1680,8 +2368,8 @@ describe('BrsFile', () => {
1680
2368
  });
1681
2369
  });
1682
2370
  describe('namespaces', () => {
1683
- it('properly transpiles namespace functions for assignments', async () => {
1684
- await testTranspile(`
2371
+ it('properly transpiles namespace functions for assignments', () => {
2372
+ testTranspile(`
1685
2373
  namespace NameA.NameB
1686
2374
  sub Speak()
1687
2375
  end sub
@@ -1702,8 +2390,8 @@ describe('BrsFile', () => {
1702
2390
  end sub
1703
2391
  `);
1704
2392
  });
1705
- it('properly transpiles inferred namespace function for assignment', async () => {
1706
- await testTranspile(`
2393
+ it('properly transpiles inferred namespace function for assignment', () => {
2394
+ testTranspile(`
1707
2395
  namespace NameA.NameB
1708
2396
  sub Speak()
1709
2397
  end sub
@@ -1723,26 +2411,25 @@ describe('BrsFile', () => {
1723
2411
  `);
1724
2412
  });
1725
2413
  });
1726
- it('includes all text to end of line for a non-terminated string', async () => {
1727
- await testTranspile('sub main()\n name = "john \nend sub', 'sub main()\n name = "john "\nend sub', null, 'source/main.bs', false);
2414
+ it('includes all text to end of line for a non-terminated string', () => {
2415
+ testTranspile('sub main()\n name = "john \nend sub', 'sub main()\n name = "john "\nend sub', null, 'source/main.bs', false);
1728
2416
  });
1729
- it('escapes quotes in string literals', async () => {
1730
- await testTranspile(`
2417
+ it('escapes quotes in string literals', () => {
2418
+ testTranspile(`
1731
2419
  sub main()
1732
- expected = "Hello"
1733
2420
  expected += chr(10) + " version=""2.0"""
1734
2421
  end sub
1735
2422
  `);
1736
2423
  });
1737
- it('keeps function parameter types in proper order', async () => {
1738
- await testTranspile(`
2424
+ it('keeps function parameter types in proper order', () => {
2425
+ testTranspile(`
1739
2426
  function CreateTestStatistic(name as string, result = "Success" as string, time = 0 as integer, errorCode = 0 as integer, errorMessage = "" as string) as object
1740
2427
  end function
1741
2428
  `);
1742
2429
  });
1743
- it('discard parameter types when removeParameterTypes is true', async () => {
2430
+ it('discard parameter types when removeParameterTypes is true', () => {
1744
2431
  program.options.removeParameterTypes = true;
1745
- await testTranspile(`
2432
+ testTranspile(`
1746
2433
  sub one(a as integer, b = "" as string, c = invalid as dynamic)
1747
2434
  end sub
1748
2435
  `, `
@@ -1750,9 +2437,9 @@ describe('BrsFile', () => {
1750
2437
  end sub
1751
2438
  `);
1752
2439
  });
1753
- it('discard return type when removeParameterTypes is true', async () => {
2440
+ it('discard return type when removeParameterTypes is true', () => {
1754
2441
  program.options.removeParameterTypes = true;
1755
- await testTranspile(`
2442
+ testTranspile(`
1756
2443
  function one() as string
1757
2444
  return ""
1758
2445
  end function
@@ -1762,8 +2449,8 @@ describe('BrsFile', () => {
1762
2449
  end function
1763
2450
  `);
1764
2451
  });
1765
- it('transpiles local var assignment operators', async () => {
1766
- await testTranspile(`
2452
+ it('transpiles local var assignment operators', () => {
2453
+ testTranspile(`
1767
2454
  sub main()
1768
2455
  count = 0
1769
2456
  count += 1
@@ -1776,8 +2463,8 @@ describe('BrsFile', () => {
1776
2463
  end sub
1777
2464
  `);
1778
2465
  });
1779
- it('transpiles AA property assignment operators', async () => {
1780
- await testTranspile(`
2466
+ it('transpiles AA property assignment operators', () => {
2467
+ testTranspile(`
1781
2468
  sub main()
1782
2469
  person = {
1783
2470
  count: 0
@@ -1786,8 +2473,8 @@ describe('BrsFile', () => {
1786
2473
  end sub
1787
2474
  `);
1788
2475
  });
1789
- it('transpiles AA indexed assignment operators', async () => {
1790
- await testTranspile(`
2476
+ it('transpiles AA indexed assignment operators', () => {
2477
+ testTranspile(`
1791
2478
  sub main()
1792
2479
  person = {
1793
2480
  count: 0
@@ -1796,8 +2483,8 @@ describe('BrsFile', () => {
1796
2483
  end sub
1797
2484
  `);
1798
2485
  });
1799
- it('relative-referenced namespaced functions get prefixed', async () => {
1800
- await testTranspile(`
2486
+ it('relative-referenced namespaced functions get prefixed', () => {
2487
+ testTranspile(`
1801
2488
  namespace Vertibrates.Birds
1802
2489
  function GetAllBirds()
1803
2490
  return [
@@ -1827,8 +2514,8 @@ describe('BrsFile', () => {
1827
2514
  end function
1828
2515
  `, 'trim', 'source/main.bs');
1829
2516
  });
1830
- it('transpiles namespaced functions', async () => {
1831
- await testTranspile(`
2517
+ it('transpiles namespaced functions', () => {
2518
+ testTranspile(`
1832
2519
  namespace NameA
1833
2520
  sub alert()
1834
2521
  end sub
@@ -1844,9 +2531,9 @@ describe('BrsFile', () => {
1844
2531
  end sub
1845
2532
  `, 'trim', 'source/main.bs');
1846
2533
  });
1847
- it('transpiles dim', async () => {
1848
- async function doTest(code) {
1849
- await testTranspile(`
2534
+ it('transpiles dim', () => {
2535
+ function doTest(code) {
2536
+ testTranspile(`
1850
2537
  sub main()
1851
2538
  requestList = []
1852
2539
  ${code}
@@ -1858,20 +2545,20 @@ describe('BrsFile', () => {
1858
2545
  end sub
1859
2546
  `);
1860
2547
  }
1861
- await doTest(`Dim c[5]`);
1862
- await doTest(`Dim c[5, 4]`);
1863
- await doTest(`Dim c[5, 4, 6]`);
1864
- await doTest(`Dim requestData[requestList.count()]`);
1865
- await doTest(`Dim requestData[1, requestList.count()]`);
1866
- await doTest(`Dim requestData[1, requestList.count(), 2]`);
1867
- await doTest(`Dim requestData[requestList[2]]`);
1868
- await doTest(`Dim requestData[1, requestList[2]]`);
1869
- await doTest(`Dim requestData[1, requestList[2], 2]`);
1870
- await doTest(`Dim requestData[requestList["2"]]`);
1871
- await doTest(`Dim requestData[1, requestList["2"]]`);
1872
- await doTest(`Dim requestData[1, requestList["2"], 2]`);
1873
- await doTest(`Dim requestData[1, StrToI("1"), 2]`);
1874
- await testTranspile(`
2548
+ doTest(`Dim c[5]`);
2549
+ doTest(`Dim c[5, 4]`);
2550
+ doTest(`Dim c[5, 4, 6]`);
2551
+ doTest(`Dim requestData[requestList.count()]`);
2552
+ doTest(`Dim requestData[1, requestList.count()]`);
2553
+ doTest(`Dim requestData[1, requestList.count(), 2]`);
2554
+ doTest(`Dim requestData[requestList[2]]`);
2555
+ doTest(`Dim requestData[1, requestList[2]]`);
2556
+ doTest(`Dim requestData[1, requestList[2], 2]`);
2557
+ doTest(`Dim requestData[requestList["2"]]`);
2558
+ doTest(`Dim requestData[1, requestList["2"]]`);
2559
+ doTest(`Dim requestData[1, requestList["2"], 2]`);
2560
+ doTest(`Dim requestData[1, StrToI("1"), 2]`);
2561
+ testTranspile(`
1875
2562
  function getValue(param1)
1876
2563
  end function
1877
2564
 
@@ -1883,8 +2570,41 @@ describe('BrsFile', () => {
1883
2570
  end sub
1884
2571
  `);
1885
2572
  });
1886
- it('transpiles calls to fully-qualified namespaced functions', async () => {
1887
- await testTranspile(`
2573
+ it('handles multi-index multi-dimensional arrays', () => {
2574
+ testTranspile(`
2575
+ sub main()
2576
+ myMultiArray = [[[[[[[[["hello"]]]]]]]]]
2577
+ myMultiArray[0][0][0][0][0][0][0][0][0] = "goodbye"
2578
+ print myMultiArray[0, 0, 0, 0, 0, 0, 0, 0, 0]
2579
+ end sub
2580
+ `, `
2581
+ sub main()
2582
+ myMultiArray = [
2583
+ [
2584
+ [
2585
+ [
2586
+ [
2587
+ [
2588
+ [
2589
+ [
2590
+ [
2591
+ "hello"
2592
+ ]
2593
+ ]
2594
+ ]
2595
+ ]
2596
+ ]
2597
+ ]
2598
+ ]
2599
+ ]
2600
+ ]
2601
+ myMultiArray[0][0][0][0][0][0][0][0][0] = "goodbye"
2602
+ print myMultiArray[0, 0, 0, 0, 0, 0, 0, 0, 0]
2603
+ end sub
2604
+ `);
2605
+ });
2606
+ it('transpiles calls to fully-qualified namespaced functions', () => {
2607
+ testTranspile(`
1888
2608
  namespace NameA
1889
2609
  sub alert()
1890
2610
  end sub
@@ -1909,15 +2629,15 @@ describe('BrsFile', () => {
1909
2629
  end sub
1910
2630
  `, 'trim', 'source/main.bs');
1911
2631
  });
1912
- it('keeps end-of-line comments with their line', async () => {
1913
- await testTranspile(`
2632
+ it('keeps end-of-line comments with their line', () => {
2633
+ testTranspile(`
1914
2634
  function DoSomething() 'comment 1
1915
2635
  name = "bob" 'comment 2
1916
2636
  end function 'comment 3
1917
2637
  `);
1918
2638
  });
1919
- it('works for functions', async () => {
1920
- await testTranspile(`
2639
+ it('works for functions', () => {
2640
+ testTranspile(`
1921
2641
  function DoSomething()
1922
2642
  'lots of empty white space
1923
2643
  'that will be removed during transpile
@@ -1932,16 +2652,36 @@ describe('BrsFile', () => {
1932
2652
  end function
1933
2653
  `);
1934
2654
  });
1935
- it('keeps empty AAs and arrays on same line', async () => {
1936
- await testTranspile(`
2655
+ it('keeps empty AAs and arrays on same line', () => {
2656
+ testTranspile(`
1937
2657
  sub a()
1938
2658
  person = {}
1939
2659
  stuff = []
1940
2660
  end sub
1941
2661
  `, null, 'trim');
1942
2662
  });
1943
- it('does not add leading or trailing newlines', async () => {
1944
- await testTranspile(`function abc()\nend function`, undefined, 'none');
2663
+ it('does not add leading or trailing newlines', () => {
2664
+ testTranspile(`function abc()\nend function`, undefined, 'none');
2665
+ });
2666
+ it('generates proper sourcemap comment', () => {
2667
+ program.options.sourceMap = true;
2668
+ const file = program.setFile('source/main.bs', `
2669
+ sub main()
2670
+ end sub
2671
+ `);
2672
+ (0, chai_config_spec_1.expect)(file.transpile().code).to.eql((0, undent_1.default) `
2673
+ sub main()
2674
+ end sub
2675
+ '//# sourceMappingURL=./main.brs.map
2676
+ `);
2677
+ });
2678
+ it('includes sourcemap.name property', () => {
2679
+ program.options.sourceMap = true;
2680
+ const file = program.setFile('source/main.bs', `
2681
+ sub main()
2682
+ end sub
2683
+ `);
2684
+ (0, chai_config_spec_1.expect)(file.transpile().map.toJSON().file).to.eql('main.brs');
1945
2685
  });
1946
2686
  it('handles sourcemap edge case', async () => {
1947
2687
  let source = 'sub main()\n' +
@@ -1950,9 +2690,9 @@ describe('BrsFile', () => {
1950
2690
  '\n' +
1951
2691
  'end sub';
1952
2692
  program.options.sourceMap = true;
1953
- let result = await testTranspile(source, `sub main()\n print 1\nend sub`, 'none', 'source/main.bs');
2693
+ let result = testTranspile(source, `sub main()\n print 1\nend sub`, 'none', 'source/main.bs');
1954
2694
  //load the source map
1955
- let location = await source_map_1.SourceMapConsumer.with(result.map, null, (consumer) => {
2695
+ let location = await source_map_1.SourceMapConsumer.with(result.map.toJSON(), null, (consumer) => {
1956
2696
  return consumer.generatedPositionFor({
1957
2697
  line: 3,
1958
2698
  column: 0,
@@ -1969,7 +2709,7 @@ describe('BrsFile', () => {
1969
2709
  //remove newlines and EOF
1970
2710
  .filter(x => x.kind !== TokenKind_1.TokenKind.Eof && x.kind !== TokenKind_1.TokenKind.Newline);
1971
2711
  program.options.sourceMap = true;
1972
- let result = await testTranspile(source, source, 'none');
2712
+ let result = testTranspile(source, source, 'none');
1973
2713
  //load the source map
1974
2714
  await source_map_1.SourceMapConsumer.with(result.map.toString(), null, (consumer) => {
1975
2715
  let tokenResult = tokens.map(token => ({
@@ -1992,8 +2732,8 @@ describe('BrsFile', () => {
1992
2732
  (0, chai_config_spec_1.expect)(sourcemapResult).to.eql(tokenResult);
1993
2733
  });
1994
2734
  });
1995
- it('handles empty if block', async () => {
1996
- await testTranspile(`
2735
+ it('handles empty if block', () => {
2736
+ testTranspile(`
1997
2737
  sub main()
1998
2738
  if true then
1999
2739
  end if
@@ -2014,8 +2754,8 @@ describe('BrsFile', () => {
2014
2754
  end sub
2015
2755
  `);
2016
2756
  });
2017
- it('handles empty elseif block', async () => {
2018
- await testTranspile(`
2757
+ it('handles empty elseif block', () => {
2758
+ testTranspile(`
2019
2759
  sub main()
2020
2760
  if true then
2021
2761
  print "if"
@@ -2029,8 +2769,8 @@ describe('BrsFile', () => {
2029
2769
  end sub
2030
2770
  `);
2031
2771
  });
2032
- it('handles empty else block', async () => {
2033
- await testTranspile(`
2772
+ it('handles empty else block', () => {
2773
+ testTranspile(`
2034
2774
  sub main()
2035
2775
  if true then
2036
2776
  print "if"
@@ -2045,8 +2785,8 @@ describe('BrsFile', () => {
2045
2785
  end sub
2046
2786
  `);
2047
2787
  });
2048
- it('handles else block with a leading comment', async () => {
2049
- await testTranspile(`
2788
+ it('handles else block with a leading comment', () => {
2789
+ testTranspile(`
2050
2790
  sub main()
2051
2791
  if true then
2052
2792
  print "if"
@@ -2057,8 +2797,8 @@ describe('BrsFile', () => {
2057
2797
  end sub
2058
2798
  `);
2059
2799
  });
2060
- it('works for function parameters', async () => {
2061
- await testTranspile(`
2800
+ it('works for function parameters', () => {
2801
+ testTranspile(`
2062
2802
  function DoSomething(name, age as integer, text as string)
2063
2803
  end function
2064
2804
  `, `
@@ -2066,8 +2806,8 @@ describe('BrsFile', () => {
2066
2806
  end function
2067
2807
  `);
2068
2808
  });
2069
- it('adds newlines between top-level statements', async () => {
2070
- await testTranspile(`
2809
+ it('adds newlines between top-level statements', () => {
2810
+ testTranspile(`
2071
2811
  function a()
2072
2812
  end function
2073
2813
 
@@ -2075,8 +2815,8 @@ describe('BrsFile', () => {
2075
2815
  end function
2076
2816
  `);
2077
2817
  });
2078
- it('properly indents nested AA literals', async () => {
2079
- await testTranspile(`
2818
+ it('properly indents nested AA literals', () => {
2819
+ testTranspile(`
2080
2820
  sub doSomething()
2081
2821
  grandparent = {
2082
2822
  parent: {
@@ -2090,8 +2830,8 @@ describe('BrsFile', () => {
2090
2830
  end sub
2091
2831
  `);
2092
2832
  });
2093
- it('does not add comma after final object property even when comments are present', async () => {
2094
- await testTranspile(`
2833
+ it('does not add comma after final object property even when comments are present', () => {
2834
+ testTranspile(`
2095
2835
  sub doSomething()
2096
2836
  person = {
2097
2837
  age: 12 'comment
@@ -2114,8 +2854,8 @@ describe('BrsFile', () => {
2114
2854
  end sub
2115
2855
  `);
2116
2856
  });
2117
- it('works for a complex function with comments all over the place', async () => {
2118
- await testTranspile(`
2857
+ it('works for a complex function with comments all over the place', () => {
2858
+ testTranspile(`
2119
2859
  'import some library
2120
2860
  library "v30/bslCore.brs" 'comment
2121
2861
 
@@ -2205,7 +2945,7 @@ describe('BrsFile', () => {
2205
2945
  sub logInfo()
2206
2946
  end sub
2207
2947
  `);
2208
- file['needsTranspiled'] = false;
2948
+ file.needsTranspiled = false;
2209
2949
  const { code } = file.transpile();
2210
2950
  (0, chai_config_spec_1.expect)(code.endsWith(`'//# sourceMappingURL=./logger.brs.map`)).to.be.true;
2211
2951
  });
@@ -2214,16 +2954,16 @@ describe('BrsFile', () => {
2214
2954
  sub logInfo()
2215
2955
  end sub
2216
2956
  `);
2217
- file['needsTranspiled'] = true;
2957
+ file.needsTranspiled = true;
2218
2958
  const { code } = file.transpile();
2219
2959
  (0, chai_config_spec_1.expect)(code.endsWith(`'//# sourceMappingURL=./logger.brs.map`)).to.be.true;
2220
2960
  });
2221
- it('replaces custom types in parameter types and return types', async () => {
2961
+ it('replaces custom types in parameter types and return types', () => {
2222
2962
  program.setFile('source/SomeKlass.bs', `
2223
2963
  class SomeKlass
2224
2964
  end class
2225
2965
  `);
2226
- await testTranspile(`
2966
+ testTranspile(`
2227
2967
  function foo() as SomeKlass
2228
2968
  return new SomeKlass()
2229
2969
  end function
@@ -2231,11 +2971,11 @@ describe('BrsFile', () => {
2231
2971
  sub bar(obj as SomeKlass)
2232
2972
  end sub
2233
2973
  `, `
2234
- function foo() as dynamic
2974
+ function foo() as object
2235
2975
  return SomeKlass()
2236
2976
  end function
2237
2977
 
2238
- sub bar(obj as dynamic)
2978
+ sub bar(obj as object)
2239
2979
  end sub
2240
2980
  `);
2241
2981
  });
@@ -2252,8 +2992,8 @@ describe('BrsFile', () => {
2252
2992
  program.validate();
2253
2993
  (0, testHelpers_spec_1.expectZeroDiagnostics)(program);
2254
2994
  });
2255
- it('sets invalid on empty callfunc', async () => {
2256
- await testTranspile(`
2995
+ it('sets invalid on empty callfunc', () => {
2996
+ testTranspile(`
2257
2997
  sub main()
2258
2998
  node = invalid
2259
2999
  node@.doSomething()
@@ -2269,8 +3009,8 @@ describe('BrsFile', () => {
2269
3009
  end sub
2270
3010
  `);
2271
3011
  });
2272
- it('includes original arguments', async () => {
2273
- await testTranspile(`
3012
+ it('includes original arguments', () => {
3013
+ testTranspile(`
2274
3014
  sub main()
2275
3015
  node = invalid
2276
3016
  node@.doSomething(1, true, m.top.someVal)
@@ -2372,8 +3112,8 @@ describe('BrsFile', () => {
2372
3112
  });
2373
3113
  });
2374
3114
  describe('typedef', () => {
2375
- it('includes enum and interface types', async () => {
2376
- await testGetTypedef(`
3115
+ it('includes enum and interface types', () => {
3116
+ testGetTypedef(`
2377
3117
  interface Foo
2378
3118
  field as string
2379
3119
  end interface
@@ -2749,8 +3489,8 @@ describe('BrsFile', () => {
2749
3489
  function plugin() {
2750
3490
  return {
2751
3491
  name: 'lower-file-name',
2752
- afterProvideFile: (evt) => {
2753
- evt.files[0]._customProp = true;
3492
+ afterFileParse: (evt) => {
3493
+ evt._customProp = true;
2754
3494
  }
2755
3495
  };
2756
3496
  }
@@ -2758,16 +3498,16 @@ describe('BrsFile', () => {
2758
3498
  `);
2759
3499
  });
2760
3500
  it('can load an absolute plugin which receives callbacks', () => {
2761
- for (const plugin of util_1.default.loadPlugins(testHelpers_spec_2.tempDir, [(0, util_1.standardizePath) `${testHelpers_spec_2.tempDir}/plugins/${pluginFileName}`])) {
2762
- program.plugins.add(plugin);
2763
- }
3501
+ program.plugins = new PluginInterface_1.default(util_1.default.loadPlugins(testHelpers_spec_2.tempDir, [
3502
+ (0, util_1.standardizePath) `${testHelpers_spec_2.tempDir}/plugins/${pluginFileName}`
3503
+ ]), { logger: (0, logging_1.createLogger)() });
2764
3504
  const file = program.setFile('source/MAIN.brs', '');
2765
3505
  (0, chai_config_spec_1.expect)(file._customProp).to.exist;
2766
3506
  });
2767
3507
  it('can load a relative plugin which receives callbacks', () => {
2768
- for (const plugin of util_1.default.loadPlugins(testHelpers_spec_2.tempDir, [`./plugins/${pluginFileName}`])) {
2769
- program.plugins.add(plugin);
2770
- }
3508
+ program.plugins = new PluginInterface_1.default(util_1.default.loadPlugins(testHelpers_spec_2.tempDir, [
3509
+ `./plugins/${pluginFileName}`
3510
+ ]), { logger: (0, logging_1.createLogger)() });
2771
3511
  const file = program.setFile('source/MAIN.brs', '');
2772
3512
  (0, chai_config_spec_1.expect)(file._customProp).to.exist;
2773
3513
  });
@@ -2807,94 +3547,26 @@ describe('BrsFile', () => {
2807
3547
  range: util_1.default.createRange(5, 25, 5, 31)
2808
3548
  }]);
2809
3549
  });
2810
- it('returns interface location', () => {
3550
+ it('does not crash on nulls', () => {
2811
3551
  const file = program.setFile('source/main.bs', `
2812
- sub test(selectedMovie as Movie)
2813
- print selectedMovie
3552
+ sub main()
3553
+ print alpha.beta
2814
3554
  end sub
2815
- interface Movie
2816
- url as string
2817
- end interface
2818
3555
  `);
2819
3556
  program.validate();
2820
- // sub test(selectedMovie as Mo|vie)
2821
- (0, chai_config_spec_1.expect)(program.getDefinition(file.srcPath, vscode_languageserver_1.Position.create(1, 44))).to.eql([{
2822
- uri: vscode_uri_1.URI.file(file.srcPath).toString(),
2823
- range: util_1.default.createRange(4, 26, 4, 31)
2824
- }]);
3557
+ sinon.stub(util_1.default, 'getAllDottedGetParts').returns(null);
3558
+ // print alpha.be|ta
3559
+ (0, chai_config_spec_1.expect)(program.getDefinition(file.srcPath, vscode_languageserver_1.Position.create(2, 34))).to.eql([]);
2825
3560
  });
2826
- it('returns namespaced interface location', () => {
3561
+ it('returns enum member locations', () => {
2827
3562
  const file = program.setFile('source/main.bs', `
2828
- sub test(selectedMovie as interfaces.Movie)
2829
- print selectedMovie
3563
+ sub main()
3564
+ print alpha.beta.people.charlie
2830
3565
  end sub
2831
- namespace interfaces
2832
- interface Movie
2833
- url as string
2834
- end interface
2835
- end namespace
2836
- `);
2837
- program.validate();
2838
- //sub test(selectedMovie as interfaces.Mo|vie)
2839
- (0, chai_config_spec_1.expect)(program.getDefinition(file.srcPath, vscode_languageserver_1.Position.create(1, 55))).to.eql([{
2840
- uri: vscode_uri_1.URI.file(file.srcPath).toString(),
2841
- range: util_1.default.createRange(5, 30, 5, 35)
2842
- }]);
2843
- });
2844
- it('returns class location', () => {
2845
- const file = program.setFile('source/main.bs', `
2846
- sub test(selectedMovie as Movie)
2847
- print selectedMovie
2848
- end sub
2849
- class Movie
2850
- url as string
2851
- end class
2852
- `);
2853
- program.validate();
2854
- //sub test(selectedMovie as Mo|vie)
2855
- (0, chai_config_spec_1.expect)(program.getDefinition(file.srcPath, vscode_languageserver_1.Position.create(1, 44))).to.eql([{
2856
- uri: vscode_uri_1.URI.file(file.srcPath).toString(),
2857
- range: util_1.default.createRange(4, 22, 4, 27)
2858
- }]);
2859
- });
2860
- it('returns namespaced class location', () => {
2861
- const file = program.setFile('source/main.bs', `
2862
- sub test(selectedMovie as classes.Movie)
2863
- print selectedMovie
2864
- end sub
2865
- namespace classes
2866
- class Movie
2867
- url as string
2868
- end class
2869
- end namespace
2870
- `);
2871
- program.validate();
2872
- //sub test(selectedMovie as classes.Mo|vie)
2873
- (0, chai_config_spec_1.expect)(program.getDefinition(file.srcPath, vscode_languageserver_1.Position.create(1, 52))).to.eql([{
2874
- uri: vscode_uri_1.URI.file(file.srcPath).toString(),
2875
- range: util_1.default.createRange(5, 26, 5, 31)
2876
- }]);
2877
- });
2878
- it('does not crash on nulls', () => {
2879
- const file = program.setFile('source/main.bs', `
2880
- sub main()
2881
- print alpha.beta
2882
- end sub
2883
- `);
2884
- program.validate();
2885
- sinon.stub(util_1.default, 'getAllDottedGetParts').returns(null);
2886
- // print alpha.be|ta
2887
- (0, chai_config_spec_1.expect)(program.getDefinition(file.srcPath, vscode_languageserver_1.Position.create(2, 34))).to.eql([]);
2888
- });
2889
- it('returns enum member locations', () => {
2890
- const file = program.setFile('source/main.bs', `
2891
- sub main()
2892
- print alpha.beta.people.charlie
2893
- end sub
2894
- namespace alpha.beta
2895
- enum people
2896
- charlie = "charles"
2897
- end enum
3566
+ namespace alpha.beta
3567
+ enum people
3568
+ charlie = "charles"
3569
+ end enum
2898
3570
  end namespace
2899
3571
  `);
2900
3572
  program.validate();
@@ -2915,787 +3587,279 @@ describe('BrsFile', () => {
2915
3587
  program.validate();
2916
3588
  (0, testHelpers_spec_1.expectDiagnostics)(program, [Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.mismatchedEndCallableKeyword('function', 'sub')), { range: util_1.default.createRange(2, 12, 2, 19) }), Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.mismatchedEndCallableKeyword('sub', 'function')), { range: util_1.default.createRange(4, 12, 4, 24) })]);
2917
3589
  });
2918
- describe('requiredSymbols', () => {
2919
- it('should be empty for a simple file', () => {
2920
- const mainFile = program.setFile('source/main.bs', `
2921
- function someFunc() as integer
2922
- return 1
2923
- end function
3590
+ describe('backporting v1 syntax changes', () => {
3591
+ it('transpiles typed arrays to dynamic', () => {
3592
+ testTranspile(`
3593
+ sub main(param1 as string[], param2 as SomeType[])
3594
+ end sub
3595
+ `, `
3596
+ sub main(param1 as dynamic, param2 as dynamic)
3597
+ end sub
2924
3598
  `);
2925
- const validateFileEvent = {
2926
- program: program,
2927
- file: mainFile
2928
- };
2929
- program.plugins.emit('onFileValidate', validateFileEvent);
2930
- (0, chai_config_spec_1.expect)(mainFile.requiredSymbols.length).to.eq(0);
2931
- });
2932
- it('should be empty if the file needs no external symbols', () => {
2933
- const mainFile = program.setFile('source/main.bs', `
2934
- function someFunc() as integer
2935
- return 1
3599
+ });
3600
+ it('transpiles typed arrays in return types to dynamic', () => {
3601
+ testTranspile(`
3602
+ function main() as integer[]
3603
+ return []
3604
+ end function
3605
+ `, `
3606
+ function main() as dynamic
3607
+ return []
2936
3608
  end function
2937
-
2938
- sub useKlass()
2939
- k = new Klass()
2940
- k.addTwo()
2941
- end sub
2942
-
2943
- class Klass
2944
- sub addTwo()
2945
- print someFunc() + someFunc()
2946
- end sub
2947
- end class
2948
3609
  `);
2949
- const validateFileEvent = {
2950
- program: program,
2951
- file: mainFile
2952
- };
2953
- program.plugins.emit('onFileValidate', validateFileEvent);
2954
- (0, chai_config_spec_1.expect)(mainFile.requiredSymbols.length).to.eq(0);
2955
- });
2956
- it('should not include global callables or types', () => {
2957
- const mainFile = program.setFile('source/main.bs', `
2958
- function printLower(s as string) as integer
2959
- print lcase(s.trim())
3610
+ });
3611
+ it('transpiles typed arrays in return types to dynamic', () => {
3612
+ testTranspile(`
3613
+ function main() as integer[]
3614
+ return []
2960
3615
  end function
2961
-
2962
- sub setLabelText( label as roSGNodeLabel, text as string)
2963
- label.text = text
3616
+ `, `
3617
+ function main() as dynamic
3618
+ return []
3619
+ end function
3620
+ `);
3621
+ });
3622
+ it('transpiles multi-dimension typed arrays to dynamic', () => {
3623
+ testTranspile(`
3624
+ sub main(param1 as float[][][])
3625
+ end sub
3626
+ `, `
3627
+ sub main(param1 as dynamic)
2964
3628
  end sub
2965
3629
  `);
2966
- const validateFileEvent = {
2967
- program: program,
2968
- file: mainFile
2969
- };
2970
- program.plugins.emit('onFileValidate', validateFileEvent);
2971
- (0, chai_config_spec_1.expect)(mainFile.requiredSymbols.length).to.eq(0);
2972
3630
  });
2973
- it('should include unknown param and return types', () => {
2974
- const mainFile = program.setFile('source/main.bs', `
2975
- function someFunc(arg as OneType) as TwoType
2976
- return arg.getTwo()
2977
- end function
3631
+ it('removes typecasts in transpiled code', () => {
3632
+ testTranspile(`
3633
+ sub main(myNode, myString)
3634
+ print (myNode as roSGNode).id
3635
+ print (myNode as roSGNode).getParent().id
3636
+ myNode2 = myNode as roSgNode
3637
+ print (myString as string).len()
3638
+ print (myString as string).right(3)
3639
+ myString2 = myString as string
3640
+ end sub
3641
+ `, `
3642
+ sub main(myNode, myString)
3643
+ print myNode.id
3644
+ print myNode.getParent().id
3645
+ myNode2 = myNode
3646
+ print myString.len()
3647
+ print myString.right(3)
3648
+ myString2 = myString
3649
+ end sub
2978
3650
  `);
2979
- const validateFileEvent = {
2980
- program: program,
2981
- file: mainFile
2982
- };
2983
- program.plugins.emit('onFileValidate', validateFileEvent);
2984
- (0, chai_config_spec_1.expect)(mainFile.requiredSymbols.length).to.eq(2);
2985
- (0, chai_config_spec_1.expect)(mainFile.requiredSymbols.map(x => x.typeChain[0].name)).to.have.same.members([
2986
- 'TwoType', 'OneType'
2987
- ]);
2988
3651
  });
2989
- it('should include unknown param and return types on class methods', () => {
2990
- const mainFile = program.setFile('source/main.bs', `
2991
- class Klass
2992
- function someFunc(arg as OneType) as TwoType
2993
- return arg.getTwo()
2994
- end function
2995
- end class
3652
+ it('allows and removes multiple typecasts in transpiled code', () => {
3653
+ testTranspile(`
3654
+ sub main(myNode)
3655
+ print ((myNode as roSGNode as roSGNodeLabel).text as string as ifStringOps).len()
3656
+ end sub
3657
+ `, `
3658
+ sub main(myNode)
3659
+ print myNode.text.len()
3660
+ end sub
2996
3661
  `);
2997
- const validateFileEvent = {
2998
- program: program,
2999
- file: mainFile
3000
- };
3001
- program.plugins.emit('onFileValidate', validateFileEvent);
3002
- (0, chai_config_spec_1.expect)(mainFile.requiredSymbols.length).to.eq(2);
3003
- (0, chai_config_spec_1.expect)(mainFile.requiredSymbols.map(x => x.typeChain[0].name)).to.have.same.members([
3004
- 'TwoType', 'OneType'
3005
- ]);
3006
3662
  });
3007
- it('should not include assigned symbols', () => {
3008
- const mainFile = program.setFile('source/main.bs', `
3009
- sub someFunc(arg as SomeOtherType)
3010
- x = arg.member
3011
- print x+1
3012
- end sub
3013
- `);
3014
- const validateFileEvent = {
3015
- program: program,
3016
- file: mainFile
3017
- };
3018
- program.plugins.emit('onFileValidate', validateFileEvent);
3019
- (0, chai_config_spec_1.expect)(mainFile.requiredSymbols.length).to.eq(1);
3020
- // x and arg are assigned.. they are not included in the required symbols
3021
- (0, chai_config_spec_1.expect)(mainFile.requiredSymbols[0].typeChain[0].name).to.equal('SomeOtherType');
3022
- });
3023
- it('should include functions called that are not in the file', () => {
3024
- const mainFile = program.setFile('source/main.bs', `
3025
- sub someFunc()
3026
- x = otherFileFunc1()
3027
- print x+1
3028
- end sub
3029
-
3030
- function deepFunctionCall(i as integer)
3031
- x = 2*i and otherFileFunc2()
3032
- y = sin(x+fix(78.2)*log(otherFileFunc3()))
3033
- ' this is a comment otherFileFunc5()
3034
- return y-otherFileFunc4()
3035
- end function
3663
+ it('allows built in objects as type names', () => {
3664
+ testTranspile(`
3665
+ sub main(x as roSGNode, y as roSGNodeEvent, z as ifArray)
3666
+ end sub
3667
+ `, `
3668
+ sub main(x as object, y as object, z as object)
3669
+ end sub
3036
3670
  `);
3037
- const validateFileEvent = {
3038
- program: program,
3039
- file: mainFile
3040
- };
3041
- program.plugins.emit('onFileValidate', validateFileEvent);
3042
- (0, chai_config_spec_1.expect)(mainFile.requiredSymbols.length).to.eq(4);
3043
- (0, chai_config_spec_1.expect)(mainFile.requiredSymbols.map(x => x.typeChain[0].name)).to.have.same.members([
3044
- 'otherFileFunc1', 'otherFileFunc2', 'otherFileFunc3', 'otherFileFunc4'
3045
- ]);
3046
3671
  });
3047
- it('should include classes called that are not in the file', () => {
3048
- const mainFile = program.setFile('source/main.bs', `
3049
- function someFunc(other as OtherKlass) as NS1.Thing
3050
- x = new AnotherClass()
3051
- return other.getThing(x)
3052
- end function
3672
+ it('allows component names as types names', () => {
3673
+ testTranspile(`
3674
+ sub main(x as roSGNodeGroup, y as roSGNodeRowList, z as roSGNodeCustomComponent)
3675
+ end sub
3676
+ `, `
3677
+ sub main(x as object, y as object, z as object)
3678
+ end sub
3053
3679
  `);
3054
- const validateFileEvent = {
3055
- program: program,
3056
- file: mainFile
3057
- };
3058
- program.plugins.emit('onFileValidate', validateFileEvent);
3059
- (0, chai_config_spec_1.expect)(mainFile.requiredSymbols.length).to.eq(3);
3060
- const requiredTypeChains = mainFile.requiredSymbols.map(x => x.typeChain.map(tc => tc.name).join('.'));
3061
- (0, chai_config_spec_1.expect)(requiredTypeChains).to.have.same.members([
3062
- 'OtherKlass', 'NS1.Thing', 'AnotherClass'
3063
- ]);
3064
- const requiredSymbolsFlags = mainFile.requiredSymbols.map(x => x.flags);
3065
- (0, chai_config_spec_1.expect)(requiredSymbolsFlags).to.have.same.members([
3066
- SymbolTable_1.SymbolTypeFlag.typetime, SymbolTable_1.SymbolTypeFlag.typetime, SymbolTable_1.SymbolTypeFlag.runtime
3067
- ]);
3068
3680
  });
3069
- it('should include enums and consts that are not in the file', () => {
3070
- const mainFile = program.setFile('source/main.bs', `
3071
- sub someFunc(myEnum as SomeEnum)
3072
- if myEnum = SomeEnum.value1
3073
- print 1
3074
- else if myEnum = SomeEnum.value2
3075
- print 2
3076
- else if myEnum = SomeConstValue
3077
- print 3
3078
- end if
3681
+ it('allows union types for primitives', () => {
3682
+ testTranspile(`
3683
+ sub main(x as string or float, y as object or float or string)
3684
+ end sub
3685
+ `, `
3686
+ sub main(x as dynamic, y as dynamic)
3079
3687
  end sub
3080
3688
  `);
3081
- const validateFileEvent = {
3082
- program: program,
3083
- file: mainFile
3084
- };
3085
- program.plugins.emit('onFileValidate', validateFileEvent);
3086
- (0, chai_config_spec_1.expect)(mainFile.requiredSymbols.length).to.eq(4);
3087
- const requiredTypeChains = mainFile.requiredSymbols.map(x => x.typeChain.map(tc => tc.name).join('.'));
3088
- (0, chai_config_spec_1.expect)(requiredTypeChains).to.have.same.members([
3089
- 'SomeEnum', 'SomeEnum.value1', 'SomeEnum.value2', 'SomeConstValue'
3090
- ]);
3091
- const requiredSymbolsFlags = mainFile.requiredSymbols.map(x => x.flags);
3092
- (0, chai_config_spec_1.expect)(requiredSymbolsFlags).to.have.same.members([
3093
- SymbolTable_1.SymbolTypeFlag.typetime, SymbolTable_1.SymbolTypeFlag.runtime, SymbolTable_1.SymbolTypeFlag.runtime, SymbolTable_1.SymbolTypeFlag.runtime
3094
- ]);
3095
3689
  });
3096
- it('should include types not defined in the file', () => {
3097
- const mainFile = program.setFile('source/main.bs', `
3098
- interface Data
3099
- kind as DataKind
3100
- getObj as DataObject
3101
- subData as SubData
3690
+ it('allows union types for classes, interfaces', () => {
3691
+ testTranspile(`
3692
+ interface IFaceA
3693
+ name as string
3694
+ data as integer
3102
3695
  end interface
3103
3696
 
3104
- class DataObject extends BaseData
3105
- kind as DataKind
3106
- function process(dataProcess as DataProcessor) as ProcessedData
3107
- return dataProcess.work(m)
3108
- end function
3109
- end class
3697
+ interface IFaceB
3698
+ name as string
3699
+ value as float
3700
+ end interface
3701
+
3702
+ sub main(x as IFaceA or IFaceB)
3703
+ end sub
3704
+ `, `
3705
+ sub main(x as dynamic)
3706
+ end sub
3110
3707
  `);
3111
- const validateFileEvent = {
3112
- program: program,
3113
- file: mainFile
3114
- };
3115
- program.plugins.emit('onFileValidate', validateFileEvent);
3116
- (0, chai_config_spec_1.expect)(mainFile.requiredSymbols.length).to.eq(5);
3117
- const requiredTypeChains = mainFile.requiredSymbols.map(x => x.typeChain.map(tc => tc.name).join('.'));
3118
- (0, chai_config_spec_1.expect)(requiredTypeChains).to.have.same.members([
3119
- 'DataKind', 'SubData', 'BaseData', 'DataProcessor', 'ProcessedData'
3120
- ]);
3121
- const requiredSymbolsFlags = mainFile.requiredSymbols.map(x => x.flags);
3122
- (0, chai_config_spec_1.expect)(requiredSymbolsFlags).to.have.same.members([
3123
- SymbolTable_1.SymbolTypeFlag.typetime, SymbolTable_1.SymbolTypeFlag.typetime, SymbolTable_1.SymbolTypeFlag.typetime, SymbolTable_1.SymbolTypeFlag.typetime, SymbolTable_1.SymbolTypeFlag.typetime
3124
- ]);
3125
3708
  });
3126
- it('includes namespace details', () => {
3127
- const mainFile = program.setFile('source/main.bs', `
3128
- namespace Alpha.Beta
3129
- sub printConstVal()
3130
- print CONST_VALUE
3131
- end sub
3132
- end namespace
3709
+ it('allows union types for classes, interfaces', () => {
3710
+ testTranspile(`
3711
+ namespace alpha.beta
3712
+ interface IFaceA
3713
+ name as string
3714
+ data as integer
3715
+ end interface
3133
3716
 
3134
- namespace Delta
3135
- namespace Gamma
3136
- namespace Eta
3137
- sub doStuff(x as OtherType)
3138
- x.something()
3139
- end sub
3140
- end namespace
3141
- end namespace
3717
+ interface IFaceB
3718
+ name as string
3719
+ value as float
3720
+ end interface
3142
3721
  end namespace
3722
+
3723
+ sub main(x as alpha.beta.IFaceA or alpha.beta.IFaceB)
3724
+ end sub
3725
+ `, `
3726
+ sub main(x as dynamic)
3727
+ end sub
3143
3728
  `);
3144
- const validateFileEvent = {
3145
- program: program,
3146
- file: mainFile
3147
- };
3148
- program.plugins.emit('onFileValidate', validateFileEvent);
3149
- (0, chai_config_spec_1.expect)(mainFile.requiredSymbols.length).to.eq(2);
3150
- const requiredTypeChains = mainFile.requiredSymbols.map(x => x.typeChain.map(tc => tc.name).join('.'));
3151
- (0, chai_config_spec_1.expect)(requiredTypeChains).to.have.same.members([
3152
- 'CONST_VALUE', 'OtherType'
3153
- ]);
3154
- (0, chai_config_spec_1.expect)(mainFile.requiredSymbols[0].containingNamespaces).to.have.same.members(['Alpha', 'Beta']);
3155
- (0, chai_config_spec_1.expect)(mainFile.requiredSymbols[1].containingNamespaces).to.have.same.members(['Delta', 'Gamma', 'Eta']);
3156
3729
  });
3157
- it('does not include namespaces that are defined in the file', () => {
3158
- const mainFile = program.setFile('source/main.bs', `
3159
- namespace name1
3160
- const PI = 3.14
3730
+ it('allows union types of arrays', () => {
3731
+ testTranspile(`
3732
+ namespace alpha.beta
3733
+ interface IFaceA
3734
+ name as string
3735
+ data as integer
3736
+ end interface
3161
3737
 
3162
- namespace name2
3163
- function getPi() as float
3164
- return name1.PI
3165
- end function
3166
- end namespace
3738
+ interface IFaceB
3739
+ name as string
3740
+ value as float
3741
+ end interface
3167
3742
  end namespace
3743
+
3744
+ sub main(x as alpha.beta.IFaceA[][] or alpha.beta.IFaceB[] or ifStringOps)
3745
+ end sub
3746
+ `, `
3747
+ sub main(x as dynamic)
3748
+ end sub
3168
3749
  `);
3169
- program.plugins.emit('onFileValidate', { program: program, file: mainFile });
3170
- (0, chai_config_spec_1.expect)(mainFile.requiredSymbols.length).to.eq(0);
3171
- });
3172
- it('should put types from typecasts as typetime required', () => {
3173
- const mainFile = program.setFile('source/main.bs', `
3174
- function takesIface(z) as string
3175
- return (z as MyInterface).name
3176
- end function
3177
- `);
3178
- program.plugins.emit('onFileValidate', { program: program, file: mainFile });
3179
- (0, chai_config_spec_1.expect)(mainFile.requiredSymbols.length).to.eq(1);
3180
- (0, chai_config_spec_1.expect)(mainFile.requiredSymbols[0].flags).to.eq(SymbolTable_1.SymbolTypeFlag.typetime);
3181
3750
  });
3182
- });
3183
- describe('providedSymbols', () => {
3184
- it('includes functions defined in the file', () => {
3185
- const mainFile = program.setFile('source/main.bs', `
3186
- function someFunc() as integer
3187
- return 1
3751
+ it('allows built-in types for return values', () => {
3752
+ testTranspile(`
3753
+ function makeLabel(text as string) as roSGNodeLabel
3754
+ label = createObject("roSGNode", "Label")
3755
+ label.text = text
3188
3756
  end function
3189
-
3190
- function someFunc2() as float
3191
- return 2.3
3757
+ `, `
3758
+ function makeLabel(text as string) as object
3759
+ label = createObject("roSGNode", "Label")
3760
+ label.text = text
3192
3761
  end function
3193
3762
  `);
3194
- const validateFileEvent = {
3195
- program: program,
3196
- file: mainFile
3197
- };
3198
- program.plugins.emit('onFileValidate', validateFileEvent);
3199
- const runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
3200
- (0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(2);
3201
- const someFuncType = runtimeSymbols.get('somefunc').type;
3202
- (0, testHelpers_spec_1.expectTypeToBe)(someFuncType, TypedFunctionType_1.TypedFunctionType);
3203
- const someFunc2Type = runtimeSymbols.get('somefunc2').type;
3204
- (0, testHelpers_spec_1.expectTypeToBe)(someFunc2Type, TypedFunctionType_1.TypedFunctionType);
3205
- });
3206
- it('includes functions with unresolved params/return types', () => {
3207
- const mainFile = program.setFile('source/main.bs', `
3208
- function someFunc() as OtherFileType
3209
- return new OtherFileType()
3210
- end function
3763
+ });
3764
+ it('allows built-in types for interface members', () => {
3765
+ program.setFile('source/main.bs', `
3766
+ interface MyBase
3767
+ regex as roRegex
3768
+ node as roSGNodeLabel
3769
+ sub outputMatches(textInput as string)
3770
+ function getLabelParent() as roSGNode
3771
+ end interface
3211
3772
  `);
3212
- const validateFileEvent = {
3213
- program: program,
3214
- file: mainFile
3215
- };
3216
- program.plugins.emit('onFileValidate', validateFileEvent);
3217
- const runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
3218
- (0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(1);
3219
- const someFuncType = runtimeSymbols.get('somefunc').type;
3220
- (0, testHelpers_spec_1.expectTypeToBe)(someFuncType, TypedFunctionType_1.TypedFunctionType);
3221
- const requiredSymbols = mainFile.requiredSymbols.map(x => x.typeChain[0].name);
3222
- (0, chai_config_spec_1.expect)(requiredSymbols).to.have.same.members(['OtherFileType', 'OtherFileType']);
3223
- const requiredSymbolTypes = mainFile.requiredSymbols.map(x => x.flags);
3224
- (0, chai_config_spec_1.expect)(requiredSymbolTypes).to.have.same.members([SymbolTable_1.SymbolTypeFlag.runtime, SymbolTable_1.SymbolTypeFlag.typetime]);
3225
- });
3226
- it('includes classes defined in the file', () => {
3227
- const mainFile = program.setFile('source/main.bs', `
3228
- class Klass
3229
- name as string
3230
- end class
3231
-
3232
- class Klass2 extends Klass
3233
- age as integer
3773
+ program.validate();
3774
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(program);
3775
+ });
3776
+ it('allows extends on interfaces', () => {
3777
+ testTranspile(`
3778
+ interface MyBase
3779
+ url as string
3780
+ end interface
3234
3781
 
3235
- function getId() as string
3236
- return m.name + " " + m.age.toStr()
3237
- end function
3782
+ interface MyExtends extends MyBase
3783
+ method as string
3784
+ end interface
3785
+ `, `
3786
+ `);
3787
+ });
3788
+ it('allows extends on classes', () => {
3789
+ program.setFile('source/main.bs', `
3790
+ class MyBase
3791
+ url as string
3238
3792
  end class
3239
3793
 
3240
- class Klass3
3241
- propClass = new Klass2()
3794
+ class MyExtends extends MyBase
3795
+ method as string
3242
3796
  end class
3243
3797
  `);
3244
- const validateFileEvent = {
3245
- program: program,
3246
- file: mainFile
3247
- };
3248
- program.plugins.emit('onFileValidate', validateFileEvent);
3249
- const runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
3250
- (0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(3);
3251
- (0, testHelpers_spec_1.expectTypeToBe)(runtimeSymbols.get('klass').type, types_1.ClassType);
3252
- (0, testHelpers_spec_1.expectTypeToBe)(runtimeSymbols.get('klass2').type, types_1.ClassType);
3253
- (0, testHelpers_spec_1.expectTypeToBe)(runtimeSymbols.get('klass3').type, types_1.ClassType);
3254
- const typetimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.typetime);
3255
- (0, chai_config_spec_1.expect)(typetimeSymbols.size).to.eq(3);
3256
- (0, testHelpers_spec_1.expectTypeToBe)(runtimeSymbols.get('klass').type, types_1.ClassType);
3257
- (0, testHelpers_spec_1.expectTypeToBe)(runtimeSymbols.get('klass2').type, types_1.ClassType);
3258
- (0, testHelpers_spec_1.expectTypeToBe)(runtimeSymbols.get('klass3').type, types_1.ClassType);
3259
- });
3260
- it('includes other types defined in the file', () => {
3261
- const mainFile = program.setFile('source/main.bs', `
3262
- interface MyInterface
3263
- name as string
3264
- end interface
3265
-
3266
- enum MyEnum
3267
- val1
3268
- val2
3269
- end enum
3270
-
3271
- namespace MyNamespace
3272
- const MyConst = 3.14
3273
- end namespace
3274
- `);
3275
- const validateFileEvent = {
3276
- program: program,
3277
- file: mainFile
3278
- };
3279
- program.plugins.emit('onFileValidate', validateFileEvent);
3280
- const runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
3281
- (0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(2);
3282
- (0, testHelpers_spec_1.expectTypeToBe)(runtimeSymbols.get('myenum').type, types_1.EnumType);
3283
- (0, testHelpers_spec_1.expectTypeToBe)(runtimeSymbols.get('mynamespace.myconst').type, types_1.FloatType);
3284
- const typetimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.typetime);
3285
- (0, chai_config_spec_1.expect)(typetimeSymbols.size).to.eq(2);
3286
- (0, testHelpers_spec_1.expectTypeToBe)(typetimeSymbols.get('myinterface').type, types_1.InterfaceType);
3287
- (0, testHelpers_spec_1.expectTypeToBe)(runtimeSymbols.get('myenum').type, types_1.EnumType);
3288
- });
3289
- describe('changes', () => {
3290
- it('new symbols are added to the changes set', () => {
3291
- let mainFile = program.setFile('source/main.bs', `
3292
- sub someFunc()
3293
- print 1
3294
- end sub
3295
- `);
3296
- program.plugins.emit('onFileValidate', { program: program, file: mainFile });
3297
- let runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
3298
- (0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(1);
3299
- mainFile = program.setFile('source/main.bs', `
3300
- sub someFunc()
3301
- print 1
3302
- end sub
3303
-
3304
- sub someFunc2()
3305
- print 2
3306
- end sub
3307
- `);
3308
- program.plugins.emit('onFileValidate', { program: program, file: mainFile });
3309
- runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
3310
- (0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(2);
3311
- let runtimeChanges = mainFile.providedSymbols.changes.get(SymbolTable_1.SymbolTypeFlag.runtime);
3312
- (0, chai_config_spec_1.expect)(runtimeChanges.size).to.eq(1);
3313
- (0, chai_config_spec_1.expect)(runtimeChanges.has('somefunc2')).to.be.true;
3314
- });
3315
- it('removed symbols are added to the changes set', () => {
3316
- let mainFile = program.setFile('source/main.bs', `
3317
- sub someFunc()
3318
- print 1
3319
- end sub
3320
-
3321
- sub someFunc2()
3322
- print 2
3323
- end sub
3324
- `);
3325
- program.plugins.emit('onFileValidate', { program: program, file: mainFile });
3326
- let runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
3327
- (0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(2);
3328
- mainFile = program.setFile('source/main.bs', `
3329
- sub someFunc()
3330
- print 1
3331
- end sub
3332
- `);
3333
- program.plugins.emit('onFileValidate', { program: program, file: mainFile });
3334
- runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
3335
- (0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(1);
3336
- let runtimeChanges = mainFile.providedSymbols.changes.get(SymbolTable_1.SymbolTypeFlag.runtime);
3337
- (0, chai_config_spec_1.expect)(runtimeChanges.size).to.eq(1);
3338
- (0, chai_config_spec_1.expect)(runtimeChanges.has('somefunc2')).to.be.true;
3339
- });
3340
- it('new symbols in a namespace are added to the changes set', () => {
3341
- let mainFile = program.setFile('source/main.bs', `
3342
- namespace Alpha
3343
- end namespace
3344
- `);
3345
- program.plugins.emit('onFileValidate', { program: program, file: mainFile });
3346
- let runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
3347
- (0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(0);
3348
- mainFile = program.setFile('source/main.bs', `
3349
- namespace Alpha
3350
- const ABC = "abc"
3351
- end namespace
3352
- `);
3353
- program.plugins.emit('onFileValidate', { program: program, file: mainFile });
3354
- runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
3355
- (0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(1);
3356
- let runtimeChanges = mainFile.providedSymbols.changes.get(SymbolTable_1.SymbolTypeFlag.runtime);
3357
- (0, chai_config_spec_1.expect)(runtimeChanges.size).to.eq(1);
3358
- (0, chai_config_spec_1.expect)(runtimeChanges.has('alpha.abc')).to.be.true;
3359
- });
3360
- it('should be empty if no changes in actual provided symbols', () => {
3361
- let mainFile = program.setFile('source/main.bs', `
3362
- sub printSomething()
3363
- print "Something"
3364
- end sub
3365
-
3366
- namespace alpha.beta
3367
- const PI = 3.14
3368
- end namespace
3369
- `);
3370
- program.plugins.emit('onFileValidate', { program: program, file: mainFile });
3371
- let runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
3372
- (0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(2);
3373
- mainFile = program.setFile('source/main.bs', `
3374
- sub printSomething()
3375
- print "Something Else"
3798
+ program.validate();
3799
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(program);
3800
+ });
3801
+ it('allows built-in types for class members', () => {
3802
+ program.setFile('source/main.bs', `
3803
+ class MyBase
3804
+ regex as roRegex
3805
+ node as roSGNodeLabel
3806
+
3807
+ sub outputMatches(textInput as string)
3808
+ matches = m.regex.match(textInput)
3809
+ if matches.count() > 1
3810
+ m.node.text = matches[1]
3811
+ else
3812
+ m.node.text = "no match"
3813
+ end if
3376
3814
  end sub
3377
3815
 
3378
- namespace alpha.beta
3379
- const PI = 3.14159
3380
- end namespace
3381
- `);
3382
- program.plugins.emit('onFileValidate', { program: program, file: mainFile });
3383
- runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
3384
- (0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(2);
3385
- let runtimeChanges = mainFile.providedSymbols.changes.get(SymbolTable_1.SymbolTypeFlag.runtime);
3386
- (0, chai_config_spec_1.expect)(runtimeChanges.size).to.eq(0);
3387
- });
3388
- it('should include changes in function signatures', () => {
3389
- let mainFile = program.setFile('source/main.bs', `
3390
- function someFunc(x)
3391
- return x
3392
- end function
3393
- `);
3394
- program.plugins.emit('onFileValidate', { program: program, file: mainFile });
3395
- let runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
3396
- (0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(1);
3397
- mainFile = program.setFile('source/main.bs', `
3398
- function someFunc(x, y)
3399
- return x+y
3400
- end function
3401
- `);
3402
- program.plugins.emit('onFileValidate', { program: program, file: mainFile });
3403
- runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
3404
- (0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(1);
3405
- let runtimeChanges = mainFile.providedSymbols.changes.get(SymbolTable_1.SymbolTypeFlag.runtime);
3406
- (0, chai_config_spec_1.expect)(runtimeChanges.size).to.eq(1);
3407
- (0, chai_config_spec_1.expect)(runtimeChanges.has('somefunc'));
3408
- });
3409
- it('should include changes in classes', () => {
3410
- let mainFile = program.setFile('source/main.bs', `
3411
- class MyKlass
3412
- name as string
3413
- function getValue() as float
3414
- return 3.14
3415
- end function
3416
- end class
3417
- `);
3418
- program.plugins.emit('onFileValidate', { program: program, file: mainFile });
3419
- let runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
3420
- (0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(1);
3421
- mainFile = program.setFile('source/main.bs', `
3422
- class MyKlass
3423
- name as string
3424
- function getValue() as string
3425
- return "hello"
3426
- end function
3427
- end class
3428
- `);
3429
- program.plugins.emit('onFileValidate', { program: program, file: mainFile });
3430
- runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
3431
- (0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(1);
3432
- let runtimeChanges = mainFile.providedSymbols.changes.get(SymbolTable_1.SymbolTypeFlag.runtime);
3433
- (0, chai_config_spec_1.expect)(runtimeChanges.size).to.eq(1);
3434
- (0, chai_config_spec_1.expect)(runtimeChanges.has('myklass'));
3435
- let typeTimeChanges = mainFile.providedSymbols.changes.get(SymbolTable_1.SymbolTypeFlag.typetime);
3436
- (0, chai_config_spec_1.expect)(typeTimeChanges.size).to.eq(1);
3437
- (0, chai_config_spec_1.expect)(typeTimeChanges.has('myklass'));
3438
- });
3439
- it('should include changes in interfaces', () => {
3440
- let mainFile = program.setFile('source/main.bs', `
3441
- interface Iface1
3442
- name as string
3443
- function doStuff() as float
3444
- end interface
3445
- `);
3446
- program.plugins.emit('onFileValidate', { program: program, file: mainFile });
3447
- let typetimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.typetime);
3448
- (0, chai_config_spec_1.expect)(typetimeSymbols.size).to.eq(1);
3449
- let runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
3450
- (0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(0);
3451
- mainFile = program.setFile('source/main.bs', `
3452
- interface Iface1
3453
- name as string
3454
- age as integer
3455
- function doStuff() as float
3456
- end interface
3457
- `);
3458
- program.plugins.emit('onFileValidate', { program: program, file: mainFile });
3459
- typetimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.typetime);
3460
- (0, chai_config_spec_1.expect)(typetimeSymbols.size).to.eq(1);
3461
- let typeTimeChanges = mainFile.providedSymbols.changes.get(SymbolTable_1.SymbolTypeFlag.typetime);
3462
- (0, chai_config_spec_1.expect)(typeTimeChanges.size).to.eq(1);
3463
- (0, chai_config_spec_1.expect)(typeTimeChanges.has('iface1'));
3464
- let runtimeChanges = mainFile.providedSymbols.changes.get(SymbolTable_1.SymbolTypeFlag.runtime);
3465
- (0, chai_config_spec_1.expect)(runtimeChanges.size).to.eq(0);
3466
- });
3467
- it('should not include changes in enum values, if inner type is the same', () => {
3468
- let mainFile = program.setFile('source/main.bs', `
3469
- enum MyEnum
3470
- north = 4
3471
- east = 3
3472
- south = 2
3473
- west = 1
3474
- end enum
3475
- `);
3476
- program.plugins.emit('onFileValidate', { program: program, file: mainFile });
3477
- let runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
3478
- (0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(1);
3479
- mainFile = program.setFile('source/main.bs', `
3480
- enum MyEnum
3481
- north = 1
3482
- east = 2
3483
- south = 3
3484
- west = 4
3485
- end enum
3486
- `);
3487
- program.plugins.emit('onFileValidate', { program: program, file: mainFile });
3488
- runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
3489
- (0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(1);
3490
- let runtimeChanges = mainFile.providedSymbols.changes.get(SymbolTable_1.SymbolTypeFlag.runtime);
3491
- (0, chai_config_spec_1.expect)(runtimeChanges.size).to.eq(0);
3492
- let typetimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.typetime);
3493
- (0, chai_config_spec_1.expect)(typetimeSymbols.size).to.eq(1);
3494
- let typetimeChanges = mainFile.providedSymbols.changes.get(SymbolTable_1.SymbolTypeFlag.typetime);
3495
- (0, chai_config_spec_1.expect)(typetimeChanges.size).to.eq(0);
3496
- });
3497
- it('should include changes in enum, if different number of members', () => {
3498
- let mainFile = program.setFile('source/main.bs', `
3499
- enum Direction
3500
- north = 1
3501
- east = 2
3502
- south = 3
3503
- west = 4
3504
- end enum
3505
-
3506
- enum Weather
3507
- rainy
3508
- sunny
3509
- end enum
3510
-
3511
- enum Colors
3512
- blue
3513
- red
3514
- green
3515
- purple
3516
- end enum
3517
- `);
3518
- program.plugins.emit('onFileValidate', { program: program, file: mainFile });
3519
- let runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
3520
- (0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(3);
3521
- mainFile = program.setFile('source/main.bs', `
3522
- enum Direction ' same
3523
- north = 1
3524
- east = 2
3525
- south = 3
3526
- west = 4
3527
- end enum
3528
-
3529
- enum Weather 'added member
3530
- rainy
3531
- sunny
3532
- snowy
3533
- end enum
3534
-
3535
- enum Colors 'removed member
3536
- blue
3537
- red
3538
- green
3539
- end enum
3540
- `);
3541
- program.plugins.emit('onFileValidate', { program: program, file: mainFile });
3542
- runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
3543
- (0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(3);
3544
- let runtimeChanges = mainFile.providedSymbols.changes.get(SymbolTable_1.SymbolTypeFlag.runtime);
3545
- (0, chai_config_spec_1.expect)(runtimeChanges.size).to.eq(2);
3546
- (0, chai_config_spec_1.expect)(runtimeChanges.has('weather'));
3547
- (0, chai_config_spec_1.expect)(runtimeChanges.has('colors'));
3548
- });
3549
- it('should include changes in enum, if different underlying type', () => {
3550
- let mainFile = program.setFile('source/main.bs', `
3551
- enum Direction
3552
- north = 1
3553
- east = 2
3554
- south = 3
3555
- west = 4
3556
- end enum
3557
- `);
3558
- program.plugins.emit('onFileValidate', { program: program, file: mainFile });
3559
- let runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
3560
- (0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(1);
3561
- mainFile = program.setFile('source/main.bs', `
3562
- enum Direction ' now is a string
3563
- north = "N"
3564
- east = "E"
3565
- south = "S"
3566
- west = "W"
3567
- end enum
3568
- `);
3569
- program.plugins.emit('onFileValidate', { program: program, file: mainFile });
3570
- runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
3571
- (0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(1);
3572
- let runtimeChanges = mainFile.providedSymbols.changes.get(SymbolTable_1.SymbolTypeFlag.runtime);
3573
- (0, chai_config_spec_1.expect)(runtimeChanges.size).to.eq(1);
3574
- (0, chai_config_spec_1.expect)(runtimeChanges.has('direction'));
3575
- });
3576
- it('should include changes in const, if different underlying type', () => {
3577
- let mainFile = program.setFile('source/main.bs', `
3578
- namespace alpha.beta
3579
- const PI = 3.14
3580
- end namespace
3581
- `);
3582
- program.plugins.emit('onFileValidate', { program: program, file: mainFile });
3583
- let runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
3584
- (0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(1);
3585
- mainFile = program.setFile('source/main.bs', `
3586
- namespace alpha.beta
3587
- const PI = "lemon chiffon"
3588
- end namespace
3589
- `);
3590
- program.plugins.emit('onFileValidate', { program: program, file: mainFile });
3591
- runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
3592
- (0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(1);
3593
- let runtimeChanges = mainFile.providedSymbols.changes.get(SymbolTable_1.SymbolTypeFlag.runtime);
3594
- (0, chai_config_spec_1.expect)(runtimeChanges.size).to.eq(1);
3595
- (0, chai_config_spec_1.expect)(runtimeChanges.has('alpha.beta.pi'));
3596
- });
3597
- it('should not include changes inside a function if the param types are known', () => {
3598
- let mainFile = program.setFile('source/main.bs', `
3599
- function func1(p as string) as integer
3600
- return len(p)
3601
- end function
3602
-
3603
- sub displayModelTypeInLabel(myLabel as roSgNodeLabel)
3604
- print myLabel.text
3605
- di = createObject("roDeviceInfo")' as roDeviceInfo
3606
- myLabel.text = di.GetFriendlyName()
3607
- print myLabel.getChildren(0, -1)
3608
- end sub
3609
- `);
3610
- program.plugins.emit('onFileValidate', { program: program, file: mainFile });
3611
- let runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
3612
- (0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(2);
3613
- mainFile = program.setFile('source/main.bs', `
3614
- function func1(p as string) as integer
3615
- return len(p)+1
3816
+ function getLabelParent() as roSGNode
3817
+ return m.node.getParent()
3616
3818
  end function
3617
-
3618
- sub displayModelTypeInLabel(myLabel as roSgNodeLabel)
3619
- print myLabel.text
3620
- di = createObject("roDeviceInfo") as roDeviceInfo
3621
- myLabel.text = di.GetFriendlyName()
3622
- print myLabel.getChildren(0, -1)
3623
- end sub
3624
- `);
3625
- program.plugins.emit('onFileValidate', { program: program, file: mainFile });
3626
- runtimeSymbols = mainFile.providedSymbols.symbolMap.get(SymbolTable_1.SymbolTypeFlag.runtime);
3627
- (0, chai_config_spec_1.expect)(runtimeSymbols.size).to.eq(2);
3628
- let runtimeChanges = mainFile.providedSymbols.changes.get(SymbolTable_1.SymbolTypeFlag.runtime);
3629
- (0, chai_config_spec_1.expect)(runtimeChanges.size).to.eq(0);
3630
- });
3631
- it('classes that override AA built-in methods show change properly', () => {
3632
- const classFileContent = `
3633
- class AAOverRide
3634
- sub count(num as integer) as void
3635
- print num
3636
- end sub
3637
- end class
3638
- `;
3639
- let mainFile = program.setFile('source/class.bs', classFileContent);
3640
- program.plugins.emit('onFileValidate', { program: program, file: mainFile });
3641
- // No changes!
3642
- mainFile = program.setFile('source/class.bs', classFileContent);
3643
- program.plugins.emit('onFileValidate', { program: program, file: mainFile });
3644
- let runtimeChanges = mainFile.providedSymbols.changes.get(SymbolTable_1.SymbolTypeFlag.runtime);
3645
- (0, chai_config_spec_1.expect)(runtimeChanges.size).to.eq(0);
3646
- });
3647
- it('functions in a namespace that return classes show change properly', () => {
3648
- const fileContent = `
3649
- namespace Alpha.Beta
3650
-
3651
- class SomeKlass
3652
- name as string
3653
- function combineName(klass as SomeKlass)
3654
- m.name = m.name+klass.name
3655
- end function
3656
- end class
3657
-
3658
- function getSomeKlass(name as string) as SomeKlass
3659
- k = new SomeKlass()
3660
- k.name = name
3661
- return k
3662
- end function
3663
- end namespace
3664
- `;
3665
- let mainFile = program.setFile('source/class.bs', fileContent);
3666
- program.plugins.emit('onFileValidate', { program: program, file: mainFile });
3667
- // No changes!
3668
- mainFile = program.setFile('source/class.bs', fileContent);
3669
- program.plugins.emit('onFileValidate', { program: program, file: mainFile });
3670
- let runtimeChanges = mainFile.providedSymbols.changes.get(SymbolTable_1.SymbolTypeFlag.runtime);
3671
- (0, chai_config_spec_1.expect)(runtimeChanges.size).to.eq(0);
3672
- });
3673
- it('functions in a namespace that have class params show change properly', () => {
3674
- const fileContent = `
3675
- namespace Alpha.Beta
3676
-
3677
- class SomeKlass
3678
- name as string
3679
- function combineName(klass as SomeKlass)
3680
- m.name = m.name+klass.name
3681
- end function
3682
- end class
3683
-
3684
- function combineKlass(klass1 as SomeKlass, klass2 as SomeKlass) as SomeKlass
3685
- klass1.combineName(klass2)
3686
- return klass1
3687
- end function
3688
- end namespace
3689
- `;
3690
- let mainFile = program.setFile('source/class.bs', fileContent);
3691
- program.plugins.emit('onFileValidate', { program: program, file: mainFile });
3692
- // No changes!
3693
- mainFile = program.setFile('source/class.bs', fileContent);
3694
- program.plugins.emit('onFileValidate', { program: program, file: mainFile });
3695
- let runtimeChanges = mainFile.providedSymbols.changes.get(SymbolTable_1.SymbolTypeFlag.runtime);
3696
- (0, chai_config_spec_1.expect)(runtimeChanges.size).to.eq(0);
3697
- });
3819
+ end class
3820
+ `);
3821
+ program.validate();
3822
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(program);
3823
+ });
3824
+ it('allows types on lhs of assignments', () => {
3825
+ testTranspile(`
3826
+ sub foo(node as roSGNode)
3827
+ nodeParent as roSGNode = node.getParent()
3828
+ text as string = nodeParent.id
3829
+ print text
3830
+ end sub
3831
+ `, `
3832
+ sub foo(node as object)
3833
+ nodeParent = node.getParent()
3834
+ text = nodeParent.id
3835
+ print text
3836
+ end sub
3837
+ `);
3698
3838
  });
3699
3839
  });
3840
+ it('allows up to 63 function params', () => {
3841
+ program.setFile('source/main.bs', `
3842
+ function test(p1 = 1, p2 = 2, p3 = 3, p4 = 4, p5 = 5, p6 = 6, p7 = 7, p8 = 8, p9 = 9, p10 = 10, p11 = 11, p12 = 12, p13 = 13, p14 = 14, p15 = 15, p16 = 16, p17 = 17, p18 = 18, p19 = 19, p20 = 20, p21 = 21, p22 = 22, p23 = 23, p24 = 24, p25 = 25, p26 = 26, p27 = 27, p28 = 28, p29 = 29, p30 = 30, p31 = 31, p32 = 32, p33 = 33, p34 = 34, p35 = 35, p36 = 36, p37 = 37, p38 = 38, p39 = 39, p40 = 40, p41 = 41, p42 = 42, p43 = 43, p44 = 44, p45 = 45, p46 = 46, p47 = 47, p48 = 48, p49 = 49, p50 = 50, p51 = 51, p52 = 52, p53 = 53, p54 = 54, p55 = 55, p56 = 56, p57 = 57, p58 = 58, p59 = 59, p60 = 60, p61 = 61, p62 = 62, p63 = 63)
3843
+ end function
3844
+ `);
3845
+ program.validate();
3846
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(program);
3847
+ });
3848
+ it('flags functions having 64 parameters', () => {
3849
+ program.setFile('source/main.bs', `
3850
+ function test(p1 = 1, p2 = 2, p3 = 3, p4 = 4, p5 = 5, p6 = 6, p7 = 7, p8 = 8, p9 = 9, p10 = 10, p11 = 11, p12 = 12, p13 = 13, p14 = 14, p15 = 15, p16 = 16, p17 = 17, p18 = 18, p19 = 19, p20 = 20, p21 = 21, p22 = 22, p23 = 23, p24 = 24, p25 = 25, p26 = 26, p27 = 27, p28 = 28, p29 = 29, p30 = 30, p31 = 31, p32 = 32, p33 = 33, p34 = 34, p35 = 35, p36 = 36, p37 = 37, p38 = 38, p39 = 39, p40 = 40, p41 = 41, p42 = 42, p43 = 43, p44 = 44, p45 = 45, p46 = 46, p47 = 47, p48 = 48, p49 = 49, p50 = 50, p51 = 51, p52 = 52, p53 = 53, p54 = 54, p55 = 55, p56 = 56, p57 = 57, p58 = 58, p59 = 59, p60 = 60, p61 = 61, p62 = 62, p63 = 63, p64 = 64)
3851
+ end function
3852
+ `);
3853
+ program.validate();
3854
+ (0, testHelpers_spec_1.expectDiagnostics)(program, [Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.tooManyCallableParameters(64, 63)), { range: util_1.default.createRange(1, 638, 1, 641) })]);
3855
+ });
3856
+ it('flags functions having 65 parameters', () => {
3857
+ program.setFile('source/main.bs', `
3858
+ function test(p1 = 1, p2 = 2, p3 = 3, p4 = 4, p5 = 5, p6 = 6, p7 = 7, p8 = 8, p9 = 9, p10 = 10, p11 = 11, p12 = 12, p13 = 13, p14 = 14, p15 = 15, p16 = 16, p17 = 17, p18 = 18, p19 = 19, p20 = 20, p21 = 21, p22 = 22, p23 = 23, p24 = 24, p25 = 25, p26 = 26, p27 = 27, p28 = 28, p29 = 29, p30 = 30, p31 = 31, p32 = 32, p33 = 33, p34 = 34, p35 = 35, p36 = 36, p37 = 37, p38 = 38, p39 = 39, p40 = 40, p41 = 41, p42 = 42, p43 = 43, p44 = 44, p45 = 45, p46 = 46, p47 = 47, p48 = 48, p49 = 49, p50 = 50, p51 = 51, p52 = 52, p53 = 53, p54 = 54, p55 = 55, p56 = 56, p57 = 57, p58 = 58, p59 = 59, p60 = 60, p61 = 61, p62 = 62, p63 = 63, p64 = 64, p65 = 65)
3859
+ end function
3860
+ `);
3861
+ program.validate();
3862
+ (0, testHelpers_spec_1.expectDiagnostics)(program, [Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.tooManyCallableParameters(65, 63)), { range: util_1.default.createRange(1, 638, 1, 641) }), Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.tooManyCallableParameters(65, 63)), { range: util_1.default.createRange(1, 648, 1, 651) })]);
3863
+ });
3700
3864
  });
3701
3865
  //# sourceMappingURL=BrsFile.spec.js.map