brighterscript 1.0.0-alpha.5 → 1.0.0-alpha.50

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 (715) hide show
  1. package/README.md +76 -138
  2. package/bsconfig.schema.json +121 -5
  3. package/dist/ActionPipeline.d.ts +10 -0
  4. package/dist/ActionPipeline.js +40 -0
  5. package/dist/ActionPipeline.js.map +1 -0
  6. package/dist/AstValidationSegmenter.d.ts +45 -0
  7. package/dist/AstValidationSegmenter.js +322 -0
  8. package/dist/AstValidationSegmenter.js.map +1 -0
  9. package/dist/BsConfig.d.ts +72 -39
  10. package/dist/BusyStatusTracker.d.ts +61 -0
  11. package/dist/BusyStatusTracker.js +148 -0
  12. package/dist/BusyStatusTracker.js.map +1 -0
  13. package/dist/Cache.d.ts +3 -8
  14. package/dist/Cache.js +9 -14
  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 +12 -4
  20. package/dist/CodeActionUtil.js +22 -5
  21. package/dist/CodeActionUtil.js.map +1 -1
  22. package/dist/CommentFlagProcessor.d.ts +7 -6
  23. package/dist/CommentFlagProcessor.js +11 -8
  24. package/dist/CommentFlagProcessor.js.map +1 -1
  25. package/dist/CrossScopeValidator.d.ts +68 -0
  26. package/dist/CrossScopeValidator.js +642 -0
  27. package/dist/CrossScopeValidator.js.map +1 -0
  28. package/dist/DependencyGraph.d.ts +8 -3
  29. package/dist/DependencyGraph.js +49 -16
  30. package/dist/DependencyGraph.js.map +1 -1
  31. package/dist/DiagnosticCollection.d.ts +21 -5
  32. package/dist/DiagnosticCollection.js +77 -24
  33. package/dist/DiagnosticCollection.js.map +1 -1
  34. package/dist/DiagnosticFilterer.d.ts +27 -6
  35. package/dist/DiagnosticFilterer.js +273 -60
  36. package/dist/DiagnosticFilterer.js.map +1 -1
  37. package/dist/DiagnosticManager.d.ts +82 -0
  38. package/dist/DiagnosticManager.js +406 -0
  39. package/dist/DiagnosticManager.js.map +1 -0
  40. package/dist/DiagnosticMessages.d.ts +558 -196
  41. package/dist/DiagnosticMessages.js +870 -340
  42. package/dist/DiagnosticMessages.js.map +1 -1
  43. package/dist/DiagnosticSeverityAdjuster.d.ts +7 -0
  44. package/dist/DiagnosticSeverityAdjuster.js +45 -0
  45. package/dist/DiagnosticSeverityAdjuster.js.map +1 -0
  46. package/dist/FunctionScope.d.ts +28 -0
  47. package/dist/FunctionScope.js +52 -0
  48. package/dist/FunctionScope.js.map +1 -0
  49. package/dist/KeyedThrottler.d.ts +3 -3
  50. package/dist/KeyedThrottler.js +3 -3
  51. package/dist/KeyedThrottler.js.map +1 -1
  52. package/dist/LanguageServer.d.ts +100 -105
  53. package/dist/LanguageServer.js +444 -745
  54. package/dist/LanguageServer.js.map +1 -1
  55. package/dist/Logger.d.ts +17 -13
  56. package/dist/Logger.js +64 -34
  57. package/dist/Logger.js.map +1 -1
  58. package/dist/PluginInterface.d.ts +32 -10
  59. package/dist/PluginInterface.js +117 -7
  60. package/dist/PluginInterface.js.map +1 -1
  61. package/dist/Program.d.ts +241 -98
  62. package/dist/Program.js +1432 -717
  63. package/dist/Program.js.map +1 -1
  64. package/dist/ProgramBuilder.d.ts +47 -23
  65. package/dist/ProgramBuilder.js +224 -178
  66. package/dist/ProgramBuilder.js.map +1 -1
  67. package/dist/Scope.d.ts +149 -109
  68. package/dist/Scope.js +557 -550
  69. package/dist/Scope.js.map +1 -1
  70. package/dist/SemanticTokenUtils.js +5 -1
  71. package/dist/SemanticTokenUtils.js.map +1 -1
  72. package/dist/Stopwatch.d.ts +4 -0
  73. package/dist/Stopwatch.js +8 -1
  74. package/dist/Stopwatch.js.map +1 -1
  75. package/dist/SymbolTable.d.ts +136 -24
  76. package/dist/SymbolTable.js +565 -64
  77. package/dist/SymbolTable.js.map +1 -1
  78. package/dist/SymbolTypeFlag.d.ts +9 -0
  79. package/dist/SymbolTypeFlag.js +14 -0
  80. package/dist/SymbolTypeFlag.js.map +1 -0
  81. package/dist/Throttler.d.ts +12 -0
  82. package/dist/Throttler.js +39 -0
  83. package/dist/Throttler.js.map +1 -1
  84. package/dist/Watcher.d.ts +0 -3
  85. package/dist/Watcher.js +0 -3
  86. package/dist/Watcher.js.map +1 -1
  87. package/dist/XmlScope.d.ts +5 -15
  88. package/dist/XmlScope.js +34 -90
  89. package/dist/XmlScope.js.map +1 -1
  90. package/dist/astUtils/CachedLookups.d.ts +50 -0
  91. package/dist/astUtils/CachedLookups.js +334 -0
  92. package/dist/astUtils/CachedLookups.js.map +1 -0
  93. package/dist/astUtils/CachedLookups.spec.js +39 -0
  94. package/dist/astUtils/CachedLookups.spec.js.map +1 -0
  95. package/dist/astUtils/Editor.d.ts +69 -0
  96. package/dist/astUtils/Editor.js +245 -0
  97. package/dist/astUtils/Editor.js.map +1 -0
  98. package/dist/astUtils/Editor.spec.js +258 -0
  99. package/dist/astUtils/Editor.spec.js.map +1 -0
  100. package/dist/astUtils/creators.d.ts +54 -19
  101. package/dist/astUtils/creators.js +242 -42
  102. package/dist/astUtils/creators.js.map +1 -1
  103. package/dist/astUtils/creators.spec.js +5 -5
  104. package/dist/astUtils/creators.spec.js.map +1 -1
  105. package/dist/astUtils/reflection.d.ts +196 -85
  106. package/dist/astUtils/reflection.js +497 -144
  107. package/dist/astUtils/reflection.js.map +1 -1
  108. package/dist/astUtils/reflection.spec.js +267 -167
  109. package/dist/astUtils/reflection.spec.js.map +1 -1
  110. package/dist/astUtils/stackedVisitor.js.map +1 -1
  111. package/dist/astUtils/stackedVisitor.spec.js +14 -14
  112. package/dist/astUtils/stackedVisitor.spec.js.map +1 -1
  113. package/dist/astUtils/visitors.d.ts +116 -53
  114. package/dist/astUtils/visitors.js +95 -15
  115. package/dist/astUtils/visitors.js.map +1 -1
  116. package/dist/astUtils/visitors.spec.js +629 -51
  117. package/dist/astUtils/visitors.spec.js.map +1 -1
  118. package/dist/astUtils/xml.d.ts +9 -8
  119. package/dist/astUtils/xml.js +12 -7
  120. package/dist/astUtils/xml.js.map +1 -1
  121. package/dist/bscPlugin/BscPlugin.d.ts +24 -4
  122. package/dist/bscPlugin/BscPlugin.js +88 -4
  123. package/dist/bscPlugin/BscPlugin.js.map +1 -1
  124. package/dist/bscPlugin/CallExpressionInfo.d.ts +36 -0
  125. package/dist/bscPlugin/CallExpressionInfo.js +143 -0
  126. package/dist/bscPlugin/CallExpressionInfo.js.map +1 -0
  127. package/dist/bscPlugin/FileWriter.d.ts +6 -0
  128. package/dist/bscPlugin/FileWriter.js +24 -0
  129. package/dist/bscPlugin/FileWriter.js.map +1 -0
  130. package/dist/bscPlugin/SignatureHelpUtil.d.ts +10 -0
  131. package/dist/bscPlugin/SignatureHelpUtil.js +137 -0
  132. package/dist/bscPlugin/SignatureHelpUtil.js.map +1 -0
  133. package/dist/bscPlugin/codeActions/CodeActionsProcessor.d.ts +6 -5
  134. package/dist/bscPlugin/codeActions/CodeActionsProcessor.js +173 -27
  135. package/dist/bscPlugin/codeActions/CodeActionsProcessor.js.map +1 -1
  136. package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js +138 -21
  137. package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js.map +1 -1
  138. package/dist/bscPlugin/completions/CompletionsProcessor.d.ts +65 -0
  139. package/dist/bscPlugin/completions/CompletionsProcessor.js +633 -0
  140. package/dist/bscPlugin/completions/CompletionsProcessor.js.map +1 -0
  141. package/dist/bscPlugin/completions/CompletionsProcessor.spec.js +2512 -0
  142. package/dist/bscPlugin/completions/CompletionsProcessor.spec.js.map +1 -0
  143. package/dist/bscPlugin/definition/DefinitionProvider.d.ts +13 -0
  144. package/dist/bscPlugin/definition/DefinitionProvider.js +212 -0
  145. package/dist/bscPlugin/definition/DefinitionProvider.js.map +1 -0
  146. package/dist/bscPlugin/definition/DefinitionProvider.spec.js +87 -0
  147. package/dist/bscPlugin/definition/DefinitionProvider.spec.js.map +1 -0
  148. package/dist/bscPlugin/fileProviders/FileProvider.d.ts +9 -0
  149. package/dist/bscPlugin/fileProviders/FileProvider.js +51 -0
  150. package/dist/bscPlugin/fileProviders/FileProvider.js.map +1 -0
  151. package/dist/bscPlugin/hover/HoverProcessor.d.ts +18 -0
  152. package/dist/bscPlugin/hover/HoverProcessor.js +230 -0
  153. package/dist/bscPlugin/hover/HoverProcessor.js.map +1 -0
  154. package/dist/bscPlugin/hover/HoverProcessor.spec.js +991 -0
  155. package/dist/bscPlugin/hover/HoverProcessor.spec.js.map +1 -0
  156. package/dist/bscPlugin/references/ReferencesProvider.d.ts +12 -0
  157. package/dist/bscPlugin/references/ReferencesProvider.js +57 -0
  158. package/dist/bscPlugin/references/ReferencesProvider.js.map +1 -0
  159. package/dist/bscPlugin/references/ReferencesProvider.spec.d.ts +1 -0
  160. package/dist/bscPlugin/references/ReferencesProvider.spec.js +51 -0
  161. package/dist/bscPlugin/references/ReferencesProvider.spec.js.map +1 -0
  162. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.d.ts +14 -0
  163. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js +164 -0
  164. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js.map +1 -0
  165. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.d.ts +1 -0
  166. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js +564 -0
  167. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js.map +1 -0
  168. package/dist/bscPlugin/serialize/BslibInjector.spec.d.ts +1 -0
  169. package/dist/bscPlugin/serialize/BslibInjector.spec.js +33 -0
  170. package/dist/bscPlugin/serialize/BslibInjector.spec.js.map +1 -0
  171. package/dist/bscPlugin/serialize/BslibManager.d.ts +12 -0
  172. package/dist/bscPlugin/serialize/BslibManager.js +46 -0
  173. package/dist/bscPlugin/serialize/BslibManager.js.map +1 -0
  174. package/dist/bscPlugin/serialize/FileSerializer.d.ts +9 -0
  175. package/dist/bscPlugin/serialize/FileSerializer.js +75 -0
  176. package/dist/bscPlugin/serialize/FileSerializer.js.map +1 -0
  177. package/dist/bscPlugin/symbols/DocumentSymbolProcessor.d.ts +7 -0
  178. package/dist/bscPlugin/symbols/DocumentSymbolProcessor.js +22 -0
  179. package/dist/bscPlugin/symbols/DocumentSymbolProcessor.js.map +1 -0
  180. package/dist/bscPlugin/symbols/DocumentSymbolProcessor.spec.d.ts +1 -0
  181. package/dist/bscPlugin/symbols/DocumentSymbolProcessor.spec.js +291 -0
  182. package/dist/bscPlugin/symbols/DocumentSymbolProcessor.spec.js.map +1 -0
  183. package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.d.ts +7 -0
  184. package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.js +26 -0
  185. package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.js.map +1 -0
  186. package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.spec.d.ts +1 -0
  187. package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.spec.js +245 -0
  188. package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.spec.js.map +1 -0
  189. package/dist/bscPlugin/symbols/symbolUtils.d.ts +5 -0
  190. package/dist/bscPlugin/symbols/symbolUtils.js +141 -0
  191. package/dist/bscPlugin/symbols/symbolUtils.js.map +1 -0
  192. package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.d.ts +27 -0
  193. package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.js +418 -0
  194. package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.js.map +1 -0
  195. package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.spec.d.ts +1 -0
  196. package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.spec.js +75 -0
  197. package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.spec.js.map +1 -0
  198. package/dist/bscPlugin/transpile/XmlFilePreTranspileProcessor.d.ts +12 -0
  199. package/dist/bscPlugin/transpile/XmlFilePreTranspileProcessor.js +99 -0
  200. package/dist/bscPlugin/transpile/XmlFilePreTranspileProcessor.js.map +1 -0
  201. package/dist/bscPlugin/validation/BrsFileAfterValidator.d.ts +7 -0
  202. package/dist/bscPlugin/validation/BrsFileAfterValidator.js +18 -0
  203. package/dist/bscPlugin/validation/BrsFileAfterValidator.js.map +1 -0
  204. package/dist/bscPlugin/validation/BrsFileValidator.d.ts +37 -0
  205. package/dist/bscPlugin/validation/BrsFileValidator.js +638 -0
  206. package/dist/bscPlugin/validation/BrsFileValidator.js.map +1 -0
  207. package/dist/bscPlugin/validation/BrsFileValidator.spec.d.ts +1 -0
  208. package/dist/bscPlugin/validation/BrsFileValidator.spec.js +1517 -0
  209. package/dist/bscPlugin/validation/BrsFileValidator.spec.js.map +1 -0
  210. package/dist/bscPlugin/validation/ProgramValidator.d.ts +11 -0
  211. package/dist/bscPlugin/validation/ProgramValidator.js +33 -0
  212. package/dist/bscPlugin/validation/ProgramValidator.js.map +1 -0
  213. package/dist/bscPlugin/validation/ScopeValidator.d.ts +141 -0
  214. package/dist/bscPlugin/validation/ScopeValidator.js +1323 -0
  215. package/dist/bscPlugin/validation/ScopeValidator.js.map +1 -0
  216. package/dist/bscPlugin/validation/ScopeValidator.spec.d.ts +1 -0
  217. package/dist/bscPlugin/validation/ScopeValidator.spec.js +6135 -0
  218. package/dist/bscPlugin/validation/ScopeValidator.spec.js.map +1 -0
  219. package/dist/bscPlugin/validation/XmlFileValidator.d.ts +8 -0
  220. package/dist/bscPlugin/validation/XmlFileValidator.js +36 -0
  221. package/dist/bscPlugin/validation/XmlFileValidator.js.map +1 -0
  222. package/dist/cli.js +126 -27
  223. package/dist/cli.js.map +1 -1
  224. package/dist/common/Sequencer.d.ts +53 -0
  225. package/dist/common/Sequencer.js +233 -0
  226. package/dist/common/Sequencer.js.map +1 -0
  227. package/dist/common/Sequencer.spec.d.ts +1 -0
  228. package/dist/common/Sequencer.spec.js +75 -0
  229. package/dist/common/Sequencer.spec.js.map +1 -0
  230. package/dist/deferred.d.ts +5 -3
  231. package/dist/deferred.js +10 -0
  232. package/dist/deferred.js.map +1 -1
  233. package/dist/diagnosticUtils.d.ts +10 -3
  234. package/dist/diagnosticUtils.js +64 -25
  235. package/dist/diagnosticUtils.js.map +1 -1
  236. package/dist/examples/plugins/removePrint.d.ts +2 -2
  237. package/dist/examples/plugins/removePrint.js +8 -12
  238. package/dist/examples/plugins/removePrint.js.map +1 -1
  239. package/dist/files/AssetFile.d.ts +24 -0
  240. package/dist/files/AssetFile.js +25 -0
  241. package/dist/files/AssetFile.js.map +1 -0
  242. package/dist/files/BrsFile.Class.spec.js +1213 -259
  243. package/dist/files/BrsFile.Class.spec.js.map +1 -1
  244. package/dist/files/BrsFile.d.ts +145 -87
  245. package/dist/files/BrsFile.js +836 -934
  246. package/dist/files/BrsFile.js.map +1 -1
  247. package/dist/files/BrsFile.spec.js +4226 -902
  248. package/dist/files/BrsFile.spec.js.map +1 -1
  249. package/dist/files/BscFile.d.ts +102 -0
  250. package/dist/files/BscFile.js +15 -0
  251. package/dist/files/BscFile.js.map +1 -0
  252. package/dist/files/Factory.d.ts +25 -0
  253. package/dist/files/Factory.js +22 -0
  254. package/dist/files/Factory.js.map +1 -0
  255. package/dist/files/LazyFileData.d.ts +21 -0
  256. package/dist/files/LazyFileData.js +54 -0
  257. package/dist/files/LazyFileData.js.map +1 -0
  258. package/dist/files/LazyFileData.spec.d.ts +1 -0
  259. package/dist/files/LazyFileData.spec.js +27 -0
  260. package/dist/files/LazyFileData.spec.js.map +1 -0
  261. package/dist/files/XmlFile.d.ts +80 -41
  262. package/dist/files/XmlFile.js +161 -137
  263. package/dist/files/XmlFile.js.map +1 -1
  264. package/dist/files/XmlFile.spec.js +444 -336
  265. package/dist/files/XmlFile.spec.js.map +1 -1
  266. package/dist/files/tests/imports.spec.js +62 -52
  267. package/dist/files/tests/imports.spec.js.map +1 -1
  268. package/dist/files/tests/optionalChaning.spec.d.ts +1 -0
  269. package/dist/files/tests/optionalChaning.spec.js +152 -0
  270. package/dist/files/tests/optionalChaning.spec.js.map +1 -0
  271. package/dist/globalCallables.d.ts +3 -1
  272. package/dist/globalCallables.js +424 -184
  273. package/dist/globalCallables.js.map +1 -1
  274. package/dist/index.d.ts +32 -4
  275. package/dist/index.js +54 -7
  276. package/dist/index.js.map +1 -1
  277. package/dist/interfaces.d.ts +942 -125
  278. package/dist/interfaces.js +21 -0
  279. package/dist/interfaces.js.map +1 -1
  280. package/dist/lexer/Character.spec.js +5 -5
  281. package/dist/lexer/Character.spec.js.map +1 -1
  282. package/dist/lexer/Lexer.d.ts +51 -12
  283. package/dist/lexer/Lexer.js +215 -65
  284. package/dist/lexer/Lexer.js.map +1 -1
  285. package/dist/lexer/Lexer.spec.js +812 -568
  286. package/dist/lexer/Lexer.spec.js.map +1 -1
  287. package/dist/lexer/Token.d.ts +27 -11
  288. package/dist/lexer/Token.js +10 -2
  289. package/dist/lexer/Token.js.map +1 -1
  290. package/dist/lexer/TokenKind.d.ts +40 -2
  291. package/dist/lexer/TokenKind.js +147 -10
  292. package/dist/lexer/TokenKind.js.map +1 -1
  293. package/dist/logging.d.ts +14 -0
  294. package/dist/logging.js +29 -0
  295. package/dist/logging.js.map +1 -0
  296. package/dist/lsp/ActionQueue.d.ts +35 -0
  297. package/dist/lsp/ActionQueue.js +115 -0
  298. package/dist/lsp/ActionQueue.js.map +1 -0
  299. package/dist/lsp/ActionQueue.spec.d.ts +1 -0
  300. package/dist/lsp/ActionQueue.spec.js +80 -0
  301. package/dist/lsp/ActionQueue.spec.js.map +1 -0
  302. package/dist/lsp/DocumentManager.d.ts +63 -0
  303. package/dist/lsp/DocumentManager.js +122 -0
  304. package/dist/lsp/DocumentManager.js.map +1 -0
  305. package/dist/lsp/DocumentManager.spec.d.ts +1 -0
  306. package/dist/lsp/DocumentManager.spec.js +103 -0
  307. package/dist/lsp/DocumentManager.spec.js.map +1 -0
  308. package/dist/lsp/LspProject.d.ts +239 -0
  309. package/dist/lsp/LspProject.js +3 -0
  310. package/dist/lsp/LspProject.js.map +1 -0
  311. package/dist/lsp/PathFilterer.d.ts +75 -0
  312. package/dist/lsp/PathFilterer.js +196 -0
  313. package/dist/lsp/PathFilterer.js.map +1 -0
  314. package/dist/lsp/PathFilterer.spec.d.ts +1 -0
  315. package/dist/lsp/PathFilterer.spec.js +182 -0
  316. package/dist/lsp/PathFilterer.spec.js.map +1 -0
  317. package/dist/lsp/Project.d.ts +168 -0
  318. package/dist/lsp/Project.js +437 -0
  319. package/dist/lsp/Project.js.map +1 -0
  320. package/dist/lsp/Project.spec.d.ts +1 -0
  321. package/dist/lsp/Project.spec.js +267 -0
  322. package/dist/lsp/Project.spec.js.map +1 -0
  323. package/dist/lsp/ProjectManager.d.ts +242 -0
  324. package/dist/lsp/ProjectManager.js +824 -0
  325. package/dist/lsp/ProjectManager.js.map +1 -0
  326. package/dist/lsp/ProjectManager.spec.d.ts +1 -0
  327. package/dist/lsp/ProjectManager.spec.js +913 -0
  328. package/dist/lsp/ProjectManager.spec.js.map +1 -0
  329. package/dist/lsp/ReaderWriterManager.d.ts +21 -0
  330. package/dist/lsp/ReaderWriterManager.js +60 -0
  331. package/dist/lsp/ReaderWriterManager.js.map +1 -0
  332. package/dist/lsp/worker/MessageHandler.d.ts +99 -0
  333. package/dist/lsp/worker/MessageHandler.js +138 -0
  334. package/dist/lsp/worker/MessageHandler.js.map +1 -0
  335. package/dist/lsp/worker/MessageHandler.spec.d.ts +1 -0
  336. package/dist/lsp/worker/MessageHandler.spec.js +64 -0
  337. package/dist/lsp/worker/MessageHandler.spec.js.map +1 -0
  338. package/dist/lsp/worker/WorkerPool.d.ts +38 -0
  339. package/dist/lsp/worker/WorkerPool.js +78 -0
  340. package/dist/lsp/worker/WorkerPool.js.map +1 -0
  341. package/dist/lsp/worker/WorkerPool.spec.d.ts +1 -0
  342. package/dist/lsp/worker/WorkerPool.spec.js +59 -0
  343. package/dist/lsp/worker/WorkerPool.spec.js.map +1 -0
  344. package/dist/lsp/worker/WorkerThreadProject.d.ts +143 -0
  345. package/dist/lsp/worker/WorkerThreadProject.js +189 -0
  346. package/dist/lsp/worker/WorkerThreadProject.js.map +1 -0
  347. package/dist/lsp/worker/WorkerThreadProject.spec.d.ts +2 -0
  348. package/dist/lsp/worker/WorkerThreadProject.spec.js +71 -0
  349. package/dist/lsp/worker/WorkerThreadProject.spec.js.map +1 -0
  350. package/dist/lsp/worker/WorkerThreadProjectRunner.d.ts +15 -0
  351. package/dist/lsp/worker/WorkerThreadProjectRunner.js +58 -0
  352. package/dist/lsp/worker/WorkerThreadProjectRunner.js.map +1 -0
  353. package/dist/lsp/worker/run.d.ts +1 -0
  354. package/dist/lsp/worker/run.js +14 -0
  355. package/dist/lsp/worker/run.js.map +1 -0
  356. package/dist/parser/AstNode.d.ts +203 -0
  357. package/dist/parser/AstNode.js +303 -0
  358. package/dist/parser/AstNode.js.map +1 -0
  359. package/dist/parser/AstNode.spec.d.ts +1 -0
  360. package/dist/parser/AstNode.spec.js +1455 -0
  361. package/dist/parser/AstNode.spec.js.map +1 -0
  362. package/dist/parser/BrightScriptDocParser.d.ts +56 -0
  363. package/dist/parser/BrightScriptDocParser.js +294 -0
  364. package/dist/parser/BrightScriptDocParser.js.map +1 -0
  365. package/dist/parser/BrightScriptDocParser.spec.d.ts +1 -0
  366. package/dist/parser/BrightScriptDocParser.spec.js +310 -0
  367. package/dist/parser/BrightScriptDocParser.spec.js.map +1 -0
  368. package/dist/parser/BrsTranspileState.d.ts +22 -3
  369. package/dist/parser/BrsTranspileState.js +19 -0
  370. package/dist/parser/BrsTranspileState.js.map +1 -1
  371. package/dist/parser/Expression.d.ts +553 -221
  372. package/dist/parser/Expression.js +1414 -505
  373. package/dist/parser/Expression.js.map +1 -1
  374. package/dist/parser/Expression.spec.d.ts +1 -0
  375. package/dist/parser/Expression.spec.js +40 -0
  376. package/dist/parser/Expression.spec.js.map +1 -0
  377. package/dist/parser/Parser.Class.spec.js +255 -125
  378. package/dist/parser/Parser.Class.spec.js.map +1 -1
  379. package/dist/parser/Parser.d.ts +117 -124
  380. package/dist/parser/Parser.js +1669 -982
  381. package/dist/parser/Parser.js.map +1 -1
  382. package/dist/parser/Parser.spec.d.ts +3 -1
  383. package/dist/parser/Parser.spec.js +2111 -525
  384. package/dist/parser/Parser.spec.js.map +1 -1
  385. package/dist/parser/SGParser.d.ts +29 -13
  386. package/dist/parser/SGParser.js +85 -56
  387. package/dist/parser/SGParser.js.map +1 -1
  388. package/dist/parser/SGParser.spec.js +30 -45
  389. package/dist/parser/SGParser.spec.js.map +1 -1
  390. package/dist/parser/SGTypes.d.ts +134 -46
  391. package/dist/parser/SGTypes.js +206 -115
  392. package/dist/parser/SGTypes.js.map +1 -1
  393. package/dist/parser/Statement.d.ts +849 -267
  394. package/dist/parser/Statement.js +2412 -625
  395. package/dist/parser/Statement.js.map +1 -1
  396. package/dist/parser/Statement.spec.js +133 -36
  397. package/dist/parser/Statement.spec.js.map +1 -1
  398. package/dist/parser/TranspileState.d.ts +26 -12
  399. package/dist/parser/TranspileState.js +115 -24
  400. package/dist/parser/TranspileState.js.map +1 -1
  401. package/dist/parser/tests/Parser.spec.d.ts +3 -9
  402. package/dist/parser/tests/Parser.spec.js +7 -13
  403. package/dist/parser/tests/Parser.spec.js.map +1 -1
  404. package/dist/parser/tests/controlFlow/For.spec.js +83 -75
  405. package/dist/parser/tests/controlFlow/For.spec.js.map +1 -1
  406. package/dist/parser/tests/controlFlow/ForEach.spec.js +85 -51
  407. package/dist/parser/tests/controlFlow/ForEach.spec.js.map +1 -1
  408. package/dist/parser/tests/controlFlow/If.spec.js +382 -239
  409. package/dist/parser/tests/controlFlow/If.spec.js.map +1 -1
  410. package/dist/parser/tests/controlFlow/While.spec.js +52 -45
  411. package/dist/parser/tests/controlFlow/While.spec.js.map +1 -1
  412. package/dist/parser/tests/expression/Additive.spec.js +51 -43
  413. package/dist/parser/tests/expression/Additive.spec.js.map +1 -1
  414. package/dist/parser/tests/expression/ArrayLiterals.spec.js +192 -142
  415. package/dist/parser/tests/expression/ArrayLiterals.spec.js.map +1 -1
  416. package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js +236 -160
  417. package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js.map +1 -1
  418. package/dist/parser/tests/expression/Boolean.spec.js +41 -34
  419. package/dist/parser/tests/expression/Boolean.spec.js.map +1 -1
  420. package/dist/parser/tests/expression/Call.spec.js +173 -55
  421. package/dist/parser/tests/expression/Call.spec.js.map +1 -1
  422. package/dist/parser/tests/expression/Exponential.spec.js +20 -20
  423. package/dist/parser/tests/expression/Exponential.spec.js.map +1 -1
  424. package/dist/parser/tests/expression/Function.spec.js +291 -282
  425. package/dist/parser/tests/expression/Function.spec.js.map +1 -1
  426. package/dist/parser/tests/expression/Indexing.spec.js +193 -110
  427. package/dist/parser/tests/expression/Indexing.spec.js.map +1 -1
  428. package/dist/parser/tests/expression/Multiplicative.spec.js +42 -42
  429. package/dist/parser/tests/expression/Multiplicative.spec.js.map +1 -1
  430. package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js +260 -115
  431. package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js.map +1 -1
  432. package/dist/parser/tests/expression/PrefixUnary.spec.js +58 -52
  433. package/dist/parser/tests/expression/PrefixUnary.spec.js.map +1 -1
  434. package/dist/parser/tests/expression/Primary.spec.js +76 -60
  435. package/dist/parser/tests/expression/Primary.spec.js.map +1 -1
  436. package/dist/parser/tests/expression/RegexLiteralExpression.spec.d.ts +1 -0
  437. package/dist/parser/tests/expression/RegexLiteralExpression.spec.js +171 -0
  438. package/dist/parser/tests/expression/RegexLiteralExpression.spec.js.map +1 -0
  439. package/dist/parser/tests/expression/Relational.spec.js +50 -50
  440. package/dist/parser/tests/expression/Relational.spec.js.map +1 -1
  441. package/dist/parser/tests/expression/SourceLiteralExpression.spec.js +31 -31
  442. package/dist/parser/tests/expression/SourceLiteralExpression.spec.js.map +1 -1
  443. package/dist/parser/tests/expression/TemplateStringExpression.spec.js +281 -94
  444. package/dist/parser/tests/expression/TemplateStringExpression.spec.js.map +1 -1
  445. package/dist/parser/tests/expression/TernaryExpression.spec.js +747 -192
  446. package/dist/parser/tests/expression/TernaryExpression.spec.js.map +1 -1
  447. package/dist/parser/tests/expression/TypeExpression.spec.d.ts +1 -0
  448. package/dist/parser/tests/expression/TypeExpression.spec.js +126 -0
  449. package/dist/parser/tests/expression/TypeExpression.spec.js.map +1 -0
  450. package/dist/parser/tests/expression/UnaryExpression.spec.d.ts +1 -0
  451. package/dist/parser/tests/expression/UnaryExpression.spec.js +52 -0
  452. package/dist/parser/tests/expression/UnaryExpression.spec.js.map +1 -0
  453. package/dist/parser/tests/statement/AssignmentOperators.spec.js +44 -44
  454. package/dist/parser/tests/statement/AssignmentOperators.spec.js.map +1 -1
  455. package/dist/parser/tests/statement/ConstStatement.spec.d.ts +1 -0
  456. package/dist/parser/tests/statement/ConstStatement.spec.js +500 -0
  457. package/dist/parser/tests/statement/ConstStatement.spec.js.map +1 -0
  458. package/dist/parser/tests/statement/Continue.spec.d.ts +1 -0
  459. package/dist/parser/tests/statement/Continue.spec.js +119 -0
  460. package/dist/parser/tests/statement/Continue.spec.js.map +1 -0
  461. package/dist/parser/tests/statement/Declaration.spec.js +61 -55
  462. package/dist/parser/tests/statement/Declaration.spec.js.map +1 -1
  463. package/dist/parser/tests/statement/Dim.spec.js +29 -22
  464. package/dist/parser/tests/statement/Dim.spec.js.map +1 -1
  465. package/dist/parser/tests/statement/Enum.spec.d.ts +1 -0
  466. package/dist/parser/tests/statement/Enum.spec.js +744 -0
  467. package/dist/parser/tests/statement/Enum.spec.js.map +1 -0
  468. package/dist/parser/tests/statement/For.spec.d.ts +1 -0
  469. package/dist/parser/tests/statement/For.spec.js +45 -0
  470. package/dist/parser/tests/statement/For.spec.js.map +1 -0
  471. package/dist/parser/tests/statement/ForEach.spec.d.ts +1 -0
  472. package/dist/parser/tests/statement/ForEach.spec.js +36 -0
  473. package/dist/parser/tests/statement/ForEach.spec.js.map +1 -0
  474. package/dist/parser/tests/statement/Function.spec.js +226 -215
  475. package/dist/parser/tests/statement/Function.spec.js.map +1 -1
  476. package/dist/parser/tests/statement/Goto.spec.js +16 -15
  477. package/dist/parser/tests/statement/Goto.spec.js.map +1 -1
  478. package/dist/parser/tests/statement/Increment.spec.js +64 -61
  479. package/dist/parser/tests/statement/Increment.spec.js.map +1 -1
  480. package/dist/parser/tests/statement/InterfaceStatement.spec.d.ts +1 -0
  481. package/dist/parser/tests/statement/InterfaceStatement.spec.js +110 -0
  482. package/dist/parser/tests/statement/InterfaceStatement.spec.js.map +1 -0
  483. package/dist/parser/tests/statement/LibraryStatement.spec.js +22 -22
  484. package/dist/parser/tests/statement/LibraryStatement.spec.js.map +1 -1
  485. package/dist/parser/tests/statement/Misc.spec.js +127 -168
  486. package/dist/parser/tests/statement/Misc.spec.js.map +1 -1
  487. package/dist/parser/tests/statement/PrintStatement.spec.js +133 -114
  488. package/dist/parser/tests/statement/PrintStatement.spec.js.map +1 -1
  489. package/dist/parser/tests/statement/ReturnStatement.spec.js +57 -54
  490. package/dist/parser/tests/statement/ReturnStatement.spec.js.map +1 -1
  491. package/dist/parser/tests/statement/Set.spec.js +131 -117
  492. package/dist/parser/tests/statement/Set.spec.js.map +1 -1
  493. package/dist/parser/tests/statement/Stop.spec.js +14 -13
  494. package/dist/parser/tests/statement/Stop.spec.js.map +1 -1
  495. package/dist/parser/tests/statement/Throw.spec.js +11 -8
  496. package/dist/parser/tests/statement/Throw.spec.js.map +1 -1
  497. package/dist/parser/tests/statement/TryCatch.spec.js +26 -15
  498. package/dist/parser/tests/statement/TryCatch.spec.js.map +1 -1
  499. package/dist/preprocessor/Manifest.d.ts +6 -6
  500. package/dist/preprocessor/Manifest.js +17 -38
  501. package/dist/preprocessor/Manifest.js.map +1 -1
  502. package/dist/preprocessor/Manifest.spec.d.ts +1 -0
  503. package/dist/preprocessor/Manifest.spec.js +78 -103
  504. package/dist/preprocessor/Manifest.spec.js.map +1 -1
  505. package/dist/roku-types/data.json +20347 -0
  506. package/dist/roku-types/index.d.ts +5726 -0
  507. package/dist/roku-types/index.js +11 -0
  508. package/dist/roku-types/index.js.map +1 -0
  509. package/dist/types/ArrayType.d.ts +12 -5
  510. package/dist/types/ArrayType.js +89 -24
  511. package/dist/types/ArrayType.js.map +1 -1
  512. package/dist/types/ArrayType.spec.js +39 -11
  513. package/dist/types/ArrayType.spec.js.map +1 -1
  514. package/dist/types/AssociativeArrayType.d.ts +15 -0
  515. package/dist/types/AssociativeArrayType.js +64 -0
  516. package/dist/types/AssociativeArrayType.js.map +1 -0
  517. package/dist/types/BaseFunctionType.d.ts +10 -0
  518. package/dist/types/BaseFunctionType.js +26 -0
  519. package/dist/types/BaseFunctionType.js.map +1 -0
  520. package/dist/types/BooleanType.d.ts +9 -5
  521. package/dist/types/BooleanType.js +19 -8
  522. package/dist/types/BooleanType.js.map +1 -1
  523. package/dist/types/BooleanType.spec.js +10 -4
  524. package/dist/types/BooleanType.spec.js.map +1 -1
  525. package/dist/types/BscType.d.ts +41 -3
  526. package/dist/types/BscType.js +152 -0
  527. package/dist/types/BscType.js.map +1 -1
  528. package/dist/types/BscTypeKind.d.ts +28 -0
  529. package/dist/types/BscTypeKind.js +33 -0
  530. package/dist/types/BscTypeKind.js.map +1 -0
  531. package/dist/types/BuiltInInterfaceAdder.d.ts +28 -0
  532. package/dist/types/BuiltInInterfaceAdder.js +212 -0
  533. package/dist/types/BuiltInInterfaceAdder.js.map +1 -0
  534. package/dist/types/BuiltInInterfaceAdder.spec.d.ts +1 -0
  535. package/dist/types/BuiltInInterfaceAdder.spec.js +115 -0
  536. package/dist/types/BuiltInInterfaceAdder.spec.js.map +1 -0
  537. package/dist/types/CallFuncableType.d.ts +24 -0
  538. package/dist/types/CallFuncableType.js +91 -0
  539. package/dist/types/CallFuncableType.js.map +1 -0
  540. package/dist/types/ClassType.d.ts +17 -0
  541. package/dist/types/ClassType.js +60 -0
  542. package/dist/types/ClassType.js.map +1 -0
  543. package/dist/types/ClassType.spec.d.ts +1 -0
  544. package/dist/types/ClassType.spec.js +76 -0
  545. package/dist/types/ClassType.spec.js.map +1 -0
  546. package/dist/types/ComponentType.d.ts +22 -0
  547. package/dist/types/ComponentType.js +107 -0
  548. package/dist/types/ComponentType.js.map +1 -0
  549. package/dist/types/DoubleType.d.ts +10 -5
  550. package/dist/types/DoubleType.js +21 -17
  551. package/dist/types/DoubleType.js.map +1 -1
  552. package/dist/types/DoubleType.spec.js +12 -4
  553. package/dist/types/DoubleType.spec.js.map +1 -1
  554. package/dist/types/DynamicType.d.ts +13 -5
  555. package/dist/types/DynamicType.js +26 -5
  556. package/dist/types/DynamicType.js.map +1 -1
  557. package/dist/types/DynamicType.spec.js +16 -5
  558. package/dist/types/DynamicType.spec.js.map +1 -1
  559. package/dist/types/EnumType.d.ts +42 -0
  560. package/dist/types/EnumType.js +98 -0
  561. package/dist/types/EnumType.js.map +1 -0
  562. package/dist/types/EnumType.spec.d.ts +1 -0
  563. package/dist/types/EnumType.spec.js +33 -0
  564. package/dist/types/EnumType.spec.js.map +1 -0
  565. package/dist/types/FloatType.d.ts +10 -5
  566. package/dist/types/FloatType.js +21 -17
  567. package/dist/types/FloatType.js.map +1 -1
  568. package/dist/types/FloatType.spec.js +4 -4
  569. package/dist/types/FloatType.spec.js.map +1 -1
  570. package/dist/types/FunctionType.d.ts +8 -22
  571. package/dist/types/FunctionType.js +25 -63
  572. package/dist/types/FunctionType.js.map +1 -1
  573. package/dist/types/InheritableType.d.ts +29 -0
  574. package/dist/types/InheritableType.js +173 -0
  575. package/dist/types/InheritableType.js.map +1 -0
  576. package/dist/types/InlineInterfaceType.d.ts +5 -0
  577. package/dist/types/InlineInterfaceType.js +17 -0
  578. package/dist/types/InlineInterfaceType.js.map +1 -0
  579. package/dist/types/IntegerType.d.ts +10 -5
  580. package/dist/types/IntegerType.js +21 -17
  581. package/dist/types/IntegerType.js.map +1 -1
  582. package/dist/types/IntegerType.spec.js +8 -4
  583. package/dist/types/IntegerType.spec.js.map +1 -1
  584. package/dist/types/InterfaceType.d.ts +14 -6
  585. package/dist/types/InterfaceType.js +30 -15
  586. package/dist/types/InterfaceType.js.map +1 -1
  587. package/dist/types/InterfaceType.spec.d.ts +1 -0
  588. package/dist/types/InterfaceType.spec.js +227 -0
  589. package/dist/types/InterfaceType.spec.js.map +1 -0
  590. package/dist/types/IntersectionType.d.ts +29 -0
  591. package/dist/types/IntersectionType.js +253 -0
  592. package/dist/types/IntersectionType.js.map +1 -0
  593. package/dist/types/IntersectionType.spec.d.ts +1 -0
  594. package/dist/types/IntersectionType.spec.js +150 -0
  595. package/dist/types/IntersectionType.spec.js.map +1 -0
  596. package/dist/types/InvalidType.d.ts +10 -5
  597. package/dist/types/InvalidType.js +21 -9
  598. package/dist/types/InvalidType.js.map +1 -1
  599. package/dist/types/InvalidType.spec.js +8 -4
  600. package/dist/types/InvalidType.spec.js.map +1 -1
  601. package/dist/types/LongIntegerType.d.ts +10 -5
  602. package/dist/types/LongIntegerType.js +21 -17
  603. package/dist/types/LongIntegerType.js.map +1 -1
  604. package/dist/types/LongIntegerType.spec.js +10 -4
  605. package/dist/types/LongIntegerType.spec.js.map +1 -1
  606. package/dist/types/NamespaceType.d.ts +12 -0
  607. package/dist/types/NamespaceType.js +28 -0
  608. package/dist/types/NamespaceType.js.map +1 -0
  609. package/dist/types/ObjectType.d.ts +12 -5
  610. package/dist/types/ObjectType.js +25 -8
  611. package/dist/types/ObjectType.js.map +1 -1
  612. package/dist/types/ObjectType.spec.js +3 -3
  613. package/dist/types/ObjectType.spec.js.map +1 -1
  614. package/dist/types/ReferenceType.d.ts +123 -0
  615. package/dist/types/ReferenceType.js +720 -0
  616. package/dist/types/ReferenceType.js.map +1 -0
  617. package/dist/types/ReferenceType.spec.d.ts +1 -0
  618. package/dist/types/ReferenceType.spec.js +151 -0
  619. package/dist/types/ReferenceType.spec.js.map +1 -0
  620. package/dist/types/StringType.d.ts +12 -5
  621. package/dist/types/StringType.js +23 -8
  622. package/dist/types/StringType.js.map +1 -1
  623. package/dist/types/StringType.spec.js +3 -3
  624. package/dist/types/StringType.spec.js.map +1 -1
  625. package/dist/types/TypeStatementType.d.ts +18 -0
  626. package/dist/types/TypeStatementType.js +45 -0
  627. package/dist/types/TypeStatementType.js.map +1 -0
  628. package/dist/types/TypedFunctionType.d.ts +34 -0
  629. package/dist/types/TypedFunctionType.js +147 -0
  630. package/dist/types/TypedFunctionType.js.map +1 -0
  631. package/dist/types/TypedFunctionType.spec.d.ts +1 -0
  632. package/dist/types/TypedFunctionType.spec.js +122 -0
  633. package/dist/types/TypedFunctionType.spec.js.map +1 -0
  634. package/dist/types/UninitializedType.d.ts +11 -6
  635. package/dist/types/UninitializedType.js +20 -11
  636. package/dist/types/UninitializedType.js.map +1 -1
  637. package/dist/types/UnionType.d.ts +27 -0
  638. package/dist/types/UnionType.js +193 -0
  639. package/dist/types/UnionType.js.map +1 -0
  640. package/dist/types/UnionType.spec.d.ts +1 -0
  641. package/dist/types/UnionType.spec.js +205 -0
  642. package/dist/types/UnionType.spec.js.map +1 -0
  643. package/dist/types/VoidType.d.ts +11 -5
  644. package/dist/types/VoidType.js +22 -8
  645. package/dist/types/VoidType.js.map +1 -1
  646. package/dist/types/VoidType.spec.js +3 -3
  647. package/dist/types/VoidType.spec.js.map +1 -1
  648. package/dist/types/helper.spec.d.ts +1 -0
  649. package/dist/types/helper.spec.js +174 -0
  650. package/dist/types/helper.spec.js.map +1 -0
  651. package/dist/types/helpers.d.ts +51 -0
  652. package/dist/types/helpers.js +323 -0
  653. package/dist/types/helpers.js.map +1 -0
  654. package/dist/types/index.d.ts +22 -0
  655. package/dist/types/index.js +39 -0
  656. package/dist/types/index.js.map +1 -0
  657. package/dist/types/roFunctionType.d.ts +11 -0
  658. package/dist/types/roFunctionType.js +37 -0
  659. package/dist/types/roFunctionType.js.map +1 -0
  660. package/dist/types/roFunctionType.spec.d.ts +1 -0
  661. package/dist/types/roFunctionType.spec.js +20 -0
  662. package/dist/types/roFunctionType.spec.js.map +1 -0
  663. package/dist/util.d.ts +288 -187
  664. package/dist/util.js +2018 -575
  665. package/dist/util.js.map +1 -1
  666. package/dist/validators/ClassValidator.d.ts +9 -15
  667. package/dist/validators/ClassValidator.js +93 -138
  668. package/dist/validators/ClassValidator.js.map +1 -1
  669. package/package.json +185 -138
  670. package/CHANGELOG.md +0 -1188
  671. package/dist/astUtils/index.d.ts +0 -7
  672. package/dist/astUtils/index.js +0 -26
  673. package/dist/astUtils/index.js.map +0 -1
  674. package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.d.ts +0 -7
  675. package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.js +0 -63
  676. package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.js.map +0 -1
  677. package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.spec.js +0 -45
  678. package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.spec.js.map +0 -1
  679. package/dist/lexer/index.d.ts +0 -3
  680. package/dist/lexer/index.js +0 -17
  681. package/dist/lexer/index.js.map +0 -1
  682. package/dist/parser/SGTypes.spec.js +0 -351
  683. package/dist/parser/SGTypes.spec.js.map +0 -1
  684. package/dist/parser/index.d.ts +0 -3
  685. package/dist/parser/index.js +0 -16
  686. package/dist/parser/index.js.map +0 -1
  687. package/dist/preprocessor/Chunk.d.ts +0 -82
  688. package/dist/preprocessor/Chunk.js +0 -77
  689. package/dist/preprocessor/Chunk.js.map +0 -1
  690. package/dist/preprocessor/Preprocessor.d.ts +0 -60
  691. package/dist/preprocessor/Preprocessor.js +0 -156
  692. package/dist/preprocessor/Preprocessor.js.map +0 -1
  693. package/dist/preprocessor/Preprocessor.spec.js +0 -152
  694. package/dist/preprocessor/Preprocessor.spec.js.map +0 -1
  695. package/dist/preprocessor/PreprocessorParser.d.ts +0 -61
  696. package/dist/preprocessor/PreprocessorParser.js +0 -194
  697. package/dist/preprocessor/PreprocessorParser.js.map +0 -1
  698. package/dist/preprocessor/PreprocessorParser.spec.js +0 -116
  699. package/dist/preprocessor/PreprocessorParser.spec.js.map +0 -1
  700. package/dist/preprocessor/index.d.ts +0 -3
  701. package/dist/preprocessor/index.js +0 -16
  702. package/dist/preprocessor/index.js.map +0 -1
  703. package/dist/types/CustomType.d.ts +0 -10
  704. package/dist/types/CustomType.js +0 -35
  705. package/dist/types/CustomType.js.map +0 -1
  706. package/dist/types/FunctionType.spec.js +0 -29
  707. package/dist/types/FunctionType.spec.js.map +0 -1
  708. package/dist/types/LazyType.d.ts +0 -15
  709. package/dist/types/LazyType.js +0 -32
  710. package/dist/types/LazyType.js.map +0 -1
  711. /package/dist/{bscPlugin/semanticTokens/SemanticTokensProcessor.spec.d.ts → astUtils/CachedLookups.spec.d.ts} +0 -0
  712. /package/dist/{parser/SGTypes.spec.d.ts → astUtils/Editor.spec.d.ts} +0 -0
  713. /package/dist/{preprocessor/Preprocessor.spec.d.ts → bscPlugin/completions/CompletionsProcessor.spec.d.ts} +0 -0
  714. /package/dist/{preprocessor/PreprocessorParser.spec.d.ts → bscPlugin/definition/DefinitionProvider.spec.d.ts} +0 -0
  715. /package/dist/{types/FunctionType.spec.d.ts → bscPlugin/hover/HoverProcessor.spec.d.ts} +0 -0
