brighterscript 1.0.0-alpha.24 → 1.0.0-alpha.26

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 (536) hide show
  1. package/CHANGELOG.md +521 -233
  2. package/README.md +45 -139
  3. package/bsconfig.schema.json +46 -0
  4. package/dist/ActionPipeline.d.ts +10 -0
  5. package/dist/ActionPipeline.js +40 -0
  6. package/dist/ActionPipeline.js.map +1 -0
  7. package/dist/AstValidationSegmenter.d.ts +25 -0
  8. package/dist/AstValidationSegmenter.js +152 -0
  9. package/dist/AstValidationSegmenter.js.map +1 -0
  10. package/dist/BsConfig.d.ts +40 -4
  11. package/dist/BusyStatusTracker.d.ts +31 -0
  12. package/dist/BusyStatusTracker.js +83 -0
  13. package/dist/BusyStatusTracker.js.map +1 -0
  14. package/dist/Cache.js +3 -3
  15. package/dist/Cache.js.map +1 -1
  16. package/dist/CacheVerifier.d.ts +7 -0
  17. package/dist/CacheVerifier.js +20 -0
  18. package/dist/CacheVerifier.js.map +1 -0
  19. package/dist/CodeActionUtil.d.ts +3 -3
  20. package/dist/CodeActionUtil.js.map +1 -1
  21. package/dist/CommentFlagProcessor.d.ts +3 -2
  22. package/dist/CommentFlagProcessor.js +5 -4
  23. package/dist/CommentFlagProcessor.js.map +1 -1
  24. package/dist/DependencyGraph.d.ts +3 -2
  25. package/dist/DependencyGraph.js +11 -10
  26. package/dist/DependencyGraph.js.map +1 -1
  27. package/dist/DiagnosticCollection.js +9 -5
  28. package/dist/DiagnosticCollection.js.map +1 -1
  29. package/dist/DiagnosticFilterer.d.ts +1 -0
  30. package/dist/DiagnosticFilterer.js +5 -3
  31. package/dist/DiagnosticFilterer.js.map +1 -1
  32. package/dist/DiagnosticMessages.d.ts +61 -13
  33. package/dist/DiagnosticMessages.js +116 -19
  34. package/dist/DiagnosticMessages.js.map +1 -1
  35. package/dist/DiagnosticSeverityAdjuster.d.ts +7 -0
  36. package/dist/DiagnosticSeverityAdjuster.js +41 -0
  37. package/dist/DiagnosticSeverityAdjuster.js.map +1 -0
  38. package/dist/FunctionScope.d.ts +28 -0
  39. package/dist/FunctionScope.js +52 -0
  40. package/dist/FunctionScope.js.map +1 -0
  41. package/dist/KeyedThrottler.d.ts +3 -3
  42. package/dist/KeyedThrottler.js +3 -3
  43. package/dist/KeyedThrottler.js.map +1 -1
  44. package/dist/LanguageServer.d.ts +23 -11
  45. package/dist/LanguageServer.js +150 -69
  46. package/dist/LanguageServer.js.map +1 -1
  47. package/dist/Logger.d.ts +3 -2
  48. package/dist/Logger.js +11 -3
  49. package/dist/Logger.js.map +1 -1
  50. package/dist/PluginInterface.d.ts +21 -3
  51. package/dist/PluginInterface.js +74 -6
  52. package/dist/PluginInterface.js.map +1 -1
  53. package/dist/Program.d.ts +158 -79
  54. package/dist/Program.js +841 -706
  55. package/dist/Program.js.map +1 -1
  56. package/dist/ProgramBuilder.d.ts +22 -12
  57. package/dist/ProgramBuilder.js +130 -103
  58. package/dist/ProgramBuilder.js.map +1 -1
  59. package/dist/Scope.d.ts +86 -137
  60. package/dist/Scope.js +453 -519
  61. package/dist/Scope.js.map +1 -1
  62. package/dist/Stopwatch.js +1 -1
  63. package/dist/Stopwatch.js.map +1 -1
  64. package/dist/SymbolTable.d.ts +89 -34
  65. package/dist/SymbolTable.js +239 -114
  66. package/dist/SymbolTable.js.map +1 -1
  67. package/dist/Throttler.d.ts +12 -0
  68. package/dist/Throttler.js +39 -0
  69. package/dist/Throttler.js.map +1 -1
  70. package/dist/Watcher.d.ts +0 -3
  71. package/dist/Watcher.js +0 -3
  72. package/dist/Watcher.js.map +1 -1
  73. package/dist/XmlScope.d.ts +4 -11
  74. package/dist/XmlScope.js +75 -88
  75. package/dist/XmlScope.js.map +1 -1
  76. package/dist/astUtils/CachedLookups.d.ts +48 -0
  77. package/dist/astUtils/CachedLookups.js +323 -0
  78. package/dist/astUtils/CachedLookups.js.map +1 -0
  79. package/dist/astUtils/{AstEditor.d.ts → Editor.d.ts} +9 -5
  80. package/dist/astUtils/{AstEditor.js → Editor.js} +10 -4
  81. package/dist/astUtils/Editor.js.map +1 -0
  82. package/dist/astUtils/{AstEditor.spec.js → Editor.spec.js} +69 -65
  83. package/dist/astUtils/Editor.spec.js.map +1 -0
  84. package/dist/astUtils/creators.d.ts +10 -10
  85. package/dist/astUtils/creators.js +54 -24
  86. package/dist/astUtils/creators.js.map +1 -1
  87. package/dist/astUtils/creators.spec.js +5 -5
  88. package/dist/astUtils/creators.spec.js.map +1 -1
  89. package/dist/astUtils/reflection.d.ts +132 -104
  90. package/dist/astUtils/reflection.js +220 -174
  91. package/dist/astUtils/reflection.js.map +1 -1
  92. package/dist/astUtils/reflection.spec.js +256 -157
  93. package/dist/astUtils/reflection.spec.js.map +1 -1
  94. package/dist/astUtils/stackedVisitor.spec.js +12 -12
  95. package/dist/astUtils/stackedVisitor.spec.js.map +1 -1
  96. package/dist/astUtils/visitors.d.ts +53 -35
  97. package/dist/astUtils/visitors.js +29 -3
  98. package/dist/astUtils/visitors.js.map +1 -1
  99. package/dist/astUtils/visitors.spec.js +208 -52
  100. package/dist/astUtils/visitors.spec.js.map +1 -1
  101. package/dist/astUtils/xml.d.ts +9 -9
  102. package/dist/astUtils/xml.js +9 -9
  103. package/dist/astUtils/xml.js.map +1 -1
  104. package/dist/bscPlugin/BscPlugin.d.ts +11 -2
  105. package/dist/bscPlugin/BscPlugin.js +37 -3
  106. package/dist/bscPlugin/BscPlugin.js.map +1 -1
  107. package/dist/bscPlugin/CallExpressionInfo.d.ts +36 -0
  108. package/dist/bscPlugin/CallExpressionInfo.js +131 -0
  109. package/dist/bscPlugin/CallExpressionInfo.js.map +1 -0
  110. package/dist/bscPlugin/FileWriter.d.ts +6 -0
  111. package/dist/bscPlugin/FileWriter.js +24 -0
  112. package/dist/bscPlugin/FileWriter.js.map +1 -0
  113. package/dist/bscPlugin/SignatureHelpUtil.d.ts +10 -0
  114. package/dist/bscPlugin/SignatureHelpUtil.js +136 -0
  115. package/dist/bscPlugin/SignatureHelpUtil.js.map +1 -0
  116. package/dist/bscPlugin/codeActions/CodeActionsProcessor.js +16 -13
  117. package/dist/bscPlugin/codeActions/CodeActionsProcessor.js.map +1 -1
  118. package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js +16 -16
  119. package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js.map +1 -1
  120. package/dist/bscPlugin/completions/CompletionsProcessor.d.ts +52 -1
  121. package/dist/bscPlugin/completions/CompletionsProcessor.js +517 -26
  122. package/dist/bscPlugin/completions/CompletionsProcessor.js.map +1 -1
  123. package/dist/bscPlugin/completions/CompletionsProcessor.spec.js +1909 -0
  124. package/dist/bscPlugin/completions/CompletionsProcessor.spec.js.map +1 -0
  125. package/dist/bscPlugin/definition/DefinitionProvider.d.ts +13 -0
  126. package/dist/bscPlugin/definition/DefinitionProvider.js +210 -0
  127. package/dist/bscPlugin/definition/DefinitionProvider.js.map +1 -0
  128. package/dist/bscPlugin/definition/DefinitionProvider.spec.js +88 -0
  129. package/dist/bscPlugin/definition/DefinitionProvider.spec.js.map +1 -0
  130. package/dist/bscPlugin/fileProviders/FileProvider.d.ts +9 -0
  131. package/dist/bscPlugin/fileProviders/FileProvider.js +51 -0
  132. package/dist/bscPlugin/fileProviders/FileProvider.js.map +1 -0
  133. package/dist/bscPlugin/hover/HoverProcessor.d.ts +7 -7
  134. package/dist/bscPlugin/hover/HoverProcessor.js +123 -125
  135. package/dist/bscPlugin/hover/HoverProcessor.js.map +1 -1
  136. package/dist/bscPlugin/hover/HoverProcessor.spec.js +371 -53
  137. package/dist/bscPlugin/hover/HoverProcessor.spec.js.map +1 -1
  138. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.d.ts +2 -1
  139. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js +83 -23
  140. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js.map +1 -1
  141. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js +83 -6
  142. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js.map +1 -1
  143. package/dist/bscPlugin/serialize/BslibInjector.spec.d.ts +1 -0
  144. package/dist/bscPlugin/serialize/BslibInjector.spec.js +19 -0
  145. package/dist/bscPlugin/serialize/BslibInjector.spec.js.map +1 -0
  146. package/dist/bscPlugin/serialize/BslibManager.d.ts +9 -0
  147. package/dist/bscPlugin/serialize/BslibManager.js +40 -0
  148. package/dist/bscPlugin/serialize/BslibManager.js.map +1 -0
  149. package/dist/bscPlugin/serialize/FileSerializer.d.ts +9 -0
  150. package/dist/bscPlugin/serialize/FileSerializer.js +72 -0
  151. package/dist/bscPlugin/serialize/FileSerializer.js.map +1 -0
  152. package/dist/bscPlugin/transpile/{BrsFilePreTranspileProcessor.d.ts → BrsFileTranspileProcessor.d.ts} +4 -2
  153. package/dist/bscPlugin/transpile/{BrsFilePreTranspileProcessor.js → BrsFileTranspileProcessor.js} +38 -12
  154. package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.js.map +1 -0
  155. package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.spec.d.ts +1 -0
  156. package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.spec.js +41 -0
  157. package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.spec.js.map +1 -0
  158. package/dist/bscPlugin/transpile/XmlFilePreTranspileProcessor.d.ts +12 -0
  159. package/dist/bscPlugin/transpile/XmlFilePreTranspileProcessor.js +99 -0
  160. package/dist/bscPlugin/transpile/XmlFilePreTranspileProcessor.js.map +1 -0
  161. package/dist/bscPlugin/validation/BrsFileValidator.d.ts +13 -5
  162. package/dist/bscPlugin/validation/BrsFileValidator.js +262 -52
  163. package/dist/bscPlugin/validation/BrsFileValidator.js.map +1 -1
  164. package/dist/bscPlugin/validation/BrsFileValidator.spec.js +230 -14
  165. package/dist/bscPlugin/validation/BrsFileValidator.spec.js.map +1 -1
  166. package/dist/bscPlugin/validation/ProgramValidator.d.ts +10 -0
  167. package/dist/bscPlugin/validation/ProgramValidator.js +32 -0
  168. package/dist/bscPlugin/validation/ProgramValidator.js.map +1 -0
  169. package/dist/bscPlugin/validation/ScopeValidator.d.ts +58 -27
  170. package/dist/bscPlugin/validation/ScopeValidator.js +514 -286
  171. package/dist/bscPlugin/validation/ScopeValidator.js.map +1 -1
  172. package/dist/bscPlugin/validation/ScopeValidator.spec.d.ts +1 -0
  173. package/dist/bscPlugin/validation/ScopeValidator.spec.js +2527 -0
  174. package/dist/bscPlugin/validation/ScopeValidator.spec.js.map +1 -0
  175. package/dist/bscPlugin/validation/XmlFileValidator.d.ts +8 -0
  176. package/dist/bscPlugin/validation/XmlFileValidator.js +44 -0
  177. package/dist/bscPlugin/validation/XmlFileValidator.js.map +1 -0
  178. package/dist/cli.js +104 -13
  179. package/dist/cli.js.map +1 -1
  180. package/dist/deferred.d.ts +3 -3
  181. package/dist/deferred.js.map +1 -1
  182. package/dist/diagnosticUtils.d.ts +8 -2
  183. package/dist/diagnosticUtils.js +47 -17
  184. package/dist/diagnosticUtils.js.map +1 -1
  185. package/dist/examples/plugins/removePrint.js +8 -10
  186. package/dist/examples/plugins/removePrint.js.map +1 -1
  187. package/dist/files/AssetFile.d.ts +26 -0
  188. package/dist/files/AssetFile.js +26 -0
  189. package/dist/files/AssetFile.js.map +1 -0
  190. package/dist/files/BrsFile.Class.spec.js +523 -493
  191. package/dist/files/BrsFile.Class.spec.js.map +1 -1
  192. package/dist/files/BrsFile.d.ts +111 -117
  193. package/dist/files/BrsFile.js +684 -1142
  194. package/dist/files/BrsFile.js.map +1 -1
  195. package/dist/files/BrsFile.spec.js +1783 -1233
  196. package/dist/files/BrsFile.spec.js.map +1 -1
  197. package/dist/files/BscFile.d.ts +104 -0
  198. package/dist/files/BscFile.js +16 -0
  199. package/dist/files/BscFile.js.map +1 -0
  200. package/dist/files/Factory.d.ts +25 -0
  201. package/dist/files/Factory.js +22 -0
  202. package/dist/files/Factory.js.map +1 -0
  203. package/dist/files/LazyFileData.d.ts +20 -0
  204. package/dist/files/LazyFileData.js +54 -0
  205. package/dist/files/LazyFileData.js.map +1 -0
  206. package/dist/files/LazyFileData.spec.d.ts +1 -0
  207. package/dist/files/LazyFileData.spec.js +27 -0
  208. package/dist/files/LazyFileData.spec.js.map +1 -0
  209. package/dist/files/XmlFile.d.ts +70 -32
  210. package/dist/files/XmlFile.js +106 -118
  211. package/dist/files/XmlFile.js.map +1 -1
  212. package/dist/files/XmlFile.spec.js +325 -262
  213. package/dist/files/XmlFile.spec.js.map +1 -1
  214. package/dist/files/tests/imports.spec.js +48 -40
  215. package/dist/files/tests/imports.spec.js.map +1 -1
  216. package/dist/files/tests/optionalChaning.spec.js +84 -24
  217. package/dist/files/tests/optionalChaning.spec.js.map +1 -1
  218. package/dist/globalCallables.js +16 -21
  219. package/dist/globalCallables.js.map +1 -1
  220. package/dist/index.d.ts +12 -1
  221. package/dist/index.js +12 -1
  222. package/dist/index.js.map +1 -1
  223. package/dist/interfaces.d.ts +421 -162
  224. package/dist/interfaces.js +27 -0
  225. package/dist/interfaces.js.map +1 -1
  226. package/dist/lexer/Character.spec.js +5 -5
  227. package/dist/lexer/Character.spec.js.map +1 -1
  228. package/dist/lexer/Lexer.d.ts +12 -5
  229. package/dist/lexer/Lexer.js +28 -13
  230. package/dist/lexer/Lexer.js.map +1 -1
  231. package/dist/lexer/Lexer.spec.js +181 -135
  232. package/dist/lexer/Lexer.spec.js.map +1 -1
  233. package/dist/lexer/Token.d.ts +9 -1
  234. package/dist/lexer/Token.js +9 -1
  235. package/dist/lexer/Token.js.map +1 -1
  236. package/dist/lexer/TokenKind.d.ts +8 -0
  237. package/dist/lexer/TokenKind.js +24 -4
  238. package/dist/lexer/TokenKind.js.map +1 -1
  239. package/dist/parser/AstNode.d.ts +162 -0
  240. package/dist/parser/AstNode.js +225 -0
  241. package/dist/parser/AstNode.js.map +1 -0
  242. package/dist/parser/AstNode.spec.d.ts +1 -0
  243. package/dist/parser/AstNode.spec.js +165 -0
  244. package/dist/parser/AstNode.spec.js.map +1 -0
  245. package/dist/parser/BrsTranspileState.d.ts +4 -7
  246. package/dist/parser/BrsTranspileState.js +4 -12
  247. package/dist/parser/BrsTranspileState.js.map +1 -1
  248. package/dist/parser/Expression.d.ts +376 -283
  249. package/dist/parser/Expression.js +742 -585
  250. package/dist/parser/Expression.js.map +1 -1
  251. package/dist/parser/Parser.Class.spec.js +151 -145
  252. package/dist/parser/Parser.Class.spec.js.map +1 -1
  253. package/dist/parser/Parser.d.ts +48 -201
  254. package/dist/parser/Parser.js +705 -1026
  255. package/dist/parser/Parser.js.map +1 -1
  256. package/dist/parser/Parser.spec.d.ts +3 -1
  257. package/dist/parser/Parser.spec.js +861 -848
  258. package/dist/parser/Parser.spec.js.map +1 -1
  259. package/dist/parser/SGParser.d.ts +9 -8
  260. package/dist/parser/SGParser.js +10 -8
  261. package/dist/parser/SGParser.js.map +1 -1
  262. package/dist/parser/SGParser.spec.js +27 -38
  263. package/dist/parser/SGParser.spec.js.map +1 -1
  264. package/dist/parser/SGTypes.d.ts +98 -35
  265. package/dist/parser/SGTypes.js +169 -99
  266. package/dist/parser/SGTypes.js.map +1 -1
  267. package/dist/parser/Statement.d.ts +468 -272
  268. package/dist/parser/Statement.js +904 -631
  269. package/dist/parser/Statement.js.map +1 -1
  270. package/dist/parser/Statement.spec.js +47 -23
  271. package/dist/parser/Statement.spec.js.map +1 -1
  272. package/dist/parser/TranspileState.d.ts +1 -1
  273. package/dist/parser/TranspileState.js +7 -12
  274. package/dist/parser/TranspileState.js.map +1 -1
  275. package/dist/parser/tests/Parser.spec.js +3 -2
  276. package/dist/parser/tests/Parser.spec.js.map +1 -1
  277. package/dist/parser/tests/controlFlow/For.spec.js +33 -23
  278. package/dist/parser/tests/controlFlow/For.spec.js.map +1 -1
  279. package/dist/parser/tests/controlFlow/ForEach.spec.js +25 -20
  280. package/dist/parser/tests/controlFlow/ForEach.spec.js.map +1 -1
  281. package/dist/parser/tests/controlFlow/If.spec.js +96 -94
  282. package/dist/parser/tests/controlFlow/If.spec.js.map +1 -1
  283. package/dist/parser/tests/controlFlow/While.spec.js +22 -16
  284. package/dist/parser/tests/controlFlow/While.spec.js.map +1 -1
  285. package/dist/parser/tests/expression/Additive.spec.js +8 -8
  286. package/dist/parser/tests/expression/Additive.spec.js.map +1 -1
  287. package/dist/parser/tests/expression/ArrayLiterals.spec.js +58 -21
  288. package/dist/parser/tests/expression/ArrayLiterals.spec.js.map +1 -1
  289. package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js +62 -21
  290. package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js.map +1 -1
  291. package/dist/parser/tests/expression/Boolean.spec.js +8 -8
  292. package/dist/parser/tests/expression/Boolean.spec.js.map +1 -1
  293. package/dist/parser/tests/expression/Call.spec.js +129 -21
  294. package/dist/parser/tests/expression/Call.spec.js.map +1 -1
  295. package/dist/parser/tests/expression/Exponential.spec.js +5 -5
  296. package/dist/parser/tests/expression/Exponential.spec.js.map +1 -1
  297. package/dist/parser/tests/expression/Function.spec.js +36 -36
  298. package/dist/parser/tests/expression/Function.spec.js.map +1 -1
  299. package/dist/parser/tests/expression/Indexing.spec.js +92 -22
  300. package/dist/parser/tests/expression/Indexing.spec.js.map +1 -1
  301. package/dist/parser/tests/expression/Multiplicative.spec.js +9 -9
  302. package/dist/parser/tests/expression/Multiplicative.spec.js.map +1 -1
  303. package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js +59 -59
  304. package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js.map +1 -1
  305. package/dist/parser/tests/expression/PrefixUnary.spec.js +12 -12
  306. package/dist/parser/tests/expression/PrefixUnary.spec.js.map +1 -1
  307. package/dist/parser/tests/expression/Primary.spec.js +12 -12
  308. package/dist/parser/tests/expression/Primary.spec.js.map +1 -1
  309. package/dist/parser/tests/expression/RegexLiteralExpression.spec.js +10 -10
  310. package/dist/parser/tests/expression/RegexLiteralExpression.spec.js.map +1 -1
  311. package/dist/parser/tests/expression/Relational.spec.js +13 -13
  312. package/dist/parser/tests/expression/Relational.spec.js.map +1 -1
  313. package/dist/parser/tests/expression/SourceLiteralExpression.spec.js +24 -24
  314. package/dist/parser/tests/expression/SourceLiteralExpression.spec.js.map +1 -1
  315. package/dist/parser/tests/expression/TemplateStringExpression.spec.js +96 -57
  316. package/dist/parser/tests/expression/TemplateStringExpression.spec.js.map +1 -1
  317. package/dist/parser/tests/expression/TernaryExpression.spec.js +89 -89
  318. package/dist/parser/tests/expression/TernaryExpression.spec.js.map +1 -1
  319. package/dist/parser/tests/expression/TypeExpression.spec.d.ts +1 -0
  320. package/dist/parser/tests/expression/TypeExpression.spec.js +127 -0
  321. package/dist/parser/tests/expression/TypeExpression.spec.js.map +1 -0
  322. package/dist/parser/tests/expression/UnaryExpression.spec.d.ts +1 -0
  323. package/dist/parser/tests/expression/UnaryExpression.spec.js +52 -0
  324. package/dist/parser/tests/expression/UnaryExpression.spec.js.map +1 -0
  325. package/dist/parser/tests/statement/AssignmentOperators.spec.js +15 -15
  326. package/dist/parser/tests/statement/AssignmentOperators.spec.js.map +1 -1
  327. package/dist/parser/tests/statement/ConstStatement.spec.js +82 -33
  328. package/dist/parser/tests/statement/ConstStatement.spec.js.map +1 -1
  329. package/dist/parser/tests/statement/Continue.spec.d.ts +1 -0
  330. package/dist/parser/tests/statement/Continue.spec.js +119 -0
  331. package/dist/parser/tests/statement/Continue.spec.js.map +1 -0
  332. package/dist/parser/tests/statement/Declaration.spec.js +19 -19
  333. package/dist/parser/tests/statement/Declaration.spec.js.map +1 -1
  334. package/dist/parser/tests/statement/Dim.spec.js +22 -22
  335. package/dist/parser/tests/statement/Dim.spec.js.map +1 -1
  336. package/dist/parser/tests/statement/Enum.spec.js +98 -302
  337. package/dist/parser/tests/statement/Enum.spec.js.map +1 -1
  338. package/dist/parser/tests/statement/For.spec.js +9 -10
  339. package/dist/parser/tests/statement/For.spec.js.map +1 -1
  340. package/dist/parser/tests/statement/ForEach.spec.js +8 -9
  341. package/dist/parser/tests/statement/ForEach.spec.js.map +1 -1
  342. package/dist/parser/tests/statement/Function.spec.js +44 -35
  343. package/dist/parser/tests/statement/Function.spec.js.map +1 -1
  344. package/dist/parser/tests/statement/Goto.spec.js +5 -5
  345. package/dist/parser/tests/statement/Goto.spec.js.map +1 -1
  346. package/dist/parser/tests/statement/Increment.spec.js +20 -20
  347. package/dist/parser/tests/statement/Increment.spec.js.map +1 -1
  348. package/dist/parser/tests/statement/InterfaceStatement.spec.js +30 -196
  349. package/dist/parser/tests/statement/InterfaceStatement.spec.js.map +1 -1
  350. package/dist/parser/tests/statement/LibraryStatement.spec.js +11 -11
  351. package/dist/parser/tests/statement/LibraryStatement.spec.js.map +1 -1
  352. package/dist/parser/tests/statement/Misc.spec.js +16 -78
  353. package/dist/parser/tests/statement/Misc.spec.js.map +1 -1
  354. package/dist/parser/tests/statement/PrintStatement.spec.js +36 -34
  355. package/dist/parser/tests/statement/PrintStatement.spec.js.map +1 -1
  356. package/dist/parser/tests/statement/ReturnStatement.spec.js +14 -12
  357. package/dist/parser/tests/statement/ReturnStatement.spec.js.map +1 -1
  358. package/dist/parser/tests/statement/Set.spec.js +48 -35
  359. package/dist/parser/tests/statement/Set.spec.js.map +1 -1
  360. package/dist/parser/tests/statement/Stop.spec.js +6 -6
  361. package/dist/parser/tests/statement/Stop.spec.js.map +1 -1
  362. package/dist/parser/tests/statement/Throw.spec.js +6 -6
  363. package/dist/parser/tests/statement/Throw.spec.js.map +1 -1
  364. package/dist/parser/tests/statement/TryCatch.spec.js +18 -16
  365. package/dist/parser/tests/statement/TryCatch.spec.js.map +1 -1
  366. package/dist/preprocessor/Manifest.d.ts +1 -1
  367. package/dist/preprocessor/Manifest.js +2 -2
  368. package/dist/preprocessor/Manifest.js.map +1 -1
  369. package/dist/preprocessor/Manifest.spec.js +8 -8
  370. package/dist/preprocessor/Manifest.spec.js.map +1 -1
  371. package/dist/preprocessor/Preprocessor.d.ts +5 -6
  372. package/dist/preprocessor/Preprocessor.js +5 -5
  373. package/dist/preprocessor/Preprocessor.js.map +1 -1
  374. package/dist/preprocessor/Preprocessor.spec.js +25 -25
  375. package/dist/preprocessor/Preprocessor.spec.js.map +1 -1
  376. package/dist/preprocessor/PreprocessorParser.d.ts +1 -1
  377. package/dist/preprocessor/PreprocessorParser.js +7 -1
  378. package/dist/preprocessor/PreprocessorParser.js.map +1 -1
  379. package/dist/preprocessor/PreprocessorParser.spec.js +13 -13
  380. package/dist/preprocessor/PreprocessorParser.spec.js.map +1 -1
  381. package/dist/roku-types/data.json +5892 -10081
  382. package/dist/roku-types/index.d.ts +622 -1719
  383. package/dist/types/ArrayType.d.ts +10 -9
  384. package/dist/types/ArrayType.js +65 -60
  385. package/dist/types/ArrayType.js.map +1 -1
  386. package/dist/types/ArrayType.spec.js +36 -68
  387. package/dist/types/ArrayType.spec.js.map +1 -1
  388. package/dist/types/AssociativeArrayType.d.ts +11 -0
  389. package/dist/types/AssociativeArrayType.js +52 -0
  390. package/dist/types/AssociativeArrayType.js.map +1 -0
  391. package/dist/types/BaseFunctionType.d.ts +9 -0
  392. package/dist/types/BaseFunctionType.js +25 -0
  393. package/dist/types/BaseFunctionType.js.map +1 -0
  394. package/dist/types/BooleanType.d.ts +8 -5
  395. package/dist/types/BooleanType.js +14 -7
  396. package/dist/types/BooleanType.js.map +1 -1
  397. package/dist/types/BooleanType.spec.js +10 -6
  398. package/dist/types/BooleanType.spec.js.map +1 -1
  399. package/dist/types/BscType.d.ts +32 -21
  400. package/dist/types/BscType.js +118 -21
  401. package/dist/types/BscType.js.map +1 -1
  402. package/dist/types/BscTypeKind.d.ts +25 -0
  403. package/dist/types/BscTypeKind.js +30 -0
  404. package/dist/types/BscTypeKind.js.map +1 -0
  405. package/dist/types/BuiltInInterfaceAdder.d.ts +23 -0
  406. package/dist/types/BuiltInInterfaceAdder.js +171 -0
  407. package/dist/types/BuiltInInterfaceAdder.js.map +1 -0
  408. package/dist/types/BuiltInInterfaceAdder.spec.d.ts +1 -0
  409. package/dist/types/BuiltInInterfaceAdder.spec.js +116 -0
  410. package/dist/types/BuiltInInterfaceAdder.spec.js.map +1 -0
  411. package/dist/types/ClassType.d.ts +17 -0
  412. package/dist/types/ClassType.js +58 -0
  413. package/dist/types/ClassType.js.map +1 -0
  414. package/dist/types/ClassType.spec.d.ts +1 -0
  415. package/dist/types/ClassType.spec.js +77 -0
  416. package/dist/types/ClassType.spec.js.map +1 -0
  417. package/dist/types/ComponentType.d.ts +26 -0
  418. package/dist/types/ComponentType.js +83 -0
  419. package/dist/types/ComponentType.js.map +1 -0
  420. package/dist/types/DoubleType.d.ts +8 -5
  421. package/dist/types/DoubleType.js +18 -16
  422. package/dist/types/DoubleType.js.map +1 -1
  423. package/dist/types/DoubleType.spec.js +12 -6
  424. package/dist/types/DoubleType.spec.js.map +1 -1
  425. package/dist/types/DynamicType.d.ts +9 -5
  426. package/dist/types/DynamicType.js +15 -4
  427. package/dist/types/DynamicType.js.map +1 -1
  428. package/dist/types/DynamicType.spec.js +16 -5
  429. package/dist/types/DynamicType.spec.js.map +1 -1
  430. package/dist/types/EnumType.d.ts +30 -12
  431. package/dist/types/EnumType.js +43 -17
  432. package/dist/types/EnumType.js.map +1 -1
  433. package/dist/types/EnumType.spec.d.ts +1 -0
  434. package/dist/types/EnumType.spec.js +33 -0
  435. package/dist/types/EnumType.spec.js.map +1 -0
  436. package/dist/types/FloatType.d.ts +8 -5
  437. package/dist/types/FloatType.js +18 -16
  438. package/dist/types/FloatType.js.map +1 -1
  439. package/dist/types/FloatType.spec.js +4 -6
  440. package/dist/types/FloatType.spec.js.map +1 -1
  441. package/dist/types/FunctionType.d.ts +13 -8
  442. package/dist/types/FunctionType.js +30 -14
  443. package/dist/types/FunctionType.js.map +1 -1
  444. package/dist/types/InheritableType.d.ts +28 -0
  445. package/dist/types/InheritableType.js +152 -0
  446. package/dist/types/InheritableType.js.map +1 -0
  447. package/dist/types/IntegerType.d.ts +8 -5
  448. package/dist/types/IntegerType.js +18 -16
  449. package/dist/types/IntegerType.js.map +1 -1
  450. package/dist/types/IntegerType.spec.js +8 -6
  451. package/dist/types/IntegerType.spec.js.map +1 -1
  452. package/dist/types/InterfaceType.d.ts +12 -13
  453. package/dist/types/InterfaceType.js +20 -48
  454. package/dist/types/InterfaceType.js.map +1 -1
  455. package/dist/types/InterfaceType.spec.js +90 -56
  456. package/dist/types/InterfaceType.spec.js.map +1 -1
  457. package/dist/types/InvalidType.d.ts +7 -5
  458. package/dist/types/InvalidType.js +13 -7
  459. package/dist/types/InvalidType.js.map +1 -1
  460. package/dist/types/InvalidType.spec.js +8 -6
  461. package/dist/types/InvalidType.spec.js.map +1 -1
  462. package/dist/types/LongIntegerType.d.ts +8 -5
  463. package/dist/types/LongIntegerType.js +17 -15
  464. package/dist/types/LongIntegerType.js.map +1 -1
  465. package/dist/types/LongIntegerType.spec.js +10 -6
  466. package/dist/types/LongIntegerType.spec.js.map +1 -1
  467. package/dist/types/NamespaceType.d.ts +12 -0
  468. package/dist/types/NamespaceType.js +28 -0
  469. package/dist/types/NamespaceType.js.map +1 -0
  470. package/dist/types/ObjectType.d.ts +9 -8
  471. package/dist/types/ObjectType.js +21 -11
  472. package/dist/types/ObjectType.js.map +1 -1
  473. package/dist/types/ObjectType.spec.js +3 -3
  474. package/dist/types/ObjectType.spec.js.map +1 -1
  475. package/dist/types/ReferenceType.d.ts +63 -0
  476. package/dist/types/ReferenceType.js +423 -0
  477. package/dist/types/ReferenceType.js.map +1 -0
  478. package/dist/types/ReferenceType.spec.d.ts +1 -0
  479. package/dist/types/ReferenceType.spec.js +137 -0
  480. package/dist/types/ReferenceType.spec.js.map +1 -0
  481. package/dist/types/StringType.d.ts +11 -5
  482. package/dist/types/StringType.js +18 -7
  483. package/dist/types/StringType.js.map +1 -1
  484. package/dist/types/StringType.spec.js +3 -5
  485. package/dist/types/StringType.spec.js.map +1 -1
  486. package/dist/types/TypedFunctionType.d.ts +22 -17
  487. package/dist/types/TypedFunctionType.js +78 -60
  488. package/dist/types/TypedFunctionType.js.map +1 -1
  489. package/dist/types/TypedFunctionType.spec.js +105 -20
  490. package/dist/types/TypedFunctionType.spec.js.map +1 -1
  491. package/dist/types/UninitializedType.d.ts +8 -6
  492. package/dist/types/UninitializedType.js +13 -7
  493. package/dist/types/UninitializedType.js.map +1 -1
  494. package/dist/types/UnionType.d.ts +20 -0
  495. package/dist/types/UnionType.js +123 -0
  496. package/dist/types/UnionType.js.map +1 -0
  497. package/dist/types/UnionType.spec.d.ts +1 -0
  498. package/dist/types/UnionType.spec.js +130 -0
  499. package/dist/types/UnionType.spec.js.map +1 -0
  500. package/dist/types/VoidType.d.ts +8 -5
  501. package/dist/types/VoidType.js +14 -7
  502. package/dist/types/VoidType.js.map +1 -1
  503. package/dist/types/VoidType.spec.js +3 -3
  504. package/dist/types/VoidType.spec.js.map +1 -1
  505. package/dist/types/helper.spec.d.ts +1 -0
  506. package/dist/types/helper.spec.js +145 -0
  507. package/dist/types/helper.spec.js.map +1 -0
  508. package/dist/types/helpers.d.ts +19 -37
  509. package/dist/types/helpers.js +159 -99
  510. package/dist/types/helpers.js.map +1 -1
  511. package/dist/types/index.d.ts +22 -0
  512. package/dist/types/index.js +39 -0
  513. package/dist/types/index.js.map +1 -0
  514. package/dist/util.d.ts +143 -139
  515. package/dist/util.js +864 -385
  516. package/dist/util.js.map +1 -1
  517. package/dist/validators/ClassValidator.d.ts +8 -25
  518. package/dist/validators/ClassValidator.js +99 -179
  519. package/dist/validators/ClassValidator.js.map +1 -1
  520. package/package.json +165 -152
  521. package/dist/astUtils/AstEditor.js.map +0 -1
  522. package/dist/astUtils/AstEditor.spec.js.map +0 -1
  523. package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.js.map +0 -1
  524. package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.js +0 -32
  525. package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.js.map +0 -1
  526. package/dist/parser/SGTypes.spec.js +0 -351
  527. package/dist/parser/SGTypes.spec.js.map +0 -1
  528. package/dist/types/CustomType.d.ts +0 -12
  529. package/dist/types/CustomType.js +0 -44
  530. package/dist/types/CustomType.js.map +0 -1
  531. package/dist/types/LazyType.d.ts +0 -16
  532. package/dist/types/LazyType.js +0 -44
  533. package/dist/types/LazyType.js.map +0 -1
  534. /package/dist/astUtils/{AstEditor.spec.d.ts → Editor.spec.d.ts} +0 -0
  535. /package/dist/bscPlugin/{transpile/BrsFilePreTranspileProcessor.spec.d.ts → completions/CompletionsProcessor.spec.d.ts} +0 -0
  536. /package/dist/{parser/SGTypes.spec.d.ts → bscPlugin/definition/DefinitionProvider.spec.d.ts} +0 -0
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.failStatementType = exports.rangeToArray = void 0;
4
- const chai_1 = require("chai");
3
+ exports.failStatementType = exports.rangeToArray = exports.parse = void 0;
4
+ const chai_config_spec_1 = require("../chai-config.spec");
5
5
  const Lexer_1 = require("../lexer/Lexer");
