brighterscript 1.0.0-alpha.50 → 1.0.0-alpha.51

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