@@ -1,8 +1,9 @@
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");
5
- const lexer_1 = require("../lexer");
3
+ exports.failStatementType = exports.rangeToArray = exports.parse = void 0;
4
+ const chai_config_spec_1 = require("../chai-config.spec");
5
+ const Lexer_1 = require("../lexer/Lexer");
6
+ const TokenKind_1 = require("../lexer/TokenKind");
6
7
  const Expression_1 = require("./Expression");
7
8
  const Parser_1 = require("./Parser");
8
9
  const Statement_1 = require("./Statement");
@@ -10,96 +11,19 @@ const vscode_languageserver_1 = require("vscode-languageserver");
10
11
  const DiagnosticMessages_1 = require("../DiagnosticMessages");
11
12
  const reflection_1 = require("../astUtils/reflection");
12
13
  const testHelpers_spec_1 = require("../testHelpers.spec");
13
- const VoidType_1 = require("../types/VoidType");
14
- const FunctionType_1 = require("../types/FunctionType");
15
- const StringType_1 = require("../types/StringType");
16
- const CustomType_1 = require("../types/CustomType");
14
+ const visitors_1 = require("../astUtils/visitors");
17
15
  const IntegerType_1 = require("../types/IntegerType");
18
- const ObjectType_1 = require("../types/ObjectType");
19
- const LazyType_1 = require("../types/LazyType");
20
- const SymbolTable_1 = require("../SymbolTable");
21
- const DynamicType_1 = require("../types/DynamicType");
16
+ const FloatType_1 = require("../types/FloatType");
17
+ const StringType_1 = require("../types/StringType");
18
+ const types_1 = require("../types");
22
19
  const util_1 = require("../util");