6
6
  const TokenKind_1 = require("../lexer/TokenKind");
7
7
  const Expression_1 = require("./Expression");
@@ -11,212 +11,19 @@ const vscode_languageserver_1 = require("vscode-languageserver");
11
11
  const DiagnosticMessages_1 = require("../DiagnosticMessages");
12
12
  const reflection_1 = require("../astUtils/reflection");
13
13
  const testHelpers_spec_1 = require("../testHelpers.spec");
14
- const BrsTranspileState_1 = require("./BrsTranspileState");
15
- const source_map_1 = require("source-map");
16
- const BrsFile_1 = require("../files/BrsFile");
17
- const Program_1 = require("../Program");
18
14
  const visitors_1 = require("../astUtils/visitors");
19
15
  const SymbolTable_1 = require("../SymbolTable");
20
- const ArrayType_1 = require("../types/ArrayType");
21
- const CustomType_1 = require("../types/CustomType");
22
- const DynamicType_1 = require("../types/DynamicType");
23
16
  const IntegerType_1 = require("../types/IntegerType");
24
- const LazyType_1 = require("../types/LazyType");
25
- const ObjectType_1 = require("../types/ObjectType");
17
+ const FloatType_1 = require("../types/FloatType");
26
18
  const StringType_1 = require("../types/StringType");
