brighterscript 1.0.0-alpha.24 → 1.0.0-alpha.25

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