20
+ const InlineInterfaceType_1 = require("../types/InlineInterfaceType");
23
21
  describe('parser', () => {
24
22
  it('emits empty object when empty token list is provided', () => {
25
- chai_1.expect(Parser_1.Parser.parse([])).to.deep.include({
26
- statements: [],
27
- diagnostics: []
28
- });
29
- });
30
- describe('findReferences', () => {
31
- it('recomputes localVars', () => {
32
- const parser = Parser_1.Parser.parse(`
33
- sub main(herd)
34
- for each zombie in herd
35
- isAlive = false
36
- end for
37
- for i = 0 to 10 step 1
38
- j = i
39
- end for
40
- humansAreAlive = false
41
- end sub
42
- `);
43
- chai_1.expect(parser.references.functionExpressions[0].symbolTable.ownSymbols.map(x => x.name).sort()).to.eql([
44
- 'herd',
45
- 'humansAreAlive',
46
- 'i',
47
- 'isAlive',
48
- 'j',
49
- 'zombie'
50
- ]);
51
- parser.invalidateReferences();
52
- chai_1.expect(parser.references.functionExpressions[0].symbolTable.ownSymbols.map(x => x.name).sort()).to.eql([
53
- 'herd',
54
- 'humansAreAlive',
55
- 'i',
56
- 'isAlive',
57
- 'j',
58
- 'zombie'
59
- ]);
60
- });
61
- it('assigns localVars to correct function expression bucket', () => {
62
- const parser = Parser_1.Parser.parse(`
63
- sub main()
64
- outerName = "bob"
65
- speak = sub()
66
- innerName = "innerBob"
67
- end sub
68
- age = 12
69
- end sub
70
- `);
71
- parser.invalidateReferences();
72
- chai_1.expect(parser.references.functionExpressions[0].symbolTable.ownSymbols.map(x => x.name)).to.eql([
73
- 'outerName',
74
- 'speak',
75
- 'age'
76
- ]);
77
- chai_1.expect(parser.references.functionExpressions[1].symbolTable.ownSymbols.map(x => x.name)).to.eql([
78
- 'innerName'
79
- ]);
80
- });
81
- it('gets called if references are missing', () => {
82
- const parser = Parser_1.Parser.parse(`
83
- sub main()
84
- end sub
85
-
86
- sub UnusedFunction()
87
- end sub
88
- `);
89
- chai_1.expect(parser.references.functionStatements.map(x => x.name.text)).to.eql([
90
- 'main',
91
- 'UnusedFunction'
92
- ]);
93
- //simulate a tree-shaking plugin by removing the `UnusedFunction`
94
- parser.ast.statements.splice(1);
95
- //tell the parser we modified the AST and need to regenerate references
96
- parser.invalidateReferences();
97
- chai_1.expect(parser['_references']).not.to.exist;
98
- //calling `references` automatically regenerates the references
99
- chai_1.expect(parser.references.functionStatements.map(x => x.name.text)).to.eql([
100
- 'main'
101
- ]);
102
- });
23
+ let { ast, diagnostics } = Parser_1.Parser.parse([]);
24
+ (0, chai_config_spec_1.expect)((0, reflection_1.isBody)(ast)).to.be.true;
25
+ (0, chai_config_spec_1.expect)(ast.statements).to.be.empty;
26
+ (0, chai_config_spec_1.expect)(diagnostics).to.be.empty;
103
27
  });
104
28
  describe('callfunc operator', () => {
105
29
  it('is not allowed in brightscript mode', () => {
@@ -109,7 +33,7 @@ describe('parser', () => {
109
33
  node@.doSomething(1, 2)
110
34
  end sub
111
35
  `, Parser_1.ParseMode.BrightScript);
112
- chai_1.expect((_a = parser.diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('callfunc operator').message);
36
+ (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);
113
37
  });
114
38
  it('does not cause parse errors', () => {
115
39
  var _a, _b, _c, _d, _e;
@@ -118,17 +42,118 @@ describe('parser', () => {
118
42
  node@.doSomething(1, 2)
119
43
  end sub
120
44
  `, Parser_1.ParseMode.BrighterScript);
121
- chai_1.expect((_a = parser.diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
122
- 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);
45
+ (0, chai_config_spec_1.expect)((_a = parser.diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
46
+ (0, chai_config_spec_1.expect)((_e = (_d = (_c = (_b = parser.ast.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);
47
+ });
48
+ });
49
+ it('flags function names with invalid characters', () => {
50
+ const { diagnostics } = Parser_1.Parser.parse(`
51
+ function alpha$() : end function
52
+ function beta%() : end function
53
+ function charlie!() : end function
54
+ function delta#() : end function
55
+ function echo&() : end function
56
+ `);
57
+ (0, testHelpers_spec_1.expectDiagnostics)(diagnostics, [
58
+ DiagnosticMessages_1.DiagnosticMessages.invalidIdentifier('alpha$', '$'),
59
+ DiagnosticMessages_1.DiagnosticMessages.invalidIdentifier('beta%', '%'),
60
+ DiagnosticMessages_1.DiagnosticMessages.invalidIdentifier('charlie!', '!'),
61
+ DiagnosticMessages_1.DiagnosticMessages.invalidIdentifier('delta#', '#'),
62
+ DiagnosticMessages_1.DiagnosticMessages.invalidIdentifier('echo&', '&')
63
+ ]);
64
+ });
65
+ describe('optional chaining operator', () => {
66
+ function getExpression(text, options) {
67
+ const parser = parse(text, options === null || options === void 0 ? void 0 : options.parseMode);
68
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(parser);
69
+ const expressions = parser.ast.findChildren(reflection_1.isExpression);
70
+ if (options === null || options === void 0 ? void 0 : options.matcher) {
71
+ return expressions.find(options.matcher);
72
+ }
73
+ else {
74
+ return expressions[0];
75
+ }
76
+ }
77
+ it('works for ?.', () => {
78
+ const expression = getExpression(`value = person?.name`);
79
+ (0, chai_config_spec_1.expect)(expression).to.be.instanceOf(Expression_1.DottedGetExpression);
80
+ (0, chai_config_spec_1.expect)(expression.tokens.dot.kind).to.eql(TokenKind_1.TokenKind.QuestionDot);
81
+ });
82
+ it('works for ?[', () => {
83
+ const expression = getExpression(`value = person?["name"]`, { matcher: reflection_1.isIndexedGetExpression });
84
+ (0, chai_config_spec_1.expect)(expression).to.be.instanceOf(Expression_1.IndexedGetExpression);
85
+ (0, chai_config_spec_1.expect)(expression.tokens.openingSquare.kind).to.eql(TokenKind_1.TokenKind.QuestionLeftSquare);
86
+ (0, chai_config_spec_1.expect)(expression.tokens.questionDot).not.to.exist;
87
+ });
88
+ it('works for ?.[', () => {
89
+ var _a;
90
+ const expression = getExpression(`value = person?.["name"]`, { matcher: reflection_1.isIndexedGetExpression });
91
+ (0, chai_config_spec_1.expect)(expression).to.be.instanceOf(Expression_1.IndexedGetExpression);
92
+ (0, chai_config_spec_1.expect)(expression.tokens.openingSquare.kind).to.eql(TokenKind_1.TokenKind.LeftSquareBracket);
93
+ (0, chai_config_spec_1.expect)((_a = expression.tokens.questionDot) === null || _a === void 0 ? void 0 : _a.kind).to.eql(TokenKind_1.TokenKind.QuestionDot);
94
+ });
95
+ it('works for ?@', () => {
96
+ const expression = getExpression(`value = someXml?@someAttr`);
97
+ (0, chai_config_spec_1.expect)(expression).to.be.instanceOf(Expression_1.XmlAttributeGetExpression);
98
+ (0, chai_config_spec_1.expect)(expression.tokens.at.kind).to.eql(TokenKind_1.TokenKind.QuestionAt);
99
+ });
100
+ it('works for ?(', () => {
101
+ const expression = getExpression(`value = person.getName?()`);
102
+ (0, chai_config_spec_1.expect)(expression).to.be.instanceOf(Expression_1.CallExpression);
103
+ (0, chai_config_spec_1.expect)(expression.tokens.openingParen.kind).to.eql(TokenKind_1.TokenKind.QuestionLeftParen);
104
+ });
105
+ it('works for print statements using question mark', () => {
106
+ const { ast } = parse(`
107
+ ?[1]
108
+ ?(1+1)
109
+ `);
110
+ (0, chai_config_spec_1.expect)(ast.statements[0]).to.be.instanceOf(Statement_1.PrintStatement);
111
+ (0, chai_config_spec_1.expect)(ast.statements[1]).to.be.instanceOf(Statement_1.PrintStatement);
112
+ });
113
+ //TODO enable this once we properly parse IIFEs
114
+ it.skip('works for ?( in anonymous function', () => {
115
+ const expression = getExpression(`thing = (function() : end function)?()`);
116
+ (0, chai_config_spec_1.expect)(expression).to.be.instanceOf(Expression_1.CallExpression);
117
+ (0, chai_config_spec_1.expect)(expression.tokens.openingParen.kind).to.eql(TokenKind_1.TokenKind.QuestionLeftParen);
118
+ });
119
+ it('works for ?( in new call', () => {
120
+ const expression = getExpression(`thing = new Person?()`, { parseMode: Parser_1.ParseMode.BrighterScript });
121
+ (0, chai_config_spec_1.expect)(expression).to.be.instanceOf(Expression_1.NewExpression);
122
+ (0, chai_config_spec_1.expect)(expression.call.tokens.openingParen.kind).to.eql(TokenKind_1.TokenKind.QuestionLeftParen);
123
+ });
124
+ it('distinguishes between optional chaining and ternary expression', () => {
125
+ const parser = parse(`
126
+ sub main()
127
+ name = person?["name"]
128
+ isTrue = true
129
+ key = isTrue ? ["name"] : ["age"]
130
+ end sub
131
+ `, Parser_1.ParseMode.BrighterScript);
132
+ const assignmentStatements = parser.ast.findChildren(reflection_1.isAssignmentStatement);
133
+ (0, chai_config_spec_1.expect)(assignmentStatements[0].value).is.instanceof(Expression_1.IndexedGetExpression);
134
+ (0, chai_config_spec_1.expect)(assignmentStatements[2].value).is.instanceof(Expression_1.TernaryExpression);
135
+ });
136
+ it('distinguishes between optional chaining and ternary expression', () => {
137
+ const parser = parse(`
138
+ sub main()
139
+ 'optional chain. the lack of whitespace between ? and [ matters
140
+ key = isTrue ?["name"] : getDefault()
141
+ 'ternary
142
+ key = isTrue ? ["name"] : getDefault()
143
+ end sub
144
+ `, Parser_1.ParseMode.BrighterScript);
145
+ const assignmentStatements = parser.ast.findChildren(reflection_1.isAssignmentStatement);
146
+ (0, chai_config_spec_1.expect)(assignmentStatements[0].value).is.instanceof(Expression_1.IndexedGetExpression);
147
+ (0, chai_config_spec_1.expect)(assignmentStatements[1].value).is.instanceof(Expression_1.TernaryExpression);
123
148
  });
124
149
  });
125
150
  describe('diagnostic locations', () => {
126
151
  it('tracks basic diagnostic locations', () => {
127
- chai_1.expect(parse(`
152
+ (0, chai_config_spec_1.expect)(parse(`
128
153
  sub main()
129
154
  call()a
130
155
  end sub
131
- `).diagnostics.map(x => rangeToArray(x.range))).to.eql([
156
+ `).diagnostics.map(x => rangeToArray(x.location.range))).to.eql([
132
157
  [2, 26, 2, 27],
133
158
  [2, 27, 2, 28]
134
159
  ]);
@@ -140,8 +165,8 @@ describe('parser', () => {
140
165
  return "6c5cdf1"
141
166
  end functionasdf
142
167
  `).diagnostics;
143
- chai_1.expect((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.exist.and.to.eql(DiagnosticMessages_1.DiagnosticMessages.expectedStatementOrFunctionCallButReceivedExpression().message);
144
- 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));
168
+ (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.expectedStatement().message);
169
+ (0, chai_config_spec_1.expect)((_b = diagnostics[0]) === null || _b === void 0 ? void 0 : _b.location.range).to.eql(vscode_languageserver_1.Range.create(3, 20, 3, 32));
145
170
  });
146
171
  });
147
172
  describe('parse', () => {
@@ -154,7 +179,7 @@ describe('parser', () => {
154
179
  end function()
155
180
  end sub
156
181
  `);
157
- testHelpers_spec_1.expectZeroDiagnostics(parser);
182
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(parser);
158
183
  });
159
184
  it('supports grouped iife in assignment', () => {
160
185
  const parser = parse(`
@@ -165,7 +190,7 @@ describe('parser', () => {
165
190
  end function)()
166
191
  end sub
167
192
  `);
168
- testHelpers_spec_1.expectZeroDiagnostics(parser);
193
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(parser);
169
194
  });
170
195
  it('supports returning iife call', () => {
171
196
  const parser = parse(`
@@ -174,45 +199,143 @@ describe('parser', () => {
174
199
  end sub)()
175
200
  end sub
176
201
  `);
177
- testHelpers_spec_1.expectZeroDiagnostics(parser);
202
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(parser);
178
203
  });
179
204
  it('supports using "interface" as parameter name', () => {
180
205
  var _a;
181
- chai_1.expect((_a = parse(`
206
+ (0, chai_config_spec_1.expect)((_a = parse(`
182
207
  sub main(interface as object)
183
208
  end sub
184
209
  `, Parser_1.ParseMode.BrighterScript).diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
185
210
  });
211
+ it('does not scrap the entire function when encountering unknown parameter type', () => {
212
+ const parser = parse(`
213
+ sub test(param1 as unknownType)
214
+ end sub
215
+ `, Parser_1.ParseMode.BrighterScript);
216
+ // type validation happens at scope validation, not at the parser
217
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(parser);
218
+ (0, chai_config_spec_1.expect)((0, reflection_1.isFunctionStatement)(parser.ast.statements[0])).to.be.true;
219
+ });
220
+ it('does not scrap the entire function when encountering unknown parameter type in brightscript mode', () => {
221
+ const parser = parse(`
222
+ sub test(param1 as unknownType)
223
+ end sub
224
+ `, Parser_1.ParseMode.BrightScript);
225
+ // type validation happens at scope validation, not at the parser
226
+ (0, testHelpers_spec_1.expectDiagnosticsIncludes)(parser, DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('custom types'));
227
+ (0, chai_config_spec_1.expect)((0, reflection_1.isFunctionStatement)(parser.ast.statements[0])).to.be.true;
228
+ });
229
+ it('adds diagnostics when missing end for statements', () => {
230
+ let parser = parse(`
231
+ sub test1(x)
232
+ for each item in x
233
+ print item
234
+ end sub
235
+ `, Parser_1.ParseMode.BrightScript);
236
+ (0, testHelpers_spec_1.expectDiagnosticsIncludes)(parser, [
237
+ DiagnosticMessages_1.DiagnosticMessages.expectedEndForOrNextToTerminateForLoop('for each')
238
+ ]);
239
+ parser = parse(`
240
+ sub test2()
241
+ for i = 0 to 10
242
+ print i
243
+ end sub
244
+ `, Parser_1.ParseMode.BrightScript);
245
+ (0, testHelpers_spec_1.expectDiagnosticsIncludes)(parser, [
246
+ DiagnosticMessages_1.DiagnosticMessages.expectedEndForOrNextToTerminateForLoop('for')
247
+ ]);
248
+ parser = parse(`
249
+ sub test3(x )
250
+ for each item in x
251
+ print item
252
+ next
253
+
254
+ for i = 0 to 10
255
+ print i
256
+ next ' next works the same as "end for"
257
+ end sub
258
+ `, Parser_1.ParseMode.BrightScript);
259
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(parser);
260
+ });
261
+ it('does not allow return type as invalid', () => {
262
+ let parser = parse(`
263
+ function test(x) as invalid
264
+ return invalid
265
+ end function
266
+ `, Parser_1.ParseMode.BrighterScript);
267
+ (0, testHelpers_spec_1.expectDiagnosticsIncludes)(parser, [
268
+ DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier('as').message
269
+ ]);
270
+ });
271
+ it('does not allow param type as invalid', () => {
272
+ let parser = parse(`
273
+ function test(x as invalid)
274
+ return invalid
275
+ end function
276
+ `, Parser_1.ParseMode.BrighterScript);
277
+ (0, testHelpers_spec_1.expectDiagnosticsIncludes)(parser, [
278
+ DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier('as').message
279
+ ]);
280
+ });
281
+ it('validates when theres a fraction hex', () => {
282
+ let parser = parse(`
283
+ function test()
284
+ x = &HFF.01234
285
+ return x
286
+ end function
287
+ `);
288
+ (0, testHelpers_spec_1.expectDiagnostics)(parser, [
289
+ DiagnosticMessages_1.DiagnosticMessages.expectedStatement(),
290
+ DiagnosticMessages_1.DiagnosticMessages.expectedNewlineOrColon()
291
+ ]);
292
+ });
293
+ it('allows print statement with hex followed by dot <number>', () => {
294
+ let parser = parse(`
295
+ function test()
296
+ print &HFF.01234
297
+ end function
298
+ `);
299
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(parser);
300
+ });
186
301
  describe('namespace', () => {
187
- it('catches namespaces declared not at root level', () => {
188
- var _a;
189
- chai_1.expect((_a = parse(`
190
- sub main()
191
- namespace Name.Space
302
+ it('allows namespaces declared inside other namespaces', () => {
303
+ const parser = parse(`
304
+ namespace Level1
305
+ namespace Level2.Level3
306
+ sub main()
307
+ end sub
192
308
  end namespace
193
- end sub
194
- `, Parser_1.ParseMode.BrighterScript).diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.keywordMustBeDeclaredAtRootLevel('namespace').message);
309
+ end namespace
310
+ `, Parser_1.ParseMode.BrighterScript);
311
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(parser);
312
+ // We expect these names to be "as given" in this context, because we aren't evaluating a full program.
313
+ const namespaceStatements = parser.ast.findChildren(reflection_1.isNamespaceStatement);
314
+ (0, chai_config_spec_1.expect)(namespaceStatements.map(statement => statement.getName(Parser_1.ParseMode.BrighterScript))).to.have.deep.members([
315
+ 'Level1.Level2.Level3',
316
+ 'Level1'
317
+ ]);
195
318
  });
196
319
  it('parses empty namespace', () => {
197
320
  var _a;
198
- let { statements, diagnostics } = parse(`
321
+ let { ast, diagnostics } = parse(`
199
322
  namespace Name.Space
200
323
  end namespace
201
324
  `, Parser_1.ParseMode.BrighterScript);
202
- chai_1.expect((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
203
- chai_1.expect(statements[0]).to.be.instanceof(Statement_1.NamespaceStatement);
325
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
326
+ (0, chai_config_spec_1.expect)(ast.statements[0]).to.be.instanceof(Statement_1.NamespaceStatement);
204
327
  });
205
328
  it('includes body', () => {
206
329
  var _a;
207
- let { statements, diagnostics } = parse(`
330
+ let { ast, diagnostics } = parse(`
208
331
  namespace Name.Space
209
332
  sub main()
210
333
  end sub
211
334
  end namespace
212
335
  `, Parser_1.ParseMode.BrighterScript);
213
- chai_1.expect((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
214
- chai_1.expect(statements[0]).to.be.instanceof(Statement_1.NamespaceStatement);
215
- chai_1.expect(statements[0].body.statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
336
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
337
+ (0, chai_config_spec_1.expect)(ast.statements[0]).to.be.instanceof(Statement_1.NamespaceStatement);
338
+ (0, chai_config_spec_1.expect)(ast.statements[0].body.statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
216
339
  });
217
340
  it('supports comments and newlines', () => {
218
341
  var _a;
@@ -228,7 +351,7 @@ describe('parser', () => {
228
351
  'comment
229
352
  end namespace 'comment
230
353
  `, Parser_1.ParseMode.BrighterScript);
231
- chai_1.expect((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
354
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
232
355
  });
233
356
  it('catches missing name', () => {
234
357
  var _a;
@@ -236,7 +359,7 @@ describe('parser', () => {
236
359
  namespace
237
360
  end namespace
238
361
  `, Parser_1.ParseMode.BrighterScript);
239
- chai_1.expect((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifierAfterKeyword('namespace').message);
362
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier('namespace').message);
240
363
  });
241
364
  it('recovers after missing `end namespace`', () => {
242
365
  var _a, _b, _c;
@@ -245,9 +368,9 @@ describe('parser', () => {
245
368
  sub main()
246
369
  end sub
247
370
  `, Parser_1.ParseMode.BrighterScript);
248
- chai_1.expect(parser.ast.statements[0]).to.be.instanceof(Statement_1.NamespaceStatement);
249
- chai_1.expect((_a = parser.diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.couldNotFindMatchingEndKeyword('namespace').message);
250
- 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);
371
+ (0, chai_config_spec_1.expect)(parser.ast.statements[0]).to.be.instanceof(Statement_1.NamespaceStatement);
372
+ (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);
373
+ (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);
251
374
  });
252
375
  it('adds diagnostic when encountering namespace in brightscript mode', () => {
253
376
  var _a;
@@ -255,47 +378,12 @@ describe('parser', () => {
255
378
  namespace Name.Space
256
379
  end namespace
257
380
  `);
258
- chai_1.expect((_a = parser.diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('namespace').message);
259
- });
260
- it('declares a symbol table for the namespace', () => {
261
- let parser = parse(`
262
- namespace Name.Space
263
- function funcInt() as integer
264
- return 3
265
- end function
266
-
267
- function funcStr() as string
268
- return "hello"
269
- end function
270
- end namespace
271
- `, Parser_1.ParseMode.BrighterScript);
272
- chai_1.expect(parser.ast.statements[0]).to.be.instanceof(Statement_1.NamespaceStatement);
273
- const namespaceStmt = parser.ast.statements[0];
274
- chai_1.expect(namespaceStmt.symbolTable).to.be.instanceof(SymbolTable_1.SymbolTable);
275
- chai_1.expect(namespaceStmt.symbolTable.getSymbolType('funcInt').toString()).to.equal('function funcInt() as integer');
276
- chai_1.expect(namespaceStmt.symbolTable.getSymbolType('funcStr')).to.be.instanceof(FunctionType_1.FunctionType);
277
- const strFunctionType = namespaceStmt.symbolTable.getSymbolType('funcStr');
278
- chai_1.expect(strFunctionType.returnType.toString()).to.equal('string');
279
- });
280
- it('adds a fully qualified name of a function in a namespace to the parsers symbol table', () => {
281
- let parser = parse(`
282
- namespace Name.Space
283
- function funcInt() as integer
284
- return 3
285
- end function
286
-
287
- function funcStr() as string
288
- return "hello"
289
- end function
290
- end namespace
291
- `, Parser_1.ParseMode.BrighterScript);
292
- chai_1.expect(parser.symbolTable.getSymbolType('Name.Space.funcInt')).to.be.instanceof(FunctionType_1.FunctionType);
293
- chai_1.expect(parser.symbolTable.getSymbolType('Name.Space.funcStr')).to.be.instanceof(FunctionType_1.FunctionType);
381
+ (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);
294
382
  });
295
383
  });
296
384
  it('supports << operator', () => {
297
385
  var _a;
298
- chai_1.expect((_a = parse(`
386
+ (0, chai_config_spec_1.expect)((_a = parse(`
299
387
  sub main()
300
388
  print ((r << 24) + (g << 16) + (b << 8) + a)
301
389
  end sub
@@ -303,7 +391,7 @@ describe('parser', () => {
303
391
  });
304
392
  it('supports >> operator', () => {
305
393
  var _a;
306
- chai_1.expect((_a = parse(`
394
+ (0, chai_config_spec_1.expect)((_a = parse(`
307
395
  sub main()
308
396
  print ((r >> 24) + (g >> 16) + (b >> 8) + a)
309
397
  end sub
@@ -311,7 +399,7 @@ describe('parser', () => {
311
399
  });
312
400
  it('allows global function names with same as token to be called', () => {
313
401
  var _a;
314
- chai_1.expect((_a = parse(`
402
+ (0, chai_config_spec_1.expect)((_a = parse(`
315
403
  sub main()
316
404
  print string(123)
317
405
  end sub
@@ -325,18 +413,18 @@ describe('parser', () => {
325
413
  age = personXml.firstChild@age
326
414
  end sub
327
415
  `);
328
- chai_1.expect((_a = parser.diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.not.exist;
329
- let statements = parser.statements[0].func.body.statements;
330
- let first = statements[0].value;
331
- chai_1.expect(first).to.be.instanceof(Expression_1.XmlAttributeGetExpression);
332
- chai_1.expect(first.name.text).to.equal('firstName');
333
- chai_1.expect(first.at.text).to.equal('@');
334
- chai_1.expect(first.obj.name.text).to.equal('personXml');
335
- let second = statements[1].value;
336
- chai_1.expect(second).to.be.instanceof(Expression_1.XmlAttributeGetExpression);
337
- chai_1.expect(second.name.text).to.equal('age');
338
- chai_1.expect(second.at.text).to.equal('@');
339
- chai_1.expect(second.obj.name.text).to.equal('firstChild');
416
+ (0, chai_config_spec_1.expect)((_a = parser.diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.not.exist;
417
+ let assignments = parser.ast.statements[0].func.body.statements;
418
+ let first = assignments[0].value;
419
+ (0, chai_config_spec_1.expect)(first).to.be.instanceof(Expression_1.XmlAttributeGetExpression);
420
+ (0, chai_config_spec_1.expect)(first.tokens.name.text).to.equal('firstName');
421
+ (0, chai_config_spec_1.expect)(first.tokens.at.text).to.equal('@');
422
+ (0, chai_config_spec_1.expect)(first.obj.tokens.name.text).to.equal('personXml');
423
+ let second = assignments[1].value;
424
+ (0, chai_config_spec_1.expect)(second).to.be.instanceof(Expression_1.XmlAttributeGetExpression);
425
+ (0, chai_config_spec_1.expect)(second.tokens.name.text).to.equal('age');
426
+ (0, chai_config_spec_1.expect)(second.tokens.at.text).to.equal('@');
427
+ (0, chai_config_spec_1.expect)(second.obj.tokens.name.text).to.equal('firstChild');
340
428
  });
341
429
  it('does not allow chaining of @ symbols', () => {
342
430
  let parser = parse(`
@@ -345,58 +433,58 @@ describe('parser', () => {
345
433
  name = personXml@name@age@shoeSize
346
434
  end sub
347
435
  `);
348
- chai_1.expect(parser.diagnostics).not.to.be.empty;
436
+ (0, chai_config_spec_1.expect)(parser.diagnostics).not.to.be.empty;
349
437
  });
350
438
  it('unknown function type does not invalidate rest of function', () => {
351
- let { statements, diagnostics } = parse(`
439
+ let { ast, diagnostics } = parse(`
352
440
  function log() as UNKNOWN_TYPE
353
441
  end function
354
442
  `, Parser_1.ParseMode.BrightScript);
355
- chai_1.expect(diagnostics.length).to.be.greaterThan(0);
356
- chai_1.expect(statements[0]).to.exist;
443
+ (0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('custom types').message); // type validation happens at scope validation step
444
+ (0, chai_config_spec_1.expect)(ast.statements[0]).to.exist;
357
445
  });
358
446
  it('unknown function type is not a problem in Brighterscript mode', () => {
359
- let { statements, diagnostics } = parse(`
447
+ let { ast, diagnostics } = parse(`
360
448
  function log() as UNKNOWN_TYPE
361
449
  end function
362
450
  `, Parser_1.ParseMode.BrighterScript);
363
- chai_1.expect(diagnostics.length).to.equal(0);
364
- chai_1.expect(statements[0]).to.exist;
451
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
452
+ (0, chai_config_spec_1.expect)(ast.statements[0]).to.exist;
365
453
  });
366
454
  it('allows namespaced function type in Brighterscript mode', () => {
367
- let { statements, diagnostics } = parse(`
455
+ let { ast, diagnostics } = parse(`
368
456
  function log() as SOME_NAMESPACE.UNKNOWN_TYPE
369
457
  end function
370
458
  `, Parser_1.ParseMode.BrighterScript);
371
- chai_1.expect(diagnostics.length).to.equal(0);
372
- chai_1.expect(statements[0]).to.exist;
459
+ (0, chai_config_spec_1.expect)(diagnostics.length).to.equal(0);
460
+ (0, chai_config_spec_1.expect)(ast.statements[0]).to.exist;
373
461
  });
374
462
  it('allows custom parameter types in BrighterscriptMode', () => {
375
- let { statements, diagnostics } = parse(`
463
+ let { ast, diagnostics } = parse(`
376
464
  sub foo(value as UNKNOWN_TYPE)
377
465
  end sub
378
466
  `, Parser_1.ParseMode.BrighterScript);
379
- chai_1.expect(diagnostics.length).to.equal(0);
380
- chai_1.expect(statements[0]).to.exist;
467
+ (0, chai_config_spec_1.expect)(diagnostics.length).to.equal(0);
468
+ (0, chai_config_spec_1.expect)(ast.statements[0]).to.exist;
381
469
  });
382
- it('does not allow custom parameter types in Brightscript Mode', () => {
470
+ it('does cause diagnostics when custom parameter types are used in Brightscript Mode', () => {
383
471
  let { diagnostics } = parse(`
384
472
  sub foo(value as UNKNOWN_TYPE)
385
473
  end sub
386
474
  `, Parser_1.ParseMode.BrightScript);
387
- chai_1.expect(diagnostics.length).not.to.equal(0);
475
+ (0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('custom types').message);
388
476
  });
389
477
  it('allows custom namespaced parameter types in BrighterscriptMode', () => {
390
- let { statements, diagnostics } = parse(`
478
+ let { ast, diagnostics } = parse(`
391
479
  sub foo(value as SOME_NAMESPACE.UNKNOWN_TYPE)
392
480
  end sub
393
481
  `, Parser_1.ParseMode.BrighterScript);
394
- chai_1.expect(diagnostics.length).to.equal(0);
395
- chai_1.expect(statements[0]).to.exist;
482
+ (0, chai_config_spec_1.expect)(diagnostics.length).to.equal(0);
483
+ (0, chai_config_spec_1.expect)(ast.statements[0]).to.exist;
396
484
  });
397
485
  it('works with conditionals', () => {
398
486
  var _a;
399
- chai_1.expect((_a = parse(`
487
+ (0, chai_config_spec_1.expect)((_a = parse(`
400
488
  function printNumber()
401
489
  if true then
402
490
  print 1
@@ -408,11 +496,11 @@ describe('parser', () => {
408
496
  });
409
497
  it('supports single-line if statements', () => {
410
498
  var _a;
411
- chai_1.expect((_a = parse(`If true Then print "error" : Stop`).diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.not.exist;
499
+ (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;
412
500
  });
413
501
  it('works with excess newlines', () => {
414
502
  var _a;
415
- let { tokens } = lexer_1.Lexer.scan('function boolToNumber() as string\n\n' +
503
+ let { tokens } = Lexer_1.Lexer.scan('function boolToNumber() as string\n\n' +
416
504
  ' if true then\n\n' +
417
505
  ' print 1\n\n' +
418
506
  ' elseif true then\n\n' +
@@ -421,112 +509,230 @@ describe('parser', () => {
421
509
  ' print 1\n\n' +
422
510
  ' end if\n\n' +
423
511
  'end function\n\n');
424
- chai_1.expect((_a = Parser_1.Parser.parse(tokens).diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.not.exist;
512
+ (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;
425
513
  });
426
514
  it('does not invalidate entire file when line ends with a period', () => {
427
- let { tokens } = lexer_1.Lexer.scan(`
515
+ let { tokens } = Lexer_1.Lexer.scan(`
428
516
  sub main()
429
517
  person.a
430
518
  end sub
431
519
 
432
520
  `);
433
521
  let { diagnostics } = Parser_1.Parser.parse(tokens);
434
- chai_1.expect(diagnostics).to.be.lengthOf(1, 'Error count should be 0');
522
+ (0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(1, 'Error count should be 0');
435
523
  });
436
- it.skip('allows printing object with trailing period', () => {
437
- let { tokens } = lexer_1.Lexer.scan(`print a.`);
438
- let { statements, diagnostics } = Parser_1.Parser.parse(tokens);
439
- let printStatement = statements[0];
440
- chai_1.expect(diagnostics).to.be.empty;
441
- chai_1.expect(printStatement).to.be.instanceof(Statement_1.PrintStatement);
442
- chai_1.expect(printStatement.expressions[0]).to.be.instanceof(Expression_1.DottedGetExpression);
524
+ it('allows printing object with trailing period', () => {
525
+ let { tokens } = Lexer_1.Lexer.scan(`print a.`);
526
+ let { ast, diagnostics } = Parser_1.Parser.parse(tokens);
527
+ let printStatement = ast.statements[0];
528
+ (0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier());
529
+ (0, chai_config_spec_1.expect)(printStatement).to.be.instanceof(Statement_1.PrintStatement);
530
+ (0, chai_config_spec_1.expect)(printStatement.expressions[0]).to.be.instanceof(Expression_1.VariableExpression);
531
+ });
532
+ it('allows printing object with trailing period with multiple dotted gets', () => {
533
+ let { tokens } = Lexer_1.Lexer.scan(`print a.b.`);
534
+ let { ast, diagnostics } = Parser_1.Parser.parse(tokens);
535
+ let printStatement = ast.statements[0];
536
+ (0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier());
537
+ (0, chai_config_spec_1.expect)(printStatement).to.be.instanceof(Statement_1.PrintStatement);
538
+ (0, chai_config_spec_1.expect)(printStatement.expressions[0]).to.be.instanceof(Expression_1.DottedGetExpression);
539
+ });
540
+ describe('incomplete statements in the ast', () => {
541
+ it('adds variable expressions to the ast', () => {
542
+ let { tokens } = Lexer_1.Lexer.scan(`
543
+ function a()
544
+ NameA.
545
+ end function
546
+
547
+ namespace NameA
548
+ sub noop()
549
+ end sub
550
+ end namespace
551
+ `);
552
+ let { ast, diagnostics } = Parser_1.Parser.parse(tokens);
553
+ (0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, DiagnosticMessages_1.DiagnosticMessages.expectedStatement());
554
+ let stmt = ast.statements[0].func.body.statements[0];
555
+ (0, chai_config_spec_1.expect)((0, reflection_1.isExpressionStatement)(stmt)).to.be.true;
556
+ (0, chai_config_spec_1.expect)((0, reflection_1.isVariableExpression)((stmt).expression)).to.be.true;
557
+ (0, chai_config_spec_1.expect)(stmt.expression.tokens.name.text).to.equal('NameA');
558
+ });
559
+ it('adds unended call statements', () => {
560
+ let { tokens } = Lexer_1.Lexer.scan(`
561
+ function a()
562
+ lcase(
563
+ end function
564
+ `);
565
+ let { ast } = Parser_1.Parser.parse(tokens);
566
+ let stmt = ast.statements[0].func.body.statements[0];
567
+ (0, chai_config_spec_1.expect)((0, reflection_1.isExpressionStatement)(stmt)).to.be.true;
568
+ (0, chai_config_spec_1.expect)((0, reflection_1.isCallExpression)((stmt).expression)).to.be.true;
569
+ (0, chai_config_spec_1.expect)(stmt.expression.callee.tokens.name.text).to.equal('lcase');
570
+ });
571
+ it('adds unended indexed get statements', () => {
572
+ let { tokens } = Lexer_1.Lexer.scan(`
573
+ function a()
574
+ nums[
575
+ end function
576
+
577
+ const nums = [1, 2, 3]
578
+ `);
579
+ let { ast } = Parser_1.Parser.parse(tokens);
580
+ let stmt = ast.statements[0].func.body.statements[0];
581
+ (0, chai_config_spec_1.expect)((0, reflection_1.isExpressionStatement)(stmt)).to.be.true;
582
+ (0, chai_config_spec_1.expect)((0, reflection_1.isIndexedGetExpression)((stmt).expression)).to.be.true;
583
+ (0, chai_config_spec_1.expect)(stmt.expression.obj.tokens.name.text).to.equal('nums');
584
+ });
585
+ it('adds dotted gets', () => {
586
+ let { tokens } = Lexer_1.Lexer.scan(`
587
+ function foo(a as KlassA)
588
+ a.b.
589
+ end function
590
+
591
+ class KlassA
592
+ b as KlassB
593
+ end class
594
+
595
+ class KlassB
596
+ sub noop()
597
+ end sub
598
+ end class
599
+ `);
600
+ let { ast } = Parser_1.Parser.parse(tokens);
601
+ let stmt = ast.statements[0].func.body.statements[0];
602
+ (0, chai_config_spec_1.expect)((0, reflection_1.isExpressionStatement)(stmt)).to.be.true;
603
+ (0, chai_config_spec_1.expect)((0, reflection_1.isDottedGetExpression)((stmt).expression)).to.be.true;
604
+ (0, chai_config_spec_1.expect)(stmt.expression.obj.tokens.name.text).to.equal('a');
605
+ (0, chai_config_spec_1.expect)(stmt.expression.tokens.name.text).to.equal('b');
606
+ });
607
+ it('adds function statement with missing type after as', () => {
608
+ var _a;
609
+ let parser = parse(`
610
+ sub foo(thing as )
611
+ print thing
612
+ end sub
613
+ `, Parser_1.ParseMode.BrighterScript);
614
+ (0, chai_config_spec_1.expect)((_a = parser.diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.exist;
615
+ (0, chai_config_spec_1.expect)(parser.ast.statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
616
+ });
617
+ it('adds binary expressions to the ast', () => {
618
+ let { tokens } = Lexer_1.Lexer.scan(`
619
+ function a(x, y)
620
+ 1 or 2
621
+ x * y
622
+ x + y
623
+ x - y
624
+ end function
625
+ `);
626
+ let { ast, diagnostics } = Parser_1.Parser.parse(tokens);
627
+ (0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, DiagnosticMessages_1.DiagnosticMessages.expectedStatement());
628
+ for (const stmt of ast.statements[0].func.body.statements) {
629
+ (0, chai_config_spec_1.expect)((0, reflection_1.isExpressionStatement)(stmt)).to.be.true;
630
+ (0, chai_config_spec_1.expect)((0, reflection_1.isBinaryExpression)((stmt).expression)).to.be.true;
631
+ }
632
+ });
633
+ it('adds callfunc expressions', () => {
634
+ var _a;
635
+ let parser = parse(`
636
+ sub foo(thing)
637
+ thing@.
638
+ end sub
639
+ `, Parser_1.ParseMode.BrighterScript);
640
+ (0, chai_config_spec_1.expect)((_a = parser.diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.exist;
641
+ let body = parser.ast.statements[0].func.body;
642
+ let callFunc = body.findChild(reflection_1.isCallfuncExpression);
643
+ (0, chai_config_spec_1.expect)(callFunc).to.exist;
644
+ });
645
+ it('adds if statements', () => {
646
+ var _a;
647
+ let parser = parse(`
648
+ sub foo(thing)
649
+ if thing.
650
+ end sub
651
+ `, Parser_1.ParseMode.BrighterScript);
652
+ (0, chai_config_spec_1.expect)((_a = parser.diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.exist;
653
+ let body = parser.ast.statements[0].func.body;
654
+ let ifStmt = body.findChild(reflection_1.isIfStatement);
655
+ (0, chai_config_spec_1.expect)(ifStmt).to.exist;
656
+ });
443
657
  });
444
658
  describe('comments', () => {
445
- it('combines multi-line comments', () => {
446
- let { tokens } = lexer_1.Lexer.scan(`
659
+ it('does not include comments', () => {
660
+ let { tokens } = Lexer_1.Lexer.scan(`
447
661
  'line 1
448
662
  'line 2
449
663
  'line 3
450
664
  `);
451
- let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
452
- chai_1.expect(diagnostics).to.be.lengthOf(0, 'Error count should be 0');
453
- chai_1.expect(statements[0].text).to.equal(`'line 1\n'line 2\n'line 3`);
665
+ let { ast, diagnostics } = Parser_1.Parser.parse(tokens);
666
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
667
+ (0, chai_config_spec_1.expect)(ast.statements.length).to.equal(0);
454
668
  });
455
- it('does not combile comments separated by newlines', () => {
456
- let { tokens } = lexer_1.Lexer.scan(`
669
+ it('does matter if comments separated by newlines', () => {
670
+ let { tokens } = Lexer_1.Lexer.scan(`
457
671
  'line 1
458
672
 
459
673
  'line 2
460
674
 
461
675
  'line 3
462
676
  `);
463
- let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
464
- chai_1.expect(diagnostics).to.be.lengthOf(0, 'Error count should be 0');
465
- chai_1.expect(statements).to.be.lengthOf(3);
466
- chai_1.expect(statements[0].text).to.equal(`'line 1`);
467
- chai_1.expect(statements[1].text).to.equal(`'line 2`);
468
- chai_1.expect(statements[2].text).to.equal(`'line 3`);
677
+ let { ast, diagnostics } = Parser_1.Parser.parse(tokens);
678
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
679
+ (0, chai_config_spec_1.expect)(ast.statements).to.be.lengthOf(0);
469
680
  });
470
681
  it('works after print statement', () => {
471
- let { tokens } = lexer_1.Lexer.scan(`
682
+ let { tokens } = Lexer_1.Lexer.scan(`
472
683
  sub main()
473
684
  print "hi" 'comment 1
474
685
  end sub
475
686
  `);
476
- let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
477
- chai_1.expect(diagnostics).to.be.lengthOf(0, 'Error count should be 0');
478
- chai_1.expect(statements[0].func.body.statements[1].text).to.equal(`'comment 1`);
687
+ let { ast, diagnostics } = Parser_1.Parser.parse(tokens);
688
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
689
+ (0, chai_config_spec_1.expect)(ast.statements[0].func.body.statements.length).to.equal(1);
479
690
  });
480
- it('declaration-level', () => {
481
- let { tokens } = lexer_1.Lexer.scan(`
691
+ it('declaration-level should be set as leading trivia', () => {
692
+ let { tokens } = Lexer_1.Lexer.scan(`
482
693
  'comment 1
483
694
  function a()
484
695
  end function
485
696
  'comment 2
486
697
  `);
487
- let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
488
- chai_1.expect(diagnostics).to.be.lengthOf(0, 'Error count should be 0');
489
- chai_1.expect(statements[0].text).to.equal(`'comment 1`);
490
- chai_1.expect(statements[2].text).to.equal(`'comment 2`);
698
+ let { ast, diagnostics } = Parser_1.Parser.parse(tokens);
699
+ (0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Error count should be 0');
700
+ (0, chai_config_spec_1.expect)(ast.statements[0].leadingTrivia[2].text).to.equal(`'comment 1`);
491
701
  });
492
702
  it('works in aa literal as its own statement', () => {
493
- let { tokens } = lexer_1.Lexer.scan(`
703
+ let { tokens } = Lexer_1.Lexer.scan(`
494
704
  obj = {
495
705
  "name": true,
496
706
  'comment
497
707
  }
498
708
  `);
499
709
  let { diagnostics } = Parser_1.Parser.parse(tokens);
500
- chai_1.expect(diagnostics).to.be.lengthOf(0, 'Error count should be 0');
710
+ (0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Error count should be 0');
501
711
  });
502
712
  it('parses after function call', () => {
503
- let { tokens } = lexer_1.Lexer.scan(`
713
+ let { tokens } = Lexer_1.Lexer.scan(`
504
714
  sub Main()
505
715
  name = "Hello"
506
716
  DoSomething(name) 'comment 1
507
717
  end sub
508
718
  `);
509
- let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
510
- chai_1.expect(diagnostics).to.be.lengthOf(0, 'Should have zero diagnostics');
511
- chai_1.expect(statements[0].func.body.statements[2].text).to.equal(`'comment 1`);
719
+ let { diagnostics } = Parser_1.Parser.parse(tokens);
720
+ (0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Should have zero diagnostics');
512
721
  });
513
722
  it('function', () => {
514
- let { tokens } = lexer_1.Lexer.scan(`
723
+ let { tokens } = Lexer_1.Lexer.scan(`
515
724
  function a() 'comment 1
516
725
  'comment 2
517
726
  num = 1
518
727
  'comment 3
519
728
  end function 'comment 4
520
729
  `);
521
- let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
522
- chai_1.expect(diagnostics).to.be.lengthOf(0, 'Should have zero diagnostics');
523
- chai_1.expect(statements[0].func.body.statements[0].text).to.equal(`'comment 1`);
524
- chai_1.expect(statements[0].func.body.statements[1].text).to.equal(`'comment 2`);
525
- chai_1.expect(statements[0].func.body.statements[3].text).to.equal(`'comment 3`);
526
- chai_1.expect(statements[1].text).to.equal(`'comment 4`);
730
+ let { ast, diagnostics } = Parser_1.Parser.parse(tokens);
731
+ (0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Should have zero diagnostics');
732
+ (0, chai_config_spec_1.expect)(ast.statements[0].func.body.statements[0].leadingTrivia.filter(x => x.kind === TokenKind_1.TokenKind.Comment).map(x => x.text)).members([`'comment 1`, `'comment 2`]);
527
733
  });
528
734
  it('if statement`', () => {
529
- let { tokens } = lexer_1.Lexer.scan(`
735
+ let { tokens } = Lexer_1.Lexer.scan(`
530
736
  function a()
531
737
  if true then 'comment 1
532
738
  'comment 2
@@ -543,25 +749,19 @@ describe('parser', () => {
543
749
  end if 'comment 10
544
750
  end function
545
751
  `);
546
- let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
547
- chai_1.expect(diagnostics).to.be.lengthOf(0, 'Should have zero diagnostics');
548
- let fnSmt = statements[0];
549
- if (reflection_1.isFunctionStatement(fnSmt)) {
752
+ let { ast, diagnostics } = Parser_1.Parser.parse(tokens);
753
+ (0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Should have zero diagnostics');
754
+ let fnSmt = ast.statements[0];
755
+ if ((0, reflection_1.isFunctionStatement)(fnSmt)) {
550
756
  let ifStmt = fnSmt.func.body.statements[0];
551
- if (reflection_1.isIfStatement(ifStmt)) {
552
- expectCommentWithText(ifStmt.thenBranch.statements[0], `'comment 1`);
553
- expectCommentWithText(ifStmt.thenBranch.statements[1], `'comment 2`);
554
- expectCommentWithText(ifStmt.thenBranch.statements[3], `'comment 3`);
757
+ if ((0, reflection_1.isIfStatement)(ifStmt)) {
758
+ expectCommentWithText(ifStmt.thenBranch.statements[0], `'comment 1\n'comment 2`);
555
759
  let elseIfBranch = ifStmt.elseBranch;
556
- if (reflection_1.isIfStatement(elseIfBranch)) {
557
- expectCommentWithText(elseIfBranch.thenBranch.statements[0], `'comment 4`);
558
- expectCommentWithText(elseIfBranch.thenBranch.statements[1], `'comment 5`);
559
- expectCommentWithText(elseIfBranch.thenBranch.statements[3], `'comment 6`);
760
+ if ((0, reflection_1.isIfStatement)(elseIfBranch)) {
761
+ expectCommentWithText(elseIfBranch.thenBranch.statements[0], `'comment 4\n'comment 5`);
560
762
  let elseBranch = elseIfBranch.elseBranch;
561
- if (reflection_1.isBlock(elseBranch)) {
562
- expectCommentWithText(elseBranch.statements[0], `'comment 7`);
563
- expectCommentWithText(elseBranch.statements[1], `'comment 8`);
564
- expectCommentWithText(elseBranch.statements[3], `'comment 9`);
763
+ if ((0, reflection_1.isBlock)(elseBranch)) {
764
+ expectCommentWithText(elseBranch.statements[0], `'comment 7\n'comment 8`);
565
765
  }
566
766
  else {
567
767
  failStatementType(elseBranch, 'Block');
@@ -570,7 +770,6 @@ describe('parser', () => {
570
770
  else {
571
771
  failStatementType(elseIfBranch, 'If');
572
772
  }
573
- expectCommentWithText(fnSmt.func.body.statements[1], `'comment 10`);
574
773
  }
575
774
  else {
576
775
  failStatementType(ifStmt, 'If');
@@ -581,7 +780,7 @@ describe('parser', () => {
581
780
  }
582
781
  });
583
782
  it('while', () => {
584
- let { tokens } = lexer_1.Lexer.scan(`
783
+ let { tokens } = Lexer_1.Lexer.scan(`
585
784
  function a()
586
785
  while true 'comment 1
587
786
  'comment 2
@@ -590,16 +789,13 @@ describe('parser', () => {
590
789
  end while 'comment 4
591
790
  end function
592
791
  `);
593
- let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
594
- chai_1.expect(diagnostics).to.be.lengthOf(0, 'Error count should be zero');
595
- let stmt = statements[0].func.body.statements[0];
596
- chai_1.expect(stmt.body.statements[0].text).to.equal(`'comment 1`);
597
- chai_1.expect(stmt.body.statements[1].text).to.equal(`'comment 2`);
598
- chai_1.expect(stmt.body.statements[3].text).to.equal(`'comment 3`);
599
- chai_1.expect(statements[0].func.body.statements[1].text).to.equal(`'comment 4`);
792
+ let { ast, diagnostics } = Parser_1.Parser.parse(tokens);
793
+ (0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Error count should be zero');
794
+ let stmt = ast.statements[0].func.body.statements[0];
795
+ expectCommentWithText(stmt.body.statements[0], `'comment 1\n'comment 2`);
600
796
  });
601
797
  it('for', () => {
602
- let { tokens } = lexer_1.Lexer.scan(`
798
+ let { tokens } = Lexer_1.Lexer.scan(`
603
799
  function a()
604
800
  for i = 0 to 10 step 1 'comment 1
605
801
  'comment 2
@@ -608,16 +804,13 @@ describe('parser', () => {
608
804
  end for 'comment 4
609
805
  end function
610
806
  `);
611
- let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
612
- chai_1.expect(diagnostics).to.be.lengthOf(0, 'Error count should be zero');
613
- let stmt = statements[0].func.body.statements[0];
614
- chai_1.expect(stmt.body.statements[0].text).to.equal(`'comment 1`);
615
- chai_1.expect(stmt.body.statements[1].text).to.equal(`'comment 2`);
616
- chai_1.expect(stmt.body.statements[3].text).to.equal(`'comment 3`);
617
- chai_1.expect(statements[0].func.body.statements[1].text).to.equal(`'comment 4`);
807
+ let { ast, diagnostics } = Parser_1.Parser.parse(tokens);
808
+ (0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Error count should be zero');
809
+ let stmt = ast.statements[0].func.body.statements[0];
810
+ expectCommentWithText(stmt.body.statements[0], `'comment 1\n'comment 2`);
618
811
  });
619
812
  it('for each', () => {
620
- let { tokens } = lexer_1.Lexer.scan(`
813
+ let { tokens } = Lexer_1.Lexer.scan(`
621
814
  function a()
622
815
  for each val in [1,2,3] 'comment 1
623
816
  'comment 2
@@ -626,13 +819,10 @@ describe('parser', () => {
626
819
  end for 'comment 4
627
820
  end function
628
821
  `);
629
- let { diagnostics, statements } = Parser_1.Parser.parse(tokens);
630
- chai_1.expect(diagnostics).to.be.lengthOf(0, 'Error count should be zero');
631
- let stmt = statements[0].func.body.statements[0];
632
- chai_1.expect(stmt.body.statements[0].text).to.equal(`'comment 1`);
633
- chai_1.expect(stmt.body.statements[1].text).to.equal(`'comment 2`);
634
- chai_1.expect(stmt.body.statements[3].text).to.equal(`'comment 3`);
635
- chai_1.expect(statements[0].func.body.statements[1].text).to.equal(`'comment 4`);
822
+ let { ast, diagnostics } = Parser_1.Parser.parse(tokens);
823
+ (0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(0, 'Error count should be zero');
824
+ let stmt = ast.statements[0].func.body.statements[0];
825
+ expectCommentWithText(stmt.body.statements[0], `'comment 1\n'comment 2`);
636
826
  });
637
827
  });
638
828
  });
@@ -644,7 +834,7 @@ describe('parser', () => {
644
834
  then = true
645
835
  end sub
646
836
  `);
647
- chai_1.expect(diagnostics).to.be.lengthOf(1);
837
+ (0, chai_config_spec_1.expect)(diagnostics).to.be.lengthOf(1);
648
838
  });
649
839
  it('is allowed as an AA property name', () => {
650
840
  var _a;
@@ -657,7 +847,39 @@ describe('parser', () => {
657
847
  print person.then
658
848
  end sub
659
849
  `);
660
- chai_1.expect((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
850
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
851
+ });
852
+ it('allows `mod` as an AA literal property', () => {
853
+ const parser = parse(`
854
+ sub main()
855
+ person = {
856
+ mod: true
857
+ }
858
+ person.mod = false
859
+ print person.mod
860
+ end sub
861
+ `);
862
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(parser);
863
+ });
864
+ it('converts aa literal property TokenKind to Identifier', () => {
865
+ const parser = parse(`
866
+ sub main()
867
+ person = {
868
+ mod: true
869
+ and: true
870
+ }
871
+ end sub
872
+ `);
873
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(parser);
874
+ const elements = [];
875
+ parser.ast.walk((0, visitors_1.createVisitor)({
876
+ AAMemberExpression: (node) => {
877
+ elements.push(node);
878
+ }
879
+ }), {
880
+ walkMode: visitors_1.WalkMode.visitAllRecursive
881
+ });
882
+ (0, chai_config_spec_1.expect)(elements.map(x => x.tokens.key.kind)).to.eql([TokenKind_1.TokenKind.Identifier, TokenKind_1.TokenKind.Identifier]);
661
883
  });
662
884
  });
663
885
  it('"end" is not allowed as a local identifier', () => {
@@ -666,47 +888,47 @@ describe('parser', () => {
666
888
  end = true
667
889
  end sub
668
890
  `);
669
- chai_1.expect(diagnostics).to.be.length.greaterThan(0);
891
+ (0, chai_config_spec_1.expect)(diagnostics).to.be.length.greaterThan(0);
670
892
  });
671
893
  it('none of them can be used as local variables', () => {
672
- let reservedWords = new Set(lexer_1.ReservedWords);
894
+ let reservedWords = new Set(TokenKind_1.ReservedWords);
673
895
  //remove the rem keyword because it's a comment...won't cause error
674
896
  reservedWords.delete('rem');
675
897
  for (let reservedWord of reservedWords) {
676
- let { tokens } = lexer_1.Lexer.scan(`
898
+ let { tokens } = Lexer_1.Lexer.scan(`
677
899
  sub main()
678
900
  ${reservedWord} = true
679
901
  end sub
680
902
  `);
681
903
  let { diagnostics } = Parser_1.Parser.parse(tokens);
682
- chai_1.expect(diagnostics, `assigning to reserved word "${reservedWord}" should have been an error`).to.be.length.greaterThan(0);
904
+ (0, chai_config_spec_1.expect)(diagnostics, `assigning to reserved word "${reservedWord}" should have been an error`).to.be.length.greaterThan(0);
683
905
  }
684
906
  });
685
907
  });
686
908
  describe('import keyword', () => {
687
909
  it('parses without errors', () => {
688
910
  var _a;
689
- let { statements, diagnostics } = parse(`
911
+ let { ast, diagnostics } = parse(`
690
912
  import "somePath"
691
913
  `, Parser_1.ParseMode.BrighterScript);
692
- chai_1.expect((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
693
- chai_1.expect(statements[0]).to.be.instanceof(Statement_1.ImportStatement);
914
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
915
+ (0, chai_config_spec_1.expect)(ast.statements[0]).to.be.instanceof(Statement_1.ImportStatement);
694
916
  });
695
917
  it('catches import statements used in brightscript files', () => {
696
918
  var _a;
697
- let { statements, diagnostics } = parse(`
919
+ let { ast, diagnostics } = parse(`
698
920
  import "somePath"
699
921
  `, Parser_1.ParseMode.BrightScript);
700
- chai_1.expect((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.eql(DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('import statements').message);
701
- chai_1.expect(statements[0]).to.be.instanceof(Statement_1.ImportStatement);
922
+ (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);
923
+ (0, chai_config_spec_1.expect)(ast.statements[0]).to.be.instanceof(Statement_1.ImportStatement);
702
924
  });
703
925
  it('catchs missing file path', () => {
704
926
  var _a;
705
- let { statements, diagnostics } = parse(`
927
+ let { ast, diagnostics } = parse(`
706
928
  import
707
929
  `, Parser_1.ParseMode.BrighterScript);
708
- chai_1.expect((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.expectedStringLiteralAfterKeyword('import').message);
709
- chai_1.expect(statements[0]).to.be.instanceof(Statement_1.ImportStatement);
930
+ (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);
931
+ (0, chai_config_spec_1.expect)(ast.statements[0]).to.be.instanceof(Statement_1.ImportStatement);
710
932
  });
711
933
  });
712
934
  describe('Annotations', () => {
@@ -717,7 +939,7 @@ describe('parser', () => {
717
939
  sub main()
718
940
  end sub
719
941
  `, Parser_1.ParseMode.BrighterScript);
720
- chai_1.expect((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.foundUnexpectedToken('@').message);
942
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.unexpectedToken('@').message);
721
943
  });
722
944
  it('properly handles empty annotation above class method', () => {
723
945
  var _a;
@@ -729,7 +951,7 @@ describe('parser', () => {
729
951
  end sub
730
952
  end class
731
953
  `, Parser_1.ParseMode.BrighterScript);
732
- chai_1.expect((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier().message);
954
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier().message);
733
955
  });
734
956
  it('parses with error if annotation is not followed by a statement', () => {
735
957
  var _a, _b, _c, _d;
@@ -743,15 +965,15 @@ describe('parser', () => {
743
965
  end class
744
966
  @meta1
745
967
  `, Parser_1.ParseMode.BrighterScript);
746
- chai_1.expect(diagnostics.length).to.equal(4);
747
- chai_1.expect((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.unusedAnnotation().message);
748
- chai_1.expect((_b = diagnostics[1]) === null || _b === void 0 ? void 0 : _b.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.unusedAnnotation().message);
749
- chai_1.expect((_c = diagnostics[2]) === null || _c === void 0 ? void 0 : _c.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.unusedAnnotation().message);
750
- chai_1.expect((_d = diagnostics[3]) === null || _d === void 0 ? void 0 : _d.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.unusedAnnotation().message);
968
+ (0, chai_config_spec_1.expect)(diagnostics.length).to.equal(4);
969
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.unusedAnnotation().message);
970
+ (0, chai_config_spec_1.expect)((_b = diagnostics[1]) === null || _b === void 0 ? void 0 : _b.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.unusedAnnotation().message);
971
+ (0, chai_config_spec_1.expect)((_c = diagnostics[2]) === null || _c === void 0 ? void 0 : _c.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.unusedAnnotation().message);
972
+ (0, chai_config_spec_1.expect)((_d = diagnostics[3]) === null || _d === void 0 ? void 0 : _d.message).to.equal(DiagnosticMessages_1.DiagnosticMessages.unusedAnnotation().message);
751
973
  });
752
974
  it('attaches an annotation to next statement', () => {
753
975
  var _a;
754
- let { statements, diagnostics } = parse(`
976
+ let { ast, diagnostics } = parse(`
755
977
  @meta1
756
978
  function main()
757
979
  end function
@@ -759,69 +981,69 @@ describe('parser', () => {
759
981
  @meta2 sub init()
760
982
  end sub
761
983
  `, Parser_1.ParseMode.BrighterScript);
762
- chai_1.expect((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
763
- chai_1.expect(statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
764
- let fn = statements[0];
765
- chai_1.expect(fn.annotations).to.exist;
766
- chai_1.expect(fn.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
767
- chai_1.expect(fn.annotations[0].nameToken.text).to.equal('meta1');
768
- chai_1.expect(fn.annotations[0].name).to.equal('meta1');
769
- chai_1.expect(statements[1]).to.be.instanceof(Statement_1.FunctionStatement);
770
- fn = statements[1];
771
- chai_1.expect(fn.annotations).to.exist;
772
- chai_1.expect(fn.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
773
- chai_1.expect(fn.annotations[0].nameToken.text).to.equal('meta2');
984
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
985
+ (0, chai_config_spec_1.expect)(ast.statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
986
+ let fn = ast.statements[0];
987
+ (0, chai_config_spec_1.expect)(fn.annotations).to.exist;
988
+ (0, chai_config_spec_1.expect)(fn.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
989
+ (0, chai_config_spec_1.expect)(fn.annotations[0].tokens.name.text).to.equal('meta1');
990
+ (0, chai_config_spec_1.expect)(fn.annotations[0].name).to.equal('meta1');
991
+ (0, chai_config_spec_1.expect)(ast.statements[1]).to.be.instanceof(Statement_1.FunctionStatement);
992
+ fn = ast.statements[1];
993
+ (0, chai_config_spec_1.expect)(fn.annotations).to.exist;
994
+ (0, chai_config_spec_1.expect)(fn.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
995
+ (0, chai_config_spec_1.expect)(fn.annotations[0].tokens.name.text).to.equal('meta2');
774
996
  });
775
997
  it('attaches annotations inside a function body', () => {
776
998
  var _a, _b;
777
- let { statements, diagnostics } = parse(`
999
+ let { ast, diagnostics } = parse(`
778
1000
  function main()
779
1001
  @meta1
780
1002
  print "hello"
781
1003
  end function
782
1004
  `, Parser_1.ParseMode.BrighterScript);
783
- chai_1.expect((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
784
- let fn = statements[0];
1005
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
1006
+ let fn = ast.statements[0];
785
1007
  let fnStatements = fn.func.body.statements;
786
1008
  let stat = fnStatements[0];
787
- chai_1.expect(stat).to.exist;
788
- chai_1.expect((_b = stat.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
789
- chai_1.expect(stat.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
1009
+ (0, chai_config_spec_1.expect)(stat).to.exist;
1010
+ (0, chai_config_spec_1.expect)((_b = stat.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
1011
+ (0, chai_config_spec_1.expect)(stat.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
790
1012
  });
791
1013
  it('attaches multiple annotations to next statement', () => {
792
1014
  var _a;
793
- let { statements, diagnostics } = parse(`
1015
+ let { ast, diagnostics } = parse(`
794
1016
  @meta1
795
1017
  @meta2 @meta3
796
1018
  function main()
797
1019
  end function
798
1020
  `, Parser_1.ParseMode.BrighterScript);
799
- chai_1.expect((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
800
- chai_1.expect(statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
801
- let fn = statements[0];
802
- chai_1.expect(fn.annotations).to.exist;
803
- chai_1.expect(fn.annotations.length).to.equal(3);
804
- chai_1.expect(fn.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
805
- chai_1.expect(fn.annotations[1]).to.be.instanceof(Expression_1.AnnotationExpression);
806
- chai_1.expect(fn.annotations[2]).to.be.instanceof(Expression_1.AnnotationExpression);
1021
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
1022
+ (0, chai_config_spec_1.expect)(ast.statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
1023
+ let fn = ast.statements[0];
1024
+ (0, chai_config_spec_1.expect)(fn.annotations).to.exist;
1025
+ (0, chai_config_spec_1.expect)(fn.annotations.length).to.equal(3);
1026
+ (0, chai_config_spec_1.expect)(fn.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
1027
+ (0, chai_config_spec_1.expect)(fn.annotations[1]).to.be.instanceof(Expression_1.AnnotationExpression);
1028
+ (0, chai_config_spec_1.expect)(fn.annotations[2]).to.be.instanceof(Expression_1.AnnotationExpression);
807
1029
  });
808
1030
  it('allows annotations with parameters', () => {
809
1031
  var _a;
810
- let { statements, diagnostics } = parse(`
1032
+ let { ast, diagnostics } = parse(`
811
1033
  @meta1("arg", 2, true, { prop: "value" })
812
1034
  function main()
813
1035
  end function
814
1036
  `, Parser_1.ParseMode.BrighterScript);
815
- chai_1.expect((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
816
- let fn = statements[0];
817
- chai_1.expect(fn.annotations).to.exist;
818
- chai_1.expect(fn.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
819
- chai_1.expect(fn.annotations[0].nameToken.text).to.equal('meta1');
820
- chai_1.expect(fn.annotations[0].call).to.be.instanceof(Expression_1.CallExpression);
1037
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
1038
+ let fn = ast.statements[0];
1039
+ (0, chai_config_spec_1.expect)(fn.annotations).to.exist;
1040
+ (0, chai_config_spec_1.expect)(fn.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
1041
+ (0, chai_config_spec_1.expect)(fn.annotations[0].tokens.name.text).to.equal('meta1');
1042
+ (0, chai_config_spec_1.expect)(fn.annotations[0].call).to.be.instanceof(Expression_1.CallExpression);
821
1043
  });
822
1044
  it('attaches annotations to a class', () => {
823
1045
  var _a, _b;
824
- let { statements, diagnostics } = parse(`
1046
+ let { ast, diagnostics } = parse(`
825
1047
  @meta1
826
1048
  class MyClass
827
1049
  function main()
@@ -829,14 +1051,14 @@ describe('parser', () => {
829
1051
  end function
830
1052
  end class
831
1053
  `, Parser_1.ParseMode.BrighterScript);
832
- chai_1.expect((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
833
- let cs = statements[0];
834
- chai_1.expect((_b = cs.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
835
- chai_1.expect(cs.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
1054
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
1055
+ let cs = ast.statements[0];
1056
+ (0, chai_config_spec_1.expect)((_b = cs.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
1057
+ (0, chai_config_spec_1.expect)(cs.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
836
1058
  });
837
1059
  it('attaches annotations to multiple clases', () => {
838
1060
  var _a, _b, _c;
839
- let { statements, diagnostics } = parse(`
1061
+ let { ast, diagnostics } = parse(`
840
1062
  @meta1
841
1063
  class MyClass
842
1064
  function main()
@@ -850,19 +1072,19 @@ describe('parser', () => {
850
1072
  end function
851
1073
  end class
852
1074
  `, Parser_1.ParseMode.BrighterScript);
853
- chai_1.expect((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
854
- let cs = statements[0];
855
- chai_1.expect((_b = cs.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
856
- chai_1.expect(cs.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
857
- chai_1.expect(cs.annotations[0].name).to.equal('meta1');
858
- let cs2 = statements[1];
859
- chai_1.expect((_c = cs2.annotations) === null || _c === void 0 ? void 0 : _c.length).to.equal(1);
860
- chai_1.expect(cs2.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
861
- chai_1.expect(cs2.annotations[0].name).to.equal('meta2');
1075
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
1076
+ let cs = ast.statements[0];
1077
+ (0, chai_config_spec_1.expect)((_b = cs.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
1078
+ (0, chai_config_spec_1.expect)(cs.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
1079
+ (0, chai_config_spec_1.expect)(cs.annotations[0].name).to.equal('meta1');
1080
+ let cs2 = ast.statements[1];
1081
+ (0, chai_config_spec_1.expect)((_c = cs2.annotations) === null || _c === void 0 ? void 0 : _c.length).to.equal(1);
1082
+ (0, chai_config_spec_1.expect)(cs2.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
1083
+ (0, chai_config_spec_1.expect)(cs2.annotations[0].name).to.equal('meta2');
862
1084
  });
863
1085
  it('attaches annotations to a namespaced class', () => {
864
1086
  var _a, _b;
865
- let { statements, diagnostics } = parse(`
1087
+ let { ast, diagnostics } = parse(`
866
1088
  namespace ns
867
1089
  @meta1
868
1090
  class MyClass
@@ -872,15 +1094,15 @@ describe('parser', () => {
872
1094
  end class
873
1095
  end namespace
874
1096
  `, Parser_1.ParseMode.BrighterScript);
875
- chai_1.expect((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
876
- let ns = statements[0];
1097
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
1098
+ let ns = ast.statements[0];
877
1099
  let cs = ns.body.statements[0];
878
- chai_1.expect((_b = cs.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
879
- chai_1.expect(cs.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
1100
+ (0, chai_config_spec_1.expect)((_b = cs.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
1101
+ (0, chai_config_spec_1.expect)(cs.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
880
1102
  });
881
1103
  it('attaches annotations to a namespaced class - multiple', () => {
882
1104
  var _a, _b, _c;
883
- let { statements, diagnostics } = parse(`
1105
+ let { ast, diagnostics } = parse(`
884
1106
  namespace ns
885
1107
  @meta1
886
1108
  class MyClass
@@ -896,20 +1118,20 @@ describe('parser', () => {
896
1118
  end class
897
1119
  end namespace
898
1120
  `, Parser_1.ParseMode.BrighterScript);
899
- chai_1.expect((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
900
- let ns = statements[0];
1121
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
1122
+ let ns = ast.statements[0];
901
1123
  let cs = ns.body.statements[0];
902
- chai_1.expect((_b = cs.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
903
- chai_1.expect(cs.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
904
- chai_1.expect(cs.annotations[0].name).to.equal('meta1');
1124
+ (0, chai_config_spec_1.expect)((_b = cs.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
1125
+ (0, chai_config_spec_1.expect)(cs.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
1126
+ (0, chai_config_spec_1.expect)(cs.annotations[0].name).to.equal('meta1');
905
1127
  let cs2 = ns.body.statements[1];
906
- chai_1.expect((_c = cs2.annotations) === null || _c === void 0 ? void 0 : _c.length).to.equal(1);
907
- chai_1.expect(cs2.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
908
- chai_1.expect(cs2.annotations[0].name).to.equal('meta2');
1128
+ (0, chai_config_spec_1.expect)((_c = cs2.annotations) === null || _c === void 0 ? void 0 : _c.length).to.equal(1);
1129
+ (0, chai_config_spec_1.expect)(cs2.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
1130
+ (0, chai_config_spec_1.expect)(cs2.annotations[0].name).to.equal('meta2');
909
1131
  });
910
1132
  it('attaches annotations to a class constructor', () => {
911
1133
  var _a, _b;
912
- let { statements, diagnostics } = parse(`
1134
+ let { ast, diagnostics } = parse(`
913
1135
  class MyClass
914
1136
  @meta1
915
1137
  function new()
@@ -920,15 +1142,15 @@ describe('parser', () => {
920
1142
  end function
921
1143
  end class
922
1144
  `, Parser_1.ParseMode.BrighterScript);
923
- chai_1.expect((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
924
- let cs = statements[0];
1145
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
1146
+ let cs = ast.statements[0];
925
1147
  let stat = cs.body[0];
926
- chai_1.expect((_b = stat.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
927
- chai_1.expect(stat.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
1148
+ (0, chai_config_spec_1.expect)((_b = stat.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
1149
+ (0, chai_config_spec_1.expect)(stat.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
928
1150
  });
929
1151
  it('attaches annotations to a class methods', () => {
930
1152
  var _a, _b;
931
- let { statements, diagnostics } = parse(`
1153
+ let { ast, diagnostics } = parse(`
932
1154
  class MyClass
933
1155
  function new()
934
1156
  print "hello"
@@ -939,15 +1161,15 @@ describe('parser', () => {
939
1161
  end function
940
1162
  end class
941
1163
  `, Parser_1.ParseMode.BrighterScript);
942
- chai_1.expect((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
943
- let cs = statements[0];
1164
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
1165
+ let cs = ast.statements[0];
944
1166
  let stat = cs.body[1];
945
- chai_1.expect((_b = stat.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
946
- chai_1.expect(stat.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
1167
+ (0, chai_config_spec_1.expect)((_b = stat.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
1168
+ (0, chai_config_spec_1.expect)(stat.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
947
1169
  });
948
1170
  it('attaches annotations to a class methods, fields and constructor', () => {
949
1171
  var _a, _b, _c, _d, _e;
950
- let { statements, diagnostics } = parse(`
1172
+ let { ast, diagnostics } = parse(`
951
1173
  @meta2
952
1174
  @meta1
953
1175
  class MyClass
@@ -967,36 +1189,36 @@ describe('parser', () => {
967
1189
  public foo="bar"
968
1190
  end class
969
1191
  `, Parser_1.ParseMode.BrighterScript);
970
- chai_1.expect((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
971
- let cs = statements[0];
972
- chai_1.expect((_b = cs.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(2);
973
- chai_1.expect(cs.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
1192
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
1193
+ let cs = ast.statements[0];
1194
+ (0, chai_config_spec_1.expect)((_b = cs.annotations) === null || _b === void 0 ? void 0 : _b.length).to.equal(2);
1195
+ (0, chai_config_spec_1.expect)(cs.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
974
1196
  let stat1 = cs.body[0];
975
1197
  let stat2 = cs.body[1];
976
1198
  let f1 = cs.body[2];
977
- chai_1.expect((_c = stat1.annotations) === null || _c === void 0 ? void 0 : _c.length).to.equal(2);
978
- chai_1.expect(stat1.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
979
- chai_1.expect((_d = stat2.annotations) === null || _d === void 0 ? void 0 : _d.length).to.equal(2);
980
- chai_1.expect(stat2.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
981
- chai_1.expect((_e = f1.annotations) === null || _e === void 0 ? void 0 : _e.length).to.equal(2);
982
- chai_1.expect(f1.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
1199
+ (0, chai_config_spec_1.expect)((_c = stat1.annotations) === null || _c === void 0 ? void 0 : _c.length).to.equal(2);
1200
+ (0, chai_config_spec_1.expect)(stat1.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
1201
+ (0, chai_config_spec_1.expect)((_d = stat2.annotations) === null || _d === void 0 ? void 0 : _d.length).to.equal(2);
1202
+ (0, chai_config_spec_1.expect)(stat2.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
1203
+ (0, chai_config_spec_1.expect)((_e = f1.annotations) === null || _e === void 0 ? void 0 : _e.length).to.equal(2);
1204
+ (0, chai_config_spec_1.expect)(f1.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
983
1205
  });
984
1206
  it('ignores annotations on commented out lines', () => {
985
1207
  var _a;
986
- let { statements, diagnostics } = parse(`
1208
+ let { ast, diagnostics } = parse(`
987
1209
  '@meta1
988
1210
  ' @meta1
989
1211
  function new()
990
1212
  print "hello"
991
1213
  end function
992
1214
  `, Parser_1.ParseMode.BrighterScript);
993
- chai_1.expect((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
994
- let cs = statements[0];
995
- chai_1.expect(cs.annotations).to.be.undefined;
1215
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
1216
+ let cs = ast.statements[0];
1217
+ (0, chai_config_spec_1.expect)(cs.annotations).to.be.undefined;
996
1218
  });
997
1219
  it('can convert argument of an annotation to JS types', () => {
998
1220
  var _a;
999
- let { statements, diagnostics } = parse(`
1221
+ let { ast, diagnostics } = parse(`
1000
1222
  @meta1
1001
1223
  function main()
1002
1224
  end function
@@ -1010,26 +1232,26 @@ describe('parser', () => {
1010
1232
  sub init()
1011
1233
  end sub
1012
1234
  `, Parser_1.ParseMode.BrighterScript);
1013
- chai_1.expect((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
1014
- chai_1.expect(statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
1015
- let fn = statements[0];
1016
- chai_1.expect(fn.annotations).to.exist;
1017
- chai_1.expect(fn.annotations[0].getArguments()).to.deep.equal([]);
1018
- chai_1.expect(statements[1]).to.be.instanceof(Statement_1.FunctionStatement);
1019
- fn = statements[1];
1020
- chai_1.expect(fn.annotations).to.exist;
1021
- chai_1.expect(fn.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
1022
- chai_1.expect(fn.annotations[0].getArguments()).to.deep.equal([
1235
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
1236
+ (0, chai_config_spec_1.expect)(ast.statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
1237
+ let fn = ast.statements[0];
1238
+ (0, chai_config_spec_1.expect)(fn.annotations).to.exist;
1239
+ (0, chai_config_spec_1.expect)(fn.annotations[0].getArguments()).to.deep.equal([]);
1240
+ (0, chai_config_spec_1.expect)(ast.statements[1]).to.be.instanceof(Statement_1.FunctionStatement);
1241
+ fn = ast.statements[1];
1242
+ (0, chai_config_spec_1.expect)(fn.annotations).to.exist;
1243
+ (0, chai_config_spec_1.expect)(fn.annotations[0]).to.be.instanceof(Expression_1.AnnotationExpression);
1244
+ (0, chai_config_spec_1.expect)(fn.annotations[0].getArguments()).to.deep.equal([
1023
1245
  'arg', 2, true,
1024
1246
  { prop: 'value' }, [1, 2],
1025
1247
  null
1026
1248
  ]);
1027
1249
  let allArgs = fn.annotations[0].getArguments(false);
1028
- chai_1.expect(allArgs.pop()).to.be.instanceOf(Expression_1.FunctionExpression);
1250
+ (0, chai_config_spec_1.expect)(allArgs.pop()).to.be.instanceOf(Expression_1.FunctionExpression);
1029
1251
  });
1030
1252
  it('can handle negative numbers', () => {
1031
1253
  var _a;
1032
- let { statements, diagnostics } = parse(`
1254
+ let { ast, diagnostics } = parse(`
1033
1255
  @meta(-100)
1034
1256
  function main()
1035
1257
  end function
@@ -1037,161 +1259,1523 @@ describe('parser', () => {
1037
1259
  sub init()
1038
1260
  end sub
1039
1261
  `, Parser_1.ParseMode.BrighterScript);
1040
- chai_1.expect((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
1041
- chai_1.expect(statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
1042
- let fn = statements[0];
1043
- chai_1.expect(fn.annotations).to.exist;
1044
- chai_1.expect(fn.annotations[0].getArguments()).to.deep.equal([-100]);
1262
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
1263
+ (0, chai_config_spec_1.expect)(ast.statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
1264
+ let fn = ast.statements[0];
1265
+ (0, chai_config_spec_1.expect)(fn.annotations).to.exist;
1266
+ (0, chai_config_spec_1.expect)(fn.annotations[0].getArguments()).to.deep.equal([-100]);
1045
1267
  });
1046
1268
  });
1047
- describe('getBscTypeFromExpression', () => {
1048
- it('computes void type for sub with no return type', () => {
1049
- const parser = parse(`
1050
- sub main()
1051
- getMessage = sub()
1052
- print "hello"
1053
- end sub
1269
+ describe('type casts', () => {
1270
+ it('is not allowed in brightscript mode', () => {
1271
+ var _a;
1272
+ let parser = parse(`
1273
+ sub main(node as dynamic)
1274
+ print lcase((node as string))
1054
1275
  end sub
1055
- `);
1056
- const func = parser.ast.statements[0].func;
1057
- const type = Parser_1.getBscTypeFromExpression(func.body.statements[0].value, func);
1058
- chai_1.expect(type.returnType).to.be.instanceof(VoidType_1.VoidType);
1276
+ `, Parser_1.ParseMode.BrightScript);
1277
+ (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);
1059
1278
  });
1060
- it('computes return type for sub with explicit return type', () => {
1061
- const parser = parse(`
1279
+ it('allows type casts after function calls', () => {
1280
+ var _a;
1281
+ let { ast, diagnostics } = parse(`
1062
1282
  sub main()
1063
- getMessage = sub() as string
1064
- return "hello"
1065
- end sub
1283
+ value = getValue() as integer
1066
1284
  end sub
1067
- `);
1068
- const func = parser.ast.statements[0].func;
1069
- const type = Parser_1.getBscTypeFromExpression(func.body.statements[0].value, func);
1070
- chai_1.expect(type.returnType).to.be.instanceof(StringType_1.StringType);
1285
+
1286
+ function getValue()
1287
+ return 123
1288
+ end function
1289
+ `, Parser_1.ParseMode.BrighterScript);
1290
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
1291
+ (0, chai_config_spec_1.expect)(ast.statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
1292
+ let fn = ast.statements[0];
1293
+ (0, chai_config_spec_1.expect)(fn.func.body.statements).to.exist;
1294
+ let assignment = fn.func.body.statements[0];
1295
+ (0, chai_config_spec_1.expect)((0, reflection_1.isAssignmentStatement)(assignment)).to.be.true;
1296
+ (0, chai_config_spec_1.expect)((0, reflection_1.isTypecastExpression)(assignment.value)).to.be.true;
1297
+ (0, chai_config_spec_1.expect)((0, reflection_1.isCallExpression)(assignment.value.obj)).to.be.true;
1298
+ (0, testHelpers_spec_1.expectTypeToBe)(assignment.getType({ flags: 2 /* SymbolTypeFlag.typetime */ }), IntegerType_1.IntegerType);
1071
1299
  });
1072
- it('supports sub with custom return type', () => {
1073
- const parser = parse(`
1300
+ it('allows type casts in the middle of expressions', () => {
1301
+ var _a;
1302
+ let { ast, diagnostics } = parse(`
1074
1303
  sub main()
1075
- getPerson = sub() as Person
1076
- return new Person()
1077
- end sub
1304
+ value = (getValue() as integer).toStr()
1078
1305
  end sub
1079
1306
 
1080
- class Person
1081
- end class
1307
+ function getValue()
1308
+ return 123
1309
+ end function
1082
1310
  `, Parser_1.ParseMode.BrighterScript);
1083
- testHelpers_spec_1.expectZeroDiagnostics(parser.diagnostics);
1084
- const func = parser.ast.statements[0].func;
1085
- const type = Parser_1.getBscTypeFromExpression(func.body.statements[0].value, func);
1086
- chai_1.expect(type.returnType).to.be.instanceof(CustomType_1.CustomType);
1311
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
1312
+ (0, chai_config_spec_1.expect)(ast.statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
1313
+ let fn = ast.statements[0];
1314
+ (0, chai_config_spec_1.expect)(fn.func.body.statements).to.exist;
1315
+ let assignment = fn.func.body.statements[0];
1316
+ (0, chai_config_spec_1.expect)((0, reflection_1.isAssignmentStatement)(assignment)).to.be.true;
1317
+ (0, chai_config_spec_1.expect)((0, reflection_1.isCallExpression)(assignment.value)).to.be.true;
1318
+ (0, chai_config_spec_1.expect)((0, reflection_1.isDottedGetExpression)(assignment.value.callee)).to.be.true;
1319
+ (0, chai_config_spec_1.expect)((0, reflection_1.isGroupingExpression)(assignment.value.callee.obj)).to.be.true;
1320
+ (0, chai_config_spec_1.expect)((0, reflection_1.isTypecastExpression)(assignment.value.callee.obj.expression)).to.be.true;
1321
+ //grouping expression is an integer
1322
+ (0, testHelpers_spec_1.expectTypeToBe)(assignment.value.callee.obj.getType({ flags: 2 /* SymbolTypeFlag.typetime */ }), IntegerType_1.IntegerType);
1087
1323
  });
1088
- });
1089
- describe('symbolTable', () => {
1090
- it('stores the types', () => {
1091
- const parser = parse(`
1324
+ it('allows type casts in a function call', () => {
1325
+ var _a;
1326
+ let { ast, diagnostics } = parse(`
1092
1327
  sub main()
1093
- someNum = 123
1094
- someString = "hello world"
1095
- someObj = {foo: "bar"}
1096
- someCustom = new CustomKlass()
1328
+ print cos(getAngle() as float)
1097
1329
  end sub
1098
1330
 
1099
- class CustomKlass
1100
- end class
1331
+ function getAngle()
1332
+ return 123
1333
+ end function
1101
1334
  `, Parser_1.ParseMode.BrighterScript);
1102
- testHelpers_spec_1.expectZeroDiagnostics(parser.diagnostics);
1103
- const mainSymbolTable = parser.references.functionExpressions[0].symbolTable;
1104
- chai_1.expect(mainSymbolTable.getSymbolType('someNum')).to.be.instanceof(IntegerType_1.IntegerType);
1105
- chai_1.expect(mainSymbolTable.getSymbolType('someString')).to.be.instanceof(StringType_1.StringType);
1106
- chai_1.expect(mainSymbolTable.getSymbolType('someObj')).to.be.instanceof(ObjectType_1.ObjectType);
1107
- chai_1.expect(mainSymbolTable.getSymbolType('someCustom')).to.be.instanceof(CustomType_1.CustomType);
1335
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
1336
+ (0, chai_config_spec_1.expect)(ast.statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
1337
+ let fn = ast.statements[0];
1338
+ (0, chai_config_spec_1.expect)(fn.func.body.statements).to.exist;
1339
+ let print = fn.func.body.statements[0];
1340
+ (0, chai_config_spec_1.expect)((0, reflection_1.isPrintStatement)(print)).to.be.true;
1341
+ (0, chai_config_spec_1.expect)((0, reflection_1.isCallExpression)(print.expressions[0])).to.be.true;
1342
+ let fnCall = print.expressions[0];
1343
+ (0, chai_config_spec_1.expect)((0, reflection_1.isTypecastExpression)(fnCall.args[0])).to.be.true;
1344
+ let arg = fnCall.args[0];
1345
+ //argument type is float
1346
+ (0, testHelpers_spec_1.expectTypeToBe)(arg.getType({ flags: 2 /* SymbolTypeFlag.typetime */ }), FloatType_1.FloatType);
1108
1347
  });
1109
- it('stores typed parameters in functions', () => {
1110
- const parser = parse(`
1111
- sub someFunc(param1 as string, param2 as integer)
1112
- temp = param2
1348
+ it('allows multiple type casts', () => {
1349
+ var _a;
1350
+ let { ast, diagnostics } = parse(`
1351
+ sub main()
1352
+ print getData() as dynamic as float as string
1113
1353
  end sub
1114
1354
  `, Parser_1.ParseMode.BrighterScript);
1115
- testHelpers_spec_1.expectZeroDiagnostics(parser.diagnostics);
1116
- const someFuncSymbolTable = parser.references.functionExpressions[0].symbolTable;
1117
- chai_1.expect(someFuncSymbolTable.getSymbolType('param1')).to.be.instanceof(StringType_1.StringType);
1118
- chai_1.expect(someFuncSymbolTable.getSymbolType('param2')).to.be.instanceof(IntegerType_1.IntegerType);
1119
- chai_1.expect(someFuncSymbolTable.getSymbolType('temp')).to.be.instanceof(IntegerType_1.IntegerType);
1355
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist;
1356
+ (0, chai_config_spec_1.expect)(ast.statements[0]).to.be.instanceof(Statement_1.FunctionStatement);
1357
+ let fn = ast.statements[0];
1358
+ (0, chai_config_spec_1.expect)(fn.func.body.statements).to.exist;
1359
+ let print = fn.func.body.statements[0];
1360
+ (0, chai_config_spec_1.expect)((0, reflection_1.isPrintStatement)(print)).to.be.true;
1361
+ (0, chai_config_spec_1.expect)((0, reflection_1.isTypecastExpression)(print.expressions[0])).to.be.true;
1362
+ //argument type is float
1363
+ (0, testHelpers_spec_1.expectTypeToBe)(print.expressions[0].getType({ flags: 2 /* SymbolTypeFlag.typetime */ }), StringType_1.StringType);
1120
1364
  });
1121
- it('properly defers typing lazy types', () => {
1122
- const parser = parse(`
1123
- sub someFunc()
1124
- temp = foo()
1365
+ it('flags invalid type cast syntax - multiple as', () => {
1366
+ var _a;
1367
+ let { diagnostics } = parse(`
1368
+ sub foo(key)
1369
+ getData(key as as string)
1125
1370
  end sub
1126
-
1127
- function foo() as string
1128
- return "foo"
1129
- end function
1130
1371
  `, Parser_1.ParseMode.BrighterScript);
1131
- testHelpers_spec_1.expectZeroDiagnostics(parser.diagnostics);
1132
- const someFuncSymbolTable = parser.references.functionExpressions[0].symbolTable;
1133
- chai_1.expect(someFuncSymbolTable.getSymbolType('temp')).to.be.instanceof(LazyType_1.LazyType);
1134
- chai_1.expect(someFuncSymbolTable.getSymbolType('temp').toTypeString()).to.eq('string');
1372
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.exist;
1135
1373
  });
1136
- it('does not know about symbols declared in parent functions', () => {
1137
- const parser = parse(`
1138
- sub main()
1139
- count = 0
1140
- addOne = sub()
1141
- oldVal = count
1142
- end sub
1374
+ it('flags invalid type cast syntax - no type after as', () => {
1375
+ var _a;
1376
+ let { diagnostics } = parse(`
1377
+ sub foo(key)
1378
+ getData(key as)
1143
1379
  end sub
1144
1380
  `, Parser_1.ParseMode.BrighterScript);
1145
- testHelpers_spec_1.expectZeroDiagnostics(parser.diagnostics);
1146
- const addOneSymbolTable = parser.references.functionExpressions[0].childFunctionExpressions[0].symbolTable;
1147
- chai_1.expect(addOneSymbolTable.getSymbolType('oldVal').toString()).to.eq('uninitialized');
1381
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.exist;
1148
1382
  });
1149
- it('finds params', () => {
1150
- const parser = parse(`
1151
- sub alert(p1, p2 as string, p3 = 1)
1383
+ it('allows declaring types on assignment in Brighterscript mode', () => {
1384
+ let { diagnostics } = parse(`
1385
+ sub foo()
1386
+ x as string = formatJson("some string")
1152
1387
  end sub
1153
1388
  `, Parser_1.ParseMode.BrighterScript);
1154
- testHelpers_spec_1.expectZeroDiagnostics(parser.diagnostics);
1155
- testHelpers_spec_1.expectSymbolTableEquals(parser.references.functionExpressions[0].symbolTable, [
1156
- ['p1', new DynamicType_1.DynamicType(), util_1.default.createRange(1, 26, 1, 28)],
1157
- ['p2', new StringType_1.StringType(), util_1.default.createRange(1, 30, 1, 32)],
1158
- ['p3', new IntegerType_1.IntegerType(), util_1.default.createRange(1, 44, 1, 46)]
1159
- ]);
1389
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1160
1390
  });
1161
- describe('loops', () => {
1162
- it('stores the loop variable in a for loop', () => {
1163
- const parser = parse(`
1164
- sub main()
1165
- for i = 0 to 10 step 10
1166
- print i
1167
- end for
1391
+ it('does not allow declaring types on assignment in brightscript mode', () => {
1392
+ var _a, _b;
1393
+ let { diagnostics } = parse(`
1394
+ sub foo()
1395
+ x as string = formatJson("some string")
1168
1396
  end sub
1169
- `, Parser_1.ParseMode.BrighterScript);
1170
- testHelpers_spec_1.expectZeroDiagnostics(parser.diagnostics);
1171
- const currentSymbolTable = parser.references.functionExpressions[0].symbolTable;
1172
- chai_1.expect(currentSymbolTable.getSymbolType('i').toString()).to.eq('integer');
1173
- });
1174
- it('stores the loop variable in a for each loop', () => {
1175
- const parser = parse(`
1176
- sub doLoop(someData)
1177
- for each datum in someData
1178
- print datum
1179
- end for
1397
+ `, Parser_1.ParseMode.BrightScript);
1398
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.exist;
1399
+ (0, chai_config_spec_1.expect)((_b = diagnostics[0]) === null || _b === void 0 ? void 0 : _b.message).to.include('typed assignment');
1400
+ });
1401
+ });
1402
+ describe('grouped type expressions', () => {
1403
+ it('is not allowed in brightscript mode', () => {
1404
+ let parser = parse(`
1405
+ sub main(param as (string or integer))
1406
+ print param
1180
1407
  end sub
1181
- `, Parser_1.ParseMode.BrighterScript);
1182
- testHelpers_spec_1.expectZeroDiagnostics(parser.diagnostics);
1183
- const currentSymbolTable = parser.references.functionExpressions[0].symbolTable;
1184
- chai_1.expect(currentSymbolTable.getSymbolType('datum').toString()).to.eq('dynamic');
1185
- });
1408
+ `, Parser_1.ParseMode.BrightScript);
1409
+ (0, testHelpers_spec_1.expectDiagnosticsIncludes)(parser.diagnostics, [DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('custom types')]);
1410
+ });
1411
+ it('allows group type expressions in parameters', () => {
1412
+ let { diagnostics } = parse(`
1413
+ sub main(param as (string or integer))
1414
+ print param
1415
+ end sub
1416
+ `, Parser_1.ParseMode.BrighterScript);
1417
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1418
+ });
1419
+ it('allows group type expressions in type casts', () => {
1420
+ let { diagnostics } = parse(`
1421
+ sub main(val)
1422
+ printThing(val as (string or integer))
1423
+ end sub
1424
+ sub printThing(thing as (string or integer))
1425
+ print thing
1426
+ end sub
1427
+ `, Parser_1.ParseMode.BrighterScript);
1428
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1429
+ });
1430
+ it('allows union of grouped type expressions', () => {
1431
+ let { diagnostics } = parse(`
1432
+ sub main(param as (string or integer) or (float or dynamic))
1433
+ print param
1434
+ end sub
1435
+ `, Parser_1.ParseMode.BrighterScript);
1436
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1437
+ });
1438
+ it('allows nested grouped type expressions', () => {
1439
+ let { diagnostics } = parse(`
1440
+ sub main(param as ((string or integer) or (float or dynamic)))
1441
+ print param
1442
+ end sub
1443
+ `, Parser_1.ParseMode.BrighterScript);
1444
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1445
+ });
1446
+ it('allows complicated grouped type expression', () => {
1447
+ let { diagnostics } = parse(`
1448
+ sub main(param as (({name as string} and {age as integer}) or (string and SomeInterface) or Klass and roAssociativeArray) )
1449
+ print param
1450
+ end sub
1451
+ `, Parser_1.ParseMode.BrighterScript);
1452
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1186
1453
  });
1187
1454
  });
1188
- });
1189
- function parse(text, mode) {
1190
- let { tokens } = lexer_1.Lexer.scan(text);
1455
+ describe('union types', () => {
1456
+ it('is not allowed in brightscript mode', () => {
1457
+ let parser = parse(`
1458
+ sub main(param as string or integer)
1459
+ print param
1460
+ end sub
1461
+ `, Parser_1.ParseMode.BrightScript);
1462
+ (0, testHelpers_spec_1.expectDiagnosticsIncludes)(parser.diagnostics, [DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('custom types')]);
1463
+ });
1464
+ it('allows union types in parameters', () => {
1465
+ let { diagnostics } = parse(`
1466
+ sub main(param as string or integer)
1467
+ print param
1468
+ end sub
1469
+ `, Parser_1.ParseMode.BrighterScript);
1470
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1471
+ });
1472
+ it('allows union types in type casts', () => {
1473
+ let { diagnostics } = parse(`
1474
+ sub main(val)
1475
+ printThing(val as string or integer)
1476
+ end sub
1477
+ sub printThing(thing as string or integer)
1478
+ print thing
1479
+ end sub
1480
+ `, Parser_1.ParseMode.BrighterScript);
1481
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1482
+ });
1483
+ });
1484
+ describe('intersection types', () => {
1485
+ it('is not allowed in brightscript mode', () => {
1486
+ let parser = parse(`
1487
+ sub main(param as string and integer)
1488
+ print param
1489
+ end sub
1490
+ `, Parser_1.ParseMode.BrightScript);
1491
+ (0, testHelpers_spec_1.expectDiagnosticsIncludes)(parser.diagnostics, [DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('custom types')]);
1492
+ });
1493
+ it('allows intersection types in parameters', () => {
1494
+ let { diagnostics } = parse(`
1495
+ sub main(param as string and integer)
1496
+ print param
1497
+ end sub
1498
+ `, Parser_1.ParseMode.BrighterScript);
1499
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1500
+ });
1501
+ it('allows intersection types in type casts', () => {
1502
+ let { diagnostics } = parse(`
1503
+ sub main(val)
1504
+ printThing(val as string and integer)
1505
+ end sub
1506
+ sub printThing(thing as string and integer)
1507
+ print thing
1508
+ end sub
1509
+ `, Parser_1.ParseMode.BrighterScript);
1510
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1511
+ });
1512
+ it('follows order of operations with "or" first lexically', () => {
1513
+ let { ast, diagnostics } = parse(`
1514
+ sub main(param as string or integer and float)
1515
+ print param
1516
+ end sub
1517
+ `, Parser_1.ParseMode.BrighterScript);
1518
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1519
+ const func = ast.statements[0].func;
1520
+ const paramExpr = func.parameters[0];
1521
+ let binExpr = paramExpr.typeExpression.expression;
1522
+ //first level should be 'or'
1523
+ (0, chai_config_spec_1.expect)(binExpr.tokens.operator.kind).to.equal(TokenKind_1.TokenKind.Or);
1524
+ //right side should be 'and'
1525
+ (0, chai_config_spec_1.expect)((0, reflection_1.isBinaryExpression)(binExpr.right)).to.be.true;
1526
+ const rightAndExpr = binExpr.right;
1527
+ (0, chai_config_spec_1.expect)(rightAndExpr.tokens.operator.kind).to.equal(TokenKind_1.TokenKind.And);
1528
+ });
1529
+ it('follows order of operations with "and" first lexically', () => {
1530
+ let { ast, diagnostics } = parse(`
1531
+ sub main(param as string and integer or float)
1532
+ print param
1533
+ end sub
1534
+ `, Parser_1.ParseMode.BrighterScript);
1535
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1536
+ const func = ast.statements[0].func;
1537
+ const paramExpr = func.parameters[0];
1538
+ let binExpr = paramExpr.typeExpression.expression;
1539
+ //first level should be 'or'
1540
+ (0, chai_config_spec_1.expect)(binExpr.tokens.operator.kind).to.equal(TokenKind_1.TokenKind.Or);
1541
+ //left side should be 'and'
1542
+ (0, chai_config_spec_1.expect)((0, reflection_1.isBinaryExpression)(binExpr.left)).to.be.true;
1543
+ const leftAndExpr = binExpr.left;
1544
+ (0, chai_config_spec_1.expect)(leftAndExpr.tokens.operator.kind).to.equal(TokenKind_1.TokenKind.And);
1545
+ });
1546
+ it('allows grouped expression to override order of operations', () => {
1547
+ let { ast, diagnostics } = parse(`
1548
+ sub main(param as string and (integer or float))
1549
+ print param
1550
+ end sub
1551
+ `, Parser_1.ParseMode.BrighterScript);
1552
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1553
+ const func = ast.statements[0].func;
1554
+ const paramExpr = func.parameters[0];
1555
+ let binExpr = paramExpr.typeExpression.expression;
1556
+ //first level should be 'and'
1557
+ (0, chai_config_spec_1.expect)(binExpr.tokens.operator.kind).to.equal(TokenKind_1.TokenKind.And);
1558
+ //right side should be 'or'
1559
+ (0, chai_config_spec_1.expect)((0, reflection_1.isGroupingExpression)(binExpr.right)).to.be.true;
1560
+ const groupedExpr = binExpr.right;
1561
+ (0, chai_config_spec_1.expect)((0, reflection_1.isGroupingExpression)(groupedExpr)).to.be.true;
1562
+ (0, chai_config_spec_1.expect)((0, reflection_1.isTypeExpression)(groupedExpr.expression)).to.be.true;
1563
+ const rightOrExpr = groupedExpr.expression.expression;
1564
+ (0, chai_config_spec_1.expect)(rightOrExpr.tokens.operator.kind).to.equal(TokenKind_1.TokenKind.Or);
1565
+ });
1566
+ describe('invalid syntax', () => {
1567
+ it('flags union type with missing sides', () => {
1568
+ let { diagnostics } = parse(`
1569
+ sub main(param as Thing or )
1570
+ print param
1571
+ end sub
1572
+ `, Parser_1.ParseMode.BrighterScript);
1573
+ (0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier('or').message);
1574
+ });
1575
+ it('flags missing type inside binary type', () => {
1576
+ var _a;
1577
+ let { diagnostics } = parse(`
1578
+ sub main(param as string or and float)
1579
+ print param
1580
+ end sub
1581
+ `, Parser_1.ParseMode.BrighterScript);
1582
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.exist;
1583
+ });
1584
+ it('flags missing group paren', () => {
1585
+ var _a;
1586
+ let { diagnostics } = parse(`
1587
+ sub main(param as (string or float)
1588
+ print param
1589
+ end sub
1590
+ `, Parser_1.ParseMode.BrighterScript);
1591
+ (0, chai_config_spec_1.expect)((_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.message).to.exist;
1592
+ });
1593
+ });
1594
+ });
1595
+ describe('typed arrays', () => {
1596
+ it('is not allowed in brightscript mode', () => {
1597
+ let parser = parse(`
1598
+ sub main(things as string[])
1599
+ print things
1600
+ end sub
1601
+ `, Parser_1.ParseMode.BrightScript);
1602
+ (0, testHelpers_spec_1.expectDiagnosticsIncludes)(parser.diagnostics, [DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('typed arrays')]);
1603
+ });
1604
+ it('is allowed in brighterscript mode', () => {
1605
+ let { ast, diagnostics } = parse(`
1606
+ sub main(things as string[])
1607
+ print things
1608
+ end sub
1609
+ `, Parser_1.ParseMode.BrighterScript);
1610
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1611
+ const paramType = ast.statements[0].func.parameters[0].getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
1612
+ (0, testHelpers_spec_1.expectTypeToBe)(paramType, types_1.ArrayType);
1613
+ (0, testHelpers_spec_1.expectTypeToBe)(paramType.defaultType, StringType_1.StringType);
1614
+ });
1615
+ it('allows multi dimensional arrays', () => {
1616
+ let { ast, diagnostics } = parse(`
1617
+ sub main(things as string[][])
1618
+ print things
1619
+ end sub
1620
+ `, Parser_1.ParseMode.BrighterScript);
1621
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1622
+ const paramType = ast.statements[0].func.parameters[0].getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
1623
+ (0, testHelpers_spec_1.expectTypeToBe)(paramType, types_1.ArrayType);
1624
+ (0, testHelpers_spec_1.expectTypeToBe)(paramType.defaultType, types_1.ArrayType);
1625
+ (0, testHelpers_spec_1.expectTypeToBe)(paramType.defaultType.defaultType, StringType_1.StringType);
1626
+ });
1627
+ it('allows arrays as return types', () => {
1628
+ let { ast, diagnostics } = parse(`
1629
+ function getFourPrimes() as integer[]
1630
+ return [2, 3, 5, 7]
1631
+ end function
1632
+ `, Parser_1.ParseMode.BrighterScript);
1633
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1634
+ const paramType = ast.statements[0].func.returnTypeExpression.getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
1635
+ (0, testHelpers_spec_1.expectTypeToBe)(paramType, types_1.ArrayType);
1636
+ (0, testHelpers_spec_1.expectTypeToBe)(paramType.defaultType, IntegerType_1.IntegerType);
1637
+ });
1638
+ it('allows arrays in union types', () => {
1639
+ let { ast, diagnostics } = parse(`
1640
+ sub foo(x as integer or integer[] or string or string[])
1641
+ print x
1642
+ end sub
1643
+ `, Parser_1.ParseMode.BrighterScript);
1644
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1645
+ const paramType = ast.statements[0].func.parameters[0].getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
1646
+ (0, testHelpers_spec_1.expectTypeToBe)(paramType, types_1.UnionType);
1647
+ (0, chai_config_spec_1.expect)(paramType.toString().includes('Array<string>')).to.be.true;
1648
+ (0, chai_config_spec_1.expect)(paramType.toString().includes('Array<integer>')).to.be.true;
1649
+ });
1650
+ });
1651
+ describe('interfaces', () => {
1652
+ it('allows fields and methods', () => {
1653
+ let { ast, diagnostics } = parse(`
1654
+ interface SomeIFace
1655
+ name as string
1656
+ height as integer
1657
+ function getValue(thing as float) as object
1658
+ function getMe() as SomeIFace
1659
+ sub noop()
1660
+ end interface
1661
+ `, Parser_1.ParseMode.BrighterScript);
1662
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1663
+ (0, chai_config_spec_1.expect)(ast.statements.length).to.eq(1);
1664
+ (0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(ast.statements[0])).to.be.true;
1665
+ });
1666
+ it('allows untyped fields', () => {
1667
+ let { ast, diagnostics } = parse(`
1668
+ interface HasUntyped
1669
+ name
1670
+ end interface
1671
+ `, Parser_1.ParseMode.BrighterScript);
1672
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1673
+ (0, chai_config_spec_1.expect)(ast.statements.length).to.eq(1);
1674
+ (0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(ast.statements[0])).to.be.true;
1675
+ });
1676
+ it('allows optional fields', () => {
1677
+ let { ast, diagnostics } = parse(`
1678
+ interface HasOptional
1679
+ optional name as string
1680
+ optional height
1681
+ end interface
1682
+ `, Parser_1.ParseMode.BrighterScript);
1683
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1684
+ (0, chai_config_spec_1.expect)(ast.statements.length).to.eq(1);
1685
+ (0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(ast.statements[0])).to.be.true;
1686
+ const iface = ast.statements[0];
1687
+ iface.fields.forEach(f => (0, chai_config_spec_1.expect)(f.isOptional).to.be.true);
1688
+ const ifaceType = iface.getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
1689
+ // eslint-disable-next-line no-bitwise
1690
+ ifaceType.getMemberTable().getAllSymbols(1 /* SymbolTypeFlag.runtime */).forEach(sym => (0, chai_config_spec_1.expect)(sym.flags & 4 /* SymbolTypeFlag.optional */).to.eq(4 /* SymbolTypeFlag.optional */));
1691
+ });
1692
+ it('allows fields named optional', () => {
1693
+ let { ast, diagnostics } = parse(`
1694
+ interface IsJustOptional
1695
+ optional
1696
+ someThingElse
1697
+ end interface
1698
+ `, Parser_1.ParseMode.BrighterScript);
1699
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1700
+ (0, chai_config_spec_1.expect)(ast.statements.length).to.eq(1);
1701
+ (0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(ast.statements[0])).to.be.true;
1702
+ const iface = ast.statements[0];
1703
+ iface.fields.forEach(f => (0, chai_config_spec_1.expect)(f.isOptional).to.be.false);
1704
+ const ifaceType = iface.getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
1705
+ const iFaceMembers = ifaceType.getMemberTable().getAllSymbols(1 /* SymbolTypeFlag.runtime */);
1706
+ (0, chai_config_spec_1.expect)(iFaceMembers.length).to.eq(2);
1707
+ // eslint-disable-next-line no-bitwise
1708
+ iFaceMembers.forEach(sym => (0, chai_config_spec_1.expect)(sym.flags & 4 /* SymbolTypeFlag.optional */).to.eq(0));
1709
+ });
1710
+ it('allows fields named optional that are also optional', () => {
1711
+ let { ast, diagnostics } = parse(`
1712
+ interface IsJustOptional
1713
+ optional optional
1714
+ end interface
1715
+ `, Parser_1.ParseMode.BrighterScript);
1716
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1717
+ (0, chai_config_spec_1.expect)(ast.statements.length).to.eq(1);
1718
+ (0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(ast.statements[0])).to.be.true;
1719
+ const iface = ast.statements[0];
1720
+ iface.fields.forEach(f => (0, chai_config_spec_1.expect)(f.isOptional).to.be.true);
1721
+ const ifaceType = iface.getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
1722
+ const iFaceMembers = ifaceType.getMemberTable().getAllSymbols(1 /* SymbolTypeFlag.runtime */);
1723
+ (0, chai_config_spec_1.expect)(iFaceMembers.length).to.eq(1);
1724
+ // eslint-disable-next-line no-bitwise
1725
+ iFaceMembers.forEach(sym => (0, chai_config_spec_1.expect)(sym.flags & 4 /* SymbolTypeFlag.optional */).to.eq(4 /* SymbolTypeFlag.optional */));
1726
+ });
1727
+ it('allows optional methods', () => {
1728
+ let { ast, diagnostics } = parse(`
1729
+ interface HasOptional
1730
+ optional function getValue() as boolean
1731
+ optional sub noop()
1732
+ optional function process()
1733
+ end interface
1734
+ `, Parser_1.ParseMode.BrighterScript);
1735
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1736
+ (0, chai_config_spec_1.expect)(ast.statements.length).to.eq(1);
1737
+ (0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(ast.statements[0])).to.be.true;
1738
+ const iface = ast.statements[0];
1739
+ iface.methods.forEach(m => (0, chai_config_spec_1.expect)(m.isOptional).to.equal(true));
1740
+ const ifaceType = iface.getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
1741
+ // eslint-disable-next-line no-bitwise
1742
+ ifaceType.getMemberTable().getAllSymbols(1 /* SymbolTypeFlag.runtime */).forEach(sym => (0, chai_config_spec_1.expect)(sym.flags & 4 /* SymbolTypeFlag.optional */).to.eq(4 /* SymbolTypeFlag.optional */));
1743
+ });
1744
+ it('allows fields named `as` that are also optional', () => {
1745
+ let { ast, diagnostics } = parse(`
1746
+ interface IsJustOptional
1747
+ optional as
1748
+ end interface
1749
+ `, Parser_1.ParseMode.BrighterScript);
1750
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1751
+ (0, chai_config_spec_1.expect)(ast.statements.length).to.eq(1);
1752
+ (0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(ast.statements[0])).to.be.true;
1753
+ const iface = ast.statements[0];
1754
+ iface.fields.forEach(f => (0, chai_config_spec_1.expect)(f.isOptional).to.be.true);
1755
+ const ifaceType = iface.getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
1756
+ const iFaceMembers = ifaceType.getMemberTable().getAllSymbols(1 /* SymbolTypeFlag.runtime */);
1757
+ (0, chai_config_spec_1.expect)(iFaceMembers.length).to.eq(1);
1758
+ // eslint-disable-next-line no-bitwise
1759
+ iFaceMembers.forEach(sym => (0, chai_config_spec_1.expect)(sym.flags & 4 /* SymbolTypeFlag.optional */).to.eq(4 /* SymbolTypeFlag.optional */));
1760
+ });
1761
+ it('allows fields named `as` that are also typed', () => {
1762
+ let { ast, diagnostics } = parse(`
1763
+ interface IsJustOptional
1764
+ optional as as string
1765
+ end interface
1766
+ `, Parser_1.ParseMode.BrighterScript);
1767
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1768
+ (0, chai_config_spec_1.expect)(ast.statements.length).to.eq(1);
1769
+ (0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(ast.statements[0])).to.be.true;
1770
+ const iface = ast.statements[0];
1771
+ iface.fields.forEach(f => (0, chai_config_spec_1.expect)(f.isOptional).to.be.true);
1772
+ const ifaceType = iface.getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
1773
+ const iFaceMembers = ifaceType.getMemberTable().getAllSymbols(1 /* SymbolTypeFlag.runtime */);
1774
+ (0, chai_config_spec_1.expect)(iFaceMembers.length).to.eq(1);
1775
+ // eslint-disable-next-line no-bitwise
1776
+ iFaceMembers.forEach(sym => (0, chai_config_spec_1.expect)(sym.flags & 4 /* SymbolTypeFlag.optional */).to.eq(4 /* SymbolTypeFlag.optional */));
1777
+ });
1778
+ it('allows fields named `optional` that are also typed', () => {
1779
+ let { ast, diagnostics } = parse(`
1780
+ interface IsJustOptional
1781
+ optional as string
1782
+ end interface
1783
+ `, Parser_1.ParseMode.BrighterScript);
1784
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1785
+ (0, chai_config_spec_1.expect)(ast.statements.length).to.eq(1);
1786
+ (0, chai_config_spec_1.expect)((0, reflection_1.isInterfaceStatement)(ast.statements[0])).to.be.true;
1787
+ const iface = ast.statements[0];
1788
+ iface.fields.forEach(f => (0, chai_config_spec_1.expect)(f.isOptional).to.be.false);
1789
+ const ifaceType = iface.getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
1790
+ const iFaceMembers = ifaceType.getMemberTable().getAllSymbols(1 /* SymbolTypeFlag.runtime */);
1791
+ (0, chai_config_spec_1.expect)(iFaceMembers.length).to.eq(1);
1792
+ // eslint-disable-next-line no-bitwise
1793
+ iFaceMembers.forEach(sym => (0, chai_config_spec_1.expect)(sym.flags & 4 /* SymbolTypeFlag.optional */).to.eq(0));
1794
+ });
1795
+ });
1796
+ describe('leadingTrivia', () => {
1797
+ it('gets leading trivia from functions', () => {
1798
+ let { ast } = parse(`
1799
+ ' Nice function, bro
1800
+ function foo()
1801
+ return 1
1802
+ end function
1803
+ `);
1804
+ const funcStatements = ast.statements.filter(reflection_1.isFunctionStatement);
1805
+ const fooTrivia = funcStatements[0].leadingTrivia;
1806
+ (0, chai_config_spec_1.expect)(fooTrivia.length).to.be.greaterThan(0);
1807
+ (0, chai_config_spec_1.expect)(fooTrivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
1808
+ });
1809
+ it('gets multiple lines of leading trivia', () => {
1810
+ let { ast, diagnostics } = parse(`
1811
+ ' Say hello to someone
1812
+ '
1813
+ ' @param {string} name the person you want to say hello to.
1814
+ sub sayHello(name = "world" as string)
1815
+ end sub
1816
+ `);
1817
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1818
+ const funcStatements = ast.statements.filter(reflection_1.isFunctionStatement);
1819
+ const helloTrivia = funcStatements[0].leadingTrivia;
1820
+ (0, chai_config_spec_1.expect)(helloTrivia.length).to.be.greaterThan(0);
1821
+ (0, chai_config_spec_1.expect)(helloTrivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(3);
1822
+ });
1823
+ it('gets leading trivia from classes', () => {
1824
+ let { ast } = parse(`
1825
+ ' hello
1826
+ ' classes
1827
+ class Hello
1828
+ end class
1829
+ `, Parser_1.ParseMode.BrighterScript);
1830
+ const classStatements = ast.statements.filter(reflection_1.isClassStatement);
1831
+ const trivia = classStatements[0].leadingTrivia;
1832
+ (0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
1833
+ (0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(2);
1834
+ });
1835
+ it('gets leading trivia from functions with annotations', () => {
1836
+ let { ast } = parse(`
1837
+ ' hello comment 1
1838
+ ' hello comment 2
1839
+ @annotation
1840
+ ' hello comment 3
1841
+ @otherAnnotation
1842
+ sub sayHello(name = "world" as string)
1843
+ end sub
1844
+ `, Parser_1.ParseMode.BrighterScript);
1845
+ const funcStatements = ast.statements.filter(reflection_1.isFunctionStatement);
1846
+ const helloTrivia = funcStatements[0].leadingTrivia;
1847
+ (0, chai_config_spec_1.expect)(helloTrivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(0);
1848
+ const helloAnnotationTrivia = funcStatements[0].annotations[0].leadingTrivia;
1849
+ (0, chai_config_spec_1.expect)(helloAnnotationTrivia.length).to.be.greaterThan(0);
1850
+ (0, chai_config_spec_1.expect)(helloAnnotationTrivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(2);
1851
+ const otherAnnotationTrivia = funcStatements[0].annotations[1].leadingTrivia;
1852
+ (0, chai_config_spec_1.expect)(otherAnnotationTrivia.length).to.be.greaterThan(0);
1853
+ (0, chai_config_spec_1.expect)(otherAnnotationTrivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
1854
+ });
1855
+ it('gets leading trivia from class methods', () => {
1856
+ let { ast } = parse(`
1857
+ ' hello
1858
+ ' classes
1859
+ class Hello
1860
+
1861
+ ' Gets the value of PI
1862
+ ' Not a dessert
1863
+ function getPi() as float
1864
+ return 3.14
1865
+ end function
1866
+
1867
+ ' Gets a dessert
1868
+ function getPie() as string
1869
+ return "Apple Pie"
1870
+ end function
1871
+ end class
1872
+ `, Parser_1.ParseMode.BrighterScript);
1873
+ const classStatement = ast.statements.filter(reflection_1.isClassStatement)[0];
1874
+ const methodStatements = classStatement.methods;
1875
+ // function getPi()
1876
+ let trivia = methodStatements[0].leadingTrivia;
1877
+ (0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
1878
+ (0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(2);
1879
+ // function getPie()
1880
+ trivia = methodStatements[1].leadingTrivia;
1881
+ (0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
1882
+ (0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
1883
+ });
1884
+ it('gets leading trivia from class fields', () => {
1885
+ let { ast } = parse(`
1886
+ ' hello
1887
+ ' classes
1888
+ class Thing
1889
+ ' like the sky
1890
+ ' or a blueberry, evn though that's purple
1891
+ color = "blue"
1892
+
1893
+ ' My name
1894
+ public name as string
1895
+
1896
+ ' Only I know how old I am
1897
+ private age = 42
1898
+ end class
1899
+ `, Parser_1.ParseMode.BrighterScript);
1900
+ const classStatement = ast.statements.filter(reflection_1.isClassStatement)[0];
1901
+ const fieldStatements = classStatement.fields;
1902
+ // color = "blue"
1903
+ let trivia = fieldStatements[0].leadingTrivia;
1904
+ (0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
1905
+ (0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(2);
1906
+ // public name as string
1907
+ trivia = fieldStatements[1].leadingTrivia;
1908
+ (0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
1909
+ (0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
1910
+ // private age = 42
1911
+ trivia = fieldStatements[2].leadingTrivia;
1912
+ (0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
1913
+ (0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
1914
+ });
1915
+ it('gets leading trivia from interfaces', () => {
1916
+ let { ast } = parse(`
1917
+ ' Description of interface
1918
+ interface myIface
1919
+ ' comment
1920
+ someField as integer
1921
+
1922
+ 'comment
1923
+ function someFunc() as string
1924
+ end interface
1925
+ `, Parser_1.ParseMode.BrighterScript);
1926
+ const ifaceStatement = ast.statements.filter(reflection_1.isInterfaceStatement)[0];
1927
+ const fieldStatements = ifaceStatement.fields;
1928
+ const methodStatements = ifaceStatement.methods;
1929
+ // interface myIface
1930
+ let trivia = ifaceStatement.leadingTrivia;
1931
+ (0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
1932
+ (0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
1933
+ // someField as integer
1934
+ trivia = fieldStatements[0].leadingTrivia;
1935
+ (0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
1936
+ (0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
1937
+ // function someFunc() as string
1938
+ trivia = methodStatements[0].leadingTrivia;
1939
+ (0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
1940
+ (0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
1941
+ });
1942
+ it('gets leading trivia from namespaces', () => {
1943
+ let { ast } = parse(`
1944
+ ' Description of interface
1945
+ namespace Nested.Name.Space
1946
+
1947
+ end namespace
1948
+ `, Parser_1.ParseMode.BrighterScript);
1949
+ const nameSpaceStatement = ast.statements.filter(reflection_1.isNamespaceStatement)[0];
1950
+ // namespace Nested.Name.Space
1951
+ let trivia = nameSpaceStatement.leadingTrivia;
1952
+ (0, chai_config_spec_1.expect)(trivia.length).to.be.greaterThan(0);
1953
+ (0, chai_config_spec_1.expect)(trivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment).length).to.eq(1);
1954
+ });
1955
+ });
1956
+ describe('unary/binary ordering', () => {
1957
+ it('creates the correct operator order for `not x = x` code', () => {
1958
+ let { ast, diagnostics } = parse(`
1959
+ function isStrNotEmpty(myStr as string) as boolean
1960
+ return not myStr = ""
1961
+ end function
1962
+ `);
1963
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1964
+ (0, chai_config_spec_1.expect)((0, reflection_1.isFunctionStatement)(ast.statements[0])).to.be.true;
1965
+ const insideReturn = ast.statements[0].func.body.statements[0].value;
1966
+ (0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(insideReturn)).to.be.true;
1967
+ (0, chai_config_spec_1.expect)((0, reflection_1.isBinaryExpression)(insideReturn.right)).to.be.true;
1968
+ });
1969
+ it('creates the correct operator order for `not x + x` code', () => {
1970
+ let { ast, diagnostics } = parse(`
1971
+ function tryStuff() as integer
1972
+ return not 1 + 3 ' same as "not (3)" ... eg. the "flipped bits" of 3 (0000 0011) -> 1111 1100, or -4
1973
+ end function
1974
+ `);
1975
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1976
+ (0, chai_config_spec_1.expect)((0, reflection_1.isFunctionStatement)(ast.statements[0])).to.be.true;
1977
+ const insideReturn = ast.statements[0].func.body.statements[0].value;
1978
+ (0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(insideReturn)).to.be.true;
1979
+ (0, chai_config_spec_1.expect)((0, reflection_1.isBinaryExpression)(insideReturn.right)).to.be.true;
1980
+ });
1981
+ it('creates the correct operator order for `x = not x` code', () => {
1982
+ let { ast, diagnostics } = parse(`
1983
+ function tryStuff() as boolean
1984
+ return 4 = not -5 ' same as "4 = 4"
1985
+ end function
1986
+ `);
1987
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
1988
+ (0, chai_config_spec_1.expect)((0, reflection_1.isFunctionStatement)(ast.statements[0])).to.be.true;
1989
+ const insideReturn = ast.statements[0].func.body.statements[0].value;
1990
+ (0, chai_config_spec_1.expect)((0, reflection_1.isBinaryExpression)(insideReturn)).to.be.true;
1991
+ (0, chai_config_spec_1.expect)((0, reflection_1.isLiteralExpression)(insideReturn.left)).to.be.true;
1992
+ const right = insideReturn.right;
1993
+ (0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(right)).to.be.true;
1994
+ (0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(right.right)).to.be.true; // not ( - ( 5))
1995
+ });
1996
+ it('allows multiple nots', () => {
1997
+ let { ast, diagnostics } = parse(`
1998
+ function tryStuff() as integer
1999
+ return not not not 4
2000
+ end function
2001
+ `);
2002
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
2003
+ (0, chai_config_spec_1.expect)((0, reflection_1.isFunctionStatement)(ast.statements[0])).to.be.true;
2004
+ const insideReturn = ast.statements[0].func.body.statements[0].value;
2005
+ (0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(insideReturn)).to.be.true;
2006
+ (0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(insideReturn.right)).to.be.true;
2007
+ (0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(insideReturn.right.right)).to.be.true;
2008
+ });
2009
+ it('allows multiple -', () => {
2010
+ let { ast, diagnostics } = parse(`
2011
+ function tryStuff() as integer
2012
+ return - - - 4
2013
+ end function
2014
+ `);
2015
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
2016
+ (0, chai_config_spec_1.expect)((0, reflection_1.isFunctionStatement)(ast.statements[0])).to.be.true;
2017
+ const insideReturn = ast.statements[0].func.body.statements[0].value;
2018
+ (0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(insideReturn)).to.be.true;
2019
+ (0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(insideReturn.right)).to.be.true;
2020
+ (0, chai_config_spec_1.expect)((0, reflection_1.isUnaryExpression)(insideReturn.right.right)).to.be.true;
2021
+ });
2022
+ });
2023
+ describe('typecast statement', () => {
2024
+ it('allows typecast statement ', () => {
2025
+ let { ast, diagnostics } = parse(`
2026
+ typeCAST m AS roAssociativeArray
2027
+ `, Parser_1.ParseMode.BrighterScript);
2028
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
2029
+ (0, chai_config_spec_1.expect)((0, reflection_1.isTypecastStatement)(ast.statements[0])).to.be.true;
2030
+ const stmt = ast.statements[0];
2031
+ (0, chai_config_spec_1.expect)(stmt.tokens.typecast.text).to.eq('typeCAST');
2032
+ (0, chai_config_spec_1.expect)(stmt.typecastExpression).to.exist;
2033
+ });
2034
+ it('is disallowed in brightscript mode', () => {
2035
+ let { diagnostics } = parse(`
2036
+ typecast m AS roAssociativeArray
2037
+ `, Parser_1.ParseMode.BrightScript);
2038
+ (0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, [
2039
+ DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('typecast statements')
2040
+ ]);
2041
+ });
2042
+ it('allows `typecast` for function name', () => {
2043
+ let { ast, diagnostics } = parse(`
2044
+ function typecast() as integer
2045
+ return 1
2046
+ end function
2047
+ `, Parser_1.ParseMode.BrighterScript);
2048
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
2049
+ (0, chai_config_spec_1.expect)(ast.statements[0].tokens.name.text).to.eq('typecast');
2050
+ });
2051
+ it('allows `typecast` for variable name', () => {
2052
+ let { ast, diagnostics } = parse(`
2053
+ function foo() as integer
2054
+ typecast = 1
2055
+ return typecast
2056
+ end function
2057
+ `, Parser_1.ParseMode.BrighterScript);
2058
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
2059
+ (0, chai_config_spec_1.expect)(ast.statements[0].func.body.statements[0].tokens.name.text).to.eq('typecast');
2060
+ });
2061
+ it('is allowed in function', () => {
2062
+ let { diagnostics } = parse(`
2063
+ function foo() as integer
2064
+ typecast m as MyObject
2065
+ return m.getNum()
2066
+ end function
2067
+ `, Parser_1.ParseMode.BrighterScript);
2068
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
2069
+ });
2070
+ it('is allowed in function literal', () => {
2071
+ let { diagnostics } = parse(`
2072
+ interface PiGetter
2073
+ pi as float
2074
+ function getPi() as float
2075
+ end interface
2076
+
2077
+ function makePiGetter() as object
2078
+ x = {
2079
+ pi: 3.14,
2080
+ getPi: function() as float
2081
+ typecast m as PiGetter
2082
+ return m.pi
2083
+ end function
2084
+ }
2085
+ return x
2086
+ end function
2087
+ `, Parser_1.ParseMode.BrighterScript);
2088
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
2089
+ });
2090
+ });
2091
+ describe('conditional compilation', () => {
2092
+ it('contains code from conditional compile blocks', () => {
2093
+ let { ast, diagnostics } = parse(`
2094
+ sub foo()
2095
+ #if DEBUG
2096
+ print "hello"
2097
+ #end if
2098
+ end sub
2099
+ `, Parser_1.ParseMode.BrighterScript, { debug: true });
2100
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
2101
+ const funcBlock = ast.statements[0].func.body;
2102
+ (0, chai_config_spec_1.expect)(funcBlock.statements.length).to.eq(1);
2103
+ const ccStmt = funcBlock.statements[0];
2104
+ (0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileStatement)(ccStmt)).to.true;
2105
+ const printStmt = ccStmt.thenBranch.statements[0];
2106
+ (0, chai_config_spec_1.expect)((0, reflection_1.isPrintStatement)(printStmt)).to.true;
2107
+ });
2108
+ it('contains code from conditional compile else blocks', () => {
2109
+ let { ast, diagnostics } = parse(`
2110
+ sub foo()
2111
+ #if DEBUG
2112
+ m.pi = 3.14
2113
+ #else
2114
+ print "hello"
2115
+ #end if
2116
+ end sub
2117
+ `, Parser_1.ParseMode.BrighterScript);
2118
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
2119
+ const funcBlock = ast.statements[0].func.body;
2120
+ const ccStmt = funcBlock.statements[0];
2121
+ (0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileStatement)(ccStmt)).to.true;
2122
+ (0, chai_config_spec_1.expect)(ccStmt.elseBranch).to.exist;
2123
+ (0, chai_config_spec_1.expect)((0, reflection_1.isBlock)(ccStmt.elseBranch)).to.true;
2124
+ const printStmt = ccStmt.elseBranch.statements[0];
2125
+ (0, chai_config_spec_1.expect)((0, reflection_1.isPrintStatement)(printStmt)).to.true;
2126
+ });
2127
+ it('contains code from conditional compile else if blocks', () => {
2128
+ let { ast, diagnostics } = parse(`
2129
+ sub foo()
2130
+ #if DEBUG
2131
+ m.pi = 3.14
2132
+ #else if PROD
2133
+ print "hello"
2134
+ #end if
2135
+ end sub
2136
+ `, Parser_1.ParseMode.BrighterScript);
2137
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
2138
+ const funcBlock = ast.statements[0].func.body;
2139
+ const ccStmt = funcBlock.statements[0];
2140
+ (0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileStatement)(ccStmt)).to.true;
2141
+ (0, chai_config_spec_1.expect)(ccStmt.elseBranch).to.exist;
2142
+ const elseBranch = ccStmt.elseBranch;
2143
+ (0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileStatement)(elseBranch)).to.true;
2144
+ (0, chai_config_spec_1.expect)(elseBranch.tokens.condition.text).to.eq('PROD');
2145
+ const printStmt = elseBranch.thenBranch.statements[0];
2146
+ (0, chai_config_spec_1.expect)((0, reflection_1.isPrintStatement)(printStmt)).to.true;
2147
+ });
2148
+ it('contains code from multiple conditional compile else if blocks', () => {
2149
+ let { ast, diagnostics } = parse(`
2150
+ sub foo()
2151
+ #if DEBUG
2152
+ m.pi = 3.14
2153
+ #else if PROD
2154
+ print "hello"
2155
+ #else if ABC
2156
+ print "hello"
2157
+ #else if DEF
2158
+ print "hello"
2159
+ #else if HIJ
2160
+ print "hello"
2161
+ #else
2162
+ x = 78
2163
+ #end if
2164
+ end sub
2165
+ `, Parser_1.ParseMode.BrighterScript);
2166
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
2167
+ const funcBlock = ast.statements[0].func.body;
2168
+ const ccStmt = funcBlock.statements[0];
2169
+ (0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileStatement)(ccStmt)).to.true;
2170
+ (0, chai_config_spec_1.expect)(ccStmt.elseBranch).to.exist;
2171
+ let elseBranch = ccStmt.elseBranch;
2172
+ (0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileStatement)(elseBranch)).to.true;
2173
+ (0, chai_config_spec_1.expect)(elseBranch.tokens.condition.text).to.eq('PROD');
2174
+ elseBranch = elseBranch.elseBranch;
2175
+ (0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileStatement)(elseBranch)).to.true;
2176
+ (0, chai_config_spec_1.expect)(elseBranch.tokens.condition.text).to.eq('ABC');
2177
+ elseBranch = elseBranch.elseBranch;
2178
+ (0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileStatement)(elseBranch)).to.true;
2179
+ (0, chai_config_spec_1.expect)(elseBranch.tokens.condition.text).to.eq('DEF');
2180
+ elseBranch = elseBranch.elseBranch;
2181
+ (0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileStatement)(elseBranch)).to.true;
2182
+ (0, chai_config_spec_1.expect)(elseBranch.tokens.condition.text).to.eq('HIJ');
2183
+ let lastElse = elseBranch.elseBranch;
2184
+ (0, chai_config_spec_1.expect)((0, reflection_1.isBlock)(lastElse)).to.true;
2185
+ (0, chai_config_spec_1.expect)((0, reflection_1.isAssignmentStatement)(lastElse.statements[0])).to.true;
2186
+ });
2187
+ it('allows empty conditional compilation blocks', () => {
2188
+ let { ast, diagnostics } = parse(`
2189
+ #if DEBUG
2190
+ #else if PROD
2191
+ #else
2192
+ #end if
2193
+ `, Parser_1.ParseMode.BrighterScript);
2194
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
2195
+ const ccStmt = ast.statements[0];
2196
+ (0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileStatement)(ccStmt)).to.true;
2197
+ (0, chai_config_spec_1.expect)(ccStmt.thenBranch.statements.length).to.eq(0);
2198
+ (0, chai_config_spec_1.expect)(ccStmt.elseBranch.thenBranch.statements.length).to.eq(0);
2199
+ (0, chai_config_spec_1.expect)(ccStmt.elseBranch.elseBranch.statements.length).to.eq(0);
2200
+ });
2201
+ it('allows only comments in compilation blocks', () => {
2202
+ let { ast, diagnostics } = parse(`
2203
+ ' before if
2204
+ #if DEBUG
2205
+ ' this is debug
2206
+ #else if PROD
2207
+ ' this is prod
2208
+ #else
2209
+ ' this is neither
2210
+ #end if
2211
+ ' after if
2212
+ `, Parser_1.ParseMode.BrighterScript);
2213
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
2214
+ const ccStmt = ast.statements[0];
2215
+ (0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileStatement)(ccStmt)).to.true;
2216
+ (0, chai_config_spec_1.expect)(ccStmt.thenBranch.statements.length).to.eq(0);
2217
+ (0, chai_config_spec_1.expect)(ccStmt.elseBranch.thenBranch.statements.length).to.eq(0);
2218
+ (0, chai_config_spec_1.expect)(ccStmt.elseBranch.elseBranch.statements.length).to.eq(0);
2219
+ });
2220
+ it('has no error when safely closing block', () => {
2221
+ let { diagnostics } = parse(`
2222
+ sub foo()
2223
+ #if DEBUG
2224
+ if m.enabled
2225
+ print "hello"
2226
+ end if
2227
+ #end if
2228
+ end sub
2229
+ `, Parser_1.ParseMode.BrighterScript);
2230
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
2231
+ });
2232
+ it('has error when unsafely closing block', () => {
2233
+ let { diagnostics } = parse(`
2234
+ sub foo()
2235
+ if m.enabled
2236
+ #if DEBUG
2237
+ print "hello"
2238
+ end if
2239
+ #end if
2240
+ end sub
2241
+ `, Parser_1.ParseMode.BrighterScript);
2242
+ (0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, [
2243
+ DiagnosticMessages_1.DiagnosticMessages.unsafeUnmatchedTerminatorInConditionalCompileBlock('end if').message
2244
+ ]);
2245
+ });
2246
+ it('has error when unsafely opening block', () => {
2247
+ let { diagnostics } = parse(`
2248
+ sub foo()
2249
+ #if DEBUG
2250
+ if m.enabled
2251
+ print "hello"
2252
+ #end if
2253
+ end if
2254
+ end sub
2255
+ `, Parser_1.ParseMode.BrighterScript, { debug: true });
2256
+ (0, testHelpers_spec_1.expectDiagnostics)(diagnostics, [
2257
+ DiagnosticMessages_1.DiagnosticMessages.expectedTerminator('end if', 'if').message,
2258
+ DiagnosticMessages_1.DiagnosticMessages.unexpectedToken('end if').message
2259
+ ]);
2260
+ });
2261
+ it('has no diagnostics from false blocks', () => {
2262
+ let { diagnostics } = parse(`
2263
+ sub foo()
2264
+ #if DEBUG
2265
+ blah blah blah
2266
+ #end if
2267
+
2268
+ #if false
2269
+ there are no diagnostics here
2270
+ #end if
2271
+ end sub
2272
+ `, Parser_1.ParseMode.BrighterScript, { debug: false });
2273
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
2274
+ });
2275
+ it('allows #if not bs_const', () => {
2276
+ let { diagnostics } = parse(`
2277
+ sub foo()
2278
+ #if not DEBUG
2279
+ print "not debug"
2280
+ #end if
2281
+ end sub
2282
+ `, Parser_1.ParseMode.BrighterScript, { debug: false });
2283
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
2284
+ });
2285
+ it('allows #elseif not bs_const', () => {
2286
+ let { diagnostics } = parse(`
2287
+ sub foo()
2288
+ #if DEBUG
2289
+ print "debug"
2290
+ #else if not STAGING
2291
+ print "not debug and not staging"
2292
+ #end if
2293
+ end sub
2294
+ `, Parser_1.ParseMode.BrighterScript, { debug: false, staging: false });
2295
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
2296
+ });
2297
+ describe('#const', () => {
2298
+ it('parses #const', () => {
2299
+ let { ast, diagnostics } = parse(`
2300
+ #const test = true
2301
+ sub foo()
2302
+ #const debug = test
2303
+ end sub
2304
+ # const spaces = false
2305
+ `, Parser_1.ParseMode.BrighterScript);
2306
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
2307
+ //#const test = true
2308
+ let ccc = ast.statements[0];
2309
+ (0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileConstStatement)(ccc)).to.be.true;
2310
+ (0, chai_config_spec_1.expect)(ccc.assignment.tokens.name.text).to.eq('test');
2311
+ (0, chai_config_spec_1.expect)((0, reflection_1.isLiteralExpression)(ccc.assignment.value)).to.be.true;
2312
+ (0, chai_config_spec_1.expect)(ccc.assignment.value.tokens.value.text).to.eq('true');
2313
+ //#const debug = test
2314
+ ccc = ast.statements[1].func.body.statements[0];
2315
+ (0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileConstStatement)(ccc)).to.be.true;
2316
+ (0, chai_config_spec_1.expect)(ccc.assignment.tokens.name.text).to.eq('debug');
2317
+ (0, chai_config_spec_1.expect)((0, reflection_1.isVariableExpression)(ccc.assignment.value)).to.be.true;
2318
+ (0, chai_config_spec_1.expect)(ccc.assignment.value.tokens.name.text).to.eq('test');
2319
+ //# const spaces = false
2320
+ ccc = ast.statements[2];
2321
+ (0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileConstStatement)(ccc)).to.be.true;
2322
+ (0, chai_config_spec_1.expect)(ccc.assignment.tokens.name.text).to.eq('spaces');
2323
+ (0, chai_config_spec_1.expect)((0, reflection_1.isLiteralExpression)(ccc.assignment.value)).to.be.true;
2324
+ (0, chai_config_spec_1.expect)(ccc.assignment.value.tokens.value.text).to.eq('false');
2325
+ });
2326
+ it('has diagnostic if no lhs', () => {
2327
+ let { diagnostics } = parse(`
2328
+ #const test
2329
+ `, Parser_1.ParseMode.BrighterScript);
2330
+ (0, testHelpers_spec_1.expectDiagnostics)(diagnostics, [
2331
+ DiagnosticMessages_1.DiagnosticMessages.expectedOperator([TokenKind_1.TokenKind.Equal], 'test').message
2332
+ ]);
2333
+ });
2334
+ it('has diagnostic if invalid operator', () => {
2335
+ let { diagnostics } = parse(`
2336
+ #const test += other
2337
+ `, Parser_1.ParseMode.BrighterScript);
2338
+ (0, testHelpers_spec_1.expectDiagnostics)(diagnostics, [
2339
+ DiagnosticMessages_1.DiagnosticMessages.expectedOperator([TokenKind_1.TokenKind.Equal], 'test').message
2340
+ ]);
2341
+ });
2342
+ it('has diagnostic if invalid lhs', () => {
2343
+ let { diagnostics } = parse(`
2344
+ #const test = 4
2345
+ `, Parser_1.ParseMode.BrighterScript);
2346
+ (0, testHelpers_spec_1.expectDiagnostics)(diagnostics, [
2347
+ DiagnosticMessages_1.DiagnosticMessages.invalidHashConstValue().message
2348
+ ]);
2349
+ });
2350
+ });
2351
+ describe('#error', () => {
2352
+ it('parses #error', () => {
2353
+ let { ast, diagnostics } = parse(`
2354
+ #error
2355
+ sub foo()
2356
+ #error this is a LONG "message" :: with colons, etc.
2357
+ end sub
2358
+ # error this one has spaces
2359
+ `, Parser_1.ParseMode.BrighterScript);
2360
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
2361
+ //#error
2362
+ let cce = ast.statements[0];
2363
+ (0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileErrorStatement)(cce)).to.be.true;
2364
+ (0, chai_config_spec_1.expect)(cce.tokens.message.kind).to.eq(TokenKind_1.TokenKind.HashErrorMessage);
2365
+ (0, chai_config_spec_1.expect)(cce.tokens.message.text).to.eq('');
2366
+ //#error this is a long "message" :: with colons, etc.
2367
+ cce = ast.statements[1].func.body.statements[0];
2368
+ (0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileErrorStatement)(cce)).to.be.true;
2369
+ (0, chai_config_spec_1.expect)(cce.tokens.message.kind).to.eq(TokenKind_1.TokenKind.HashErrorMessage);
2370
+ (0, chai_config_spec_1.expect)(cce.tokens.message.text).to.eq('this is a LONG "message" :: with colons, etc.');
2371
+ //# error this one has spaces
2372
+ cce = ast.statements[2];
2373
+ (0, chai_config_spec_1.expect)((0, reflection_1.isConditionalCompileErrorStatement)(cce)).to.be.true;
2374
+ (0, chai_config_spec_1.expect)(cce.tokens.message.kind).to.eq(TokenKind_1.TokenKind.HashErrorMessage);
2375
+ (0, chai_config_spec_1.expect)(cce.tokens.message.text).to.eq('this one has spaces');
2376
+ });
2377
+ });
2378
+ });
2379
+ describe('alias statement', () => {
2380
+ it('allows alias statement ', () => {
2381
+ let { ast, diagnostics } = parse(`
2382
+ ALIAS x = lcase
2383
+ `, Parser_1.ParseMode.BrighterScript);
2384
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
2385
+ (0, chai_config_spec_1.expect)((0, reflection_1.isAliasStatement)(ast.statements[0])).to.be.true;
2386
+ const stmt = ast.statements[0];
2387
+ (0, chai_config_spec_1.expect)(stmt.tokens.alias.text).to.eq('ALIAS');
2388
+ (0, chai_config_spec_1.expect)(stmt.value).to.exist;
2389
+ });
2390
+ it('is disallowed in brightscript mode', () => {
2391
+ let { diagnostics } = parse(`
2392
+ alias x = lcase
2393
+ `, Parser_1.ParseMode.BrightScript);
2394
+ (0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, [
2395
+ DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('alias statements')
2396
+ ]);
2397
+ });
2398
+ it('allows `alias` for function name', () => {
2399
+ let { ast, diagnostics } = parse(`
2400
+ function alias() as integer
2401
+ return 1
2402
+ end function
2403
+ `, Parser_1.ParseMode.BrighterScript);
2404
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
2405
+ (0, chai_config_spec_1.expect)(ast.statements[0].tokens.name.text).to.eq('alias');
2406
+ });
2407
+ it('allows `alias` for variable name', () => {
2408
+ let { ast, diagnostics } = parse(`
2409
+ function foo() as integer
2410
+ alias = 1
2411
+ return alias
2412
+ end function
2413
+ `, Parser_1.ParseMode.BrighterScript);
2414
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
2415
+ (0, chai_config_spec_1.expect)(ast.statements[0].func.body.statements[0].tokens.name.text).to.eq('alias');
2416
+ });
2417
+ });
2418
+ describe('type statement', () => {
2419
+ it('allows type statement ', () => {
2420
+ let { ast, diagnostics } = parse(`
2421
+ TYPE x = string
2422
+ `, Parser_1.ParseMode.BrighterScript);
2423
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
2424
+ (0, chai_config_spec_1.expect)((0, reflection_1.isTypeStatement)(ast.statements[0])).to.be.true;
2425
+ const stmt = ast.statements[0];
2426
+ (0, chai_config_spec_1.expect)(stmt.tokens.type.text).to.eq('TYPE');
2427
+ (0, chai_config_spec_1.expect)(stmt.value).to.exist;
2428
+ });
2429
+ it('is disallowed in brightscript mode', () => {
2430
+ let { diagnostics } = parse(`
2431
+ type x = string
2432
+ `, Parser_1.ParseMode.BrightScript);
2433
+ (0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, [
2434
+ DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('type statements')
2435
+ ]);
2436
+ });
2437
+ it('disallows `type` for function name', () => {
2438
+ let { diagnostics } = parse(`
2439
+ function type() as integer
2440
+ return 1
2441
+ end function
2442
+ `, Parser_1.ParseMode.BrighterScript);
2443
+ (0, testHelpers_spec_1.expectDiagnostics)(diagnostics, [
2444
+ DiagnosticMessages_1.DiagnosticMessages.cannotUseReservedWordAsIdentifier('type').message
2445
+ ]);
2446
+ });
2447
+ it('disallows `type` for variable name', () => {
2448
+ let { diagnostics } = parse(`
2449
+ function foo() as integer
2450
+ type = 1
2451
+ return type
2452
+ end function
2453
+ `, Parser_1.ParseMode.BrighterScript);
2454
+ (0, testHelpers_spec_1.expectDiagnostics)(diagnostics, [
2455
+ DiagnosticMessages_1.DiagnosticMessages.cannotUseReservedWordAsIdentifier('type').message
2456
+ ]);
2457
+ });
2458
+ it('has error when rhs is not a type', () => {
2459
+ let { diagnostics } = parse(`
2460
+ type x = 123
2461
+ `, Parser_1.ParseMode.BrighterScript);
2462
+ (0, testHelpers_spec_1.expectDiagnostics)(diagnostics, [
2463
+ DiagnosticMessages_1.DiagnosticMessages.expectedIdentifier('=').message
2464
+ ]);
2465
+ });
2466
+ it('allows type statement with complicated type', () => {
2467
+ let { ast, diagnostics } = parse(`
2468
+ type x = string or CustomKlass or roAssociativeArray
2469
+ `, Parser_1.ParseMode.BrighterScript);
2470
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
2471
+ (0, chai_config_spec_1.expect)((0, reflection_1.isTypeStatement)(ast.statements[0])).to.be.true;
2472
+ const stmt = ast.statements[0];
2473
+ (0, chai_config_spec_1.expect)(stmt.tokens.type.text).to.eq('type');
2474
+ (0, chai_config_spec_1.expect)(stmt.value).to.exist;
2475
+ });
2476
+ it('allows grouped expressions in type statement', () => {
2477
+ let { ast, diagnostics } = parse(`
2478
+ type guy = ({name as string} or {age as integer}) and {foo as boolean, age as integer}
2479
+
2480
+ `, Parser_1.ParseMode.BrighterScript);
2481
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
2482
+ (0, chai_config_spec_1.expect)((0, reflection_1.isTypeStatement)(ast.statements[0])).to.be.true;
2483
+ const stmt = ast.statements[0];
2484
+ (0, chai_config_spec_1.expect)(stmt.tokens.type.text).to.eq('type');
2485
+ (0, chai_config_spec_1.expect)(stmt.value).to.exist;
2486
+ });
2487
+ });
2488
+ describe('jump statements', () => {
2489
+ it('should recognize `exit for`', () => {
2490
+ let { ast, diagnostics } = parse(`
2491
+ sub main()
2492
+ for i = 1 to 10
2493
+ exit for
2494
+ end for
2495
+ end sub
2496
+ `);
2497
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
2498
+ let loop = ast.statements[0].func.body.statements[0];
2499
+ let exitStmt = loop.body.statements[0];
2500
+ (0, chai_config_spec_1.expect)((0, reflection_1.isExitStatement)(exitStmt)).to.be.true;
2501
+ (0, chai_config_spec_1.expect)(exitStmt.tokens.loopType.text).to.eq('for');
2502
+ });
2503
+ it('should recognize `exit while`', () => {
2504
+ let { ast, diagnostics } = parse(`
2505
+ sub main(i)
2506
+ while i < 10
2507
+ exit while
2508
+ i++
2509
+ end while
2510
+ end sub
2511
+ `);
2512
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
2513
+ let loop = ast.statements[0].func.body.statements[0];
2514
+ let exitStmt = loop.body.statements[0];
2515
+ (0, chai_config_spec_1.expect)((0, reflection_1.isExitStatement)(exitStmt)).to.be.true;
2516
+ (0, chai_config_spec_1.expect)(exitStmt.tokens.loopType.text).to.eq('while');
2517
+ });
2518
+ it('should recognize `exitwhile` (one word)', () => {
2519
+ let { ast, diagnostics } = parse(`
2520
+ sub main(i)
2521
+ while i < 10
2522
+ exitwhile
2523
+ i++
2524
+ end while
2525
+ end sub
2526
+ `);
2527
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
2528
+ let loop = ast.statements[0].func.body.statements[0];
2529
+ let exitStmt = loop.body.statements[0];
2530
+ (0, chai_config_spec_1.expect)((0, reflection_1.isExitStatement)(exitStmt)).to.be.true;
2531
+ (0, chai_config_spec_1.expect)(exitStmt.tokens.loopType.text).to.eq('while');
2532
+ });
2533
+ it('should allow identifiers named `exitfor` (one word)', () => {
2534
+ let { ast, diagnostics } = parse(`
2535
+ sub main()
2536
+ for i = 1 to 10
2537
+ exitfor = 1
2538
+ exit for
2539
+ end for
2540
+ end sub
2541
+ `);
2542
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
2543
+ let loop = ast.statements[0].func.body.statements[0];
2544
+ let assignment = loop.body.statements[0];
2545
+ (0, chai_config_spec_1.expect)(assignment.tokens.name.text).to.eq('exitfor');
2546
+ let exitStmt = loop.body.statements[1];
2547
+ (0, chai_config_spec_1.expect)((0, reflection_1.isExitStatement)(exitStmt)).to.be.true;
2548
+ (0, chai_config_spec_1.expect)(exitStmt.tokens.loopType.text).to.eq('for');
2549
+ });
2550
+ });
2551
+ describe('custom types', () => {
2552
+ it('built-in interface param types disallowed in brightscript mode', () => {
2553
+ let { diagnostics } = parse(`
2554
+ sub test(foo as roAssociativeArray)
2555
+ print foo.x
2556
+ end sub
2557
+ `, Parser_1.ParseMode.BrightScript);
2558
+ (0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, [
2559
+ DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('custom types')
2560
+ ]);
2561
+ });
2562
+ it('built-in interface types disallowed in brightscript mode', () => {
2563
+ let { diagnostics } = parse(`
2564
+ function test(foo) as roAssociativeArray
2565
+ return foo.x
2566
+ end function
2567
+ `, Parser_1.ParseMode.BrightScript);
2568
+ (0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, [
2569
+ DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('custom types')
2570
+ ]);
2571
+ });
2572
+ it('custom param types disallowed in brightscript mode', () => {
2573
+ let { diagnostics } = parse(`
2574
+ sub test(foo as Whatever)
2575
+ print foo.x
2576
+ end sub
2577
+ `, Parser_1.ParseMode.BrightScript);
2578
+ (0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, [
2579
+ DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('custom types')
2580
+ ]);
2581
+ });
2582
+ it('custom return types disallowed in brightscript mode', () => {
2583
+ let { diagnostics } = parse(`
2584
+ function test(foo) as Whatever
2585
+ return foo.x
2586
+ end function
2587
+ `, Parser_1.ParseMode.BrightScript);
2588
+ (0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, [
2589
+ DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('custom types')
2590
+ ]);
2591
+ });
2592
+ it('built-in interface param types allowed in brighterscript mode', () => {
2593
+ let { diagnostics } = parse(`
2594
+ sub test(foo as roAssociativeArray)
2595
+ print foo.x
2596
+ end sub
2597
+ `, Parser_1.ParseMode.BrighterScript);
2598
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
2599
+ });
2600
+ it('built-in interface types allowed in brighterscript mode', () => {
2601
+ let { diagnostics } = parse(`
2602
+ function test(foo) as roAssociativeArray
2603
+ return foo.x
2604
+ end function
2605
+ `, Parser_1.ParseMode.BrighterScript);
2606
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
2607
+ });
2608
+ it('custom param types allowed in brighterscript mode', () => {
2609
+ let { diagnostics } = parse(`
2610
+ sub test(foo as Whatever)
2611
+ print foo.x
2612
+ end sub
2613
+ `, Parser_1.ParseMode.BrighterScript);
2614
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
2615
+ });
2616
+ it('custom return types allowed in brighterscript mode', () => {
2617
+ let { diagnostics } = parse(`
2618
+ function test(foo) as Whatever
2619
+ return foo.x
2620
+ end function
2621
+ `, Parser_1.ParseMode.BrighterScript);
2622
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
2623
+ });
2624
+ });
2625
+ describe('inline interfaces', () => {
2626
+ it('inline interface param types disallowed in brightscript mode', () => {
2627
+ let { diagnostics } = parse(`
2628
+ sub test(foo as {x as string})
2629
+ print foo.x
2630
+ end sub
2631
+ `, Parser_1.ParseMode.BrightScript);
2632
+ (0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, [
2633
+ DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('custom types')
2634
+ ]);
2635
+ });
2636
+ it('inline interface return types disallowed in brightscript mode', () => {
2637
+ let { diagnostics } = parse(`
2638
+ function test() as {x as string}
2639
+ print {x: "hello"}
2640
+ end function
2641
+ `, Parser_1.ParseMode.BrightScript);
2642
+ (0, testHelpers_spec_1.expectDiagnosticsIncludes)(diagnostics, [
2643
+ DiagnosticMessages_1.DiagnosticMessages.bsFeatureNotSupportedInBrsFiles('custom types')
2644
+ ]);
2645
+ });
2646
+ it('inline interface as param type', () => {
2647
+ var _a;
2648
+ let { ast, diagnostics } = parse(`
2649
+ sub test(foo as {x as string})
2650
+ print foo.x
2651
+ end sub
2652
+ `, Parser_1.ParseMode.BrighterScript);
2653
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
2654
+ (0, chai_config_spec_1.expect)(ast.statements.length).to.eq(1);
2655
+ const func = ast.statements[0].func;
2656
+ (0, chai_config_spec_1.expect)((0, reflection_1.isInlineInterfaceExpression)((_a = func.parameters[0].typeExpression) === null || _a === void 0 ? void 0 : _a.expression)).to.be.true;
2657
+ });
2658
+ it('inline interface as return type', () => {
2659
+ let { ast, diagnostics } = parse(`
2660
+ function test() as {x as string}
2661
+ print {x: "hello"}
2662
+ end function
2663
+ `, Parser_1.ParseMode.BrighterScript);
2664
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
2665
+ (0, chai_config_spec_1.expect)(ast.statements.length).to.eq(1);
2666
+ const func = ast.statements[0].func;
2667
+ (0, chai_config_spec_1.expect)((0, reflection_1.isInlineInterfaceExpression)(func.returnTypeExpression.expression)).to.be.true;
2668
+ });
2669
+ it('parses a big inline interface as param type', () => {
2670
+ var _a;
2671
+ let { ast, diagnostics } = parse(`
2672
+ sub test(foo as {
2673
+ x as string,
2674
+ y as {a as integer}
2675
+ z})
2676
+ print foo.x + y.a.toStr()
2677
+ end sub
2678
+ `, Parser_1.ParseMode.BrighterScript);
2679
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
2680
+ (0, chai_config_spec_1.expect)(ast.statements.length).to.eq(1);
2681
+ const func = ast.statements[0].func;
2682
+ const inlineIface = (_a = func.parameters[0].typeExpression) === null || _a === void 0 ? void 0 : _a.expression;
2683
+ (0, chai_config_spec_1.expect)((0, reflection_1.isInlineInterfaceExpression)(inlineIface)).to.be.true;
2684
+ (0, chai_config_spec_1.expect)(inlineIface.tokens.open).not.to.be.undefined;
2685
+ (0, chai_config_spec_1.expect)(inlineIface.tokens.close).not.to.be.undefined;
2686
+ (0, chai_config_spec_1.expect)(inlineIface.members).to.have.length(3);
2687
+ const iFaceType = inlineIface.getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
2688
+ (0, testHelpers_spec_1.expectTypeToBe)(iFaceType, InlineInterfaceType_1.InlineInterfaceType);
2689
+ (0, testHelpers_spec_1.expectTypeToBe)(iFaceType.getMemberType('x', { flags: 1 /* SymbolTypeFlag.runtime */ }), StringType_1.StringType);
2690
+ (0, testHelpers_spec_1.expectTypeToBe)(iFaceType.getMemberType('y', { flags: 1 /* SymbolTypeFlag.runtime */ }), InlineInterfaceType_1.InlineInterfaceType);
2691
+ (0, testHelpers_spec_1.expectTypeToBe)(iFaceType.getMemberType('z', { flags: 1 /* SymbolTypeFlag.runtime */ }), types_1.DynamicType);
2692
+ });
2693
+ it('allows optional members', () => {
2694
+ var _a;
2695
+ let { ast, diagnostics } = parse(`
2696
+ sub test(p as {x as string, optional y})
2697
+ end sub
2698
+ `, Parser_1.ParseMode.BrighterScript);
2699
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
2700
+ (0, chai_config_spec_1.expect)(ast.statements.length).to.eq(1);
2701
+ const func = ast.statements[0].func;
2702
+ const inlineIface = (_a = func.parameters[0].typeExpression) === null || _a === void 0 ? void 0 : _a.expression;
2703
+ (0, chai_config_spec_1.expect)((0, reflection_1.isInlineInterfaceExpression)(inlineIface)).to.be.true;
2704
+ (0, chai_config_spec_1.expect)(inlineIface.members).to.have.length(2);
2705
+ (0, chai_config_spec_1.expect)(inlineIface.members[1].isOptional).to.be.true;
2706
+ });
2707
+ it('is allowed as typecast', () => {
2708
+ let { diagnostics } = parse(`
2709
+ sub test(p)
2710
+ print (p as {name as string}).name
2711
+ end sub
2712
+ `, Parser_1.ParseMode.BrighterScript);
2713
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
2714
+ });
2715
+ it('is allowed as class and interface field', () => {
2716
+ let { diagnostics } = parse(`
2717
+ class Klass
2718
+ x as {name as string}
2719
+ end class
2720
+
2721
+ interface Iface
2722
+ y as {age as integer}
2723
+ end interface
2724
+ `, Parser_1.ParseMode.BrighterScript);
2725
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
2726
+ });
2727
+ it('can have custom type as member type', () => {
2728
+ let { diagnostics } = parse(`
2729
+ interface IFace
2730
+ name as string
2731
+ end interface
2732
+
2733
+ function test(z as {foo as IFace})
2734
+ return z.foo.name
2735
+ end function
2736
+ `, Parser_1.ParseMode.BrighterScript);
2737
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
2738
+ });
2739
+ it('can have per-member doc comment', () => {
2740
+ let { diagnostics } = parse(`
2741
+ interface IFace
2742
+ inline as {
2743
+ ' comment 1
2744
+ name as string
2745
+ ' comment 2
2746
+ age as integer
2747
+ }
2748
+ end interface
2749
+
2750
+ function test(z as {foo as IFace})
2751
+ return z.foo.inline.name
2752
+ end function
2753
+ `, Parser_1.ParseMode.BrighterScript);
2754
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
2755
+ });
2756
+ it('can have string literals as members', () => {
2757
+ let { diagnostics } = parse(`
2758
+ function test(z as {"this is a stringliteral" as string})
2759
+ return z["this is a stringliteral"]
2760
+ end function
2761
+ `, Parser_1.ParseMode.BrighterScript);
2762
+ (0, testHelpers_spec_1.expectZeroDiagnostics)(diagnostics);
2763
+ });
2764
+ });
2765
+ });
2766
+ function parse(text, mode, bsConsts = {}) {
2767
+ let { tokens } = Lexer_1.Lexer.scan(text);
2768
+ const bsConstMap = new Map();
2769
+ for (const constName in bsConsts) {
2770
+ bsConstMap.set(constName.toLowerCase(), bsConsts[constName]);
2771
+ }
1191
2772
  return Parser_1.Parser.parse(tokens, {
1192
- mode: mode
2773
+ srcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/main.brs`,
2774
+ mode: mode,
2775
+ bsConsts: bsConstMap
1193
2776
  });
1194
2777
  }
2778
+ exports.parse = parse;
1195
2779
  function rangeToArray(range) {
1196
2780
  return [
1197
2781
  range.start.line,
@@ -1202,15 +2786,17 @@ function rangeToArray(range) {
1202
2786
  }
1203
2787
  exports.rangeToArray = rangeToArray;
1204
2788
  function expectCommentWithText(stat, text) {
1205
- if (reflection_1.isCommentStatement(stat)) {
1206
- chai_1.expect(stat.text).to.equal(text);
2789
+ const trivia = stat.leadingTrivia;
2790
+ if (trivia) {
2791
+ (0, chai_config_spec_1.expect)(trivia.filter(tok => tok.kind === TokenKind_1.TokenKind.Comment).map(t => t.text).join('\n')).to.equal(text);
1207
2792
  }
1208
2793
  else {
1209
2794
  failStatementType(stat, 'Comment');
1210
2795
  }
1211
2796
  }
1212
2797
  function failStatementType(stat, type) {
1213
- chai_1.assert.fail(`Statement ${stat.constructor.name} line ${stat.range.start.line} is not a ${type}`);
2798
+ var _a;
2799
+ chai_config_spec_1.assert.fail(`Statement ${stat.constructor.name} line ${(_a = stat.location) === null || _a === void 0 ? void 0 : _a.range.start.line} is not a ${type}`);
1214
2800
  }
1215
2801
  exports.failStatementType = failStatementType;
1216
2802
  //# sourceMappingURL=Parser.spec.js.map