27
- const TypedFunctionType_1 = require("../types/TypedFunctionType");
28
- const VoidType_1 = require("../types/VoidType");
29
- const util_1 = require("../util");
19
+ const types_1 = require("../types");
30
20
  describe('parser', () => {
31
21
  it('emits empty object when empty token list is provided', () => {
32
- (0, chai_1.expect)(Parser_1.Parser.parse([])).to.deep.include({
22
+ (0, chai_config_spec_1.expect)(Parser_1.Parser.parse([])).to.deep.include({
33
23
  statements: [],
34
24
  diagnostics: []
35
25
  });
36
26
  });
37
- describe('findReferences', () => {
38
- it('recomputes localVars', () => {
39
- const parser = Parser_1.Parser.parse(`
40
- sub main(herd)
41
- for each zombie in herd
42
- isAlive = false
43
- end for
44
- for i = 0 to 10 step 1
45
- j = i
46
- end for
47
- humansAreAlive = false
48
- end sub
49
- `);
50
- (0, chai_1.expect)(parser.references.functionExpressions[0].symbolTable.getOwnSymbols().map(x => x.name).sort()).to.eql([
51
- 'herd',
52
- 'humansAreAlive',
53
- 'i',
54
- 'isAlive',
55
- 'j',
56
- 'zombie'
57
- ]);
58
- parser.invalidateReferences();
59
- (0, chai_1.expect)(parser.references.functionExpressions[0].symbolTable.getOwnSymbols().map(x => x.name).sort()).to.eql([
60
- 'herd',
61
- 'humansAreAlive',
62
- 'i',
63
- 'isAlive',
64
- 'j',
65
- 'zombie'
66
- ]);
67
- });
68
- it('assigns localVars to correct function expression bucket', () => {
69
- const parser = Parser_1.Parser.parse(`
70
- sub main()
71
- outerName = "bob"
72
- speak = sub()
73
- innerName = "innerBob"
74
- end sub
75
- age = 12
76
- end sub
77
- `);
78
- parser.invalidateReferences();
79
- (0, chai_1.expect)(parser.references.functionExpressions.map(x => {
80
- return x.symbolTable.getOwnSymbols().map(x => x.name);
81
- })).to.eql([
82
- [
83
- 'outerName',
84
- 'speak',
85
- 'age'
86
- ],
87
- [
88
- 'innerName'
89
- ]
90
- ]);
91
- });
92
- it('gets called if references are missing', () => {
93
- const parser = Parser_1.Parser.parse(`
94
- sub main()
95
- end sub
96
-
97
- sub UnusedFunction()
98
- end sub
99
- `);
100
- (0, chai_1.expect)(parser.references.functionStatements.map(x => x.name.text)).to.eql([
101
- 'main',
102
- 'UnusedFunction'
103
- ]);
104
- //simulate a tree-shaking plugin by removing the `UnusedFunction`
105
- parser.ast.statements.splice(1);
106
- //tell the parser we modified the AST and need to regenerate references
107
- parser.invalidateReferences();
108
- (0, chai_1.expect)(parser['_references']).not.to.exist;
109
- //calling `references` automatically regenerates the references
110
- (0, chai_1.expect)(parser.references.functionStatements.map(x => x.name.text)).to.eql([
111
- 'main'
112
- ]);
113
- });
114
- function expressionsToStrings(expressions) {
115
- return [...expressions.values()].map(x => {
116
- const file = new BrsFile_1.BrsFile('', '', new Program_1.Program({}));
117
- const state = new BrsTranspileState_1.BrsTranspileState(file);
118
- return new source_map_1.SourceNode(null, null, null, x.transpile(state)).toString();
119
- });
120
- }
121
- it('works for references.expressions', () => {
122
- const parser = Parser_1.Parser.parse(`
123
- b += "plus-equal"
124
- a += 1 + 2
125
- b += getValue1() + getValue2()
126
- increment++
127
- decrement--
128
- some.node@.doCallfunc()
129
- bravo(3 + 4).jump(callMe())
130
- obj = {
131
- val1: someValue
132
- }
133
- arr = [
134
- one
135
- ]
136
- thing = alpha.bravo
137
- alpha.charlie()
138
- delta(alpha.delta)
139
- call1().a.b.call2()
140
- class Person
141
- name as string = "bob"
142
- end class
143
- function thing(p1 = name.space.getSomething())
144
-
145
- end function
146
- `);
147
- const expected = [
148
- '"plus-equal"',
149
- 'b',
150
- 'b += "plus-equal"',
151
- '1',
152
- '2',
153
- 'a',
154
- 'a += 1 + 2',
155
- 'getValue1()',
156
- 'getValue2()',
157
- 'b',
158
- 'b += getValue1() + getValue2()',
159
- 'increment++',
160
- 'decrement--',
161
- //currently the "toString" does a transpile, so that's why this is different.
162
- 'some.node.callfunc("doCallfunc", invalid)',
163
- '3',
164
- '4',
165
- '3 + 4',
166
- 'callMe()',
167
- 'bravo(3 + 4).jump(callMe())',
168
- 'someValue',
169
- '{\n val1: someValue\n}',
170
- 'one',
171
- '[\n one\n]',
172
- 'alpha.bravo',
173
- 'alpha.charlie()',
174
- 'alpha.delta',
175
- 'delta(alpha.delta)',
176
- 'call1().a.b.call2()',
177
- '"bob"',
178
- 'name.space.getSomething()'
179
- ];
180
- (0, chai_1.expect)(expressionsToStrings(parser.references.expressions)).to.eql(expected);
181
- //tell the parser we modified the AST and need to regenerate references
182
- parser.invalidateReferences();
183
- (0, chai_1.expect)(expressionsToStrings(parser.references.expressions).sort()).to.eql(expected.sort());
184
- });
185
- it('works for references.expressions', () => {
186
- const parser = Parser_1.Parser.parse(`
187
- value = true or type(true) = "something" or Enums.A.Value = "value" and Enum1.Value = Name.Space.Enum2.Value
188
- `);
189
- const expected = [
190
- 'true',
191
- 'type(true)',
192
- '"something"',
193
- 'true',
194
- 'Enums.A.Value',
195
- '"value"',
196
- 'Enum1.Value',
197
- 'Name.Space.Enum2.Value',
198
- 'true or type(true) = "something" or Enums.A.Value = "value" and Enum1.Value = Name.Space.Enum2.Value'
199
- ];
200
- (0, chai_1.expect)(expressionsToStrings(parser.references.expressions)).to.eql(expected);
201
- //tell the parser we modified the AST and need to regenerate references
202
- parser.invalidateReferences();
203
- (0, chai_1.expect)(expressionsToStrings(parser.references.expressions).sort()).to.eql(expected.sort());
204
- });
205
- it('works for logical expression', () => {
206
- const parser = Parser_1.Parser.parse(`
207
- value = Enums.A.Value = "value"
208
- `);
209
- const expected = [
210
- 'Enums.A.Value',
211
- '"value"',
212
- 'Enums.A.Value = "value"'
213
- ];
214
- (0, chai_1.expect)(expressionsToStrings(parser.references.expressions)).to.eql(expected);
215
- //tell the parser we modified the AST and need to regenerate references
216
- parser.invalidateReferences();
217
- (0, chai_1.expect)(expressionsToStrings(parser.references.expressions).sort()).to.eql(expected.sort());
218
- });
219
- });
220
27
  describe('callfunc operator', () => {
221
28
  it('is not allowed in brightscript mode', () => {
222
29
  var _a;
@@ -225,7 +32,7 @@ describe('parser', () => {
225
32
  node@.doSomething(1, 2)
226
33
  end sub
227
34
  `, Parser_1.ParseMode.BrightScript);
228
- (0, chai_1.expect)((_a = parser.diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('callfunc operator').message);
35
+ (0, chai_config_spec_1.expect)((_a = parser.diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('callfunc operator').message);
229
36
  });
230
37
  it('does not cause parse errors', () => {
231
38
  var _a, _b, _c, _d, _e;
@@ -234,15 +41,15 @@ describe('parser', () => {
234
41
  node@.doSomething(1, 2)
235
42
  end sub
236
43
  `, Parser_1.ParseMode.BrighterScript);
237
- (0, chai_1.expect)((_a = parser.diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
238
- (0, chai_1.expect)((_e = (_d = (_c = (_b = parser.statements[0]) === null || _b === void 0 ? void 0 : _b.func) === null || _c === void 0 ? void 0 : _c.body) === null || _d === void 0 ? void 0 : _d.statements[0]) === null || _e === void 0 ? void 0 : _e.expression).to.be.instanceof(Expression_1.CallfuncExpression);
44
+ (0, chai_config_spec_1.expect)((_a = parser.diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
45
+ (0, chai_config_spec_1.expect)((_e = (_d = (_c = (_b = parser.statements[0]) === null || _b === void 0 ? void 0 : _b.func) === null || _c === void 0 ? void 0 : _c.body) === null || _d === void 0 ? void 0 : _d.statements[0]) === null || _e === void 0 ? void 0 : _e.expression).to.be.instanceof(Expression_1.CallfuncExpression);
239
46
  });
240
47
  });
241
48
  describe('optional chaining operator', () => {
242
49
  function getExpression(text, options) {
243
50
  const parser = parse(text, options === null || options === void 0 ? void 0 : options.parseMode);
244
51
  (0, testHelpers_spec_1.expectZeroDiagnostics)(parser);
245
- const expressions = [...parser.references.expressions];
52
+ const expressions = parser.ast.findChildren(reflection_1.isExpression);
246
53
  if (options === null || options === void 0 ? void 0 : options.matcher) {
247
54
  return expressions.find(options.matcher);
248
55
  }
@@ -252,50 +59,50 @@ describe('parser', () => {
252
59
  }
253
60
  it('works for ?.', () => {
254
61
  const expression = getExpression(`value = person?.name`);
255
- (0, chai_1.expect)(expression).to.be.instanceOf(Expression_1.DottedGetExpression);
256
- (0, chai_1.expect)(expression.dot.kind).to.eql(TokenKind_1.TokenKind.QuestionDot);
62
+ (0, chai_config_spec_1.expect)(expression).to.be.instanceOf(Expression_1.DottedGetExpression);
63
+ (0, chai_config_spec_1.expect)(expression.tokens.dot.kind).to.eql(TokenKind_1.TokenKind.QuestionDot);
257
64
  });
258
65
  it('works for ?[', () => {
259
66
  const expression = getExpression(`value = person?["name"]`, { matcher: reflection_1.isIndexedGetExpression });
260
- (0, chai_1.expect)(expression).to.be.instanceOf(Expression_1.IndexedGetExpression);
261
- (0, chai_1.expect)(expression.openingSquare.kind).to.eql(TokenKind_1.TokenKind.QuestionLeftSquare);
262
- (0, chai_1.expect)(expression.questionDotToken).not.to.exist;
67
+ (0, chai_config_spec_1.expect)(expression).to.be.instanceOf(Expression_1.IndexedGetExpression);
68
+ (0, chai_config_spec_1.expect)(expression.tokens.openingSquare.kind).to.eql(TokenKind_1.TokenKind.QuestionLeftSquare);
69
+ (0, chai_config_spec_1.expect)(expression.tokens.questionDot).not.to.exist;
263
70
  });
264
71
  it('works for ?.[', () => {
265
72
  var _a;
266
73
  const expression = getExpression(`value = person?.["name"]`, { matcher: reflection_1.isIndexedGetExpression });
267
- (0, chai_1.expect)(expression).to.be.instanceOf(Expression_1.IndexedGetExpression);
268
- (0, chai_1.expect)(expression.openingSquare.kind).to.eql(TokenKind_1.TokenKind.LeftSquareBracket);
269
- (0, chai_1.expect)((_a = expression.questionDotToken) === null || _a === void 0 ? void 0 : _a.kind).to.eql(TokenKind_1.TokenKind.QuestionDot);
74
+ (0, chai_config_spec_1.expect)(expression).to.be.instanceOf(Expression_1.IndexedGetExpression);
75
+ (0, chai_config_spec_1.expect)(expression.tokens.openingSquare.kind).to.eql(TokenKind_1.TokenKind.LeftSquareBracket);
76
+ (0, chai_config_spec_1.expect)((_a = expression.tokens.questionDot) === null || _a === void 0 ? void 0 : _a.kind).to.eql(TokenKind_1.TokenKind.QuestionDot);
270
77
  });
271
78
  it('works for ?@', () => {
272
79
  const expression = getExpression(`value = someXml?@someAttr`);
273
- (0, chai_1.expect)(expression).to.be.instanceOf(Expression_1.XmlAttributeGetExpression);
274
- (0, chai_1.expect)(expression.at.kind).to.eql(TokenKind_1.TokenKind.QuestionAt);
80
+ (0, chai_config_spec_1.expect)(expression).to.be.instanceOf(Expression_1.XmlAttributeGetExpression);
81
+ (0, chai_config_spec_1.expect)(expression.tokens.at.kind).to.eql(TokenKind_1.TokenKind.QuestionAt);
275
82
  });
276
83
  it('works for ?(', () => {
277
84
  const expression = getExpression(`value = person.getName?()`);
278
- (0, chai_1.expect)(expression).to.be.instanceOf(Expression_1.CallExpression);
279
- (0, chai_1.expect)(expression.openingParen.kind).to.eql(TokenKind_1.TokenKind.QuestionLeftParen);
85
+ (0, chai_config_spec_1.expect)(expression).to.be.instanceOf(Expression_1.CallExpression);
86
+ (0, chai_config_spec_1.expect)(expression.tokens.openingParen.kind).to.eql(TokenKind_1.TokenKind.QuestionLeftParen);
280
87
  });
281
88
  it('works for print statements using question mark', () => {
282
89
  const { statements } = parse(`
283
90
  ?[1]
284
91
  ?(1+1)
285
92
  `);
286
- (0, chai_1.expect)(statements[0]).to.be.instanceOf(Statement_1.PrintStatement);
287
- (0, chai_1.expect)(statements[1]).to.be.instanceOf(Statement_1.PrintStatement);
93
+ (0, chai_config_spec_1.expect)(statements[0]).to.be.instanceOf(Statement_1.PrintStatement);
94
+ (0, chai_config_spec_1.expect)(statements[1]).to.be.instanceOf(Statement_1.PrintStatement);
288
95
  });
289
96
  //TODO enable this once we properly parse IIFEs
290
97
  it.skip('works for ?( in anonymous function', () => {
291
98
  const expression = getExpression(`thing = (function() : end function)?()`);
292
- (0, chai_1.expect)(expression).to.be.instanceOf(Expression_1.CallExpression);
293
- (0, chai_1.expect)(expression.openingParen.kind).to.eql(TokenKind_1.TokenKind.QuestionLeftParen);
99
+ (0, chai_config_spec_1.expect)(expression).to.be.instanceOf(Expression_1.CallExpression);
100
+ (0, chai_config_spec_1.expect)(expression.tokens.openingParen.kind).to.eql(TokenKind_1.TokenKind.QuestionLeftParen);
294
101
  });
295
102
  it('works for ?( in new call', () => {
296
103
  const expression = getExpression(`thing = new Person?()`, { parseMode: Parser_1.ParseMode.BrighterScript });
297
- (0, chai_1.expect)(expression).to.be.instanceOf(Expression_1.NewExpression);
298
- (0, chai_1.expect)(expression.call.openingParen.kind).to.eql(TokenKind_1.TokenKind.QuestionLeftParen);
104
+ (0, chai_config_spec_1.expect)(expression).to.be.instanceOf(Expression_1.NewExpression);
105
+ (0, chai_config_spec_1.expect)(expression.call.tokens.openingParen.kind).to.eql(TokenKind_1.TokenKind.QuestionLeftParen);
299
106
  });
300
107
  it('distinguishes between optional chaining and ternary expression', () => {
301
108
  const parser = parse(`
@@ -305,8 +112,9 @@ describe('parser', () => {
305
112
  key = isTrue ? ["name"] : ["age"]
306
113
  end sub
307
114
  `, Parser_1.ParseMode.BrighterScript);
308
- (0, chai_1.expect)(parser.references.assignmentStatements[0].value).is.instanceof(Expression_1.IndexedGetExpression);
309
- (0, chai_1.expect)(parser.references.assignmentStatements[2].value).is.instanceof(Expression_1.TernaryExpression);
115
+ const assignmentStatements = parser.ast.findChildren(reflection_1.isAssignmentStatement);
116
+ (0, chai_config_spec_1.expect)(assignmentStatements[0].value).is.instanceof(Expression_1.IndexedGetExpression);
117
+ (0, chai_config_spec_1.expect)(assignmentStatements[2].value).is.instanceof(Expression_1.TernaryExpression);
310
118
  });
311
119
  it('distinguishes between optional chaining and ternary expression', () => {
312
120
  const parser = parse(`
@@ -317,13 +125,14 @@ describe('parser', () => {
317
125
  key = isTrue ? ["name"] : getDefault()
318
126
  end sub
319
127
  `, Parser_1.ParseMode.BrighterScript);
320
- (0, chai_1.expect)(parser.references.assignmentStatements[0].value).is.instanceof(Expression_1.IndexedGetExpression);
321
- (0, chai_1.expect)(parser.references.assignmentStatements[1].value).is.instanceof(Expression_1.TernaryExpression);
128
+ const assignmentStatements = parser.ast.findChildren(reflection_1.isAssignmentStatement);
129
+ (0, chai_config_spec_1.expect)(assignmentStatements[0].value).is.instanceof(Expression_1.IndexedGetExpression);
130
+ (0, chai_config_spec_1.expect)(assignmentStatements[1].value).is.instanceof(Expression_1.TernaryExpression);
322
131
  });
323
132
  });
324
133
  describe('diagnostic locations', () => {
325
134
  it('tracks basic diagnostic locations', () => {
326
- (0, chai_1.expect)(parse(`
135
+ (0, chai_config_spec_1.expect)(parse(`
327
136
  sub main()
328
137
  call()a
329
138
  end sub
@@ -339,8 +148,8 @@ describe('parser', () => {
339
148
  return "6c5cdf1"
340
149
  end functionasdf
341
150
  `).diagnostics;
342
- (0, chai_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.exist.and.to.eql(DiagnosticMessages_1.DiagnosticMessages.expectedStatementOrFunctionCallButReceivedExpression().message);
343
- (0, chai_1.expect)((_b = diagnostics[0]) === null || _b === void 0 ? void 0 : _b.range).to.eql(vscode_languageserver_1.Range.create(3, 20, 3, 32));
151
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.exist.and.to.eql(DiagnosticMessages_1.DiagnosticMessages.expectedStatementOrFunctionCallButReceivedExpression().message);
152
+ (0, chai_config_spec_1.expect)((_b = diagnostics[0]) === null || _b === void 0 ? void 0 : _b.range).to.eql(vscode_languageserver_1.Range.create(3, 20, 3, 32));
344
153
  });
345
154
  });
346
155
  describe('parse', () => {
@@ -377,20 +186,37 @@ describe('parser', () => {
377
186
  });
378
187
  it('supports using "interface" as parameter name', () => {
379
188
  var _a;
380
- (0, chai_1.expect)((_a = parse(`
189
+ (0, chai_config_spec_1.expect)((_a = parse(`
381
190
  sub main(interface as object)
382
191
  end sub
383
192
  `, Parser_1.ParseMode.BrighterScript).diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
384
193
  });
194
+ it('does not scrap the entire function when encountering unknown parameter type', () => {
195
+ const parser = parse(`
196
+ sub test(param1 as unknownType)
197
+ end sub
198
+ `);
199
+ // type validation happens at scope validation, not at the parser
200
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(parser);
201
+ (0, chai_config_spec_1.expect)((0, reflection_1.isFunctionStatement)(parser.ast.statements[0])).to.be.true;
202
+ });
385
203
  describe('namespace', () => {
386
- it('catches namespaces declared not at root level', () => {
387
- var _a;
388
- (0, chai_1.expect)((_a = parse(`
389
- sub main()
390
- namespace Name.Space
204
+ it('allows namespaces declared inside other namespaces', () => {
205
+ const parser = parse(`
206
+ namespace Level1
207
+ namespace Level2.Level3
208
+ sub main()
209
+ end sub
391
210
  end namespace
392
- end sub
393
- `, Parser_1.ParseMode.BrighterScript).diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.keywordMustBeDeclaredAtRootLevel('namespace').message);
211
+ end namespace
212
+ `, Parser_1.ParseMode.BrighterScript);
213
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(parser);
214
+ // We expect these names to be "as given" in this context, because we aren't evaluating a full program.
215
+ const namespaceStatements = parser.ast.findChildren(reflection_1.isNamespaceStatement);
216
+ (0, chai_config_spec_1.expect)(namespaceStatements.map(statement => statement.getName(Parser_1.ParseMode.BrighterScript))).to.have.deep.members([
217
+ 'Level1.Level2.Level3',
218
+ 'Level1'
219
+ ]);
394
220
  });
395
221
  it('parses empty namespace', () => {
396
222
  var _a;
@@ -398,8 +224,8 @@ describe('parser', () => {
398
224
  namespace Name.Space
399
225
  end namespace
400
226
  `, Parser_1.ParseMode.BrighterScript);
401
- (0, chai_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
402
- (0, chai_1.expect)(statements[0]).to.be.instanceof(Statement_1.NamespaceStatement);
227
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
228
+ (0, chai_config_spec_1.expect)(statements[0]).to.be.instanceof(Statement_1.NamespaceStatement);
403
229
  });
404
230
  it('includes body', () => {
405
231
  var _a;
@@ -409,9 +235,9 @@ describe('parser', () => {
409
235
  end sub
410
236
  end namespace
411
237
  `, Parser_1.ParseMode.BrighterScript);
412
- (0, chai_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
413
- (0, chai_1.expect)(statements[0]).to.be.instanceof(Statement_1.NamespaceStatement);
414
- (0, chai_1.expect)(statements[0].body.statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
238
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
239
+ (0, chai_config_spec_1.expect)(statements[0]).to.be.instanceof(Statement_1.NamespaceStatement);
240
+ (0, chai_config_spec_1.expect)(statements[0].body.statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
415
241
  });
416
242
  it('supports comments and newlines', () => {
417
243
  var _a;
@@ -427,7 +253,7 @@ describe('parser', () => {
427
253
  'comment
428
254
  end namespace 'comment
429
255
  `, Parser_1.ParseMode.BrighterScript);
430
- (0, chai_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
256
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
431
257
  });
432
258
  it('catches missing name', () => {
433
259
  var _a;
@@ -435,7 +261,7 @@ describe('parser', () => {
435
261
  namespace
436
262
  end namespace
437
263
  `, Parser_1.ParseMode.BrighterScript);
438
- (0, chai_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifierAfterKeyword('namespace').message);
264
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifierAfterKeyword('namespace').message);
439
265
  });
440
266
  it('recovers after missing `end namespace`', () => {
441
267
  var _a, _b, _c;
@@ -444,9 +270,9 @@ describe('parser', () => {
444
270
  sub main()
445
271
  end sub
446
272
  `, Parser_1.ParseMode.BrighterScript);
447
- (0, chai_1.expect)(parser.ast.statements[0]).to.be.instanceof(Statement_1.NamespaceStatement);
448
- (0, chai_1.expect)((_a = parser.diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.couldNotFindMatchingEndKeyword('namespace').message);
449
- (0, chai_1.expect)((_c = (_b = parser.ast.statements[0]) === null || _b === void 0 ? void 0 : _b.body) === null || _c === void 0 ? void 0 : _c.statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
273
+ (0, chai_config_spec_1.expect)(parser.ast.statements[0]).to.be.instanceof(Statement_1.NamespaceStatement);
274
+ (0, chai_config_spec_1.expect)((_a = parser.diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.couldNotFindMatchingEndKeyword('namespace').message);
275
+ (0, chai_config_spec_1.expect)((_c = (_b = parser.ast.statements[0]) === null || _b === void 0 ? void 0 : _b.body) === null || _c === void 0 ? void 0 : _c.statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
450
276
  });
451
277
  it('adds diagnostic when encountering namespace in brightscript mode', () => {
452
278
  var _a;
@@ -454,47 +280,12 @@ describe('parser', () => {
454
280
  namespace Name.Space
455
281
  end namespace
456
282
  `);
457
- (0, chai_1.expect)((_a = parser.diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('namespace').message);
458
- });
459
- it('declares a symbol table for the namespace', () => {
460
- let parser = parse(`
461
- namespace Name.Space
462
- function funcInt() as integer
463
- return 3
464
- end function
465
-
466
- function funcStr() as string
467
- return "hello"
468
- end function
469
- end namespace
470
- `, Parser_1.ParseMode.BrighterScript);
471
- (0, chai_1.expect)(parser.ast.statements[0]).to.be.instanceof(Statement_1.NamespaceStatement);
472
- const namespaceStmt = parser.ast.statements[0];
473
- (0, chai_1.expect)(namespaceStmt.symbolTable).to.be.instanceof(SymbolTable_1.SymbolTable);
474
- (0, chai_1.expect)(namespaceStmt.symbolTable.getSymbolType('funcInt').toString()).to.equal('function funcInt() as integer');
475
- (0, chai_1.expect)(namespaceStmt.symbolTable.getSymbolType('funcStr')).to.be.instanceof(TypedFunctionType_1.TypedFunctionType);
476
- const strFunctionType = namespaceStmt.symbolTable.getSymbolType('funcStr');
477
- (0, chai_1.expect)(strFunctionType.returnType.toString()).to.equal('string');
478
- });
479
- it('adds a transpiled name of a function in a namespace to the parsers symbol table', () => {
480
- let parser = parse(`
481
- namespace Name.Space
482
- function funcInt() as integer
483
- return 3
484
- end function
485
-
486
- function funcStr() as string
487
- return "hello"
488
- end function
489
- end namespace
490
- `, Parser_1.ParseMode.BrighterScript);
491
- (0, chai_1.expect)(parser.symbolTable.getSymbolType('Name_Space_funcInt')).to.be.instanceof(TypedFunctionType_1.TypedFunctionType);
492
- (0, chai_1.expect)(parser.symbolTable.getSymbolType('Name_Space_funcStr')).to.be.instanceof(TypedFunctionType_1.TypedFunctionType);
283
+ (0, chai_config_spec_1.expect)((_a = parser.diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('namespace').message);
493
284
  });
494
285
  });
495
286
  it('supports << operator', () => {
496
287
  var _a;
497
- (0, chai_1.expect)((_a = parse(`
288
+ (0, chai_config_spec_1.expect)((_a = parse(`
498
289
  sub main()
499
290
  print ((r << 24) + (g << 16) + (b << 8) + a)
500
291
  end sub
@@ -502,7 +293,7 @@ describe('parser', () => {
502
293
  });
503
294
  it('supports >> operator', () => {
504
295
  var _a;
505
- (0, chai_1.expect)((_a = parse(`
296
+ (0, chai_config_spec_1.expect)((_a = parse(`
506
297
  sub main()
507
298
  print ((r >> 24) + (g >> 16) + (b >> 8) + a)
508
299
  end sub
@@ -510,7 +301,7 @@ describe('parser', () => {
510
301
  });
511
302
  it('allows global function names with same as token to be called', () => {
512
303
  var _a;
513
- (0, chai_1.expect)((_a = parse(`
304
+ (0, chai_config_spec_1.expect)((_a = parse(`
514
305
  sub main()
515
306
  print string(123)
516
307
  end sub
@@ -524,18 +315,18 @@ describe('parser', () => {
524
315
  age = personXml.firstChild@age
525
316
  end sub
526
317
  `);
527
- (0, chai_1.expect)((_a = parser.diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.not.exist;
318
+ (0, chai_config_spec_1.expect)((_a = parser.diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.not.exist;
528
319
  let statements = parser.statements[0].func.body.statements;
529
320
  let first = statements[0].value;
530
- (0, chai_1.expect)(first).to.be.instanceof(Expression_1.XmlAttributeGetExpression);
531
- (0, chai_1.expect)(first.name.text).to.equal('firstName');
532
- (0, chai_1.expect)(first.at.text).to.equal('@');
533
- (0, chai_1.expect)(first.obj.name.text).to.equal('personXml');
321
+ (0, chai_config_spec_1.expect)(first).to.be.instanceof(Expression_1.XmlAttributeGetExpression);
322
+ (0, chai_config_spec_1.expect)(first.tokens.name.text).to.equal('firstName');
323
+ (0, chai_config_spec_1.expect)(first.tokens.at.text).to.equal('@');
324
+ (0, chai_config_spec_1.expect)(first.obj.tokens.name.text).to.equal('personXml');
534
325
  let second = statements[1].value;
535
- (0, chai_1.expect)(second).to.be.instanceof(Expression_1.XmlAttributeGetExpression);
536
- (0, chai_1.expect)(second.name.text).to.equal('age');
537
- (0, chai_1.expect)(second.at.text).to.equal('@');
538
- (0, chai_1.expect)(second.obj.name.text).to.equal('firstChild');
326
+ (0, chai_config_spec_1.expect)(second).to.be.instanceof(Expression_1.XmlAttributeGetExpression);
327
+ (0, chai_config_spec_1.expect)(second.tokens.name.text).to.equal('age');
328
+ (0, chai_config_spec_1.expect)(second.tokens.at.text).to.equal('@');
329
+ (0, chai_config_spec_1.expect)(second.obj.tokens.name.text).to.equal('firstChild');
539
330
  });
540
331
  it('does not allow chaining of @ symbols', () => {
541
332
  let parser = parse(`
@@ -544,58 +335,58 @@ describe('parser', () => {
544
335
  name = personXml@name@age@shoeSize
545
336
  end sub
546
337
  `);
547
- (0, chai_1.expect)(parser.diagnostics).not.to.be.empty;
338
+ (0, chai_config_spec_1.expect)(parser.diagnostics).not.to.be.empty;
548
339
  });
549
340
  it('unknown function type does not invalidate rest of function', () => {
550
341
  let { statements, diagnostics } = parse(`
551
342
  function log() as UNKNOWN_TYPE
552
343
  end function
553
344
  `, Parser_1.ParseMode.BrightScript);
554
- (0, chai_1.expect)(diagnostics.length).to.be.greaterThan(0);
555
- (0, chai_1.expect)(statements[0]).to.exist;
345
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics); // type validation happens at scope validation step
346
+ (0, chai_config_spec_1.expect)(statements[0]).to.exist;
556
347
  });
557
348
  it('unknown function type is not a problem in Brighterscript mode', () => {
558
349
  let { statements, diagnostics } = parse(`
559
350
  function log() as UNKNOWN_TYPE
560
351
  end function
561
352
  `, Parser_1.ParseMode.BrighterScript);
562
- (0, chai_1.expect)(diagnostics.length).to.equal(0);
563
- (0, chai_1.expect)(statements[0]).to.exist;
353
+ (0, chai_config_spec_1.expect)(diagnostics.length).to.equal(0);
354
+ (0, chai_config_spec_1.expect)(statements[0]).to.exist;
564
355
  });
565
356
  it('allows namespaced function type in Brighterscript mode', () => {
566
357
  let { statements, diagnostics } = parse(`
567
358
  function log() as SOME_NAMESPACE.UNKNOWN_TYPE
568
359
  end function
569
360
  `, Parser_1.ParseMode.BrighterScript);
570
- (0, chai_1.expect)(diagnostics.length).to.equal(0);
571
- (0, chai_1.expect)(statements[0]).to.exist;
361
+ (0, chai_config_spec_1.expect)(diagnostics.length).to.equal(0);
362
+ (0, chai_config_spec_1.expect)(statements[0]).to.exist;
572
363
  });
573
364
  it('allows custom parameter types in BrighterscriptMode', () => {
574
365
  let { statements, diagnostics } = parse(`
575
366
  sub foo(value as UNKNOWN_TYPE)
576
367
  end sub
577
368
  `, Parser_1.ParseMode.BrighterScript);
578
- (0, chai_1.expect)(diagnostics.length).to.equal(0);
579
- (0, chai_1.expect)(statements[0]).to.exist;
369
+ (0, chai_config_spec_1.expect)(diagnostics.length).to.equal(0);
370
+ (0, chai_config_spec_1.expect)(statements[0]).to.exist;
580
371
  });
581
- it('does not allow custom parameter types in Brightscript Mode', () => {
372
+ it('does not cause any diagnostics when custom parameter types are used in Brightscript Mode', () => {
582
373
  let { diagnostics } = parse(`
583
374
  sub foo(value as UNKNOWN_TYPE)
584
375
  end sub
585
376
  `, Parser_1.ParseMode.BrightScript);
586
- (0, chai_1.expect)(diagnostics.length).not.to.equal(0);
377
+ (0, chai_config_spec_1.expect)(diagnostics.length).to.equal(0);
587
378
  });
588
379
  it('allows custom namespaced parameter types in BrighterscriptMode', () => {
589
380
  let { statements, diagnostics } = parse(`
590
381
  sub foo(value as SOME_NAMESPACE.UNKNOWN_TYPE)
591
382
  end sub
592
383
  `, Parser_1.ParseMode.BrighterScript);
593
- (0, chai_1.expect)(diagnostics.length).to.equal(0);
594
- (0, chai_1.expect)(statements[0]).to.exist;
384
+ (0, chai_config_spec_1.expect)(diagnostics.length).to.equal(0);
385
+ (0, chai_config_spec_1.expect)(statements[0]).to.exist;
595
386
  });
596
387
  it('works with conditionals', () => {
597
388
  var _a;
598
- (0, chai_1.expect)((_a = parse(`
389
+ (0, chai_config_spec_1.expect)((_a = parse(`
599
390
  function printNumber()
600
391
  if true then
601
392
  print 1
@@ -607,7 +398,7 @@ describe('parser', () => {
607
398
  });
608
399
  it('supports single-line if statements', () => {
609
400
  var _a;
610
- (0, chai_1.expect)((_a = parse(`If true Then print "error" : Stop`).diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.not.exist;
401
+ (0, chai_config_spec_1.expect)((_a = parse(`If true Then print "error" : Stop`).diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.not.exist;
611
402
  });
612
403
  it('works with excess newlines', () => {
613
404
  var _a;
@@ -620,7 +411,7 @@ describe('parser', () => {
620
411
  ' print 1\n\n' +
621
412
  ' end if\n\n' +
622
413
  'end function\n\n');
623
- (0, chai_1.expect)((_a = Parser_1.Parser.parse(tokens).diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.not.exist;
414
+ (0, chai_config_spec_1.expect)((_a = Parser_1.Parser.parse(tokens).diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.not.exist;
624
415
  });
625
416
  it('does not invalidate entire file when line ends with a period', () => {
626
417
  let { tokens } = Lexer_1.Lexer.scan(`
@@ -630,15 +421,101 @@ describe('parser', () => {
630
421
 
631
422
  `);
632
423
  let { diagnostics } = Parser_1.Parser.parse(tokens);
633
- (0, chai_1.expect)(diagnostics).to.be.lengthOf(1, 'Error count should be 0');
424
+ (0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(1, 'Error count should be 0');
634
425
  });
635
- it.skip('allows printing object with trailing period', () => {
426
+ it('allows printing object with trailing period', () => {
636
427
  let { tokens } = Lexer_1.Lexer.scan(`print a.`);
637
- let { statements, diagnostics } = Parser_1.Parser.parse(tokens);
428
+ let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
638
429
  let printStatement = statements[0];
639
- (0, chai_1.expect)(diagnostics).to.be.empty;
640
- (0, chai_1.expect)(printStatement).to.be.instanceof(Statement_1.PrintStatement);
641
- (0, chai_1.expect)(printStatement.expressions[0]).to.be.instanceof(Expression_1.DottedGetExpression);
430
+ (0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, DiagnosticMessages_1.DiagnosticMessages.expectedPropertyNameAfterPeriod());
431
+ (0, chai_config_spec_1.expect)(printStatement).to.be.instanceof(Statement_1.PrintStatement);
432
+ (0, chai_config_spec_1.expect)(printStatement.expressions[0]).to.be.instanceof(Expression_1.VariableExpression);
433
+ });
434
+ it('allows printing object with trailing period with multiple dotted gets', () => {
435
+ let { tokens } = Lexer_1.Lexer.scan(`print a.b.`);
436
+ let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
437
+ let printStatement = statements[0];
438
+ (0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, DiagnosticMessages_1.DiagnosticMessages.expectedPropertyNameAfterPeriod());
439
+ (0, chai_config_spec_1.expect)(printStatement).to.be.instanceof(Statement_1.PrintStatement);
440
+ (0, chai_config_spec_1.expect)(printStatement.expressions[0]).to.be.instanceof(Expression_1.DottedGetExpression);
441
+ });
442
+ describe('incomplete statements in the ast', () => {
443
+ it('adds variable expressions to the ast', () => {
444
+ let { tokens } = Lexer_1.Lexer.scan(`
445
+ function a()
446
+ NameA.
447
+ end function
448
+
449
+ namespace NameA
450
+ sub noop()
451
+ end sub
452
+ end namespace
453
+ `);
454
+ let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
455
+ (0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, DiagnosticMessages_1.DiagnosticMessages.expectedStatementOrFunctionCallButReceivedExpression());
456
+ let stmt = statements[0].func.body.statements[0];
457
+ (0, chai_config_spec_1.expect)((0, reflection_1.isExpressionStatement)(stmt)).to.be.true;
458
+ (0, chai_config_spec_1.expect)((0, reflection_1.isVariableExpression)((stmt).expression)).to.be.true;
459
+ (0, chai_config_spec_1.expect)(stmt.expression.tokens.name.text).to.equal('NameA');
460
+ });
461
+ it('adds unended call statements', () => {
462
+ let { tokens } = Lexer_1.Lexer.scan(`
463
+ function a()
464
+ lcase(
465
+ end function
466
+ `);
467
+ let { statements } = Parser_1.Parser.parse(tokens);
468
+ let stmt = statements[0].func.body.statements[0];
469
+ (0, chai_config_spec_1.expect)((0, reflection_1.isExpressionStatement)(stmt)).to.be.true;
470
+ (0, chai_config_spec_1.expect)((0, reflection_1.isCallExpression)((stmt).expression)).to.be.true;
471
+ (0, chai_config_spec_1.expect)(stmt.expression.callee.tokens.name.text).to.equal('lcase');
472
+ });
473
+ it('adds unended indexed get statements', () => {
474
+ let { tokens } = Lexer_1.Lexer.scan(`
475
+ function a()
476
+ nums[
477
+ end function
478
+
479
+ const nums = [1, 2, 3]
480
+ `);
481
+ let { statements } = Parser_1.Parser.parse(tokens);
482
+ let stmt = statements[0].func.body.statements[0];
483
+ (0, chai_config_spec_1.expect)((0, reflection_1.isExpressionStatement)(stmt)).to.be.true;
484
+ (0, chai_config_spec_1.expect)((0, reflection_1.isIndexedGetExpression)((stmt).expression)).to.be.true;
485
+ (0, chai_config_spec_1.expect)(stmt.expression.obj.tokens.name.text).to.equal('nums');
486
+ });
487
+ it('adds dotted gets', () => {
488
+ let { tokens } = Lexer_1.Lexer.scan(`
489
+ function foo(a as KlassA)
490
+ a.b.
491
+ end function
492
+
493
+ class KlassA
494
+ b as KlassB
495
+ end class
496
+
497
+ class KlassB
498
+ sub noop()
499
+ end sub
500
+ end class
501
+ `);
502
+ let { statements } = Parser_1.Parser.parse(tokens);
503
+ let stmt = statements[0].func.body.statements[0];
504
+ (0, chai_config_spec_1.expect)((0, reflection_1.isExpressionStatement)(stmt)).to.be.true;
505
+ (0, chai_config_spec_1.expect)((0, reflection_1.isDottedGetExpression)((stmt).expression)).to.be.true;
506
+ (0, chai_config_spec_1.expect)(stmt.expression.obj.tokens.name.text).to.equal('a');
507
+ (0, chai_config_spec_1.expect)(stmt.expression.tokens.name.text).to.equal('b');
508
+ });
509
+ it('adds function statement with missing type after as', () => {
510
+ var _a;
511
+ let parser = parse(`
512
+ sub foo(thing as )
513
+ print thing
514
+ end sub
515
+ `, Parser_1.ParseMode.BrighterScript);
516
+ (0, chai_config_spec_1.expect)((_a = parser.diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.exist;
517
+ (0, chai_config_spec_1.expect)(parser.ast.statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
518
+ });
642
519
  });
643
520
  describe('comments', () => {
644
521
  it('combines multi-line comments', () => {
@@ -648,8 +525,8 @@ describe('parser', () => {
648
525
  'line 3
649
526
  `);
650
527
  let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
651
- (0, chai_1.expect)(diagnostics).to.be.lengthOf(0, 'Error count should be 0');
652
- (0, chai_1.expect)(statements[0].text).to.equal(`'line 1\n'line 2\n'line 3`);
528
+ (0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Error count should be 0');
529
+ (0, chai_config_spec_1.expect)(statements[0].text).to.equal(`'line 1\n'line 2\n'line 3`);
653
530
  });
654
531
  it('does not combile comments separated by newlines', () => {
655
532
  let { tokens } = Lexer_1.Lexer.scan(`
@@ -660,11 +537,11 @@ describe('parser', () => {
660
537
  'line 3
661
538
  `);
662
539
  let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
663
- (0, chai_1.expect)(diagnostics).to.be.lengthOf(0, 'Error count should be 0');
664
- (0, chai_1.expect)(statements).to.be.lengthOf(3);
665
- (0, chai_1.expect)(statements[0].text).to.equal(`'line 1`);
666
- (0, chai_1.expect)(statements[1].text).to.equal(`'line 2`);
667
- (0, chai_1.expect)(statements[2].text).to.equal(`'line 3`);
540
+ (0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Error count should be 0');
541
+ (0, chai_config_spec_1.expect)(statements).to.be.lengthOf(3);
542
+ (0, chai_config_spec_1.expect)(statements[0].text).to.equal(`'line 1`);
543
+ (0, chai_config_spec_1.expect)(statements[1].text).to.equal(`'line 2`);
544
+ (0, chai_config_spec_1.expect)(statements[2].text).to.equal(`'line 3`);
668
545
  });
669
546
  it('works after print statement', () => {
670
547
  let { tokens } = Lexer_1.Lexer.scan(`
@@ -673,8 +550,8 @@ describe('parser', () => {
673
550
  end sub
674
551
  `);
675
552
  let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
676
- (0, chai_1.expect)(diagnostics).to.be.lengthOf(0, 'Error count should be 0');
677
- (0, chai_1.expect)(statements[0].func.body.statements[1].text).to.equal(`'comment 1`);
553
+ (0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Error count should be 0');
554
+ (0, chai_config_spec_1.expect)(statements[0].func.body.statements[1].text).to.equal(`'comment 1`);
678
555
  });
679
556
  it('declaration-level', () => {
680
557
  let { tokens } = Lexer_1.Lexer.scan(`
@@ -684,9 +561,9 @@ describe('parser', () => {
684
561
  'comment 2
685
562
  `);
686
563
  let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
687
- (0, chai_1.expect)(diagnostics).to.be.lengthOf(0, 'Error count should be 0');
688
- (0, chai_1.expect)(statements[0].text).to.equal(`'comment 1`);
689
- (0, chai_1.expect)(statements[2].text).to.equal(`'comment 2`);
564
+ (0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Error count should be 0');
565
+ (0, chai_config_spec_1.expect)(statements[0].text).to.equal(`'comment 1`);
566
+ (0, chai_config_spec_1.expect)(statements[2].text).to.equal(`'comment 2`);
690
567
  });
691
568
  it('works in aa literal as its own statement', () => {
692
569
  let { tokens } = Lexer_1.Lexer.scan(`
@@ -696,7 +573,7 @@ describe('parser', () => {
696
573
  }
697
574
  `);
698
575
  let { diagnostics } = Parser_1.Parser.parse(tokens);
699
- (0, chai_1.expect)(diagnostics).to.be.lengthOf(0, 'Error count should be 0');
576
+ (0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Error count should be 0');
700
577
  });
701
578
  it('parses after function call', () => {
702
579
  let { tokens } = Lexer_1.Lexer.scan(`
@@ -706,8 +583,8 @@ describe('parser', () => {
706
583
  end sub
707
584
  `);
708
585
  let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
709
- (0, chai_1.expect)(diagnostics).to.be.lengthOf(0, 'Should have zero diagnostics');
710
- (0, chai_1.expect)(statements[0].func.body.statements[2].text).to.equal(`'comment 1`);
586
+ (0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Should have zero diagnostics');
587
+ (0, chai_config_spec_1.expect)(statements[0].func.body.statements[2].text).to.equal(`'comment 1`);
711
588
  });
712
589
  it('function', () => {
713
590
  let { tokens } = Lexer_1.Lexer.scan(`
@@ -718,11 +595,11 @@ describe('parser', () => {
718
595
  end function 'comment 4
719
596
  `);
720
597
  let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
721
- (0, chai_1.expect)(diagnostics).to.be.lengthOf(0, 'Should have zero diagnostics');
722
- (0, chai_1.expect)(statements[0].func.body.statements[0].text).to.equal(`'comment 1`);
723
- (0, chai_1.expect)(statements[0].func.body.statements[1].text).to.equal(`'comment 2`);
724
- (0, chai_1.expect)(statements[0].func.body.statements[3].text).to.equal(`'comment 3`);
725
- (0, chai_1.expect)(statements[1].text).to.equal(`'comment 4`);
598
+ (0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Should have zero diagnostics');
599
+ (0, chai_config_spec_1.expect)(statements[0].func.body.statements[0].text).to.equal(`'comment 1`);
600
+ (0, chai_config_spec_1.expect)(statements[0].func.body.statements[1].text).to.equal(`'comment 2`);
601
+ (0, chai_config_spec_1.expect)(statements[0].func.body.statements[3].text).to.equal(`'comment 3`);
602
+ (0, chai_config_spec_1.expect)(statements[1].text).to.equal(`'comment 4`);
726
603
  });
727
604
  it('if statement`', () => {
728
605
  let { tokens } = Lexer_1.Lexer.scan(`
@@ -743,7 +620,7 @@ describe('parser', () => {
743
620
  end function
744
621
  `);
745
622
  let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
746
- (0, chai_1.expect)(diagnostics).to.be.lengthOf(0, 'Should have zero diagnostics');
623
+ (0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Should have zero diagnostics');
747
624
  let fnSmt = statements[0];
748
625
  if ((0, reflection_1.isFunctionStatement)(fnSmt)) {
749
626
  let ifStmt = fnSmt.func.body.statements[0];
@@ -790,12 +667,12 @@ describe('parser', () => {
790
667
  end function
791
668
  `);
792
669
  let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
793
- (0, chai_1.expect)(diagnostics).to.be.lengthOf(0, 'Error count should be zero');
670
+ (0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Error count should be zero');
794
671
  let stmt = statements[0].func.body.statements[0];
795
- (0, chai_1.expect)(stmt.body.statements[0].text).to.equal(`'comment 1`);
796
- (0, chai_1.expect)(stmt.body.statements[1].text).to.equal(`'comment 2`);
797
- (0, chai_1.expect)(stmt.body.statements[3].text).to.equal(`'comment 3`);
798
- (0, chai_1.expect)(statements[0].func.body.statements[1].text).to.equal(`'comment 4`);
672
+ (0, chai_config_spec_1.expect)(stmt.body.statements[0].text).to.equal(`'comment 1`);
673
+ (0, chai_config_spec_1.expect)(stmt.body.statements[1].text).to.equal(`'comment 2`);
674
+ (0, chai_config_spec_1.expect)(stmt.body.statements[3].text).to.equal(`'comment 3`);
675
+ (0, chai_config_spec_1.expect)(statements[0].func.body.statements[1].text).to.equal(`'comment 4`);
799
676
  });
800
677
  it('for', () => {
801
678
  let { tokens } = Lexer_1.Lexer.scan(`
@@ -808,12 +685,12 @@ describe('parser', () => {
808
685
  end function
809
686
  `);
810
687
  let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
811
- (0, chai_1.expect)(diagnostics).to.be.lengthOf(0, 'Error count should be zero');
688
+ (0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Error count should be zero');
812
689
  let stmt = statements[0].func.body.statements[0];
813
- (0, chai_1.expect)(stmt.body.statements[0].text).to.equal(`'comment 1`);
814
- (0, chai_1.expect)(stmt.body.statements[1].text).to.equal(`'comment 2`);
815
- (0, chai_1.expect)(stmt.body.statements[3].text).to.equal(`'comment 3`);
816
- (0, chai_1.expect)(statements[0].func.body.statements[1].text).to.equal(`'comment 4`);
690
+ (0, chai_config_spec_1.expect)(stmt.body.statements[0].text).to.equal(`'comment 1`);
691
+ (0, chai_config_spec_1.expect)(stmt.body.statements[1].text).to.equal(`'comment 2`);
692
+ (0, chai_config_spec_1.expect)(stmt.body.statements[3].text).to.equal(`'comment 3`);
693
+ (0, chai_config_spec_1.expect)(statements[0].func.body.statements[1].text).to.equal(`'comment 4`);
817
694
  });
818
695
  it('for each', () => {
819
696
  let { tokens } = Lexer_1.Lexer.scan(`
@@ -826,12 +703,12 @@ describe('parser', () => {
826
703
  end function
827
704
  `);
828
705
  let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
829
- (0, chai_1.expect)(diagnostics).to.be.lengthOf(0, 'Error count should be zero');
706
+ (0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Error count should be zero');
830
707
  let stmt = statements[0].func.body.statements[0];
831
- (0, chai_1.expect)(stmt.body.statements[0].text).to.equal(`'comment 1`);
832
- (0, chai_1.expect)(stmt.body.statements[1].text).to.equal(`'comment 2`);
833
- (0, chai_1.expect)(stmt.body.statements[3].text).to.equal(`'comment 3`);
834
- (0, chai_1.expect)(statements[0].func.body.statements[1].text).to.equal(`'comment 4`);
708
+ (0, chai_config_spec_1.expect)(stmt.body.statements[0].text).to.equal(`'comment 1`);
709
+ (0, chai_config_spec_1.expect)(stmt.body.statements[1].text).to.equal(`'comment 2`);
710
+ (0, chai_config_spec_1.expect)(stmt.body.statements[3].text).to.equal(`'comment 3`);
711
+ (0, chai_config_spec_1.expect)(statements[0].func.body.statements[1].text).to.equal(`'comment 4`);
835
712
  });
836
713
  });
837
714
  });
@@ -843,7 +720,7 @@ describe('parser', () => {
843
720
  then = true
844
721
  end sub
845
722
  `);
846
- (0, chai_1.expect)(diagnostics).to.be.lengthOf(1);
723
+ (0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(1);
847
724
  });
848
725
  it('is allowed as an AA property name', () => {
849
726
  var _a;
@@ -856,7 +733,7 @@ describe('parser', () => {
856
733
  print person.then
857
734
  end sub
858
735
  `);
859
- (0, chai_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
736
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
860
737
  });
861
738
  it('allows `mod` as an AA literal property', () => {
862
739
  const parser = parse(`
@@ -888,7 +765,7 @@ describe('parser', () => {
888
765
  }), {
889
766
  walkMode: visitors_1.WalkMode.visitAllRecursive
890
767
  });
891
- (0, chai_1.expect)(elements.map(x => x.keyToken.kind)).to.eql([TokenKind_1.TokenKind.Identifier, TokenKind_1.TokenKind.Identifier]);
768
+ (0, chai_config_spec_1.expect)(elements.map(x => x.tokens.key.kind)).to.eql([TokenKind_1.TokenKind.Identifier, TokenKind_1.TokenKind.Identifier]);
892
769
  });
893
770
  });
894
771
  it('"end" is not allowed as a local identifier', () => {
@@ -897,7 +774,7 @@ describe('parser', () => {
897
774
  end = true
898
775
  end sub
899
776
  `);
900
- (0, chai_1.expect)(diagnostics).to.be.length.greaterThan(0);
777
+ (0, chai_config_spec_1.expect)(diagnostics).to.be.length.greaterThan(0);
901
778
  });
902
779
  it('none of them can be used as local variables', () => {
903
780
  let reservedWords = new Set(TokenKind_1.ReservedWords);
@@ -910,7 +787,7 @@ describe('parser', () => {
910
787
  end sub
911
788
  `);
912
789
  let { diagnostics } = Parser_1.Parser.parse(tokens);
913
- (0, chai_1.expect)(diagnostics, `assigning to reserved word "${reservedWord}" should have been an error`).to.be.length.greaterThan(0);
790
+ (0, chai_config_spec_1.expect)(diagnostics, `assigning to reserved word "${reservedWord}" should have been an error`).to.be.length.greaterThan(0);
914
791
  }
915
792
  });
916
793
  });
@@ -920,24 +797,24 @@ describe('parser', () => {
920
797
  let { statements, diagnostics } = parse(`
921
798
  import "somePath"
922
799
  `, Parser_1.ParseMode.BrighterScript);
923
- (0, chai_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
924
- (0, chai_1.expect)(statements[0]).to.be.instanceof(Statement_1.ImportStatement);
800
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
801
+ (0, chai_config_spec_1.expect)(statements[0]).to.be.instanceof(Statement_1.ImportStatement);
925
802
  });
926
803
  it('catches import statements used in brightscript files', () => {
927
804
  var _a;
928
805
  let { statements, diagnostics } = parse(`
929
806
  import "somePath"
930
807
  `, Parser_1.ParseMode.BrightScript);
931
- (0, chai_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.eql(DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('import statements').message);
932
- (0, chai_1.expect)(statements[0]).to.be.instanceof(Statement_1.ImportStatement);
808
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.eql(DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('import statements').message);
809
+ (0, chai_config_spec_1.expect)(statements[0]).to.be.instanceof(Statement_1.ImportStatement);
933
810
  });
934
- it('catches missing file path', () => {
811
+ it('catchs missing file path', () => {
935
812
  var _a;
936
813
  let { statements, diagnostics } = parse(`
937
814
  import
938
815
  `, Parser_1.ParseMode.BrighterScript);
939
- (0, chai_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.expectedStringLiteralAfterKeyword('import').message);
940
- (0, chai_1.expect)(statements[0]).to.be.instanceof(Statement_1.ImportStatement);
816
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.expectedStringLiteralAfterKeyword('import').message);
817
+ (0, chai_config_spec_1.expect)(statements[0]).to.be.instanceof(Statement_1.ImportStatement);
941
818
  });
942
819
  });
943
820
  describe('Annotations', () => {
@@ -948,7 +825,7 @@ describe('parser', () => {
948
825
  sub main()
949
826
  end sub
950
827
  `, Parser_1.ParseMode.BrighterScript);
951
- (0, chai_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.unexpectedToken('@').message);
828
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.unexpectedToken('@').message);
952
829
  });
953
830
  it('properly handles empty annotation above class method', () => {
954
831
  var _a;
@@ -960,7 +837,7 @@ describe('parser', () => {
960
837
  end sub
961
838
  end class
962
839
  `, Parser_1.ParseMode.BrighterScript);
963
- (0, chai_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier().message);
840
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier().message);
964
841
  });
965
842
  it('parses with error if annotation is not followed by a statement', () => {
966
843
  var _a, _b, _c, _d;
@@ -974,11 +851,11 @@ describe('parser', () => {
974
851
  end class
975
852
  @meta1
976
853
  `, Parser_1.ParseMode.BrighterScript);
977
- (0, chai_1.expect)(diagnostics.length).to.equal(4);
978
- (0, chai_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.unusedAnnotation().message);
979
- (0, chai_1.expect)((_b = diagnostics[1]) === null || _b === void 0 ? void 0 : _b.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.unusedAnnotation().message);
980
- (0, chai_1.expect)((_c = diagnostics[2]) === null || _c === void 0 ? void 0 : _c.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.unusedAnnotation().message);
981
- (0, chai_1.expect)((_d = diagnostics[3]) === null || _d === void 0 ? void 0 : _d.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.unusedAnnotation().message);
854
+ (0, chai_config_spec_1.expect)(diagnostics.length).to.equal(4);
855
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.unusedAnnotation().message);
856
+ (0, chai_config_spec_1.expect)((_b = diagnostics[1]) === null || _b === void 0 ? void 0 : _b.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.unusedAnnotation().message);
857
+ (0, chai_config_spec_1.expect)((_c = diagnostics[2]) === null || _c === void 0 ? void 0 : _c.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.unusedAnnotation().message);
858
+ (0, chai_config_spec_1.expect)((_d = diagnostics[3]) === null || _d === void 0 ? void 0 : _d.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.unusedAnnotation().message);
982
859
  });
983
860
  it('attaches an annotation to next statement', () => {
984
861
  var _a;
@@ -990,18 +867,18 @@ describe('parser', () => {
990
867
  @meta2 sub init()
991
868
  end sub
992
869
  `, Parser_1.ParseMode.BrighterScript);
993
- (0, chai_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
994
- (0, chai_1.expect)(statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
870
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
871
+ (0, chai_config_spec_1.expect)(statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
995
872
  let fn = statements[0];
996
- (0, chai_1.expect)(fn.annotations).to.exist;
997
- (0, chai_1.expect)(fn.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
998
- (0, chai_1.expect)(fn.annotations[0].nameToken.text).to.equal('meta1');
999
- (0, chai_1.expect)(fn.annotations[0].name).to.equal('meta1');
1000
- (0, chai_1.expect)(statements[1]).to.be.instanceof(Statement_1.FunctionStatement);
873
+ (0, chai_config_spec_1.expect)(fn.annotations).to.exist;
874
+ (0, chai_config_spec_1.expect)(fn.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
875
+ (0, chai_config_spec_1.expect)(fn.annotations[0].tokens.name.text).to.equal('meta1');
876
+ (0, chai_config_spec_1.expect)(fn.annotations[0].name).to.equal('meta1');
877
+ (0, chai_config_spec_1.expect)(statements[1]).to.be.instanceof(Statement_1.FunctionStatement);
1001
878
  fn = statements[1];
1002
- (0, chai_1.expect)(fn.annotations).to.exist;
1003
- (0, chai_1.expect)(fn.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
1004
- (0, chai_1.expect)(fn.annotations[0].nameToken.text).to.equal('meta2');
879
+ (0, chai_config_spec_1.expect)(fn.annotations).to.exist;
880
+ (0, chai_config_spec_1.expect)(fn.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
881
+ (0, chai_config_spec_1.expect)(fn.annotations[0].tokens.name.text).to.equal('meta2');
1005
882
  });
1006
883
  it('attaches annotations inside a function body', () => {
1007
884
  var _a, _b;
@@ -1011,13 +888,13 @@ describe('parser', () => {
1011
888
  print "hello"
1012
889
  end function
1013
890
  `, Parser_1.ParseMode.BrighterScript);
1014
- (0, chai_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
891
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
1015
892
  let fn = statements[0];
1016
893
  let fnStatements = fn.func.body.statements;
1017
894
  let stat = fnStatements[0];
1018
- (0, chai_1.expect)(stat).to.exist;
1019
- (0, chai_1.expect)((_b = stat.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
1020
- (0, chai_1.expect)(stat.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
895
+ (0, chai_config_spec_1.expect)(stat).to.exist;
896
+ (0, chai_config_spec_1.expect)((_b = stat.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
897
+ (0, chai_config_spec_1.expect)(stat.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
1021
898
  });
1022
899
  it('attaches multiple annotations to next statement', () => {
1023
900
  var _a;
@@ -1027,14 +904,14 @@ describe('parser', () => {
1027
904
  function main()
1028
905
  end function
1029
906
  `, Parser_1.ParseMode.BrighterScript);
1030
- (0, chai_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
1031
- (0, chai_1.expect)(statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
907
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
908
+ (0, chai_config_spec_1.expect)(statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
1032
909
  let fn = statements[0];
1033
- (0, chai_1.expect)(fn.annotations).to.exist;
1034
- (0, chai_1.expect)(fn.annotations.length).to.equal(3);
1035
- (0, chai_1.expect)(fn.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
1036
- (0, chai_1.expect)(fn.annotations[1]).to.be.instanceof(Expression_1.AnnotationExpression);
1037
- (0, chai_1.expect)(fn.annotations[2]).to.be.instanceof(Expression_1.AnnotationExpression);
910
+ (0, chai_config_spec_1.expect)(fn.annotations).to.exist;
911
+ (0, chai_config_spec_1.expect)(fn.annotations.length).to.equal(3);
912
+ (0, chai_config_spec_1.expect)(fn.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
913
+ (0, chai_config_spec_1.expect)(fn.annotations[1]).to.be.instanceof(Expression_1.AnnotationExpression);
914
+ (0, chai_config_spec_1.expect)(fn.annotations[2]).to.be.instanceof(Expression_1.AnnotationExpression);
1038
915
  });
1039
916
  it('allows annotations with parameters', () => {
1040
917
  var _a;
@@ -1043,12 +920,12 @@ describe('parser', () => {
1043
920
  function main()
1044
921
  end function
1045
922
  `, Parser_1.ParseMode.BrighterScript);
1046
- (0, chai_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
923
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
1047
924
  let fn = statements[0];
1048
- (0, chai_1.expect)(fn.annotations).to.exist;
1049
- (0, chai_1.expect)(fn.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
1050
- (0, chai_1.expect)(fn.annotations[0].nameToken.text).to.equal('meta1');
1051
- (0, chai_1.expect)(fn.annotations[0].call).to.be.instanceof(Expression_1.CallExpression);
925
+ (0, chai_config_spec_1.expect)(fn.annotations).to.exist;
926
+ (0, chai_config_spec_1.expect)(fn.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
927
+ (0, chai_config_spec_1.expect)(fn.annotations[0].tokens.name.text).to.equal('meta1');
928
+ (0, chai_config_spec_1.expect)(fn.annotations[0].call).to.be.instanceof(Expression_1.CallExpression);
1052
929
  });
1053
930
  it('attaches annotations to a class', () => {
1054
931
  var _a, _b;
@@ -1060,10 +937,10 @@ describe('parser', () => {
1060
937
  end function
1061
938
  end class
1062
939
  `, Parser_1.ParseMode.BrighterScript);
1063
- (0, chai_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
940
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
1064
941
  let cs = statements[0];
1065
- (0, chai_1.expect)((_b = cs.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
1066
- (0, chai_1.expect)(cs.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
942
+ (0, chai_config_spec_1.expect)((_b = cs.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
943
+ (0, chai_config_spec_1.expect)(cs.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
1067
944
  });
1068
945
  it('attaches annotations to multiple clases', () => {
1069
946
  var _a, _b, _c;
@@ -1081,15 +958,15 @@ describe('parser', () => {
1081
958
  end function
1082
959
  end class
1083
960
  `, Parser_1.ParseMode.BrighterScript);
1084
- (0, chai_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
961
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
1085
962
  let cs = statements[0];
1086
- (0, chai_1.expect)((_b = cs.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
1087
- (0, chai_1.expect)(cs.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
1088
- (0, chai_1.expect)(cs.annotations[0].name).to.equal('meta1');
963
+ (0, chai_config_spec_1.expect)((_b = cs.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
964
+ (0, chai_config_spec_1.expect)(cs.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
965
+ (0, chai_config_spec_1.expect)(cs.annotations[0].name).to.equal('meta1');
1089
966
  let cs2 = statements[1];
1090
- (0, chai_1.expect)((_c = cs2.annotations) === null || _c === void 0 ? void 0 : _c.length).to.equal(1);
1091
- (0, chai_1.expect)(cs2.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
1092
- (0, chai_1.expect)(cs2.annotations[0].name).to.equal('meta2');
967
+ (0, chai_config_spec_1.expect)((_c = cs2.annotations) === null || _c === void 0 ? void 0 : _c.length).to.equal(1);
968
+ (0, chai_config_spec_1.expect)(cs2.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
969
+ (0, chai_config_spec_1.expect)(cs2.annotations[0].name).to.equal('meta2');
1093
970
  });
1094
971
  it('attaches annotations to a namespaced class', () => {
1095
972
  var _a, _b;
@@ -1103,11 +980,11 @@ describe('parser', () => {
1103
980
  end class
1104
981
  end namespace
1105
982
  `, Parser_1.ParseMode.BrighterScript);
1106
- (0, chai_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
983
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
1107
984
  let ns = statements[0];
1108
985
  let cs = ns.body.statements[0];
1109
- (0, chai_1.expect)((_b = cs.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
1110
- (0, chai_1.expect)(cs.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
986
+ (0, chai_config_spec_1.expect)((_b = cs.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
987
+ (0, chai_config_spec_1.expect)(cs.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
1111
988
  });
1112
989
  it('attaches annotations to a namespaced class - multiple', () => {
1113
990
  var _a, _b, _c;
@@ -1127,16 +1004,16 @@ describe('parser', () => {
1127
1004
  end class
1128
1005
  end namespace
1129
1006
  `, Parser_1.ParseMode.BrighterScript);
1130
- (0, chai_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
1007
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
1131
1008
  let ns = statements[0];
1132
1009
  let cs = ns.body.statements[0];
1133
- (0, chai_1.expect)((_b = cs.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
1134
- (0, chai_1.expect)(cs.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
1135
- (0, chai_1.expect)(cs.annotations[0].name).to.equal('meta1');
1010
+ (0, chai_config_spec_1.expect)((_b = cs.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
1011
+ (0, chai_config_spec_1.expect)(cs.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
1012
+ (0, chai_config_spec_1.expect)(cs.annotations[0].name).to.equal('meta1');
1136
1013
  let cs2 = ns.body.statements[1];
1137
- (0, chai_1.expect)((_c = cs2.annotations) === null || _c === void 0 ? void 0 : _c.length).to.equal(1);
1138
- (0, chai_1.expect)(cs2.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
1139
- (0, chai_1.expect)(cs2.annotations[0].name).to.equal('meta2');
1014
+ (0, chai_config_spec_1.expect)((_c = cs2.annotations) === null || _c === void 0 ? void 0 : _c.length).to.equal(1);
1015
+ (0, chai_config_spec_1.expect)(cs2.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
1016
+ (0, chai_config_spec_1.expect)(cs2.annotations[0].name).to.equal('meta2');
1140
1017
  });
1141
1018
  it('attaches annotations to a class constructor', () => {
1142
1019
  var _a, _b;
@@ -1151,11 +1028,11 @@ describe('parser', () => {
1151
1028
  end function
1152
1029
  end class
1153
1030
  `, Parser_1.ParseMode.BrighterScript);
1154
- (0, chai_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
1031
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
1155
1032
  let cs = statements[0];
1156
1033
  let stat = cs.body[0];
1157
- (0, chai_1.expect)((_b = stat.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
1158
- (0, chai_1.expect)(stat.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
1034
+ (0, chai_config_spec_1.expect)((_b = stat.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
1035
+ (0, chai_config_spec_1.expect)(stat.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
1159
1036
  });
1160
1037
  it('attaches annotations to a class methods', () => {
1161
1038
  var _a, _b;
@@ -1170,11 +1047,11 @@ describe('parser', () => {
1170
1047
  end function
1171
1048
  end class
1172
1049
  `, Parser_1.ParseMode.BrighterScript);
1173
- (0, chai_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
1050
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
1174
1051
  let cs = statements[0];
1175
1052
  let stat = cs.body[1];
1176
- (0, chai_1.expect)((_b = stat.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
1177
- (0, chai_1.expect)(stat.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
1053
+ (0, chai_config_spec_1.expect)((_b = stat.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
1054
+ (0, chai_config_spec_1.expect)(stat.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
1178
1055
  });
1179
1056
  it('attaches annotations to a class methods, fields and constructor', () => {
1180
1057
  var _a, _b, _c, _d, _e;
@@ -1198,19 +1075,19 @@ describe('parser', () => {
1198
1075
  public foo="bar"
1199
1076
  end class
1200
1077
  `, Parser_1.ParseMode.BrighterScript);
1201
- (0, chai_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
1078
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
1202
1079
  let cs = statements[0];
1203
- (0, chai_1.expect)((_b = cs.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(2);
1204
- (0, chai_1.expect)(cs.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
1080
+ (0, chai_config_spec_1.expect)((_b = cs.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(2);
1081
+ (0, chai_config_spec_1.expect)(cs.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
1205
1082
  let stat1 = cs.body[0];
1206
1083
  let stat2 = cs.body[1];
1207
1084
  let f1 = cs.body[2];
1208
- (0, chai_1.expect)((_c = stat1.annotations) === null || _c === void 0 ? void 0 : _c.length).to.equal(2);
1209
- (0, chai_1.expect)(stat1.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
1210
- (0, chai_1.expect)((_d = stat2.annotations) === null || _d === void 0 ? void 0 : _d.length).to.equal(2);
1211
- (0, chai_1.expect)(stat2.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
1212
- (0, chai_1.expect)((_e = f1.annotations) === null || _e === void 0 ? void 0 : _e.length).to.equal(2);
1213
- (0, chai_1.expect)(f1.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
1085
+ (0, chai_config_spec_1.expect)((_c = stat1.annotations) === null || _c === void 0 ? void 0 : _c.length).to.equal(2);
1086
+ (0, chai_config_spec_1.expect)(stat1.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
1087
+ (0, chai_config_spec_1.expect)((_d = stat2.annotations) === null || _d === void 0 ? void 0 : _d.length).to.equal(2);
1088
+ (0, chai_config_spec_1.expect)(stat2.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
1089
+ (0, chai_config_spec_1.expect)((_e = f1.annotations) === null || _e === void 0 ? void 0 : _e.length).to.equal(2);
1090
+ (0, chai_config_spec_1.expect)(f1.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
1214
1091
  });
1215
1092
  it('ignores annotations on commented out lines', () => {
1216
1093
  var _a;
@@ -1221,9 +1098,9 @@ describe('parser', () => {
1221
1098
  print "hello"
1222
1099
  end function
1223
1100
  `, Parser_1.ParseMode.BrighterScript);
1224
- (0, chai_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
1101
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
1225
1102
  let cs = statements[0];
1226
- (0, chai_1.expect)(cs.annotations).to.be.undefined;
1103
+ (0, chai_config_spec_1.expect)(cs.annotations).to.be.undefined;
1227
1104
  });
1228
1105
  it('can convert argument of an annotation to JS types', () => {
1229
1106
  var _a;
@@ -1241,22 +1118,22 @@ describe('parser', () => {
1241
1118
  sub init()
1242
1119
  end sub
1243
1120
  `, Parser_1.ParseMode.BrighterScript);
1244
- (0, chai_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
1245
- (0, chai_1.expect)(statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
1121
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
1122
+ (0, chai_config_spec_1.expect)(statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
1246
1123
  let fn = statements[0];
1247
- (0, chai_1.expect)(fn.annotations).to.exist;
1248
- (0, chai_1.expect)(fn.annotations[0].getArguments()).to.deep.equal([]);
1249
- (0, chai_1.expect)(statements[1]).to.be.instanceof(Statement_1.FunctionStatement);
1124
+ (0, chai_config_spec_1.expect)(fn.annotations).to.exist;
1125
+ (0, chai_config_spec_1.expect)(fn.annotations[0].getArguments()).to.deep.equal([]);
1126
+ (0, chai_config_spec_1.expect)(statements[1]).to.be.instanceof(Statement_1.FunctionStatement);
1250
1127
  fn = statements[1];
1251
- (0, chai_1.expect)(fn.annotations).to.exist;
1252
- (0, chai_1.expect)(fn.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
1253
- (0, chai_1.expect)(fn.annotations[0].getArguments()).to.deep.equal([
1128
+ (0, chai_config_spec_1.expect)(fn.annotations).to.exist;
1129
+ (0, chai_config_spec_1.expect)(fn.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
1130
+ (0, chai_config_spec_1.expect)(fn.annotations[0].getArguments()).to.deep.equal([
1254
1131
  'arg', 2, true,
1255
1132
  { prop: 'value' }, [1, 2],
1256
1133
  null
1257
1134
  ]);
1258
1135
  let allArgs = fn.annotations[0].getArguments(false);
1259
- (0, chai_1.expect)(allArgs.pop()).to.be.instanceOf(Expression_1.FunctionExpression);
1136
+ (0, chai_config_spec_1.expect)(allArgs.pop()).to.be.instanceOf(Expression_1.FunctionExpression);
1260
1137
  });
1261
1138
  it('can handle negative numbers', () => {
1262
1139
  var _a;
@@ -1268,459 +1145,594 @@ describe('parser', () => {
1268
1145
  sub init()
1269
1146
  end sub
1270
1147
  `, Parser_1.ParseMode.BrighterScript);
1271
- (0, chai_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
1272
- (0, chai_1.expect)(statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
1148
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
1149
+ (0, chai_config_spec_1.expect)(statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
1273
1150
  let fn = statements[0];
1274
- (0, chai_1.expect)(fn.annotations).to.exist;
1275
- (0, chai_1.expect)(fn.annotations[0].getArguments()).to.deep.equal([-100]);
1151
+ (0, chai_config_spec_1.expect)(fn.annotations).to.exist;
1152
+ (0, chai_config_spec_1.expect)(fn.annotations[0].getArguments()).to.deep.equal([-100]);
1276
1153
  });
1277
1154
  });
1278
- describe('getBscTypeFromExpression', () => {
1279
- it('computes void type for sub with no return type', () => {
1280
- const parser = parse(`
1281
- sub main()
1282
- getMessage = sub()
1283
- print "hello"
1284
- end sub
1155
+ describe('type casts', () => {
1156
+ it('is not allowed in brightscript mode', () => {
1157
+ var _a;
1158
+ let parser = parse(`
1159
+ sub main(node as dynamic)
1160
+ print lcase((node as string))
1285
1161
  end sub
1286
- `);
1287
- const func = parser.ast.statements[0].func;
1288
- const type = (0, Parser_1.getBscTypeFromExpression)(func.body.statements[0].value, func);
1289
- (0, chai_1.expect)(type.returnType).to.be.instanceof(VoidType_1.VoidType);
1162
+ `, Parser_1.ParseMode.BrightScript);
1163
+ (0, chai_config_spec_1.expect)((_a = parser.diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('type cast').message);
1290
1164
  });
1291
- it('computes return type for sub with explicit return type', () => {
1292
- const parser = parse(`
1165
+ it('allows type casts after function calls', () => {
1166
+ var _a;
1167
+ let { statements, diagnostics } = parse(`
1293
1168
  sub main()
1294
- getMessage = sub() as string
1295
- return "hello"
1296
- end sub
1169
+ value = getValue() as integer
1297
1170
  end sub
1298
- `);
1299
- const func = parser.ast.statements[0].func;
1300
- const type = (0, Parser_1.getBscTypeFromExpression)(func.body.statements[0].value, func);
1301
- (0, chai_1.expect)(type.returnType).to.be.instanceof(StringType_1.StringType);
1302
- });
1303
- it('supports sub with custom return type', () => {
1304
- const parser = parse(`
1171
+
1172
+ function getValue()
1173
+ return 123
1174
+ end function
1175
+ `, Parser_1.ParseMode.BrighterScript);
1176
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
1177
+ (0, chai_config_spec_1.expect)(statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
1178
+ let fn = statements[0];
1179
+ (0, chai_config_spec_1.expect)(fn.func.body.statements).to.exist;
1180
+ let assignment = fn.func.body.statements[0];
1181
+ (0, chai_config_spec_1.expect)((0, reflection_1.isAssignmentStatement)(assignment)).to.be.true;
1182
+ (0, chai_config_spec_1.expect)((0, reflection_1.isTypeCastExpression)(assignment.value)).to.be.true;
1183
+ (0, chai_config_spec_1.expect)((0, reflection_1.isCallExpression)(assignment.value.obj)).to.be.true;
1184
+ (0, testHelpers_spec_1.expectTypeToBe)(assignment.getType({ flags: SymbolTable_1.SymbolTypeFlag.typetime }), IntegerType_1.IntegerType);
1185
+ });
1186
+ it('allows type casts in the middle of expressions', () => {
1187
+ var _a;
1188
+ let { statements, diagnostics } = parse(`
1305
1189
  sub main()
1306
- getPerson = sub() as Person
1307
- return new Person()
1308
- end sub
1190
+ value = (getValue() as integer).toStr()
1309
1191
  end sub
1310
1192
 
1311
- class Person
1312
- end class
1193
+ function getValue()
1194
+ return 123
1195
+ end function
1313
1196
  `, Parser_1.ParseMode.BrighterScript);
1314
- (0, testHelpers_spec_1.expectZeroDiagnostics)(parser.diagnostics);
1315
- const func = parser.ast.statements[0].func;
1316
- const type = (0, Parser_1.getBscTypeFromExpression)(func.body.statements[0].value, func);
1317
- // Return type is LazyType, because "Person" is not fully known yet
1318
- (0, chai_1.expect)(type.returnType).to.be.instanceof(LazyType_1.LazyType);
1319
- });
1320
- it('supports function with array return type', () => {
1321
- const parser = parse(`
1197
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
1198
+ (0, chai_config_spec_1.expect)(statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
1199
+ let fn = statements[0];
1200
+ (0, chai_config_spec_1.expect)(fn.func.body.statements).to.exist;
1201
+ let assignment = fn.func.body.statements[0];
1202
+ (0, chai_config_spec_1.expect)((0, reflection_1.isAssignmentStatement)(assignment)).to.be.true;
1203
+ (0, chai_config_spec_1.expect)((0, reflection_1.isCallExpression)(assignment.value)).to.be.true;
1204
+ (0, chai_config_spec_1.expect)((0, reflection_1.isDottedGetExpression)(assignment.value.callee)).to.be.true;
1205
+ (0, chai_config_spec_1.expect)((0, reflection_1.isGroupingExpression)(assignment.value.callee.obj)).to.be.true;
1206
+ (0, chai_config_spec_1.expect)((0, reflection_1.isTypeCastExpression)(assignment.value.callee.obj.expression)).to.be.true;
1207
+ //grouping expression is an integer
1208
+ (0, testHelpers_spec_1.expectTypeToBe)(assignment.value.callee.obj.getType({ flags: SymbolTable_1.SymbolTypeFlag.typetime }), IntegerType_1.IntegerType);
1209
+ });
1210
+ it('allows type casts in a function call', () => {
1211
+ var _a;
1212
+ let { statements, diagnostics } = parse(`
1322
1213
  sub main()
1323
- getNums = sub() as integer[]
1324
- return [1,2,3]
1325
- end sub
1214
+ print cos(getAngle() as float)
1326
1215
  end sub
1216
+
1217
+ function getAngle()
1218
+ return 123
1219
+ end function
1327
1220
  `, Parser_1.ParseMode.BrighterScript);
1328
- (0, testHelpers_spec_1.expectZeroDiagnostics)(parser.diagnostics);
1329
- const func = parser.ast.statements[0].func;
1330
- const type = (0, Parser_1.getBscTypeFromExpression)(func.body.statements[0].value, func);
1331
- (0, chai_1.expect)(type.returnType).to.be.instanceof(ArrayType_1.ArrayType);
1332
- (0, chai_1.expect)(type.returnType.getDefaultType()).to.be.instanceof(IntegerType_1.IntegerType);
1333
- });
1334
- });
1335
- describe('symbolTable', () => {
1336
- it('stores the types', () => {
1337
- const parser = parse(`
1221
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
1222
+ (0, chai_config_spec_1.expect)(statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
1223
+ let fn = statements[0];
1224
+ (0, chai_config_spec_1.expect)(fn.func.body.statements).to.exist;
1225
+ let print = fn.func.body.statements[0];
1226
+ (0, chai_config_spec_1.expect)((0, reflection_1.isPrintStatement)(print)).to.be.true;
1227
+ (0, chai_config_spec_1.expect)((0, reflection_1.isCallExpression)(print.expressions[0])).to.be.true;
1228
+ let fnCall = print.expressions[0];
1229
+ (0, chai_config_spec_1.expect)((0, reflection_1.isTypeCastExpression)(fnCall.args[0])).to.be.true;
1230
+ let arg = fnCall.args[0];
1231
+ //argument type is float
1232
+ (0, testHelpers_spec_1.expectTypeToBe)(arg.getType({ flags: SymbolTable_1.SymbolTypeFlag.typetime }), FloatType_1.FloatType);
1233
+ });
1234
+ it('allows multiple type casts', () => {
1235
+ var _a;
1236
+ let { statements, diagnostics } = parse(`
1338
1237
  sub main()
1339
- someNum = 123
1340
- someString = "hello world"
1341
- someObj = {foo: "bar"}
1342
- someCustom = new CustomKlass()
1238
+ print getData() as dynamic as float as string
1343
1239
  end sub
1344
-
1345
- class CustomKlass
1346
- end class
1347
1240
  `, Parser_1.ParseMode.BrighterScript);
1348
- (0, testHelpers_spec_1.expectZeroDiagnostics)(parser.diagnostics);
1349
- const mainSymbolTable = parser.references.functionExpressions[0].symbolTable;
1350
- (0, chai_1.expect)(mainSymbolTable.getSymbolType('someNum')).to.be.instanceof(IntegerType_1.IntegerType);
1351
- (0, chai_1.expect)(mainSymbolTable.getSymbolType('someString')).to.be.instanceof(StringType_1.StringType);
1352
- (0, chai_1.expect)(mainSymbolTable.getSymbolType('someObj')).to.be.instanceof(ObjectType_1.ObjectType);
1353
- (0, chai_1.expect)(mainSymbolTable.getSymbolType('someCustom')).to.be.instanceof(CustomType_1.CustomType);
1354
- });
1355
- it('stores typed parameters in functions', () => {
1356
- const parser = parse(`
1357
- sub someFunc(param1 as string, param2 as integer)
1358
- temp = param2
1241
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
1242
+ (0, chai_config_spec_1.expect)(statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
1243
+ let fn = statements[0];
1244
+ (0, chai_config_spec_1.expect)(fn.func.body.statements).to.exist;
1245
+ let print = fn.func.body.statements[0];
1246
+ (0, chai_config_spec_1.expect)((0, reflection_1.isPrintStatement)(print)).to.be.true;
1247
+ (0, chai_config_spec_1.expect)((0, reflection_1.isTypeCastExpression)(print.expressions[0])).to.be.true;
1248
+ //argument type is float
1249
+ (0, testHelpers_spec_1.expectTypeToBe)(print.expressions[0].getType({ flags: SymbolTable_1.SymbolTypeFlag.typetime }), StringType_1.StringType);
1250
+ });
1251
+ it('flags invalid type cast syntax - multiple as', () => {
1252
+ var _a;
1253
+ let { diagnostics } = parse(`
1254
+ sub foo(key)
1255
+ getData(key as as string)
1359
1256
  end sub
1360
1257
  `, Parser_1.ParseMode.BrighterScript);
1361
- (0, testHelpers_spec_1.expectZeroDiagnostics)(parser.diagnostics);
1362
- const someFuncSymbolTable = parser.references.functionExpressions[0].symbolTable;
1363
- (0, chai_1.expect)(someFuncSymbolTable.getSymbolType('param1')).to.be.instanceof(StringType_1.StringType);
1364
- (0, chai_1.expect)(someFuncSymbolTable.getSymbolType('param2')).to.be.instanceof(IntegerType_1.IntegerType);
1365
- (0, chai_1.expect)(someFuncSymbolTable.getSymbolType('temp')).to.be.instanceof(IntegerType_1.IntegerType);
1258
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.exist;
1366
1259
  });
1367
- it('properly defers typing lazy types', () => {
1368
- const parser = parse(`
1369
- sub someFunc()
1370
- temp = foo()
1260
+ it('flags invalid type cast syntax - no type after as', () => {
1261
+ var _a;
1262
+ let { diagnostics } = parse(`
1263
+ sub foo(key)
1264
+ getData(key as)
1371
1265
  end sub
1372
-
1373
- function foo() as string
1374
- return "foo"
1375
- end function
1376
1266
  `, Parser_1.ParseMode.BrighterScript);
1377
- (0, testHelpers_spec_1.expectZeroDiagnostics)(parser.diagnostics);
1378
- const someFuncSymbolTable = parser.references.functionExpressions[0].symbolTable;
1379
- (0, chai_1.expect)((0, reflection_1.isLazyType)(someFuncSymbolTable.getSymbol('temp')[0].type)).to.be.true;
1380
- (0, chai_1.expect)(someFuncSymbolTable.getSymbolType('temp').toTypeString()).to.eq('string');
1267
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.exist;
1381
1268
  });
1382
- it('does not know about symbols declared in parent functions', () => {
1383
- const parser = parse(`
1384
- sub main()
1385
- count = 0
1386
- addOne = sub()
1387
- oldVal = count
1388
- end sub
1269
+ it('allows declaring types on assignment in Brighterscript mode', () => {
1270
+ let { diagnostics } = parse(`
1271
+ sub foo()
1272
+ x as string = formatJson("some string")
1389
1273
  end sub
1390
1274
  `, Parser_1.ParseMode.BrighterScript);
1391
- (0, testHelpers_spec_1.expectZeroDiagnostics)(parser.diagnostics);
1392
- const addOneSymbolTable = parser.references.functionExpressions[0].childFunctionExpressions[0].symbolTable;
1393
- (0, chai_1.expect)((0, reflection_1.isUninitializedType)(addOneSymbolTable.getSymbolType('oldVal'))).to.be.true;
1275
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1394
1276
  });
1395
- it('finds params', () => {
1396
- const parser = parse(`
1397
- sub alert(p1, p2 as string, p3 = 1)
1277
+ it('does not allow declaring types on assignment in brightscript mode', () => {
1278
+ var _a, _b;
1279
+ let { diagnostics } = parse(`
1280
+ sub foo()
1281
+ x as string = formatJson("some string")
1398
1282
  end sub
1399
- `, Parser_1.ParseMode.BrighterScript);
1400
- (0, testHelpers_spec_1.expectZeroDiagnostics)(parser.diagnostics);
1401
- (0, testHelpers_spec_1.expectSymbolTableEquals)(parser.references.functionExpressions[0].symbolTable, [
1402
- ['p1', new DynamicType_1.DynamicType(), util_1.util.createRange(1, 26, 1, 28)],
1403
- ['p2', new StringType_1.StringType(), util_1.util.createRange(1, 30, 1, 32)],
1404
- ['p3', new IntegerType_1.IntegerType(), util_1.util.createRange(1, 44, 1, 46)]
1405
- ]);
1283
+ `, Parser_1.ParseMode.BrightScript);
1284
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.exist;
1285
+ (0, chai_config_spec_1.expect)((_b = diagnostics[0]) === null || _b === void 0 ? void 0 : _b.message).to.include('typed assignment');
1406
1286
  });
1407
- it('finds arrays of primitives', () => {
1408
- const parser = parse(`
1409
- function alert(numbers as integer[], words as string[]) as float[]
1410
- end function
1411
- `, Parser_1.ParseMode.BrighterScript);
1412
- (0, testHelpers_spec_1.expectZeroDiagnostics)(parser.diagnostics);
1413
- const symbolTable = parser.references.functionExpressions[0].symbolTable;
1414
- const numArraySymbolType = symbolTable.getSymbolType('numbers');
1415
- const wordArraySymbolType = symbolTable.getSymbolType('words');
1416
- (0, chai_1.expect)((0, reflection_1.isArrayType)(numArraySymbolType)).to.be.true;
1417
- (0, chai_1.expect)((0, reflection_1.isIntegerType)(numArraySymbolType.getDefaultType())).to.be.true;
1418
- (0, chai_1.expect)((0, reflection_1.isArrayType)(wordArraySymbolType)).to.be.true;
1419
- (0, chai_1.expect)((0, reflection_1.isStringType)(wordArraySymbolType.getDefaultType())).to.be.true;
1420
- const funcReturnType = parser.references.functionExpressions[0].getReturnType();
1421
- (0, chai_1.expect)((0, reflection_1.isArrayType)(funcReturnType)).to.be.true;
1422
- (0, chai_1.expect)((0, reflection_1.isFloatType)(funcReturnType.getDefaultType())).to.be.true;
1423
- });
1424
- it('finds multidimensional arrays', () => {
1425
- const parser = parse(`
1426
- sub alert(data as integer[][])
1287
+ });
1288
+ describe('union types', () => {
1289
+ it('is not allowed in brightscript mode', () => {
1290
+ let parser = parse(`
1291
+ sub main(param as string or integer)
1292
+ print param
1427
1293
  end sub
1428
- `, Parser_1.ParseMode.BrighterScript);
1429
- (0, testHelpers_spec_1.expectZeroDiagnostics)(parser.diagnostics);
1430
- const symbolTable = parser.references.functionExpressions[0].symbolTable;
1431
- const dataType = symbolTable.getSymbolType('data');
1432
- (0, chai_1.expect)((0, reflection_1.isArrayType)(dataType)).to.be.true;
1433
- (0, chai_1.expect)((0, reflection_1.isArrayType)(dataType.getDefaultType())).to.be.true;
1434
- (0, chai_1.expect)((0, reflection_1.isIntegerType)(dataType.getDefaultType().getDefaultType())).to.be.true;
1435
- });
1436
- it('finds arrays of custom types', () => {
1437
- const parser = parse(`
1438
- sub alert(data as SomeKlass[])
1294
+ `, Parser_1.ParseMode.BrightScript);
1295
+ (0, testHelpers_spec_1.expectDiagnosticsIncludes)(parser.diagnostics, [DiagnosticMessages_1.DiagnosticMessages.expectedStatementOrFunctionCallButReceivedExpression()]);
1296
+ });
1297
+ it('allows union types in parameters', () => {
1298
+ let { diagnostics } = parse(`
1299
+ sub main(param as string or integer)
1300
+ print param
1439
1301
  end sub
1440
1302
  `, Parser_1.ParseMode.BrighterScript);
1441
- (0, testHelpers_spec_1.expectZeroDiagnostics)(parser.diagnostics);
1442
- const symbolTable = parser.references.functionExpressions[0].symbolTable;
1443
- const dataType = symbolTable.getSymbolType('data');
1444
- (0, chai_1.expect)((0, reflection_1.isArrayType)(dataType)).to.be.true;
1445
- (0, chai_1.expect)((0, reflection_1.isLazyType)(dataType.getDefaultType())).to.be.true;
1446
- });
1447
- describe('loops', () => {
1448
- it('stores the loop variable in a for loop', () => {
1449
- const parser = parse(`
1450
- sub main()
1451
- for i = 0 to 10 step 10
1452
- print i
1453
- end for
1454
- end sub
1455
- `, Parser_1.ParseMode.BrighterScript);
1456
- (0, testHelpers_spec_1.expectZeroDiagnostics)(parser.diagnostics);
1457
- const currentSymbolTable = parser.references.functionExpressions[0].symbolTable;
1458
- (0, chai_1.expect)((0, reflection_1.isIntegerType)(currentSymbolTable.getSymbolType('i'))).to.be.true;
1459
- });
1460
- it('stores the loop variable in a for each loop', () => {
1461
- const parser = parse(`
1462
- sub doLoop(someData)
1463
- for each datum in someData
1464
- print datum
1465
- end for
1303
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1304
+ });
1305
+ it('allows union types in type casts', () => {
1306
+ let { diagnostics } = parse(`
1307
+ sub main(val)
1308
+ printThing(val as string or integer)
1466
1309
  end sub
1467
- `, Parser_1.ParseMode.BrighterScript);
1468
- (0, testHelpers_spec_1.expectZeroDiagnostics)(parser.diagnostics);
1469
- const currentSymbolTable = parser.references.functionExpressions[0].symbolTable;
1470
- (0, chai_1.expect)((0, reflection_1.isDynamicType)(currentSymbolTable.getSymbolType('datum'))).to.be.true;
1471
- });
1472
- it('determines the type of the variable in a for each if the target is an array literal', () => {
1473
- const parser = parse(`
1474
- sub doLoop()
1475
- someData = [1,2,3]
1476
- for each datum in someData
1477
- print datum
1478
- end for
1479
- end sub
1480
- `, Parser_1.ParseMode.BrighterScript);
1481
- (0, testHelpers_spec_1.expectZeroDiagnostics)(parser.diagnostics);
1482
- const currentSymbolTable = parser.references.functionExpressions[0].symbolTable;
1483
- (0, chai_1.expect)((0, reflection_1.isIntegerType)(currentSymbolTable.getSymbolType('datum'))).to.be.true;
1484
- });
1485
- it('determines the type of the variable in a for each if the target is an array', () => {
1486
- const parser = parse(`
1487
- sub doLoop(someData as integer[])
1488
- for each datum in someData
1489
- print datum
1490
- end for
1491
- end sub
1492
- `, Parser_1.ParseMode.BrighterScript);
1493
- (0, testHelpers_spec_1.expectZeroDiagnostics)(parser.diagnostics);
1494
- const currentSymbolTable = parser.references.functionExpressions[0].symbolTable;
1495
- (0, chai_1.expect)((0, reflection_1.isIntegerType)(currentSymbolTable.getSymbolType('datum'))).to.be.true;
1496
- });
1497
- it('determines the type of the variable in a for each if the target is an array of some custom type', () => {
1498
- const parser = parse(`
1499
- sub doLoop(someData as MyKlass[])
1500
- for each datum in someData
1501
- print datum.name
1502
- end for
1503
- end sub
1504
1310
 
1505
- class MyKlass
1506
- name as string
1507
- end class
1508
- `, Parser_1.ParseMode.BrighterScript);
1509
- (0, testHelpers_spec_1.expectZeroDiagnostics)(parser.diagnostics);
1510
- const currentSymbolTable = parser.references.functionExpressions[0].symbolTable;
1511
- (0, chai_1.expect)((0, reflection_1.isLazyType)(currentSymbolTable.getSymbol('datum')[0].type)).to.be.true;
1512
- });
1513
- it('determines the type of the variable in a for each if the target is a multidimensional array', () => {
1514
- const parser = parse(`
1515
- sub doLoop(data as float[][])
1516
- for each row in data
1517
- for each item in row
1518
- print item
1519
- end for
1520
- end for
1521
- end sub
1522
- `, Parser_1.ParseMode.BrighterScript);
1523
- (0, testHelpers_spec_1.expectZeroDiagnostics)(parser.diagnostics);
1524
- const currentSymbolTable = parser.references.functionExpressions[0].symbolTable;
1525
- (0, chai_1.expect)((0, reflection_1.isArrayType)(currentSymbolTable.getSymbol('row')[0].type)).to.be.true;
1526
- (0, chai_1.expect)((0, reflection_1.isFloatType)(currentSymbolTable.getSymbol('item')[0].type)).to.be.true;
1527
- });
1311
+ sub printThing(thing as string or integer)
1312
+ print thing
1313
+ end sub
1314
+ `, Parser_1.ParseMode.BrighterScript);
1315
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1528
1316
  });
1529
1317
  });
1530
- describe('tokenChain', () => {
1531
- it('can find a chain of tokens', () => {
1532
- const parser = parse(`
1533
- sub someFunc(var)
1534
- print var.field.childField
1535
- end sub
1536
- `);
1537
- const childFieldToken = parser.getTokenAt(vscode_languageserver_1.Position.create(2, 42));
1538
- const tokenChain = parser.getTokenChain(childFieldToken).chain;
1539
- const tokenChainTokens = tokenChain.map(tcm => tcm.token);
1540
- (0, chai_1.expect)(tokenChain.length).to.equal(3);
1541
- (0, chai_1.expect)(tokenChainTokens.map(token => token.text)).to.eql(['var', 'field', 'childField']);
1542
- (0, chai_1.expect)(tokenChain.map(tcm => tcm.usage)).to.eql([Parser_1.TokenUsage.Direct, Parser_1.TokenUsage.Direct, Parser_1.TokenUsage.Direct]);
1543
- });
1544
- it('can find a chain of tokens with function call with no args in the middle', () => {
1545
- const parser = parse(`
1546
- sub someFunc(var)
1547
- print var.field.funcCall().childField
1548
- end sub
1549
- `);
1550
- const childFieldToken = parser.getTokenAt(vscode_languageserver_1.Position.create(2, 49));
1551
- const tokenChain = parser.getTokenChain(childFieldToken).chain;
1552
- const tokenChainTokens = tokenChain.map(tcm => tcm.token);
1553
- (0, chai_1.expect)(tokenChain.length).to.equal(4);
1554
- (0, chai_1.expect)(tokenChainTokens.map(token => token.text)).to.eql(['var', 'field', 'funcCall', 'childField']);
1555
- (0, chai_1.expect)(tokenChain[2].usage).to.eql(Parser_1.TokenUsage.Call);
1556
- });
1557
- it('can find a chain of tokens with function call with multiple args in the middle', () => {
1558
- const parser = parse(`
1559
- sub someFunc(var)
1560
- print var.field.funcCall(1, "string", {key: value}).childField
1561
- end sub
1562
- `);
1563
- const childFieldToken = parser.getTokenAt(vscode_languageserver_1.Position.create(2, 75));
1564
- const tokenChain = parser.getTokenChain(childFieldToken).chain;
1565
- const tokenChainTokens = tokenChain.map(tcm => tcm.token);
1566
- (0, chai_1.expect)(tokenChain.length).to.equal(4);
1567
- (0, chai_1.expect)(tokenChainTokens.map(token => token.text)).to.eql(['var', 'field', 'funcCall', 'childField']);
1568
- (0, chai_1.expect)(tokenChain[2].usage).to.eql(Parser_1.TokenUsage.Call);
1569
- });
1570
- it('can find a chain of tokens with function call with function call inside', () => {
1571
- const parser = parse(`
1572
- sub someFunc(var)
1573
- print var.field.funcCall(a(), b(), otherFunc2(c(), {d: func3(e)})).childField
1574
- end sub
1575
- `);
1576
- const childFieldToken = parser.getTokenAt(vscode_languageserver_1.Position.create(2, 90));
1577
- const tokenChain = parser.getTokenChain(childFieldToken).chain;
1578
- const tokenChainTokens = tokenChain.map(tcm => tcm.token);
1579
- (0, chai_1.expect)(tokenChain.length).to.equal(4);
1580
- (0, chai_1.expect)(tokenChainTokens.map(token => token.text)).to.eql(['var', 'field', 'funcCall', 'childField']);
1581
- (0, chai_1.expect)(tokenChain[2].usage).to.eql(Parser_1.TokenUsage.Call);
1582
- });
1583
- it('can find a chain of tokens with array references inside', () => {
1584
- const parser = parse(`
1585
- sub someFunc(var)
1586
- print var.field.myArray[0].childField
1587
- end sub
1588
- `);
1589
- const childFieldToken = parser.getTokenAt(vscode_languageserver_1.Position.create(2, 50));
1590
- const tokenChain = parser.getTokenChain(childFieldToken).chain;
1591
- const tokenChainTokens = tokenChain.map(tcm => tcm.token);
1592
- (0, chai_1.expect)(tokenChain.length).to.equal(4);
1593
- (0, chai_1.expect)(tokenChainTokens.map(token => token.text)).to.eql(['var', 'field', 'myArray', 'childField']);
1594
- (0, chai_1.expect)(tokenChain[2].usage).to.eql(Parser_1.TokenUsage.ArrayReference);
1595
- });
1596
- it('includes unknown when an expression in brackets is part of the chain', () => {
1597
- const parser = parse(`
1598
- sub someFunc()
1599
- print (1 + 1).toStr()
1318
+ describe('typed arrays', () => {
1319
+ it('is not allowed in brightscript mode', () => {
1320
+ let parser = parse(`
1321
+ sub main(things as string[])
1322
+ print things
1600
1323
  end sub
1601
- `);
1602
- const toStrToken = parser.getTokenAt(vscode_languageserver_1.Position.create(2, 38));
1603
- const tokenChainResponse = parser.getTokenChain(toStrToken);
1604
- (0, chai_1.expect)(tokenChainResponse.includesUnknowableTokenType).to.be.true;
1324
+ `, Parser_1.ParseMode.BrightScript);
1325
+ (0, testHelpers_spec_1.expectDiagnosticsIncludes)(parser.diagnostics, [DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('typed arrays')]);
1605
1326
  });
1606
- it('includes unknown when an expression in double brackets is part of the chain', () => {
1607
- const parser = parse(`
1608
- sub someFunc()
1609
- print ((2 + 1)*3).toStr()
1327
+ it('is allowed in brighterscript mode', () => {
1328
+ let { statements, diagnostics } = parse(`
1329
+ sub main(things as string[])
1330
+ print things
1610
1331
  end sub
1611
- `);
1612
- const toStrToken = parser.getTokenAt(vscode_languageserver_1.Position.create(2, 42));
1613
- const tokenChainResponse = parser.getTokenChain(toStrToken);
1614
- (0, chai_1.expect)(tokenChainResponse.includesUnknowableTokenType).to.be.true;
1332
+ `, Parser_1.ParseMode.BrighterScript);
1333
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1334
+ const paramType = statements[0].func.parameters[0].getType({ flags: SymbolTable_1.SymbolTypeFlag.typetime });
1335
+ (0, testHelpers_spec_1.expectTypeToBe)(paramType, types_1.ArrayType);
1336
+ (0, testHelpers_spec_1.expectTypeToBe)(paramType.defaultType, StringType_1.StringType);
1615
1337
  });
1616
- it('includes unknown when a complicated expression in brackets is part of the chain', () => {
1617
- const parser = parse(`
1618
- sub someFunc(currentDate, lastUpdate)
1619
- print (INT((currentDate.asSeconds() - lastUpdate) / 86400)).toStr()
1338
+ it('allows multi dimensional arrays', () => {
1339
+ let { statements, diagnostics } = parse(`
1340
+ sub main(things as string[][])
1341
+ print things
1620
1342
  end sub
1621
- `);
1622
- const toStrToken = parser.getTokenAt(vscode_languageserver_1.Position.create(2, 81));
1623
- const tokenChainResponse = parser.getTokenChain(toStrToken);
1624
- (0, chai_1.expect)(tokenChainResponse.includesUnknowableTokenType).to.be.true;
1343
+ `, Parser_1.ParseMode.BrighterScript);
1344
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1345
+ const paramType = statements[0].func.parameters[0].getType({ flags: SymbolTable_1.SymbolTypeFlag.typetime });
1346
+ (0, testHelpers_spec_1.expectTypeToBe)(paramType, types_1.ArrayType);
1347
+ (0, testHelpers_spec_1.expectTypeToBe)(paramType.defaultType, types_1.ArrayType);
1348
+ (0, testHelpers_spec_1.expectTypeToBe)(paramType.defaultType.defaultType, StringType_1.StringType);
1625
1349
  });
1626
- it('indicates IndexedGet when referenced via brackets', () => {
1627
- const parser = parse(`
1628
- sub someFunc()
1629
- complexObj = {prop: "hello", subObj: {prop: "foo", grandChildObj:{prop:"bar"}}}
1630
- print complexObj.subObj.prop
1631
- print complexObj["subObj"].prop
1632
- print complexObj["subObj"]["grandChildObj"].prop
1350
+ it('allows arrays as return types', () => {
1351
+ let { statements, diagnostics } = parse(`
1352
+ function getFourPrimes() as integer[]
1353
+ return [2, 3, 5, 7]
1354
+ end function
1355
+ `, Parser_1.ParseMode.BrighterScript);
1356
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1357
+ const paramType = statements[0].func.returnTypeExpression.getType({ flags: SymbolTable_1.SymbolTypeFlag.typetime });
1358
+ (0, testHelpers_spec_1.expectTypeToBe)(paramType, types_1.ArrayType);
1359
+ (0, testHelpers_spec_1.expectTypeToBe)(paramType.defaultType, IntegerType_1.IntegerType);
1360
+ });
1361
+ it('allows arrays in union types', () => {
1362
+ let { statements, diagnostics } = parse(`
1363
+ sub foo(x as integer or integer[] or string or string[])
1364
+ print x
1633
1365
  end sub
1366
+ `, Parser_1.ParseMode.BrighterScript);
1367
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1368
+ const paramType = statements[0].func.parameters[0].getType({ flags: SymbolTable_1.SymbolTypeFlag.typetime });
1369
+ (0, testHelpers_spec_1.expectTypeToBe)(paramType, types_1.UnionType);
1370
+ (0, chai_config_spec_1.expect)(paramType.toString().includes('Array<string>')).to.be.true;
1371
+ (0, chai_config_spec_1.expect)(paramType.toString().includes('Array<integer>')).to.be.true;
1372
+ });
1373
+ });
1374
+ describe('interfaces', () => {
1375
+ it('allows fields and methods', () => {
1376
+ let { statements, diagnostics } = parse(`
1377
+ interface SomeIFace
1378
+ name as string
1379
+ height as integer
1380
+ function getValue(thing as float) as object
1381
+ function getMe() as SomeIFace
1382
+ sub noop()
1383
+ end interface
1384
+ `, Parser_1.ParseMode.BrighterScript);
1385
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1386
+ (0, chai_config_spec_1.expect)(statements.length).to.eq(1);
1387
+ (0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(statements[0])).to.be.true;
1388
+ });
1389
+ it('allows untyped fields', () => {
1390
+ let { statements, diagnostics } = parse(`
1391
+ interface HasUntyped
1392
+ name
1393
+ end interface
1394
+ `, Parser_1.ParseMode.BrighterScript);
1395
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1396
+ (0, chai_config_spec_1.expect)(statements.length).to.eq(1);
1397
+ (0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(statements[0])).to.be.true;
1398
+ });
1399
+ it('allows optional fields', () => {
1400
+ let { statements, diagnostics } = parse(`
1401
+ interface HasOptional
1402
+ optional name as string
1403
+ optional height
1404
+ end interface
1405
+ `, Parser_1.ParseMode.BrighterScript);
1406
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1407
+ (0, chai_config_spec_1.expect)(statements.length).to.eq(1);
1408
+ (0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(statements[0])).to.be.true;
1409
+ const iface = statements[0];
1410
+ iface.fields.forEach(f => (0, chai_config_spec_1.expect)(f.isOptional).to.be.true);
1411
+ const ifaceType = iface.getType({ flags: SymbolTable_1.SymbolTypeFlag.typetime });
1412
+ // eslint-disable-next-line no-bitwise
1413
+ ifaceType.getMemberTable().getAllSymbols(SymbolTable_1.SymbolTypeFlag.runtime).forEach(sym => (0, chai_config_spec_1.expect)(sym.flags & SymbolTable_1.SymbolTypeFlag.optional).to.eq(SymbolTable_1.SymbolTypeFlag.optional));
1414
+ });
1415
+ it('allows fields named optional', () => {
1416
+ let { statements, diagnostics } = parse(`
1417
+ interface IsJustOptional
1418
+ optional
1419
+ someThingElse
1420
+ end interface
1421
+ `, Parser_1.ParseMode.BrighterScript);
1422
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1423
+ (0, chai_config_spec_1.expect)(statements.length).to.eq(1);
1424
+ (0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(statements[0])).to.be.true;
1425
+ const iface = statements[0];
1426
+ iface.fields.forEach(f => (0, chai_config_spec_1.expect)(f.isOptional).to.be.false);
1427
+ const ifaceType = iface.getType({ flags: SymbolTable_1.SymbolTypeFlag.typetime });
1428
+ const iFaceMembers = ifaceType.getMemberTable().getAllSymbols(SymbolTable_1.SymbolTypeFlag.runtime);
1429
+ (0, chai_config_spec_1.expect)(iFaceMembers.length).to.eq(2);
1430
+ // eslint-disable-next-line no-bitwise
1431
+ iFaceMembers.forEach(sym => (0, chai_config_spec_1.expect)(sym.flags & SymbolTable_1.SymbolTypeFlag.optional).to.eq(0));
1432
+ });
1433
+ it('allows fields named optional that are also optional', () => {
1434
+ let { statements, diagnostics } = parse(`
1435
+ interface IsJustOptional
1436
+ optional optional
1437
+ end interface
1438
+ `, Parser_1.ParseMode.BrighterScript);
1439
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1440
+ (0, chai_config_spec_1.expect)(statements.length).to.eq(1);
1441
+ (0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(statements[0])).to.be.true;
1442
+ const iface = statements[0];
1443
+ iface.fields.forEach(f => (0, chai_config_spec_1.expect)(f.isOptional).to.be.true);
1444
+ const ifaceType = iface.getType({ flags: SymbolTable_1.SymbolTypeFlag.typetime });
1445
+ const iFaceMembers = ifaceType.getMemberTable().getAllSymbols(SymbolTable_1.SymbolTypeFlag.runtime);
1446
+ (0, chai_config_spec_1.expect)(iFaceMembers.length).to.eq(1);
1447
+ // eslint-disable-next-line no-bitwise
1448
+ iFaceMembers.forEach(sym => (0, chai_config_spec_1.expect)(sym.flags & SymbolTable_1.SymbolTypeFlag.optional).to.eq(SymbolTable_1.SymbolTypeFlag.optional));
1449
+ });
1450
+ it('allows optional methods', () => {
1451
+ let { statements, diagnostics } = parse(`
1452
+ interface HasOptional
1453
+ optional function getValue() as boolean
1454
+ optional sub noop()
1455
+ optional function process()
1456
+ end interface
1457
+ `, Parser_1.ParseMode.BrighterScript);
1458
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1459
+ (0, chai_config_spec_1.expect)(statements.length).to.eq(1);
1460
+ (0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(statements[0])).to.be.true;
1461
+ const iface = statements[0];
1462
+ iface.methods.forEach(m => (0, chai_config_spec_1.expect)(m.isOptional).to.equal(true));
1463
+ const ifaceType = iface.getType({ flags: SymbolTable_1.SymbolTypeFlag.typetime });
1464
+ // eslint-disable-next-line no-bitwise
1465
+ ifaceType.getMemberTable().getAllSymbols(SymbolTable_1.SymbolTypeFlag.runtime).forEach(sym => (0, chai_config_spec_1.expect)(sym.flags & SymbolTable_1.SymbolTypeFlag.optional).to.eq(SymbolTable_1.SymbolTypeFlag.optional));
1466
+ });
1467
+ it('allows fields named `as` that are also optional', () => {
1468
+ let { statements, diagnostics } = parse(`
1469
+ interface IsJustOptional
1470
+ optional as
1471
+ end interface
1472
+ `, Parser_1.ParseMode.BrighterScript);
1473
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1474
+ (0, chai_config_spec_1.expect)(statements.length).to.eq(1);
1475
+ (0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(statements[0])).to.be.true;
1476
+ const iface = statements[0];
1477
+ iface.fields.forEach(f => (0, chai_config_spec_1.expect)(f.isOptional).to.be.true);
1478
+ const ifaceType = iface.getType({ flags: SymbolTable_1.SymbolTypeFlag.typetime });
1479
+ const iFaceMembers = ifaceType.getMemberTable().getAllSymbols(SymbolTable_1.SymbolTypeFlag.runtime);
1480
+ (0, chai_config_spec_1.expect)(iFaceMembers.length).to.eq(1);
1481
+ // eslint-disable-next-line no-bitwise
1482
+ iFaceMembers.forEach(sym => (0, chai_config_spec_1.expect)(sym.flags & SymbolTable_1.SymbolTypeFlag.optional).to.eq(SymbolTable_1.SymbolTypeFlag.optional));
1483
+ });
1484
+ it('allows fields named `as` that are also typed', () => {
1485
+ let { statements, diagnostics } = parse(`
1486
+ interface IsJustOptional
1487
+ optional as as string
1488
+ end interface
1489
+ `, Parser_1.ParseMode.BrighterScript);
1490
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1491
+ (0, chai_config_spec_1.expect)(statements.length).to.eq(1);
1492
+ (0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(statements[0])).to.be.true;
1493
+ const iface = statements[0];
1494
+ iface.fields.forEach(f => (0, chai_config_spec_1.expect)(f.isOptional).to.be.true);
1495
+ const ifaceType = iface.getType({ flags: SymbolTable_1.SymbolTypeFlag.typetime });
1496
+ const iFaceMembers = ifaceType.getMemberTable().getAllSymbols(SymbolTable_1.SymbolTypeFlag.runtime);
1497
+ (0, chai_config_spec_1.expect)(iFaceMembers.length).to.eq(1);
1498
+ // eslint-disable-next-line no-bitwise
1499
+ iFaceMembers.forEach(sym => (0, chai_config_spec_1.expect)(sym.flags & SymbolTable_1.SymbolTypeFlag.optional).to.eq(SymbolTable_1.SymbolTypeFlag.optional));
1500
+ });
1501
+ it('allows fields named `optional` that are also typed', () => {
1502
+ let { statements, diagnostics } = parse(`
1503
+ interface IsJustOptional
1504
+ optional as string
1505
+ end interface
1506
+ `, Parser_1.ParseMode.BrighterScript);
1507
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1508
+ (0, chai_config_spec_1.expect)(statements.length).to.eq(1);
1509
+ (0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(statements[0])).to.be.true;
1510
+ const iface = statements[0];
1511
+ iface.fields.forEach(f => (0, chai_config_spec_1.expect)(f.isOptional).to.be.false);
1512
+ const ifaceType = iface.getType({ flags: SymbolTable_1.SymbolTypeFlag.typetime });
1513
+ const iFaceMembers = ifaceType.getMemberTable().getAllSymbols(SymbolTable_1.SymbolTypeFlag.runtime);
1514
+ (0, chai_config_spec_1.expect)(iFaceMembers.length).to.eq(1);
1515
+ // eslint-disable-next-line no-bitwise
1516
+ iFaceMembers.forEach(sym => (0, chai_config_spec_1.expect)(sym.flags & SymbolTable_1.SymbolTypeFlag.optional).to.eq(0));
1517
+ });
1518
+ });
1519
+ describe('leadingTrivia', () => {
1520
+ it('gets leading trivia from functions', () => {
1521
+ let { statements } = parse(`
1522
+ ' Nice function, bro
1523
+ function foo()
1524
+ return 1
1525
+ end function
1634
1526
  `);
1635
- const propAsChainToken = parser.getTokenAt(vscode_languageserver_1.Position.create(3, 48)); // complexObj.subObj.prop
1636
- const propAsAsBracketToken = parser.getTokenAt(vscode_languageserver_1.Position.create(4, 51)); // complexObj["subObj"].prop
1637
- const propAsAsDoubleBracketToken = parser.getTokenAt(vscode_languageserver_1.Position.create(5, 68)); // complexObj["subObj"]["grandChildObj"].prop
1638
- let tokenChainResponse = parser.getTokenChain(propAsChainToken);
1639
- (0, chai_1.expect)(tokenChainResponse.includesUnknowableTokenType).to.be.false;
1640
- (0, chai_1.expect)(tokenChainResponse.chain.map(tcm => tcm.token).map(token => token.text)).to.eql(['complexObj', 'subObj', 'prop']);
1641
- tokenChainResponse = parser.getTokenChain(propAsAsBracketToken);
1642
- (0, chai_1.expect)(tokenChainResponse.includesUnknowableTokenType).to.be.false;
1643
- (0, chai_1.expect)(tokenChainResponse.chain[0].usage).to.eql(Parser_1.TokenUsage.ArrayReference);
1644
- tokenChainResponse = parser.getTokenChain(propAsAsDoubleBracketToken);
1645
- (0, chai_1.expect)(tokenChainResponse.chain[0].usage).to.equal(Parser_1.TokenUsage.Direct);
1646
- });
1647
- it('allows token kinds from AllowedLocalIdentifiers as start of a chain', () => {
1648
- const parser = parse(`
1649
- sub testLocalIdentifiers(override, string, float)
1650
- override.someProp.someFunc()
1651
- string.someProp.someFunc()
1652
- float.someProp.someFunc()
1527
+ const funcStatements = statements.filter(reflection_1.isFunctionStatement);
1528
+ const fooTrivia = funcStatements[0].getLeadingTrivia();
1529
+ (0, chai_config_spec_1.expect)(fooTrivia.length).to.be.greaterThan(0);
1530
+ (0, chai_config_spec_1.expect)(fooTrivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
1531
+ });
1532
+ it('gets multiple lines of leading trivia', () => {
1533
+ let { statements } = parse(`
1534
+ ' Say hello to someone
1535
+ '
1536
+ ' @param {string} name the person you want to say hello to.
1537
+ sub sayHello(name as string = "world")
1653
1538
  end sub
1654
1539
  `);
1655
- const overrideFuncToken = parser.getTokenAt(vscode_languageserver_1.Position.create(2, 40)); // override.someProp.someFunc()
1656
- const stringFuncToken = parser.getTokenAt(vscode_languageserver_1.Position.create(3, 40)); // string.someProp.someFunc()
1657
- const floatFuncToken = parser.getTokenAt(vscode_languageserver_1.Position.create(4, 38)); // float.someProp.someFunc()
1658
- let tokenChainResponse = parser.getTokenChain(overrideFuncToken);
1659
- (0, chai_1.expect)(tokenChainResponse.includesUnknowableTokenType).to.be.false;
1660
- (0, chai_1.expect)(tokenChainResponse.chain.map(tcm => tcm.token).map(token => token.text)).to.eql(['override', 'someProp', 'someFunc']);
1661
- tokenChainResponse = parser.getTokenChain(stringFuncToken);
1662
- (0, chai_1.expect)(tokenChainResponse.includesUnknowableTokenType).to.be.false;
1663
- (0, chai_1.expect)(tokenChainResponse.chain.map(tcm => tcm.token).map(token => token.text)).to.eql(['string', 'someProp', 'someFunc']);
1664
- tokenChainResponse = parser.getTokenChain(floatFuncToken);
1665
- (0, chai_1.expect)(tokenChainResponse.includesUnknowableTokenType).to.be.false;
1666
- (0, chai_1.expect)(tokenChainResponse.chain.map(tcm => tcm.token).map(token => token.text)).to.eql(['float', 'someProp', 'someFunc']);
1667
- });
1668
- it('allows token kinds from AllowedProperties in middle of a chain', () => {
1669
- const parser = parse(`
1670
- sub testAllowedProperties(someObj)
1671
- someObj.override.someFunc()
1672
- someObj.string.someFunc()
1673
- someObj.float.someFunc()
1540
+ const funcStatements = statements.filter(reflection_1.isFunctionStatement);
1541
+ const helloTrivia = funcStatements[0].getLeadingTrivia();
1542
+ (0, chai_config_spec_1.expect)(helloTrivia.length).to.be.greaterThan(0);
1543
+ (0, chai_config_spec_1.expect)(helloTrivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(3);
1544
+ });
1545
+ it('gets leading trivia from classes', () => {
1546
+ let { statements } = parse(`
1547
+ ' hello
1548
+ ' classes
1549
+ class Hello
1550
+ end class
1551
+ `, Parser_1.ParseMode.BrighterScript);
1552
+ const classStatements = statements.filter(reflection_1.isClassStatement);
1553
+ const trivia = classStatements[0].getLeadingTrivia();
1554
+ (0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
1555
+ (0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(2);
1556
+ });
1557
+ it('gets leading trivia from functions with annotations', () => {
1558
+ let { statements } = parse(`
1559
+ ' hello comment 1
1560
+ ' hello comment 2
1561
+ @annotation
1562
+ sub sayHello(name as string = "world")
1674
1563
  end sub
1564
+ `, Parser_1.ParseMode.BrighterScript);
1565
+ const funcStatements = statements.filter(reflection_1.isFunctionStatement);
1566
+ const helloTrivia = funcStatements[0].getLeadingTrivia();
1567
+ (0, chai_config_spec_1.expect)(helloTrivia.length).to.be.greaterThan(0);
1568
+ (0, chai_config_spec_1.expect)(helloTrivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(2);
1569
+ });
1570
+ it('gets leading trivia from class methods', () => {
1571
+ let { statements } = parse(`
1572
+ ' hello
1573
+ ' classes
1574
+ class Hello
1575
+
1576
+ ' Gets the value of PI
1577
+ ' Not a dessert
1578
+ function getPi() as float
1579
+ return 3.14
1580
+ end function
1581
+
1582
+ ' Gets a dessert
1583
+ function getPie() as string
1584
+ return "Apple Pie"
1585
+ end function
1586
+ end class
1587
+ `, Parser_1.ParseMode.BrighterScript);
1588
+ const classStatement = statements.filter(reflection_1.isClassStatement)[0];
1589
+ const methodStatements = classStatement.methods;
1590
+ // function getPi()
1591
+ let trivia = methodStatements[0].getLeadingTrivia();
1592
+ (0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
1593
+ (0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(2);
1594
+ // function getPie()
1595
+ trivia = methodStatements[1].getLeadingTrivia();
1596
+ (0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
1597
+ (0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
1598
+ });
1599
+ it('gets leading trivia from class fields', () => {
1600
+ let { statements } = parse(`
1601
+ ' hello
1602
+ ' classes
1603
+ class Thing
1604
+ ' like the sky
1605
+ ' or a blueberry, evn though that's purple
1606
+ color = "blue"
1607
+
1608
+ ' My name
1609
+ public name as string
1610
+
1611
+ ' Only I know how old I am
1612
+ private age = 42
1613
+ end class
1614
+ `, Parser_1.ParseMode.BrighterScript);
1615
+ const classStatement = statements.filter(reflection_1.isClassStatement)[0];
1616
+ const fieldStatements = classStatement.fields;
1617
+ // color = "blue"
1618
+ let trivia = fieldStatements[0].getLeadingTrivia();
1619
+ (0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
1620
+ (0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(2);
1621
+ // public name as string
1622
+ trivia = fieldStatements[1].getLeadingTrivia();
1623
+ (0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
1624
+ (0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
1625
+ // private age = 42
1626
+ trivia = fieldStatements[2].getLeadingTrivia();
1627
+ (0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
1628
+ (0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
1629
+ });
1630
+ it('gets leading trivia from interfaces', () => {
1631
+ let { statements } = parse(`
1632
+ ' Description of interface
1633
+ interface myIface
1634
+ ' comment
1635
+ someField as integer
1636
+
1637
+ 'comment
1638
+ function someFunc() as string
1639
+ end interface
1640
+ `, Parser_1.ParseMode.BrighterScript);
1641
+ const ifaceStatement = statements.filter(reflection_1.isInterfaceStatement)[0];
1642
+ const fieldStatements = ifaceStatement.fields;
1643
+ const methodStatements = ifaceStatement.methods;
1644
+ // interface myIface
1645
+ let trivia = ifaceStatement.getLeadingTrivia();
1646
+ (0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
1647
+ (0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
1648
+ // someField as integer
1649
+ trivia = fieldStatements[0].getLeadingTrivia();
1650
+ (0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
1651
+ (0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
1652
+ // function someFunc() as string
1653
+ trivia = methodStatements[0].getLeadingTrivia();
1654
+ (0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
1655
+ (0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
1656
+ });
1657
+ it('gets leading trivia from namespaces', () => {
1658
+ let { statements } = parse(`
1659
+ ' Description of interface
1660
+ namespace Nested.Name.Space
1661
+
1662
+ end namespace
1663
+ `, Parser_1.ParseMode.BrighterScript);
1664
+ const nameSpaceStatement = statements.filter(reflection_1.isNamespaceStatement)[0];
1665
+ // namespace Nested.Name.Space
1666
+ let trivia = nameSpaceStatement.getLeadingTrivia();
1667
+ (0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
1668
+ (0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
1669
+ });
1670
+ });
1671
+ describe('unary/binary ordering', () => {
1672
+ it('creates the correct operator order for `not x = x` code', () => {
1673
+ let { diagnostics, statements } = parse(`
1674
+ function isStrNotEmpty(myStr as string) as boolean
1675
+ return not myStr = ""
1676
+ end function
1675
1677
  `);
1676
- const overrideFuncToken = parser.getTokenAt(vscode_languageserver_1.Position.create(2, 40)); // someObj.override.someFunc()
1677
- const stringFuncToken = parser.getTokenAt(vscode_languageserver_1.Position.create(3, 40)); // someObj.string.someFunc()
1678
- const floatFuncToken = parser.getTokenAt(vscode_languageserver_1.Position.create(4, 40)); // someObj.float.someFunc()
1679
- let tokenChainResponse = parser.getTokenChain(overrideFuncToken);
1680
- (0, chai_1.expect)(tokenChainResponse.includesUnknowableTokenType).to.be.false;
1681
- (0, chai_1.expect)(tokenChainResponse.chain.map(tcm => tcm.token).map(token => token.text)).to.eql(['someObj', 'override', 'someFunc']);
1682
- tokenChainResponse = parser.getTokenChain(stringFuncToken);
1683
- (0, chai_1.expect)(tokenChainResponse.includesUnknowableTokenType).to.be.false;
1684
- (0, chai_1.expect)(tokenChainResponse.chain.map(tcm => tcm.token).map(token => token.text)).to.eql(['someObj', 'string', 'someFunc']);
1685
- tokenChainResponse = parser.getTokenChain(floatFuncToken);
1686
- (0, chai_1.expect)(tokenChainResponse.includesUnknowableTokenType).to.be.false;
1687
- (0, chai_1.expect)(tokenChainResponse.chain.map(tcm => tcm.token).map(token => token.text)).to.eql(['someObj', 'float', 'someFunc']);
1688
- });
1689
- it('finds tokens in the middle of a chain', () => {
1690
- const parser = parse(`
1691
- sub testMiddleOfChain()
1692
- print m.nodes[8].label.text
1693
- print alpha.bravo(charlie.delta)
1694
- print m.otherFunc().name
1695
- end sub
1678
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1679
+ (0, chai_config_spec_1.expect)((0, reflection_1.isFunctionStatement)(statements[0])).to.be.true;
1680
+ const insideReturn = statements[0].func.body.statements[0].value;
1681
+ (0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(insideReturn)).to.be.true;
1682
+ (0, chai_config_spec_1.expect)((0, reflection_1.isBinaryExpression)(insideReturn.right)).to.be.true;
1683
+ });
1684
+ it('creates the correct operator order for `not x + x` code', () => {
1685
+ let { diagnostics, statements } = parse(`
1686
+ function tryStuff() as integer
1687
+ return not 1 + 3 ' same as "not (3)" ... eg. the "flipped bits" of 3 (0000 0011) -> 1111 1100, or -4
1688
+ end function
1696
1689
  `);
1697
- const labelToken = parser.getTokenAt(vscode_languageserver_1.Position.create(2, 40)); // 'label'
1698
- const nodesToken = parser.getTokenAt(vscode_languageserver_1.Position.create(2, 31)); // 'nodes'
1699
- const bravoToken = parser.getTokenAt(vscode_languageserver_1.Position.create(3, 35)); // 'bravo'
1700
- let tokenChainResponse = parser.getTokenChain(labelToken);
1701
- (0, chai_1.expect)(tokenChainResponse.includesUnknowableTokenType).to.be.false;
1702
- (0, chai_1.expect)(tokenChainResponse.chain.map(tcm => tcm.token).map(token => token.text)).to.eql(['m', 'nodes', 'label']);
1703
- (0, chai_1.expect)(tokenChainResponse.chain.map(tcm => tcm.usage)).to.eql([Parser_1.TokenUsage.Direct, Parser_1.TokenUsage.ArrayReference, Parser_1.TokenUsage.Direct]);
1704
- tokenChainResponse = parser.getTokenChain(nodesToken);
1705
- (0, chai_1.expect)(tokenChainResponse.includesUnknowableTokenType).to.be.false;
1706
- (0, chai_1.expect)(tokenChainResponse.chain.map(tcm => tcm.token).map(token => token.text)).to.eql(['m', 'nodes']);
1707
- (0, chai_1.expect)(tokenChainResponse.chain.map(tcm => tcm.usage)).to.eql([Parser_1.TokenUsage.Direct, Parser_1.TokenUsage.Direct]);
1708
- tokenChainResponse = parser.getTokenChain(bravoToken);
1709
- (0, chai_1.expect)(tokenChainResponse.includesUnknowableTokenType).to.be.false;
1710
- (0, chai_1.expect)(tokenChainResponse.chain.map(tcm => tcm.token).map(token => token.text)).to.eql(['alpha', 'bravo']);
1711
- (0, chai_1.expect)(tokenChainResponse.chain.map(tcm => tcm.usage)).to.eql([Parser_1.TokenUsage.Direct, Parser_1.TokenUsage.Direct]);
1712
- });
1713
- it('gets chain from ending dot', () => {
1714
- const parser = parse(`
1715
- sub testDotAtEndOfChain()
1716
- m.someFunc().data[0].param.
1717
- end sub
1690
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1691
+ (0, chai_config_spec_1.expect)((0, reflection_1.isFunctionStatement)(statements[0])).to.be.true;
1692
+ const insideReturn = statements[0].func.body.statements[0].value;
1693
+ (0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(insideReturn)).to.be.true;
1694
+ (0, chai_config_spec_1.expect)((0, reflection_1.isBinaryExpression)(insideReturn.right)).to.be.true;
1695
+ });
1696
+ it('creates the correct operator order for `x = not x` code', () => {
1697
+ let { diagnostics, statements } = parse(`
1698
+ function tryStuff() as boolean
1699
+ return 4 = not -5 ' same as "4 = 4"
1700
+ end function
1701
+ `);
1702
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1703
+ (0, chai_config_spec_1.expect)((0, reflection_1.isFunctionStatement)(statements[0])).to.be.true;
1704
+ const insideReturn = statements[0].func.body.statements[0].value;
1705
+ (0, chai_config_spec_1.expect)((0, reflection_1.isBinaryExpression)(insideReturn)).to.be.true;
1706
+ (0, chai_config_spec_1.expect)((0, reflection_1.isLiteralExpression)(insideReturn.left)).to.be.true;
1707
+ const right = insideReturn.right;
1708
+ (0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(right)).to.be.true;
1709
+ (0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(right.right)).to.be.true; // not ( - ( 5))
1710
+ });
1711
+ it('allows multiple nots', () => {
1712
+ let { diagnostics, statements } = parse(`
1713
+ function tryStuff() as integer
1714
+ return not not not 4
1715
+ end function
1716
+ `);
1717
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1718
+ (0, chai_config_spec_1.expect)((0, reflection_1.isFunctionStatement)(statements[0])).to.be.true;
1719
+ const insideReturn = statements[0].func.body.statements[0].value;
1720
+ (0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(insideReturn)).to.be.true;
1721
+ (0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(insideReturn.right)).to.be.true;
1722
+ (0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(insideReturn.right.right)).to.be.true;
1723
+ });
1724
+ it('allows multiple -', () => {
1725
+ let { diagnostics, statements } = parse(`
1726
+ function tryStuff() as integer
1727
+ return - - - 4
1728
+ end function
1718
1729
  `);
1719
- const endDotToken = parser.getTokenAt(vscode_languageserver_1.Position.create(2, 46)); // dot of 'param.'
1720
- let tokenChainResponse = parser.getTokenChain(endDotToken);
1721
- (0, chai_1.expect)(tokenChainResponse.includesUnknowableTokenType).to.be.false;
1722
- (0, chai_1.expect)(tokenChainResponse.chain.map(tcm => tcm.token).map(token => token.text)).to.eql(['m', 'someFunc', 'data', 'param']);
1723
- (0, chai_1.expect)(tokenChainResponse.chain.map(tcm => tcm.usage)).to.eql([Parser_1.TokenUsage.Direct, Parser_1.TokenUsage.Call, Parser_1.TokenUsage.ArrayReference, Parser_1.TokenUsage.Direct]);
1730
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1731
+ (0, chai_config_spec_1.expect)((0, reflection_1.isFunctionStatement)(statements[0])).to.be.true;
1732
+ const insideReturn = statements[0].func.body.statements[0].value;
1733
+ (0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(insideReturn)).to.be.true;
1734
+ (0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(insideReturn.right)).to.be.true;
1735
+ (0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(insideReturn.right.right)).to.be.true;
1724
1736
  });
1725
1737
  });
1726
1738
  });
@@ -1730,6 +1742,7 @@ function parse(text, mode) {
1730
1742
  mode: mode
1731
1743
  });
1732
1744
  }
1745
+ exports.parse = parse;
1733
1746
  function rangeToArray(range) {
1734
1747
  return [
1735
1748
  range.start.line,
@@ -1741,14 +1754,14 @@ function rangeToArray(range) {
1741
1754
  exports.rangeToArray = rangeToArray;
1742
1755
  function expectCommentWithText(stat, text) {
1743
1756
  if ((0, reflection_1.isCommentStatement)(stat)) {
1744
- (0, chai_1.expect)(stat.text).to.equal(text);
1757
+ (0, chai_config_spec_1.expect)(stat.text).to.equal(text);
1745
1758
  }
1746
1759
  else {
1747
1760
  failStatementType(stat, 'Comment');
1748
1761
  }
1749
1762
  }
1750
1763
  function failStatementType(stat, type) {
1751
- chai_1.assert.fail(`Statement ${stat.constructor.name} line ${stat.range.start.line} is not a ${type}`);
1764
+ chai_config_spec_1.assert.fail(`Statement ${stat.constructor.name} line ${stat.range.start.line} is not a ${type}`);
1752
1765
  }
1753
1766
  exports.failStatementType = failStatementType;
1754
1767
  //# sourceMappingURL=Parser.spec.js.map