brighterscript 1.0.0-alpha.3 → 1.0.0-alpha.30

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 (605) hide show
  1. package/CHANGELOG.md +1230 -285
  2. package/README.md +61 -131
  3. package/bsconfig.schema.json +68 -2
  4. package/dist/ActionPipeline.d.ts +10 -0
  5. package/dist/ActionPipeline.js +40 -0
  6. package/dist/ActionPipeline.js.map +1 -0
  7. package/dist/AstValidationSegmenter.d.ts +35 -0
  8. package/dist/AstValidationSegmenter.js +209 -0
  9. package/dist/AstValidationSegmenter.js.map +1 -0
  10. package/dist/BsConfig.d.ts +51 -6
  11. package/dist/BusyStatusTracker.d.ts +31 -0
  12. package/dist/BusyStatusTracker.js +83 -0
  13. package/dist/BusyStatusTracker.js.map +1 -0
  14. package/dist/Cache.d.ts +5 -6
  15. package/dist/Cache.js +12 -11
  16. package/dist/Cache.js.map +1 -1
  17. package/dist/CacheVerifier.d.ts +7 -0
  18. package/dist/CacheVerifier.js +20 -0
  19. package/dist/CacheVerifier.js.map +1 -0
  20. package/dist/CodeActionUtil.d.ts +11 -2
  21. package/dist/CodeActionUtil.js +17 -3
  22. package/dist/CodeActionUtil.js.map +1 -1
  23. package/dist/CommentFlagProcessor.d.ts +7 -6
  24. package/dist/CommentFlagProcessor.js +10 -7
  25. package/dist/CommentFlagProcessor.js.map +1 -1
  26. package/dist/DependencyGraph.d.ts +8 -3
  27. package/dist/DependencyGraph.js +49 -16
  28. package/dist/DependencyGraph.js.map +1 -1
  29. package/dist/DiagnosticCollection.d.ts +5 -3
  30. package/dist/DiagnosticCollection.js +18 -16
  31. package/dist/DiagnosticCollection.js.map +1 -1
  32. package/dist/DiagnosticFilterer.d.ts +8 -4
  33. package/dist/DiagnosticFilterer.js +77 -44
  34. package/dist/DiagnosticFilterer.js.map +1 -1
  35. package/dist/DiagnosticManager.d.ts +55 -0
  36. package/dist/DiagnosticManager.js +214 -0
  37. package/dist/DiagnosticManager.js.map +1 -0
  38. package/dist/DiagnosticMessages.d.ts +184 -17
  39. package/dist/DiagnosticMessages.js +242 -24
  40. package/dist/DiagnosticMessages.js.map +1 -1
  41. package/dist/DiagnosticSeverityAdjuster.d.ts +7 -0
  42. package/dist/DiagnosticSeverityAdjuster.js +41 -0
  43. package/dist/DiagnosticSeverityAdjuster.js.map +1 -0
  44. package/dist/FunctionScope.d.ts +28 -0
  45. package/dist/FunctionScope.js +52 -0
  46. package/dist/FunctionScope.js.map +1 -0
  47. package/dist/KeyedThrottler.d.ts +3 -3
  48. package/dist/KeyedThrottler.js +3 -3
  49. package/dist/KeyedThrottler.js.map +1 -1
  50. package/dist/LanguageServer.d.ts +72 -47
  51. package/dist/LanguageServer.js +544 -312
  52. package/dist/LanguageServer.js.map +1 -1
  53. package/dist/Logger.d.ts +9 -10
  54. package/dist/Logger.js +36 -30
  55. package/dist/Logger.js.map +1 -1
  56. package/dist/PluginInterface.d.ts +29 -7
  57. package/dist/PluginInterface.js +90 -7
  58. package/dist/PluginInterface.js.map +1 -1
  59. package/dist/Program.d.ts +204 -99
  60. package/dist/Program.js +1060 -699
  61. package/dist/Program.js.map +1 -1
  62. package/dist/ProgramBuilder.d.ts +29 -18
  63. package/dist/ProgramBuilder.js +170 -132
  64. package/dist/ProgramBuilder.js.map +1 -1
  65. package/dist/Scope.d.ts +144 -109
  66. package/dist/Scope.js +538 -551
  67. package/dist/Scope.js.map +1 -1
  68. package/dist/SemanticTokenUtils.d.ts +14 -0
  69. package/dist/SemanticTokenUtils.js +81 -0
  70. package/dist/SemanticTokenUtils.js.map +1 -0
  71. package/dist/Stopwatch.d.ts +4 -0
  72. package/dist/Stopwatch.js +8 -1
  73. package/dist/Stopwatch.js.map +1 -1
  74. package/dist/SymbolTable.d.ts +91 -24
  75. package/dist/SymbolTable.js +286 -63
  76. package/dist/SymbolTable.js.map +1 -1
  77. package/dist/SymbolTypeFlag.d.ts +8 -0
  78. package/dist/SymbolTypeFlag.js +13 -0
  79. package/dist/SymbolTypeFlag.js.map +1 -0
  80. package/dist/Throttler.d.ts +12 -0
  81. package/dist/Throttler.js +39 -0
  82. package/dist/Throttler.js.map +1 -1
  83. package/dist/Watcher.d.ts +0 -3
  84. package/dist/Watcher.js +0 -3
  85. package/dist/Watcher.js.map +1 -1
  86. package/dist/XmlScope.d.ts +5 -15
  87. package/dist/XmlScope.js +35 -87
  88. package/dist/XmlScope.js.map +1 -1
  89. package/dist/astUtils/CachedLookups.d.ts +49 -0
  90. package/dist/astUtils/CachedLookups.js +324 -0
  91. package/dist/astUtils/CachedLookups.js.map +1 -0
  92. package/dist/astUtils/Editor.d.ts +69 -0
  93. package/dist/astUtils/Editor.js +245 -0
  94. package/dist/astUtils/Editor.js.map +1 -0
  95. package/dist/astUtils/Editor.spec.js +258 -0
  96. package/dist/astUtils/Editor.spec.js.map +1 -0
  97. package/dist/astUtils/creators.d.ts +33 -10
  98. package/dist/astUtils/creators.js +224 -30
  99. package/dist/astUtils/creators.js.map +1 -1
  100. package/dist/astUtils/creators.spec.js +5 -5
  101. package/dist/astUtils/creators.spec.js.map +1 -1
  102. package/dist/astUtils/reflection.d.ts +145 -82
  103. package/dist/astUtils/reflection.js +304 -132
  104. package/dist/astUtils/reflection.js.map +1 -1
  105. package/dist/astUtils/reflection.spec.js +267 -162
  106. package/dist/astUtils/reflection.spec.js.map +1 -1
  107. package/dist/astUtils/stackedVisitor.js.map +1 -1
  108. package/dist/astUtils/stackedVisitor.spec.js +14 -14
  109. package/dist/astUtils/stackedVisitor.spec.js.map +1 -1
  110. package/dist/astUtils/visitors.d.ts +114 -53
  111. package/dist/astUtils/visitors.js +70 -13
  112. package/dist/astUtils/visitors.js.map +1 -1
  113. package/dist/astUtils/visitors.spec.js +465 -51
  114. package/dist/astUtils/visitors.spec.js.map +1 -1
  115. package/dist/astUtils/xml.d.ts +9 -8
  116. package/dist/astUtils/xml.js +10 -5
  117. package/dist/astUtils/xml.js.map +1 -1
  118. package/dist/bscPlugin/BscPlugin.d.ts +22 -1
  119. package/dist/bscPlugin/BscPlugin.js +88 -0
  120. package/dist/bscPlugin/BscPlugin.js.map +1 -1
  121. package/dist/bscPlugin/CallExpressionInfo.d.ts +36 -0
  122. package/dist/bscPlugin/CallExpressionInfo.js +131 -0
  123. package/dist/bscPlugin/CallExpressionInfo.js.map +1 -0
  124. package/dist/bscPlugin/FileWriter.d.ts +6 -0
  125. package/dist/bscPlugin/FileWriter.js +24 -0
  126. package/dist/bscPlugin/FileWriter.js.map +1 -0
  127. package/dist/bscPlugin/SignatureHelpUtil.d.ts +10 -0
  128. package/dist/bscPlugin/SignatureHelpUtil.js +137 -0
  129. package/dist/bscPlugin/SignatureHelpUtil.js.map +1 -0
  130. package/dist/bscPlugin/codeActions/CodeActionsProcessor.d.ts +1 -1
  131. package/dist/bscPlugin/codeActions/CodeActionsProcessor.js +26 -17
  132. package/dist/bscPlugin/codeActions/CodeActionsProcessor.js.map +1 -1
  133. package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js +94 -20
  134. package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js.map +1 -1
  135. package/dist/bscPlugin/completions/CompletionsProcessor.d.ts +60 -0
  136. package/dist/bscPlugin/completions/CompletionsProcessor.js +601 -0
  137. package/dist/bscPlugin/completions/CompletionsProcessor.js.map +1 -0
  138. package/dist/bscPlugin/completions/CompletionsProcessor.spec.js +2139 -0
  139. package/dist/bscPlugin/completions/CompletionsProcessor.spec.js.map +1 -0
  140. package/dist/bscPlugin/definition/DefinitionProvider.d.ts +13 -0
  141. package/dist/bscPlugin/definition/DefinitionProvider.js +210 -0
  142. package/dist/bscPlugin/definition/DefinitionProvider.js.map +1 -0
  143. package/dist/bscPlugin/definition/DefinitionProvider.spec.js +88 -0
  144. package/dist/bscPlugin/definition/DefinitionProvider.spec.js.map +1 -0
  145. package/dist/bscPlugin/fileProviders/FileProvider.d.ts +9 -0
  146. package/dist/bscPlugin/fileProviders/FileProvider.js +51 -0
  147. package/dist/bscPlugin/fileProviders/FileProvider.js.map +1 -0
  148. package/dist/bscPlugin/hover/HoverProcessor.d.ts +18 -0
  149. package/dist/bscPlugin/hover/HoverProcessor.js +218 -0
  150. package/dist/bscPlugin/hover/HoverProcessor.js.map +1 -0
  151. package/dist/bscPlugin/hover/HoverProcessor.spec.d.ts +1 -0
  152. package/dist/bscPlugin/hover/HoverProcessor.spec.js +737 -0
  153. package/dist/bscPlugin/hover/HoverProcessor.spec.js.map +1 -0
  154. package/dist/bscPlugin/references/ReferencesProvider.d.ts +12 -0
  155. package/dist/bscPlugin/references/ReferencesProvider.js +56 -0
  156. package/dist/bscPlugin/references/ReferencesProvider.js.map +1 -0
  157. package/dist/bscPlugin/references/ReferencesProvider.spec.d.ts +1 -0
  158. package/dist/bscPlugin/references/ReferencesProvider.spec.js +51 -0
  159. package/dist/bscPlugin/references/ReferencesProvider.spec.js.map +1 -0
  160. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.d.ts +14 -0
  161. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js +138 -0
  162. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js.map +1 -0
  163. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.d.ts +1 -0
  164. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js +491 -0
  165. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js.map +1 -0
  166. package/dist/bscPlugin/serialize/BslibInjector.spec.d.ts +1 -0
  167. package/dist/bscPlugin/serialize/BslibInjector.spec.js +19 -0
  168. package/dist/bscPlugin/serialize/BslibInjector.spec.js.map +1 -0
  169. package/dist/bscPlugin/serialize/BslibManager.d.ts +9 -0
  170. package/dist/bscPlugin/serialize/BslibManager.js +40 -0
  171. package/dist/bscPlugin/serialize/BslibManager.js.map +1 -0
  172. package/dist/bscPlugin/serialize/FileSerializer.d.ts +9 -0
  173. package/dist/bscPlugin/serialize/FileSerializer.js +72 -0
  174. package/dist/bscPlugin/serialize/FileSerializer.js.map +1 -0
  175. package/dist/bscPlugin/symbols/DocumentSymbolProcessor.d.ts +7 -0
  176. package/dist/bscPlugin/symbols/DocumentSymbolProcessor.js +22 -0
  177. package/dist/bscPlugin/symbols/DocumentSymbolProcessor.js.map +1 -0
  178. package/dist/bscPlugin/symbols/DocumentSymbolProcessor.spec.d.ts +1 -0
  179. package/dist/bscPlugin/symbols/DocumentSymbolProcessor.spec.js +291 -0
  180. package/dist/bscPlugin/symbols/DocumentSymbolProcessor.spec.js.map +1 -0
  181. package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.d.ts +7 -0
  182. package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.js +26 -0
  183. package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.js.map +1 -0
  184. package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.spec.d.ts +1 -0
  185. package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.spec.js +245 -0
  186. package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.spec.js.map +1 -0
  187. package/dist/bscPlugin/symbols/symbolUtils.d.ts +5 -0
  188. package/dist/bscPlugin/symbols/symbolUtils.js +140 -0
  189. package/dist/bscPlugin/symbols/symbolUtils.js.map +1 -0
  190. package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.d.ts +21 -0
  191. package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.js +202 -0
  192. package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.js.map +1 -0
  193. package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.spec.d.ts +1 -0
  194. package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.spec.js +41 -0
  195. package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.spec.js.map +1 -0
  196. package/dist/bscPlugin/transpile/XmlFilePreTranspileProcessor.d.ts +12 -0
  197. package/dist/bscPlugin/transpile/XmlFilePreTranspileProcessor.js +99 -0
  198. package/dist/bscPlugin/transpile/XmlFilePreTranspileProcessor.js.map +1 -0
  199. package/dist/bscPlugin/validation/BrsFileAfterValidatior.d.ts +7 -0
  200. package/dist/bscPlugin/validation/BrsFileAfterValidatior.js +18 -0
  201. package/dist/bscPlugin/validation/BrsFileAfterValidatior.js.map +1 -0
  202. package/dist/bscPlugin/validation/BrsFileValidator.d.ts +34 -0
  203. package/dist/bscPlugin/validation/BrsFileValidator.js +462 -0
  204. package/dist/bscPlugin/validation/BrsFileValidator.js.map +1 -0
  205. package/dist/bscPlugin/validation/BrsFileValidator.spec.d.ts +1 -0
  206. package/dist/bscPlugin/validation/BrsFileValidator.spec.js +758 -0
  207. package/dist/bscPlugin/validation/BrsFileValidator.spec.js.map +1 -0
  208. package/dist/bscPlugin/validation/ProgramValidator.d.ts +11 -0
  209. package/dist/bscPlugin/validation/ProgramValidator.js +33 -0
  210. package/dist/bscPlugin/validation/ProgramValidator.js.map +1 -0
  211. package/dist/bscPlugin/validation/ScopeValidator.d.ts +131 -0
  212. package/dist/bscPlugin/validation/ScopeValidator.js +1097 -0
  213. package/dist/bscPlugin/validation/ScopeValidator.js.map +1 -0
  214. package/dist/bscPlugin/validation/ScopeValidator.spec.d.ts +1 -0
  215. package/dist/bscPlugin/validation/ScopeValidator.spec.js +2796 -0
  216. package/dist/bscPlugin/validation/ScopeValidator.spec.js.map +1 -0
  217. package/dist/bscPlugin/validation/XmlFileValidator.d.ts +8 -0
  218. package/dist/bscPlugin/validation/XmlFileValidator.js +44 -0
  219. package/dist/bscPlugin/validation/XmlFileValidator.js.map +1 -0
  220. package/dist/cli.js +117 -11
  221. package/dist/cli.js.map +1 -1
  222. package/dist/deferred.d.ts +3 -3
  223. package/dist/deferred.js.map +1 -1
  224. package/dist/diagnosticUtils.d.ts +10 -3
  225. package/dist/diagnosticUtils.js +58 -21
  226. package/dist/diagnosticUtils.js.map +1 -1
  227. package/dist/examples/plugins/removePrint.js +8 -12
  228. package/dist/examples/plugins/removePrint.js.map +1 -1
  229. package/dist/files/AssetFile.d.ts +24 -0
  230. package/dist/files/AssetFile.js +25 -0
  231. package/dist/files/AssetFile.js.map +1 -0
  232. package/dist/files/BrsFile.Class.spec.js +858 -153
  233. package/dist/files/BrsFile.Class.spec.js.map +1 -1
  234. package/dist/files/BrsFile.d.ts +144 -82
  235. package/dist/files/BrsFile.js +847 -911
  236. package/dist/files/BrsFile.js.map +1 -1
  237. package/dist/files/BrsFile.spec.js +2928 -834
  238. package/dist/files/BrsFile.spec.js.map +1 -1
  239. package/dist/files/BscFile.d.ts +101 -0
  240. package/dist/files/BscFile.js +15 -0
  241. package/dist/files/BscFile.js.map +1 -0
  242. package/dist/files/Factory.d.ts +25 -0
  243. package/dist/files/Factory.js +22 -0
  244. package/dist/files/Factory.js.map +1 -0
  245. package/dist/files/LazyFileData.d.ts +20 -0
  246. package/dist/files/LazyFileData.js +54 -0
  247. package/dist/files/LazyFileData.js.map +1 -0
  248. package/dist/files/LazyFileData.spec.d.ts +1 -0
  249. package/dist/files/LazyFileData.spec.js +27 -0
  250. package/dist/files/LazyFileData.spec.js.map +1 -0
  251. package/dist/files/XmlFile.d.ts +73 -41
  252. package/dist/files/XmlFile.js +126 -138
  253. package/dist/files/XmlFile.js.map +1 -1
  254. package/dist/files/XmlFile.spec.js +450 -318
  255. package/dist/files/XmlFile.spec.js.map +1 -1
  256. package/dist/files/tests/imports.spec.js +62 -52
  257. package/dist/files/tests/imports.spec.js.map +1 -1
  258. package/dist/files/tests/optionalChaning.spec.d.ts +1 -0
  259. package/dist/files/tests/optionalChaning.spec.js +152 -0
  260. package/dist/files/tests/optionalChaning.spec.js.map +1 -0
  261. package/dist/globalCallables.d.ts +3 -1
  262. package/dist/globalCallables.js +416 -162
  263. package/dist/globalCallables.js.map +1 -1
  264. package/dist/index.d.ts +25 -3
  265. package/dist/index.js +42 -5
  266. package/dist/index.js.map +1 -1
  267. package/dist/interfaces.d.ts +722 -119
  268. package/dist/interfaces.js +31 -0
  269. package/dist/interfaces.js.map +1 -1
  270. package/dist/lexer/Character.spec.js +5 -5
  271. package/dist/lexer/Character.spec.js.map +1 -1
  272. package/dist/lexer/Lexer.d.ts +40 -9
  273. package/dist/lexer/Lexer.js +191 -49
  274. package/dist/lexer/Lexer.js.map +1 -1
  275. package/dist/lexer/Lexer.spec.js +775 -563
  276. package/dist/lexer/Lexer.spec.js.map +1 -1
  277. package/dist/lexer/Token.d.ts +11 -3
  278. package/dist/lexer/Token.js +10 -2
  279. package/dist/lexer/Token.js.map +1 -1
  280. package/dist/lexer/TokenKind.d.ts +27 -1
  281. package/dist/lexer/TokenKind.js +112 -5
  282. package/dist/lexer/TokenKind.js.map +1 -1
  283. package/dist/logging.d.ts +9 -0
  284. package/dist/logging.js +16 -0
  285. package/dist/logging.js.map +1 -0
  286. package/dist/parser/AstNode.d.ts +180 -0
  287. package/dist/parser/AstNode.js +245 -0
  288. package/dist/parser/AstNode.js.map +1 -0
  289. package/dist/parser/AstNode.spec.d.ts +1 -0
  290. package/dist/parser/AstNode.spec.js +165 -0
  291. package/dist/parser/AstNode.spec.js.map +1 -0
  292. package/dist/parser/BrsTranspileState.d.ts +12 -2
  293. package/dist/parser/BrsTranspileState.js +6 -0
  294. package/dist/parser/BrsTranspileState.js.map +1 -1
  295. package/dist/parser/Expression.d.ts +454 -210
  296. package/dist/parser/Expression.js +953 -498
  297. package/dist/parser/Expression.js.map +1 -1
  298. package/dist/parser/Parser.Class.spec.js +200 -95
  299. package/dist/parser/Parser.Class.spec.js.map +1 -1
  300. package/dist/parser/Parser.d.ts +105 -120
  301. package/dist/parser/Parser.js +1406 -912
  302. package/dist/parser/Parser.js.map +1 -1
  303. package/dist/parser/Parser.spec.d.ts +3 -1
  304. package/dist/parser/Parser.spec.js +1383 -456
  305. package/dist/parser/Parser.spec.js.map +1 -1
  306. package/dist/parser/SGParser.d.ts +44 -6
  307. package/dist/parser/SGParser.js +212 -185
  308. package/dist/parser/SGParser.js.map +1 -1
  309. package/dist/parser/SGParser.spec.js +30 -28
  310. package/dist/parser/SGParser.spec.js.map +1 -1
  311. package/dist/parser/SGTypes.d.ts +293 -50
  312. package/dist/parser/SGTypes.js +540 -187
  313. package/dist/parser/SGTypes.js.map +1 -1
  314. package/dist/parser/Statement.d.ts +734 -244
  315. package/dist/parser/Statement.js +1758 -611
  316. package/dist/parser/Statement.js.map +1 -1
  317. package/dist/parser/Statement.spec.js +45 -34
  318. package/dist/parser/Statement.spec.js.map +1 -1
  319. package/dist/parser/TranspileState.d.ts +17 -8
  320. package/dist/parser/TranspileState.js +73 -11
  321. package/dist/parser/TranspileState.js.map +1 -1
  322. package/dist/parser/tests/Parser.spec.d.ts +10 -9
  323. package/dist/parser/tests/Parser.spec.js +18 -14
  324. package/dist/parser/tests/Parser.spec.js.map +1 -1
  325. package/dist/parser/tests/controlFlow/For.spec.js +79 -69
  326. package/dist/parser/tests/controlFlow/For.spec.js.map +1 -1
  327. package/dist/parser/tests/controlFlow/ForEach.spec.js +53 -47
  328. package/dist/parser/tests/controlFlow/ForEach.spec.js.map +1 -1
  329. package/dist/parser/tests/controlFlow/If.spec.js +217 -196
  330. package/dist/parser/tests/controlFlow/If.spec.js.map +1 -1
  331. package/dist/parser/tests/controlFlow/While.spec.js +48 -42
  332. package/dist/parser/tests/controlFlow/While.spec.js.map +1 -1
  333. package/dist/parser/tests/expression/Additive.spec.js +31 -31
  334. package/dist/parser/tests/expression/Additive.spec.js.map +1 -1
  335. package/dist/parser/tests/expression/ArrayLiterals.spec.js +157 -120
  336. package/dist/parser/tests/expression/ArrayLiterals.spec.js.map +1 -1
  337. package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js +202 -139
  338. package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js.map +1 -1
  339. package/dist/parser/tests/expression/Boolean.spec.js +25 -25
  340. package/dist/parser/tests/expression/Boolean.spec.js.map +1 -1
  341. package/dist/parser/tests/expression/Call.spec.js +150 -41
  342. package/dist/parser/tests/expression/Call.spec.js.map +1 -1
  343. package/dist/parser/tests/expression/Exponential.spec.js +18 -18
  344. package/dist/parser/tests/expression/Exponential.spec.js.map +1 -1
  345. package/dist/parser/tests/expression/Function.spec.js +257 -257
  346. package/dist/parser/tests/expression/Function.spec.js.map +1 -1
  347. package/dist/parser/tests/expression/Indexing.spec.js +160 -90
  348. package/dist/parser/tests/expression/Indexing.spec.js.map +1 -1
  349. package/dist/parser/tests/expression/Multiplicative.spec.js +38 -38
  350. package/dist/parser/tests/expression/Multiplicative.spec.js.map +1 -1
  351. package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js +196 -98
  352. package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js.map +1 -1
  353. package/dist/parser/tests/expression/PrefixUnary.spec.js +42 -42
  354. package/dist/parser/tests/expression/PrefixUnary.spec.js.map +1 -1
  355. package/dist/parser/tests/expression/Primary.spec.js +42 -42
  356. package/dist/parser/tests/expression/Primary.spec.js.map +1 -1
  357. package/dist/parser/tests/expression/RegexLiteralExpression.spec.d.ts +1 -0
  358. package/dist/parser/tests/expression/RegexLiteralExpression.spec.js +171 -0
  359. package/dist/parser/tests/expression/RegexLiteralExpression.spec.js.map +1 -0
  360. package/dist/parser/tests/expression/Relational.spec.js +44 -44
  361. package/dist/parser/tests/expression/Relational.spec.js.map +1 -1
  362. package/dist/parser/tests/expression/SourceLiteralExpression.spec.js +31 -31
  363. package/dist/parser/tests/expression/SourceLiteralExpression.spec.js.map +1 -1
  364. package/dist/parser/tests/expression/TemplateStringExpression.spec.js +230 -90
  365. package/dist/parser/tests/expression/TemplateStringExpression.spec.js.map +1 -1
  366. package/dist/parser/tests/expression/TernaryExpression.spec.js +377 -148
  367. package/dist/parser/tests/expression/TernaryExpression.spec.js.map +1 -1
  368. package/dist/parser/tests/expression/TypeExpression.spec.d.ts +1 -0
  369. package/dist/parser/tests/expression/TypeExpression.spec.js +126 -0
  370. package/dist/parser/tests/expression/TypeExpression.spec.js.map +1 -0
  371. package/dist/parser/tests/expression/UnaryExpression.spec.d.ts +1 -0
  372. package/dist/parser/tests/expression/UnaryExpression.spec.js +52 -0
  373. package/dist/parser/tests/expression/UnaryExpression.spec.js.map +1 -0
  374. package/dist/parser/tests/statement/AssignmentOperators.spec.js +37 -37
  375. package/dist/parser/tests/statement/AssignmentOperators.spec.js.map +1 -1
  376. package/dist/parser/tests/statement/ConstStatement.spec.d.ts +1 -0
  377. package/dist/parser/tests/statement/ConstStatement.spec.js +262 -0
  378. package/dist/parser/tests/statement/ConstStatement.spec.js.map +1 -0
  379. package/dist/parser/tests/statement/Continue.spec.d.ts +1 -0
  380. package/dist/parser/tests/statement/Continue.spec.js +119 -0
  381. package/dist/parser/tests/statement/Continue.spec.js.map +1 -0
  382. package/dist/parser/tests/statement/Declaration.spec.js +45 -45
  383. package/dist/parser/tests/statement/Declaration.spec.js.map +1 -1
  384. package/dist/parser/tests/statement/Dim.spec.js +22 -22
  385. package/dist/parser/tests/statement/Dim.spec.js.map +1 -1
  386. package/dist/parser/tests/statement/Enum.spec.d.ts +1 -0
  387. package/dist/parser/tests/statement/Enum.spec.js +684 -0
  388. package/dist/parser/tests/statement/Enum.spec.js.map +1 -0
  389. package/dist/parser/tests/statement/For.spec.d.ts +1 -0
  390. package/dist/parser/tests/statement/For.spec.js +45 -0
  391. package/dist/parser/tests/statement/For.spec.js.map +1 -0
  392. package/dist/parser/tests/statement/ForEach.spec.d.ts +1 -0
  393. package/dist/parser/tests/statement/ForEach.spec.js +36 -0
  394. package/dist/parser/tests/statement/ForEach.spec.js.map +1 -0
  395. package/dist/parser/tests/statement/Function.spec.js +208 -198
  396. package/dist/parser/tests/statement/Function.spec.js.map +1 -1
  397. package/dist/parser/tests/statement/Goto.spec.js +16 -15
  398. package/dist/parser/tests/statement/Goto.spec.js.map +1 -1
  399. package/dist/parser/tests/statement/Increment.spec.js +51 -51
  400. package/dist/parser/tests/statement/Increment.spec.js.map +1 -1
  401. package/dist/parser/tests/statement/InterfaceStatement.spec.d.ts +1 -0
  402. package/dist/parser/tests/statement/InterfaceStatement.spec.js +109 -0
  403. package/dist/parser/tests/statement/InterfaceStatement.spec.js.map +1 -0
  404. package/dist/parser/tests/statement/LibraryStatement.spec.js +18 -18
  405. package/dist/parser/tests/statement/LibraryStatement.spec.js.map +1 -1
  406. package/dist/parser/tests/statement/Misc.spec.js +123 -163
  407. package/dist/parser/tests/statement/Misc.spec.js.map +1 -1
  408. package/dist/parser/tests/statement/PrintStatement.spec.js +125 -108
  409. package/dist/parser/tests/statement/PrintStatement.spec.js.map +1 -1
  410. package/dist/parser/tests/statement/ReturnStatement.spec.js +51 -49
  411. package/dist/parser/tests/statement/ReturnStatement.spec.js.map +1 -1
  412. package/dist/parser/tests/statement/Set.spec.js +110 -97
  413. package/dist/parser/tests/statement/Set.spec.js.map +1 -1
  414. package/dist/parser/tests/statement/Stop.spec.js +13 -12
  415. package/dist/parser/tests/statement/Stop.spec.js.map +1 -1
  416. package/dist/parser/tests/statement/Throw.spec.js +6 -6
  417. package/dist/parser/tests/statement/Throw.spec.js.map +1 -1
  418. package/dist/parser/tests/statement/TryCatch.spec.js +26 -15
  419. package/dist/parser/tests/statement/TryCatch.spec.js.map +1 -1
  420. package/dist/preprocessor/Manifest.d.ts +6 -6
  421. package/dist/preprocessor/Manifest.js +17 -38
  422. package/dist/preprocessor/Manifest.js.map +1 -1
  423. package/dist/preprocessor/Manifest.spec.d.ts +1 -0
  424. package/dist/preprocessor/Manifest.spec.js +78 -103
  425. package/dist/preprocessor/Manifest.spec.js.map +1 -1
  426. package/dist/roku-types/data.json +19351 -0
  427. package/dist/roku-types/index.d.ts +5483 -0
  428. package/dist/roku-types/index.js +11 -0
  429. package/dist/roku-types/index.js.map +1 -0
  430. package/dist/types/ArrayType.d.ts +9 -5
  431. package/dist/types/ArrayType.js +68 -24
  432. package/dist/types/ArrayType.js.map +1 -1
  433. package/dist/types/ArrayType.spec.js +39 -11
  434. package/dist/types/ArrayType.spec.js.map +1 -1
  435. package/dist/types/AssociativeArrayType.d.ts +14 -0
  436. package/dist/types/AssociativeArrayType.js +60 -0
  437. package/dist/types/AssociativeArrayType.js.map +1 -0
  438. package/dist/types/BaseFunctionType.d.ts +9 -0
  439. package/dist/types/BaseFunctionType.js +25 -0
  440. package/dist/types/BaseFunctionType.js.map +1 -0
  441. package/dist/types/BooleanType.d.ts +10 -5
  442. package/dist/types/BooleanType.js +21 -9
  443. package/dist/types/BooleanType.js.map +1 -1
  444. package/dist/types/BooleanType.spec.js +10 -4
  445. package/dist/types/BooleanType.spec.js.map +1 -1
  446. package/dist/types/BscType.d.ts +29 -3
  447. package/dist/types/BscType.js +121 -0
  448. package/dist/types/BscType.js.map +1 -1
  449. package/dist/types/BscTypeKind.d.ts +25 -0
  450. package/dist/types/BscTypeKind.js +30 -0
  451. package/dist/types/BscTypeKind.js.map +1 -0
  452. package/dist/types/BuiltInInterfaceAdder.d.ts +23 -0
  453. package/dist/types/BuiltInInterfaceAdder.js +174 -0
  454. package/dist/types/BuiltInInterfaceAdder.js.map +1 -0
  455. package/dist/types/BuiltInInterfaceAdder.spec.d.ts +1 -0
  456. package/dist/types/BuiltInInterfaceAdder.spec.js +115 -0
  457. package/dist/types/BuiltInInterfaceAdder.spec.js.map +1 -0
  458. package/dist/types/ClassType.d.ts +17 -0
  459. package/dist/types/ClassType.js +58 -0
  460. package/dist/types/ClassType.js.map +1 -0
  461. package/dist/types/ClassType.spec.d.ts +1 -0
  462. package/dist/types/ClassType.spec.js +76 -0
  463. package/dist/types/ClassType.spec.js.map +1 -0
  464. package/dist/types/ComponentType.d.ts +27 -0
  465. package/dist/types/ComponentType.js +83 -0
  466. package/dist/types/ComponentType.js.map +1 -0
  467. package/dist/types/DoubleType.d.ts +10 -5
  468. package/dist/types/DoubleType.js +25 -18
  469. package/dist/types/DoubleType.js.map +1 -1
  470. package/dist/types/DoubleType.spec.js +12 -4
  471. package/dist/types/DoubleType.spec.js.map +1 -1
  472. package/dist/types/DynamicType.d.ts +12 -5
  473. package/dist/types/DynamicType.js +22 -6
  474. package/dist/types/DynamicType.js.map +1 -1
  475. package/dist/types/DynamicType.spec.js +16 -5
  476. package/dist/types/DynamicType.spec.js.map +1 -1
  477. package/dist/types/EnumType.d.ts +40 -0
  478. package/dist/types/EnumType.js +80 -0
  479. package/dist/types/EnumType.js.map +1 -0
  480. package/dist/types/EnumType.spec.d.ts +1 -0
  481. package/dist/types/EnumType.spec.js +33 -0
  482. package/dist/types/EnumType.spec.js.map +1 -0
  483. package/dist/types/FloatType.d.ts +10 -5
  484. package/dist/types/FloatType.js +25 -18
  485. package/dist/types/FloatType.js.map +1 -1
  486. package/dist/types/FloatType.spec.js +4 -4
  487. package/dist/types/FloatType.spec.js.map +1 -1
  488. package/dist/types/FunctionType.d.ts +10 -22
  489. package/dist/types/FunctionType.js +26 -63
  490. package/dist/types/FunctionType.js.map +1 -1
  491. package/dist/types/InheritableType.d.ts +28 -0
  492. package/dist/types/InheritableType.js +157 -0
  493. package/dist/types/InheritableType.js.map +1 -0
  494. package/dist/types/IntegerType.d.ts +10 -5
  495. package/dist/types/IntegerType.js +25 -18
  496. package/dist/types/IntegerType.js.map +1 -1
  497. package/dist/types/IntegerType.spec.js +8 -4
  498. package/dist/types/IntegerType.spec.js.map +1 -1
  499. package/dist/types/InterfaceType.d.ts +14 -6
  500. package/dist/types/InterfaceType.js +26 -15
  501. package/dist/types/InterfaceType.js.map +1 -1
  502. package/dist/types/InterfaceType.spec.d.ts +1 -0
  503. package/dist/types/InterfaceType.spec.js +227 -0
  504. package/dist/types/InterfaceType.spec.js.map +1 -0
  505. package/dist/types/InvalidType.d.ts +9 -5
  506. package/dist/types/InvalidType.js +20 -9
  507. package/dist/types/InvalidType.js.map +1 -1
  508. package/dist/types/InvalidType.spec.js +8 -4
  509. package/dist/types/InvalidType.spec.js.map +1 -1
  510. package/dist/types/LongIntegerType.d.ts +10 -5
  511. package/dist/types/LongIntegerType.js +25 -18
  512. package/dist/types/LongIntegerType.js.map +1 -1
  513. package/dist/types/LongIntegerType.spec.js +10 -4
  514. package/dist/types/LongIntegerType.spec.js.map +1 -1
  515. package/dist/types/NamespaceType.d.ts +12 -0
  516. package/dist/types/NamespaceType.js +28 -0
  517. package/dist/types/NamespaceType.js.map +1 -0
  518. package/dist/types/ObjectType.d.ts +10 -5
  519. package/dist/types/ObjectType.js +23 -9
  520. package/dist/types/ObjectType.js.map +1 -1
  521. package/dist/types/ObjectType.spec.js +3 -3
  522. package/dist/types/ObjectType.spec.js.map +1 -1
  523. package/dist/types/ReferenceType.d.ts +71 -0
  524. package/dist/types/ReferenceType.js +467 -0
  525. package/dist/types/ReferenceType.js.map +1 -0
  526. package/dist/types/ReferenceType.spec.d.ts +1 -0
  527. package/dist/types/ReferenceType.spec.js +151 -0
  528. package/dist/types/ReferenceType.spec.js.map +1 -0
  529. package/dist/types/StringType.d.ts +13 -5
  530. package/dist/types/StringType.js +25 -9
  531. package/dist/types/StringType.js.map +1 -1
  532. package/dist/types/StringType.spec.js +3 -3
  533. package/dist/types/StringType.spec.js.map +1 -1
  534. package/dist/types/TypedFunctionType.d.ts +33 -0
  535. package/dist/types/TypedFunctionType.js +106 -0
  536. package/dist/types/TypedFunctionType.js.map +1 -0
  537. package/dist/types/TypedFunctionType.spec.d.ts +1 -0
  538. package/dist/types/TypedFunctionType.spec.js +122 -0
  539. package/dist/types/TypedFunctionType.spec.js.map +1 -0
  540. package/dist/types/UninitializedType.d.ts +8 -6
  541. package/dist/types/UninitializedType.js +15 -9
  542. package/dist/types/UninitializedType.js.map +1 -1
  543. package/dist/types/UnionType.d.ts +20 -0
  544. package/dist/types/UnionType.js +127 -0
  545. package/dist/types/UnionType.js.map +1 -0
  546. package/dist/types/UnionType.spec.d.ts +1 -0
  547. package/dist/types/UnionType.spec.js +129 -0
  548. package/dist/types/UnionType.spec.js.map +1 -0
  549. package/dist/types/VoidType.d.ts +10 -5
  550. package/dist/types/VoidType.js +20 -9
  551. package/dist/types/VoidType.js.map +1 -1
  552. package/dist/types/VoidType.spec.js +3 -3
  553. package/dist/types/VoidType.spec.js.map +1 -1
  554. package/dist/types/helper.spec.d.ts +1 -0
  555. package/dist/types/helper.spec.js +144 -0
  556. package/dist/types/helper.spec.js.map +1 -0
  557. package/dist/types/helpers.d.ts +24 -0
  558. package/dist/types/helpers.js +178 -0
  559. package/dist/types/helpers.js.map +1 -0
  560. package/dist/types/index.d.ts +22 -0
  561. package/dist/types/index.js +39 -0
  562. package/dist/types/index.js.map +1 -0
  563. package/dist/util.d.ts +216 -106
  564. package/dist/util.js +1289 -319
  565. package/dist/util.js.map +1 -1
  566. package/dist/validators/ClassValidator.d.ts +9 -15
  567. package/dist/validators/ClassValidator.js +81 -134
  568. package/dist/validators/ClassValidator.js.map +1 -1
  569. package/package.json +169 -138
  570. package/dist/astUtils/index.d.ts +0 -7
  571. package/dist/astUtils/index.js +0 -26
  572. package/dist/astUtils/index.js.map +0 -1
  573. package/dist/lexer/index.d.ts +0 -3
  574. package/dist/lexer/index.js +0 -17
  575. package/dist/lexer/index.js.map +0 -1
  576. package/dist/parser/index.d.ts +0 -3
  577. package/dist/parser/index.js +0 -16
  578. package/dist/parser/index.js.map +0 -1
  579. package/dist/preprocessor/Chunk.d.ts +0 -82
  580. package/dist/preprocessor/Chunk.js +0 -77
  581. package/dist/preprocessor/Chunk.js.map +0 -1
  582. package/dist/preprocessor/Preprocessor.d.ts +0 -60
  583. package/dist/preprocessor/Preprocessor.js +0 -156
  584. package/dist/preprocessor/Preprocessor.js.map +0 -1
  585. package/dist/preprocessor/Preprocessor.spec.js +0 -152
  586. package/dist/preprocessor/Preprocessor.spec.js.map +0 -1
  587. package/dist/preprocessor/PreprocessorParser.d.ts +0 -61
  588. package/dist/preprocessor/PreprocessorParser.js +0 -194
  589. package/dist/preprocessor/PreprocessorParser.js.map +0 -1
  590. package/dist/preprocessor/PreprocessorParser.spec.js +0 -116
  591. package/dist/preprocessor/PreprocessorParser.spec.js.map +0 -1
  592. package/dist/preprocessor/index.d.ts +0 -3
  593. package/dist/preprocessor/index.js +0 -16
  594. package/dist/preprocessor/index.js.map +0 -1
  595. package/dist/types/CustomType.d.ts +0 -10
  596. package/dist/types/CustomType.js +0 -35
  597. package/dist/types/CustomType.js.map +0 -1
  598. package/dist/types/FunctionType.spec.js +0 -29
  599. package/dist/types/FunctionType.spec.js.map +0 -1
  600. package/dist/types/LazyType.d.ts +0 -15
  601. package/dist/types/LazyType.js +0 -32
  602. package/dist/types/LazyType.js.map +0 -1
  603. /package/dist/{preprocessor/Preprocessor.spec.d.ts → astUtils/Editor.spec.d.ts} +0 -0
  604. /package/dist/{preprocessor/PreprocessorParser.spec.d.ts → bscPlugin/completions/CompletionsProcessor.spec.d.ts} +0 -0
  605. /package/dist/{types/FunctionType.spec.d.ts → bscPlugin/definition/DefinitionProvider.spec.d.ts} +0 -0
@@ -1,36 +1,30 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ThrowStatement = exports.TryCatchStatement = exports.ClassFieldStatement = exports.ClassMethodStatement = exports.ClassStatement = exports.ImportStatement = exports.NamespaceStatement = exports.LibraryStatement = exports.IndexedSetStatement = exports.DottedSetStatement = exports.WhileStatement = exports.ForEachStatement = exports.ForStatement = exports.StopStatement = exports.EndStatement = exports.ReturnStatement = exports.LabelStatement = exports.GotoStatement = exports.DimStatement = exports.PrintStatement = exports.IncrementStatement = exports.IfStatement = exports.FunctionStatement = exports.ExitWhileStatement = exports.ExitForStatement = exports.CommentStatement = exports.ExpressionStatement = exports.Block = exports.AssignmentStatement = exports.Body = exports.EmptyStatement = exports.Statement = void 0;
4
- const lexer_1 = require("../lexer");
3
+ exports.ConditionalCompileConstStatement = exports.ConditionalCompileStatement = exports.AliasStatement = exports.ConditionalCompileErrorStatement = exports.TypecastStatement = exports.ContinueStatement = exports.ConstStatement = exports.EnumMemberStatement = exports.EnumStatement = exports.ThrowStatement = exports.CatchStatement = exports.TryCatchStatement = exports.FieldStatement = exports.MethodStatement = exports.ClassStatement = exports.InterfaceMethodStatement = exports.InterfaceFieldStatement = exports.InterfaceStatement = exports.ImportStatement = exports.NamespaceStatement = exports.LibraryStatement = exports.IndexedSetStatement = exports.DottedSetStatement = exports.WhileStatement = exports.ForEachStatement = exports.ForStatement = exports.StopStatement = exports.EndStatement = exports.ReturnStatement = exports.LabelStatement = exports.GotoStatement = exports.DimStatement = exports.PrintStatement = exports.IncrementStatement = exports.IfStatement = exports.FunctionStatement = exports.ExitWhileStatement = exports.ExitForStatement = exports.ExpressionStatement = exports.Block = exports.AssignmentStatement = exports.Body = exports.EmptyStatement = void 0;
4
+ const TokenKind_1 = require("../lexer/TokenKind");
5
5
  const Expression_1 = require("./Expression");
6
6
  const util_1 = require("../util");
7
- const vscode_languageserver_1 = require("vscode-languageserver");
8
7
  const Parser_1 = require("./Parser");
9
8
  const visitors_1 = require("../astUtils/visitors");
10
9
  const reflection_1 = require("../astUtils/reflection");
10
+ const interfaces_1 = require("../interfaces");
11
11
  const creators_1 = require("../astUtils/creators");
12
12
  const DynamicType_1 = require("../types/DynamicType");
13
13
  const SymbolTable_1 = require("../SymbolTable");
14
- /**
15
- * A BrightScript statement
16
- */
17
- class Statement {
18
- constructor() {
19
- /**
20
- * When being considered by the walk visitor, this describes what type of element the current class is.
21
- */
22
- this.visitMode = visitors_1.InternalWalkMode.visitStatements;
23
- }
24
- }
25
- exports.Statement = Statement;
26
- class EmptyStatement extends Statement {
27
- constructor(
28
- /**
29
- * Create a negative range to indicate this is an interpolated location
30
- */
31
- range = creators_1.interpolatedRange) {
14
+ const AstNode_1 = require("./AstNode");
15
+ const AstNode_2 = require("./AstNode");
16
+ const ClassType_1 = require("../types/ClassType");
17
+ const EnumType_1 = require("../types/EnumType");
18
+ const NamespaceType_1 = require("../types/NamespaceType");
19
+ const InterfaceType_1 = require("../types/InterfaceType");
20
+ const VoidType_1 = require("../types/VoidType");
21
+ const TypedFunctionType_1 = require("../types/TypedFunctionType");
22
+ const ArrayType_1 = require("../types/ArrayType");
23
+ class EmptyStatement extends AstNode_2.Statement {
24
+ constructor(options) {
32
25
  super();
33
- this.range = range;
26
+ this.kind = AstNode_1.AstNodeKind.EmptyStatement;
27
+ this.range = undefined;
34
28
  }
35
29
  transpile(state) {
36
30
  return [];
@@ -43,16 +37,22 @@ exports.EmptyStatement = EmptyStatement;
43
37
  /**
44
38
  * This is a top-level statement. Consider this the root of the AST
45
39
  */
46
- class Body extends Statement {
47
- constructor(statements = []) {
40
+ class Body extends AstNode_2.Statement {
41
+ constructor(options) {
42
+ var _a;
48
43
  super();
49
- this.statements = statements;
44
+ this.statements = [];
45
+ this.kind = AstNode_1.AstNodeKind.Body;
46
+ this.symbolTable = new SymbolTable_1.SymbolTable('Body', () => { var _a; return (_a = this.parent) === null || _a === void 0 ? void 0 : _a.getSymbolTable(); });
47
+ this.statements = (_a = options === null || options === void 0 ? void 0 : options.statements) !== null && _a !== void 0 ? _a : [];
50
48
  }
51
49
  get range() {
52
- var _a, _b, _c, _d;
53
- return util_1.util.createRangeFromPositions((_b = (_a = this.statements[0]) === null || _a === void 0 ? void 0 : _a.range.start) !== null && _b !== void 0 ? _b : vscode_languageserver_1.Position.create(0, 0), (_d = (_c = this.statements[this.statements.length - 1]) === null || _c === void 0 ? void 0 : _c.range.end) !== null && _d !== void 0 ? _d : vscode_languageserver_1.Position.create(0, 0));
50
+ var _a;
51
+ //this needs to be a getter because the body has its statements pushed to it after being constructed
52
+ return util_1.util.createBoundingRange(...((_a = this.statements) !== null && _a !== void 0 ? _a : []));
54
53
  }
55
54
  transpile(state) {
55
+ var _a, _b, _c, _d;
56
56
  let result = [];
57
57
  for (let i = 0; i < this.statements.length; i++) {
58
58
  let statement = this.statements[i];
@@ -62,20 +62,20 @@ class Body extends Statement {
62
62
  //this is the first statement. do nothing related to spacing and newlines
63
63
  //if comment is on same line as prior sibling
64
64
  }
65
- else if (reflection_1.isCommentStatement(statement) && previousStatement && statement.range.start.line === previousStatement.range.end.line) {
65
+ else if (util_1.util.hasLeadingComments(statement) && previousStatement && ((_c = (_b = (_a = util_1.util.getLeadingComments(statement)) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.range) === null || _c === void 0 ? void 0 : _c.start.line) === ((_d = previousStatement.range) === null || _d === void 0 ? void 0 : _d.end.line)) {
66
66
  result.push(' ');
67
67
  //add double newline if this is a comment, and next is a function
68
68
  }
69
- else if (reflection_1.isCommentStatement(statement) && nextStatement && reflection_1.isFunctionStatement(nextStatement)) {
70
- result.push('\n\n');
69
+ else if (util_1.util.hasLeadingComments(statement) && nextStatement && (0, reflection_1.isFunctionStatement)(nextStatement)) {
70
+ result.push(state.newline, state.newline);
71
71
  //add double newline if is function not preceeded by a comment
72
72
  }
73
- else if (reflection_1.isFunctionStatement(statement) && previousStatement && !(reflection_1.isCommentStatement(previousStatement))) {
74
- result.push('\n\n');
73
+ else if ((0, reflection_1.isFunctionStatement)(statement) && previousStatement && !util_1.util.hasLeadingComments(statement)) {
74
+ result.push(state.newline, state.newline);
75
75
  }
76
76
  else {
77
77
  //separate statements by a single newline
78
- result.push('\n');
78
+ result.push(state.newline);
79
79
  }
80
80
  result.push(...statement.transpile(state));
81
81
  }
@@ -85,7 +85,7 @@ class Body extends Statement {
85
85
  let result = [];
86
86
  for (const statement of this.statements) {
87
87
  //if the current statement supports generating typedef, call it
88
- if ('getTypedef' in statement) {
88
+ if ((0, reflection_1.isTypedefProvider)(statement)) {
89
89
  result.push(state.indent(), ...statement.getTypedef(state), state.newline);
90
90
  }
91
91
  }
@@ -93,33 +93,35 @@ class Body extends Statement {
93
93
  }
94
94
  walk(visitor, options) {
95
95
  if (options.walkMode & visitors_1.InternalWalkMode.walkStatements) {
96
- for (let i = 0; i < this.statements.length; i++) {
97
- visitors_1.walk(this.statements, i, visitor, options, this);
98
- }
96
+ (0, visitors_1.walkArray)(this.statements, visitor, options, this);
99
97
  }
100
98
  }
101
99
  }
102
100
  exports.Body = Body;
103
- class AssignmentStatement extends Statement {
104
- constructor(name, equals, value, containingFunction) {
101
+ class AssignmentStatement extends AstNode_2.Statement {
102
+ constructor(options) {
105
103
  super();
106
- this.name = name;
107
- this.equals = equals;
108
- this.value = value;
109
- this.containingFunction = containingFunction;
110
- this.range = util_1.util.createRangeFromPositions(this.name.range.start, this.value.range.end);
104
+ this.kind = AstNode_1.AstNodeKind.AssignmentStatement;
105
+ this.value = options.value;
106
+ this.tokens = {
107
+ equals: options.equals,
108
+ name: options.name,
109
+ as: options.as
110
+ };
111
+ this.typeExpression = options.typeExpression;
112
+ this.range = util_1.util.createBoundingRange(util_1.util.createBoundingRangeFromTokens(this.tokens), this.value);
111
113
  }
112
114
  transpile(state) {
113
- var _a, _b;
115
+ var _a, _b, _c, _d;
114
116
  //if the value is a compound assignment, just transpile the expression itself
115
- if (lexer_1.CompoundAssignmentOperators.includes((_b = (_a = this.value) === null || _a === void 0 ? void 0 : _a.operator) === null || _b === void 0 ? void 0 : _b.kind)) {
117
+ if (TokenKind_1.CompoundAssignmentOperators.includes((_c = (_b = (_a = this.value) === null || _a === void 0 ? void 0 : _a.tokens) === null || _b === void 0 ? void 0 : _b.operator) === null || _c === void 0 ? void 0 : _c.kind)) {
116
118
  return this.value.transpile(state);
117
119
  }
118
120
  else {
119
121
  return [
120
- state.transpileToken(this.name),
122
+ state.transpileToken(this.tokens.name),
121
123
  ' ',
122
- state.transpileToken(this.equals),
124
+ state.transpileToken((_d = this.tokens.equals) !== null && _d !== void 0 ? _d : (0, creators_1.createToken)(TokenKind_1.TokenKind.Equal)),
123
125
  ' ',
124
126
  ...this.value.transpile(state)
125
127
  ];
@@ -127,19 +129,32 @@ class AssignmentStatement extends Statement {
127
129
  }
128
130
  walk(visitor, options) {
129
131
  if (options.walkMode & visitors_1.InternalWalkMode.walkExpressions) {
130
- visitors_1.walk(this, 'value', visitor, options);
132
+ (0, visitors_1.walk)(this, 'typeExpression', visitor, options);
133
+ (0, visitors_1.walk)(this, 'value', visitor, options);
131
134
  }
132
135
  }
136
+ getType(options) {
137
+ var _a, _b, _c;
138
+ const variableType = (_b = (_a = this.typeExpression) === null || _a === void 0 ? void 0 : _a.getType(Object.assign(Object.assign({}, options), { typeChain: undefined }))) !== null && _b !== void 0 ? _b : this.value.getType(Object.assign(Object.assign({}, options), { typeChain: undefined }));
139
+ // Note: compound assignments (eg. +=) are internally dealt with via the RHS being a BinaryExpression
140
+ // so this.value will be a BinaryExpression, and BinaryExpressions can figure out their own types
141
+ (_c = options.typeChain) === null || _c === void 0 ? void 0 : _c.push(new interfaces_1.TypeChainEntry({ name: this.tokens.name.text, type: variableType, data: options.data, range: this.tokens.name.range, astNode: this }));
142
+ return variableType;
143
+ }
144
+ getLeadingTrivia() {
145
+ var _a;
146
+ return (_a = this.tokens.name.leadingTrivia) !== null && _a !== void 0 ? _a : [];
147
+ }
133
148
  }
134
149
  exports.AssignmentStatement = AssignmentStatement;
135
- class Block extends Statement {
136
- constructor(statements, startingRange) {
150
+ class Block extends AstNode_2.Statement {
151
+ constructor(options) {
152
+ var _a;
137
153
  super();
138
- this.statements = statements;
139
- this.startingRange = startingRange;
140
- this.range = util_1.util.createRangeFromPositions(this.startingRange.start, this.statements.length
141
- ? this.statements[this.statements.length - 1].range.end
142
- : this.startingRange.start);
154
+ this.kind = AstNode_1.AstNodeKind.Block;
155
+ this.statements = options.statements;
156
+ this.startingRange = options.startingRange;
157
+ this.range = util_1.util.createBoundingRange(this.startingRange, ...((_a = this.statements) !== null && _a !== void 0 ? _a : []));
143
158
  }
144
159
  transpile(state) {
145
160
  state.blockDepth++;
@@ -147,9 +162,10 @@ class Block extends Statement {
147
162
  for (let i = 0; i < this.statements.length; i++) {
148
163
  let previousStatement = this.statements[i - 1];
149
164
  let statement = this.statements[i];
165
+ //is not a comment
150
166
  //if comment is on same line as parent
151
- if (reflection_1.isCommentStatement(statement) &&
152
- (util_1.util.linesTouch(state.lineage[0], statement) || util_1.util.linesTouch(previousStatement, statement))) {
167
+ if (util_1.util.isLeadingCommentOnSameLine(state.lineage[0], statement) ||
168
+ util_1.util.isLeadingCommentOnSameLine(previousStatement, statement)) {
153
169
  results.push(' ');
154
170
  //is not a comment
155
171
  }
@@ -167,17 +183,16 @@ class Block extends Statement {
167
183
  }
168
184
  walk(visitor, options) {
169
185
  if (options.walkMode & visitors_1.InternalWalkMode.walkStatements) {
170
- for (let i = 0; i < this.statements.length; i++) {
171
- visitors_1.walk(this.statements, i, visitor, options, this);
172
- }
186
+ (0, visitors_1.walkArray)(this.statements, visitor, options, this);
173
187
  }
174
188
  }
175
189
  }
176
190
  exports.Block = Block;
177
- class ExpressionStatement extends Statement {
178
- constructor(expression) {
191
+ class ExpressionStatement extends AstNode_2.Statement {
192
+ constructor(options) {
179
193
  super();
180
- this.expression = expression;
194
+ this.kind = AstNode_1.AstNodeKind.ExpressionStatement;
195
+ this.expression = options.expression;
181
196
  this.range = this.expression.range;
182
197
  }
183
198
  transpile(state) {
@@ -185,147 +200,147 @@ class ExpressionStatement extends Statement {
185
200
  }
186
201
  walk(visitor, options) {
187
202
  if (options.walkMode & visitors_1.InternalWalkMode.walkExpressions) {
188
- visitors_1.walk(this, 'expression', visitor, options);
203
+ (0, visitors_1.walk)(this, 'expression', visitor, options);
189
204
  }
190
205
  }
206
+ getLeadingTrivia() {
207
+ return this.expression.getLeadingTrivia();
208
+ }
191
209
  }
192
210
  exports.ExpressionStatement = ExpressionStatement;
193
- class CommentStatement extends Statement {
194
- constructor(comments) {
211
+ class ExitForStatement extends AstNode_2.Statement {
212
+ constructor(options) {
195
213
  var _a;
196
214
  super();
197
- this.comments = comments;
198
- this.visitMode = visitors_1.InternalWalkMode.visitStatements | visitors_1.InternalWalkMode.visitExpressions;
199
- if (((_a = this.comments) === null || _a === void 0 ? void 0 : _a.length) > 0) {
200
- this.range = util_1.util.createRangeFromPositions(this.comments[0].range.start, this.comments[this.comments.length - 1].range.end);
201
- }
202
- }
203
- get text() {
204
- return this.comments.map(x => x.text).join('\n');
215
+ this.kind = AstNode_1.AstNodeKind.ExitForStatement;
216
+ this.tokens = {
217
+ exitFor: options === null || options === void 0 ? void 0 : options.exitFor
218
+ };
219
+ this.range = (_a = this.tokens.exitFor) === null || _a === void 0 ? void 0 : _a.range;
205
220
  }
206
221
  transpile(state) {
207
- let result = [];
208
- for (let i = 0; i < this.comments.length; i++) {
209
- let comment = this.comments[i];
210
- if (i > 0) {
211
- result.push(state.indent());
212
- }
213
- result.push(state.transpileToken(comment));
214
- //add newline for all except final comment
215
- if (i < this.comments.length - 1) {
216
- result.push('\n');
217
- }
218
- }
219
- return result;
220
- }
221
- getTypedef(state) {
222
- return this.transpile(state);
222
+ return this.tokens.exitFor ? state.transpileToken(this.tokens.exitFor) : ['exit for'];
223
223
  }
224
224
  walk(visitor, options) {
225
225
  //nothing to walk
226
226
  }
227
- }
228
- exports.CommentStatement = CommentStatement;
229
- class ExitForStatement extends Statement {
230
- constructor(tokens) {
231
- super();
232
- this.tokens = tokens;
233
- this.range = this.tokens.exitFor.range;
234
- }
235
- transpile(state) {
236
- return [
237
- state.transpileToken(this.tokens.exitFor)
238
- ];
239
- }
240
- walk(visitor, options) {
241
- //nothing to walk
227
+ getLeadingTrivia() {
228
+ var _a, _b;
229
+ return (_b = (_a = this.tokens.exitFor) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
242
230
  }
243
231
  }
244
232
  exports.ExitForStatement = ExitForStatement;
245
- class ExitWhileStatement extends Statement {
246
- constructor(tokens) {
233
+ class ExitWhileStatement extends AstNode_2.Statement {
234
+ constructor(options) {
235
+ var _a;
247
236
  super();
248
- this.tokens = tokens;
249
- this.range = this.tokens.exitWhile.range;
237
+ this.kind = AstNode_1.AstNodeKind.ExitWhileStatement;
238
+ this.tokens = {
239
+ exitWhile: options === null || options === void 0 ? void 0 : options.exitWhile
240
+ };
241
+ this.range = (_a = this.tokens.exitWhile) === null || _a === void 0 ? void 0 : _a.range;
250
242
  }
251
243
  transpile(state) {
252
- return [
253
- state.transpileToken(this.tokens.exitWhile)
254
- ];
244
+ return this.tokens.exitWhile ? state.transpileToken(this.tokens.exitWhile) : ['exit while'];
255
245
  }
256
246
  walk(visitor, options) {
257
247
  //nothing to walk
258
248
  }
249
+ getLeadingTrivia() {
250
+ var _a, _b;
251
+ return (_b = (_a = this.tokens.exitWhile) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
252
+ }
259
253
  }
260
254
  exports.ExitWhileStatement = ExitWhileStatement;
261
- class FunctionStatement extends Statement {
262
- constructor(name, func, namespaceName) {
255
+ class FunctionStatement extends AstNode_2.Statement {
256
+ constructor(options) {
257
+ var _a;
263
258
  super();
264
- this.name = name;
265
- this.func = func;
266
- this.namespaceName = namespaceName;
259
+ this.kind = AstNode_1.AstNodeKind.FunctionStatement;
260
+ this.tokens = {
261
+ name: options.name
262
+ };
263
+ this.func = options.func;
264
+ this.func.symbolTable.name += `: '${(_a = this.tokens.name) === null || _a === void 0 ? void 0 : _a.text}'`;
265
+ this.func.functionStatement = this;
267
266
  this.range = this.func.range;
268
267
  }
269
268
  /**
270
269
  * Get the name of this expression based on the parse mode
271
270
  */
272
271
  getName(parseMode) {
273
- if (this.namespaceName) {
272
+ var _a;
273
+ const namespace = this.findAncestor(reflection_1.isNamespaceStatement);
274
+ if (namespace) {
274
275
  let delimiter = parseMode === Parser_1.ParseMode.BrighterScript ? '.' : '_';
275
- let namespaceName = this.namespaceName.getName(parseMode);
276
- return namespaceName + delimiter + this.name.text;
276
+ let namespaceName = namespace.getName(parseMode);
277
+ return namespaceName + delimiter + ((_a = this.tokens.name) === null || _a === void 0 ? void 0 : _a.text);
277
278
  }
278
279
  else {
279
- return this.name.text;
280
+ return this.tokens.name.text;
280
281
  }
281
282
  }
283
+ getLeadingTrivia() {
284
+ return util_1.util.concatAnnotationLeadingTrivia(this, this.func.getLeadingTrivia());
285
+ }
282
286
  transpile(state) {
283
287
  //create a fake token using the full transpiled name
284
- let nameToken = Object.assign(Object.assign({}, this.name), { text: this.getName(Parser_1.ParseMode.BrightScript) });
288
+ let nameToken = Object.assign(Object.assign({}, this.tokens.name), { text: this.getName(Parser_1.ParseMode.BrightScript) });
285
289
  return this.func.transpile(state, nameToken);
286
290
  }
287
291
  getTypedef(state) {
288
- var _a;
292
+ var _a, _b;
289
293
  let result = [];
290
- for (let annotation of (_a = this.annotations) !== null && _a !== void 0 ? _a : []) {
294
+ for (let comment of (_a = util_1.util.getLeadingComments(this)) !== null && _a !== void 0 ? _a : []) {
295
+ result.push(comment.text, state.newline, state.indent());
296
+ }
297
+ for (let annotation of (_b = this.annotations) !== null && _b !== void 0 ? _b : []) {
291
298
  result.push(...annotation.getTypedef(state), state.newline, state.indent());
292
299
  }
293
- result.push(...this.func.getTypedef(state, this.name));
300
+ result.push(...this.func.getTypedef(state));
294
301
  return result;
295
302
  }
296
303
  walk(visitor, options) {
297
304
  if (options.walkMode & visitors_1.InternalWalkMode.walkExpressions) {
298
- visitors_1.walk(this, 'func', visitor, options);
305
+ (0, visitors_1.walk)(this, 'func', visitor, options);
299
306
  }
300
307
  }
308
+ getType(options) {
309
+ const funcExprType = this.func.getType(options);
310
+ funcExprType.setName(this.getName(Parser_1.ParseMode.BrighterScript));
311
+ return funcExprType;
312
+ }
301
313
  }
302
314
  exports.FunctionStatement = FunctionStatement;
303
- class IfStatement extends Statement {
304
- constructor(tokens, condition, thenBranch, elseBranch, isInline) {
305
- var _a, _b;
315
+ class IfStatement extends AstNode_2.Statement {
316
+ constructor(options) {
306
317
  super();
307
- this.tokens = tokens;
308
- this.condition = condition;
309
- this.thenBranch = thenBranch;
310
- this.elseBranch = elseBranch;
311
- this.isInline = isInline;
312
- this.range = util_1.util.createRangeFromPositions(this.tokens.if.range.start, ((_b = (_a = this.tokens.endIf) !== null && _a !== void 0 ? _a : this.elseBranch) !== null && _b !== void 0 ? _b : this.thenBranch).range.end);
318
+ this.kind = AstNode_1.AstNodeKind.IfStatement;
319
+ this.condition = options.condition;
320
+ this.thenBranch = options.thenBranch;
321
+ this.elseBranch = options.elseBranch;
322
+ this.isInline = options.isInline;
323
+ this.tokens = {
324
+ if: options.if,
325
+ then: options.then,
326
+ else: options.else,
327
+ endIf: options.endIf
328
+ };
329
+ this.range = util_1.util.createBoundingRange(util_1.util.createBoundingRangeFromTokens(this.tokens), this.condition, this.thenBranch, this.elseBranch);
313
330
  }
314
331
  transpile(state) {
332
+ var _a, _b;
315
333
  let results = [];
316
334
  //if (already indented by block)
317
- results.push(state.transpileToken(this.tokens.if));
335
+ results.push(state.transpileToken((_a = this.tokens.if) !== null && _a !== void 0 ? _a : (0, creators_1.createToken)(TokenKind_1.TokenKind.If)));
318
336
  results.push(' ');
319
337
  //conditions
320
338
  results.push(...this.condition.transpile(state));
321
- results.push(' ');
322
339
  //then
323
340
  if (this.tokens.then) {
341
+ results.push(' ');
324
342
  results.push(state.transpileToken(this.tokens.then));
325
343
  }
326
- else {
327
- results.push('then');
328
- }
329
344
  state.lineage.unshift(this);
330
345
  //if statement body
331
346
  let thenNodes = this.thenBranch.transpile(state);
@@ -333,20 +348,18 @@ class IfStatement extends Statement {
333
348
  if (thenNodes.length > 0) {
334
349
  results.push(thenNodes);
335
350
  }
336
- results.push('\n');
337
351
  //else branch
338
- if (this.tokens.else) {
339
- //else
340
- results.push(state.indent(), state.transpileToken(this.tokens.else));
341
- }
342
352
  if (this.elseBranch) {
343
- if (reflection_1.isIfStatement(this.elseBranch)) {
353
+ //else
354
+ results.push(...state.transpileEndBlockToken(this.thenBranch, this.tokens.else, 'else'));
355
+ if ((0, reflection_1.isIfStatement)(this.elseBranch)) {
344
356
  //chained elseif
345
357
  state.lineage.unshift(this.elseBranch);
346
358
  let body = this.elseBranch.transpile(state);
347
359
  state.lineage.shift();
348
360
  if (body.length > 0) {
349
- results.push(' ');
361
+ //zero or more spaces between the `else` and the `if`
362
+ results.push(this.elseBranch.tokens.if.leadingWhitespace);
350
363
  results.push(...body);
351
364
  // stop here because chained if will transpile the rest
352
365
  return results;
@@ -357,74 +370,85 @@ class IfStatement extends Statement {
357
370
  }
358
371
  else {
359
372
  //else body
360
- state.lineage.unshift(this.elseBranch);
373
+ state.lineage.unshift(this.tokens.else);
361
374
  let body = this.elseBranch.transpile(state);
362
375
  state.lineage.shift();
363
376
  if (body.length > 0) {
364
377
  results.push(...body);
365
378
  }
366
- results.push('\n');
367
379
  }
368
380
  }
369
381
  //end if
370
- results.push(state.indent());
371
- if (this.tokens.endIf) {
372
- results.push(state.transpileToken(this.tokens.endIf));
373
- }
374
- else {
375
- results.push('end if');
376
- }
382
+ results.push(...state.transpileEndBlockToken((_b = this.elseBranch) !== null && _b !== void 0 ? _b : this.thenBranch, this.tokens.endIf, 'end if'));
377
383
  return results;
378
384
  }
379
385
  walk(visitor, options) {
380
386
  if (options.walkMode & visitors_1.InternalWalkMode.walkExpressions) {
381
- visitors_1.walk(this, 'condition', visitor, options);
387
+ (0, visitors_1.walk)(this, 'condition', visitor, options);
382
388
  }
383
389
  if (options.walkMode & visitors_1.InternalWalkMode.walkStatements) {
384
- visitors_1.walk(this, 'thenBranch', visitor, options);
390
+ (0, visitors_1.walk)(this, 'thenBranch', visitor, options);
385
391
  }
386
392
  if (this.elseBranch && options.walkMode & visitors_1.InternalWalkMode.walkStatements) {
387
- visitors_1.walk(this, 'elseBranch', visitor, options);
393
+ (0, visitors_1.walk)(this, 'elseBranch', visitor, options);
388
394
  }
389
395
  }
396
+ getLeadingTrivia() {
397
+ var _a, _b;
398
+ return (_b = (_a = this.tokens.if) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
399
+ }
400
+ getEndTrivia() {
401
+ var _a, _b;
402
+ return (_b = (_a = this.tokens.endIf) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
403
+ }
390
404
  }
391
405
  exports.IfStatement = IfStatement;
392
- class IncrementStatement extends Statement {
393
- constructor(value, operator) {
406
+ class IncrementStatement extends AstNode_2.Statement {
407
+ constructor(options) {
394
408
  super();
395
- this.value = value;
396
- this.operator = operator;
397
- this.range = util_1.util.createRangeFromPositions(this.value.range.start, this.operator.range.end);
409
+ this.kind = AstNode_1.AstNodeKind.IncrementStatement;
410
+ this.value = options.value;
411
+ this.tokens = {
412
+ operator: options.operator
413
+ };
414
+ this.range = util_1.util.createBoundingRange(this.value, this.tokens.operator);
398
415
  }
399
416
  transpile(state) {
400
417
  return [
401
418
  ...this.value.transpile(state),
402
- state.transpileToken(this.operator)
419
+ state.transpileToken(this.tokens.operator)
403
420
  ];
404
421
  }
405
422
  walk(visitor, options) {
406
423
  if (options.walkMode & visitors_1.InternalWalkMode.walkExpressions) {
407
- visitors_1.walk(this, 'value', visitor, options);
424
+ (0, visitors_1.walk)(this, 'value', visitor, options);
408
425
  }
409
426
  }
427
+ getLeadingTrivia() {
428
+ var _a, _b;
429
+ return (_b = (_a = this.value) === null || _a === void 0 ? void 0 : _a.getLeadingTrivia()) !== null && _b !== void 0 ? _b : [];
430
+ }
410
431
  }
411
432
  exports.IncrementStatement = IncrementStatement;
412
433
  /**
413
434
  * Represents a `print` statement within BrightScript.
414
435
  */
415
- class PrintStatement extends Statement {
436
+ class PrintStatement extends AstNode_2.Statement {
416
437
  /**
417
438
  * Creates a new internal representation of a BrightScript `print` statement.
418
- * @param expressions an array of expressions or `PrintSeparator`s to be
419
- * evaluated and printed.
439
+ * @param options the options for this statement
440
+ * @param options.print a print token
441
+ * @param options.expressions an array of expressions or `PrintSeparator`s to be evaluated and printed.
420
442
  */
421
- constructor(tokens, expressions) {
443
+ constructor(options) {
444
+ var _a;
422
445
  super();
423
- this.tokens = tokens;
424
- this.expressions = expressions;
425
- this.range = util_1.util.createRangeFromPositions(this.tokens.print.range.start, this.expressions.length
426
- ? this.expressions[this.expressions.length - 1].range.end
427
- : this.tokens.print.range.end);
446
+ this.kind = AstNode_1.AstNodeKind.PrintStatement;
447
+ this.tokens = {
448
+ print: options.print
449
+ };
450
+ this.expressions = options.expressions;
451
+ this.range = util_1.util.createBoundingRange(this.tokens.print, ...((_a = this.expressions) !== null && _a !== void 0 ? _a : []));
428
452
  }
429
453
  transpile(state) {
430
454
  var _a;
@@ -449,33 +473,36 @@ class PrintStatement extends Statement {
449
473
  }
450
474
  walk(visitor, options) {
451
475
  if (options.walkMode & visitors_1.InternalWalkMode.walkExpressions) {
452
- for (let i = 0; i < this.expressions.length; i++) {
453
- //sometimes we have semicolon `Token`s in the expressions list (should probably fix that...), so only emit the actual expressions
454
- if (reflection_1.isExpression(this.expressions[i])) {
455
- visitors_1.walk(this.expressions, i, visitor, options, this);
456
- }
457
- }
476
+ //sometimes we have semicolon Tokens in the expressions list (should probably fix that...), so only walk the actual expressions
477
+ (0, visitors_1.walkArray)(this.expressions, visitor, options, this, (item) => (0, reflection_1.isExpression)(item));
458
478
  }
459
479
  }
480
+ getLeadingTrivia() {
481
+ var _a, _b;
482
+ return (_b = (_a = this.tokens.print) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
483
+ }
460
484
  }
461
485
  exports.PrintStatement = PrintStatement;
462
- class DimStatement extends Statement {
463
- constructor(dimToken, identifier, openingSquare, dimensions, closingSquare) {
464
- var _a, _b, _c, _d;
486
+ class DimStatement extends AstNode_2.Statement {
487
+ constructor(options) {
488
+ var _a;
465
489
  super();
466
- this.dimToken = dimToken;
467
- this.identifier = identifier;
468
- this.openingSquare = openingSquare;
469
- this.dimensions = dimensions;
470
- this.closingSquare = closingSquare;
471
- this.range = util_1.util.createRangeFromPositions(this.dimToken.range.start, ((_d = (_c = (_b = (_a = this.closingSquare) !== null && _a !== void 0 ? _a : this.dimensions[this.dimensions.length - 1]) !== null && _b !== void 0 ? _b : this.openingSquare) !== null && _c !== void 0 ? _c : this.identifier) !== null && _d !== void 0 ? _d : this.dimToken).range.end);
490
+ this.kind = AstNode_1.AstNodeKind.DimStatement;
491
+ this.tokens = {
492
+ dim: options === null || options === void 0 ? void 0 : options.dim,
493
+ name: options.name,
494
+ openingSquare: options.openingSquare,
495
+ closingSquare: options.closingSquare
496
+ };
497
+ this.dimensions = options.dimensions;
498
+ this.range = util_1.util.createBoundingRange(options.dim, options.name, options.openingSquare, ...((_a = this.dimensions) !== null && _a !== void 0 ? _a : []), options.closingSquare);
472
499
  }
473
500
  transpile(state) {
474
501
  let result = [
475
- state.transpileToken(this.dimToken),
502
+ state.transpileToken(this.tokens.dim, 'dim'),
476
503
  ' ',
477
- state.transpileToken(this.identifier),
478
- state.transpileToken(this.openingSquare)
504
+ state.transpileToken(this.tokens.name),
505
+ state.transpileToken(this.tokens.openingSquare, '[')
479
506
  ];
480
507
  for (let i = 0; i < this.dimensions.length; i++) {
481
508
  if (i > 0) {
@@ -483,28 +510,43 @@ class DimStatement extends Statement {
483
510
  }
484
511
  result.push(...this.dimensions[i].transpile(state));
485
512
  }
486
- result.push(state.transpileToken(this.closingSquare));
513
+ result.push(state.transpileToken(this.tokens.closingSquare, ']'));
487
514
  return result;
488
515
  }
489
516
  walk(visitor, options) {
490
- var _a;
491
- if (((_a = this.dimensions) === null || _a === void 0 ? void 0 : _a.length) > 0 && options.walkMode & visitors_1.InternalWalkMode.walkExpressions) {
492
- for (let i = 0; i < this.dimensions.length; i++) {
493
- visitors_1.walk(this.dimensions, i, visitor, options, this);
494
- }
517
+ var _a, _b;
518
+ if (((_a = this.dimensions) === null || _a === void 0 ? void 0 : _a.length) !== undefined && ((_b = this.dimensions) === null || _b === void 0 ? void 0 : _b.length) > 0 && options.walkMode & visitors_1.InternalWalkMode.walkExpressions) {
519
+ (0, visitors_1.walkArray)(this.dimensions, visitor, options, this);
520
+ }
521
+ }
522
+ getType(options) {
523
+ var _a, _b;
524
+ const numDimensions = (_b = (_a = this.dimensions) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 1;
525
+ let type = new ArrayType_1.ArrayType();
526
+ for (let i = 0; i < numDimensions - 1; i++) {
527
+ type = new ArrayType_1.ArrayType(type);
495
528
  }
529
+ return type;
530
+ }
531
+ getLeadingTrivia() {
532
+ var _a, _b;
533
+ return (_b = (_a = this.tokens.dim) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
496
534
  }
497
535
  }
498
536
  exports.DimStatement = DimStatement;
499
- class GotoStatement extends Statement {
500
- constructor(tokens) {
537
+ class GotoStatement extends AstNode_2.Statement {
538
+ constructor(options) {
501
539
  super();
502
- this.tokens = tokens;
503
- this.range = util_1.util.createRangeFromPositions(this.tokens.goto.range.start, this.tokens.label.range.end);
540
+ this.kind = AstNode_1.AstNodeKind.GotoStatement;
541
+ this.tokens = {
542
+ goto: options.goto,
543
+ label: options.label
544
+ };
545
+ this.range = util_1.util.createBoundingRange(this.tokens.goto, this.tokens.label);
504
546
  }
505
547
  transpile(state) {
506
548
  return [
507
- state.transpileToken(this.tokens.goto),
549
+ state.transpileToken(this.tokens.goto, 'goto'),
508
550
  ' ',
509
551
  state.transpileToken(this.tokens.label)
510
552
  ];
@@ -512,18 +554,29 @@ class GotoStatement extends Statement {
512
554
  walk(visitor, options) {
513
555
  //nothing to walk
514
556
  }
557
+ getLeadingTrivia() {
558
+ var _a, _b;
559
+ return (_b = (_a = this.tokens.goto) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
560
+ }
515
561
  }
516
562
  exports.GotoStatement = GotoStatement;
517
- class LabelStatement extends Statement {
518
- constructor(tokens) {
563
+ class LabelStatement extends AstNode_2.Statement {
564
+ constructor(options) {
519
565
  super();
520
- this.tokens = tokens;
521
- this.range = util_1.util.createRangeFromPositions(this.tokens.identifier.range.start, this.tokens.colon.range.end);
566
+ this.kind = AstNode_1.AstNodeKind.LabelStatement;
567
+ this.tokens = {
568
+ name: options.name,
569
+ colon: options.colon
570
+ };
571
+ this.range = util_1.util.createBoundingRange(this.tokens.name, this.tokens.colon);
572
+ }
573
+ getLeadingTrivia() {
574
+ return util_1.util.concatAnnotationLeadingTrivia(this, this.tokens.name.leadingTrivia);
522
575
  }
523
576
  transpile(state) {
524
577
  return [
525
- state.transpileToken(this.tokens.identifier),
526
- state.transpileToken(this.tokens.colon)
578
+ state.transpileToken(this.tokens.name),
579
+ state.transpileToken(this.tokens.colon, ':')
527
580
  ];
528
581
  }
529
582
  walk(visitor, options) {
@@ -531,17 +584,19 @@ class LabelStatement extends Statement {
531
584
  }
532
585
  }
533
586
  exports.LabelStatement = LabelStatement;
534
- class ReturnStatement extends Statement {
535
- constructor(tokens, value) {
536
- var _a;
587
+ class ReturnStatement extends AstNode_2.Statement {
588
+ constructor(options) {
537
589
  super();
538
- this.tokens = tokens;
539
- this.value = value;
540
- this.range = util_1.util.createRangeFromPositions(this.tokens.return.range.start, ((_a = this.value) === null || _a === void 0 ? void 0 : _a.range.end) || this.tokens.return.range.end);
590
+ this.kind = AstNode_1.AstNodeKind.ReturnStatement;
591
+ this.tokens = {
592
+ return: options === null || options === void 0 ? void 0 : options.return
593
+ };
594
+ this.value = options === null || options === void 0 ? void 0 : options.value;
595
+ this.range = util_1.util.createBoundingRange(this.tokens.return, this.value);
541
596
  }
542
597
  transpile(state) {
543
598
  let result = [];
544
- result.push(state.transpileToken(this.tokens.return));
599
+ result.push(state.transpileToken(this.tokens.return, 'return'));
545
600
  if (this.value) {
546
601
  result.push(' ');
547
602
  result.push(...this.value.transpile(state));
@@ -550,197 +605,243 @@ class ReturnStatement extends Statement {
550
605
  }
551
606
  walk(visitor, options) {
552
607
  if (options.walkMode & visitors_1.InternalWalkMode.walkExpressions) {
553
- visitors_1.walk(this, 'value', visitor, options);
608
+ (0, visitors_1.walk)(this, 'value', visitor, options);
554
609
  }
555
610
  }
611
+ getLeadingTrivia() {
612
+ var _a, _b;
613
+ return (_b = (_a = this.tokens.return) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
614
+ }
556
615
  }
557
616
  exports.ReturnStatement = ReturnStatement;
558
- class EndStatement extends Statement {
559
- constructor(tokens) {
617
+ class EndStatement extends AstNode_2.Statement {
618
+ constructor(options) {
619
+ var _a;
560
620
  super();
561
- this.tokens = tokens;
562
- this.range = util_1.util.createRangeFromPositions(this.tokens.end.range.start, this.tokens.end.range.end);
621
+ this.kind = AstNode_1.AstNodeKind.EndStatement;
622
+ this.tokens = {
623
+ end: options === null || options === void 0 ? void 0 : options.end
624
+ };
625
+ this.range = (_a = this.tokens.end) === null || _a === void 0 ? void 0 : _a.range;
563
626
  }
564
627
  transpile(state) {
565
628
  return [
566
- state.transpileToken(this.tokens.end)
629
+ state.transpileToken(this.tokens.end, 'end')
567
630
  ];
568
631
  }
569
632
  walk(visitor, options) {
570
633
  //nothing to walk
571
634
  }
635
+ getLeadingTrivia() {
636
+ var _a, _b;
637
+ return (_b = (_a = this.tokens.end) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
638
+ }
572
639
  }
573
640
  exports.EndStatement = EndStatement;
574
- class StopStatement extends Statement {
575
- constructor(tokens) {
641
+ class StopStatement extends AstNode_2.Statement {
642
+ constructor(options) {
643
+ var _a, _b;
576
644
  super();
577
- this.tokens = tokens;
578
- this.range = util_1.util.createRangeFromPositions(this.tokens.stop.range.start, this.tokens.stop.range.end);
645
+ this.kind = AstNode_1.AstNodeKind.StopStatement;
646
+ this.tokens = { stop: options === null || options === void 0 ? void 0 : options.stop };
647
+ this.range = (_b = (_a = this.tokens) === null || _a === void 0 ? void 0 : _a.stop) === null || _b === void 0 ? void 0 : _b.range;
579
648
  }
580
649
  transpile(state) {
581
650
  return [
582
- state.transpileToken(this.tokens.stop)
651
+ state.transpileToken(this.tokens.stop, 'stop')
583
652
  ];
584
653
  }
585
654
  walk(visitor, options) {
586
655
  //nothing to walk
587
656
  }
657
+ getLeadingTrivia() {
658
+ var _a, _b;
659
+ return (_b = (_a = this.tokens.stop) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
660
+ }
588
661
  }
589
662
  exports.StopStatement = StopStatement;
590
- class ForStatement extends Statement {
591
- constructor(forToken, counterDeclaration, toToken, finalValue, body, endForToken, stepToken, increment) {
592
- var _a, _b;
663
+ class ForStatement extends AstNode_2.Statement {
664
+ constructor(options) {
593
665
  super();
594
- this.forToken = forToken;
595
- this.counterDeclaration = counterDeclaration;
596
- this.toToken = toToken;
597
- this.finalValue = finalValue;
598
- this.body = body;
599
- this.endForToken = endForToken;
600
- this.stepToken = stepToken;
601
- this.increment = increment;
602
- const lastRange = (_b = (_a = this.endForToken) === null || _a === void 0 ? void 0 : _a.range) !== null && _b !== void 0 ? _b : body.range;
603
- this.range = util_1.util.createRangeFromPositions(this.forToken.range.start, lastRange.end);
666
+ this.kind = AstNode_1.AstNodeKind.ForStatement;
667
+ this.tokens = {
668
+ for: options.for,
669
+ to: options.to,
670
+ endFor: options.endFor,
671
+ step: options.step
672
+ };
673
+ this.counterDeclaration = options.counterDeclaration;
674
+ this.finalValue = options.finalValue;
675
+ this.body = options.body;
676
+ this.increment = options.increment;
677
+ this.range = util_1.util.createBoundingRange(this.tokens.for, this.counterDeclaration, this.tokens.to, this.finalValue, this.tokens.step, this.increment, this.body, this.tokens.endFor);
604
678
  }
605
679
  transpile(state) {
606
680
  let result = [];
607
681
  //for
608
- result.push(state.transpileToken(this.forToken), ' ');
682
+ result.push(state.transpileToken(this.tokens.for, 'for'), ' ');
609
683
  //i=1
610
684
  result.push(...this.counterDeclaration.transpile(state), ' ');
611
685
  //to
612
- result.push(state.transpileToken(this.toToken), ' ');
686
+ result.push(state.transpileToken(this.tokens.to, 'to'), ' ');
613
687
  //final value
614
688
  result.push(this.finalValue.transpile(state));
615
689
  //step
616
- if (this.stepToken) {
617
- result.push(' ', state.transpileToken(this.stepToken), ' ', this.increment.transpile(state));
690
+ if (this.increment) {
691
+ result.push(' ', state.transpileToken(this.tokens.step, 'step'), ' ', this.increment.transpile(state));
618
692
  }
619
693
  //loop body
620
694
  state.lineage.unshift(this);
621
695
  result.push(...this.body.transpile(state));
622
696
  state.lineage.shift();
623
- if (this.body.statements.length > 0) {
624
- result.push('\n');
625
- }
626
697
  //end for
627
- result.push(state.indent(), state.transpileToken(this.endForToken));
698
+ result.push(...state.transpileEndBlockToken(this.body, this.tokens.endFor, 'end for'));
628
699
  return result;
629
700
  }
630
701
  walk(visitor, options) {
631
702
  if (options.walkMode & visitors_1.InternalWalkMode.walkStatements) {
632
- visitors_1.walk(this, 'counterDeclaration', visitor, options);
703
+ (0, visitors_1.walk)(this, 'counterDeclaration', visitor, options);
633
704
  }
634
705
  if (options.walkMode & visitors_1.InternalWalkMode.walkExpressions) {
635
- visitors_1.walk(this, 'finalValue', visitor, options);
636
- visitors_1.walk(this, 'increment', visitor, options);
706
+ (0, visitors_1.walk)(this, 'finalValue', visitor, options);
707
+ (0, visitors_1.walk)(this, 'increment', visitor, options);
637
708
  }
638
709
  if (options.walkMode & visitors_1.InternalWalkMode.walkStatements) {
639
- visitors_1.walk(this, 'body', visitor, options);
710
+ (0, visitors_1.walk)(this, 'body', visitor, options);
640
711
  }
641
712
  }
713
+ getLeadingTrivia() {
714
+ var _a, _b;
715
+ return (_b = (_a = this.tokens.for) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
716
+ }
717
+ getEndTrivia() {
718
+ var _a, _b;
719
+ return (_b = (_a = this.tokens.endFor) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
720
+ }
642
721
  }
643
722
  exports.ForStatement = ForStatement;
644
- class ForEachStatement extends Statement {
645
- constructor(forEachToken, item, inToken, target, body, endForToken) {
646
- var _a, _b, _c, _d, _e;
723
+ class ForEachStatement extends AstNode_2.Statement {
724
+ constructor(options) {
647
725
  super();
648
- this.forEachToken = forEachToken;
649
- this.item = item;
650
- this.inToken = inToken;
651
- this.target = target;
652
- this.body = body;
653
- this.endForToken = endForToken;
654
- this.range = util_1.util.createRangeFromPositions(this.forEachToken.range.start, ((_e = (_d = (_c = (_b = (_a = this.endForToken) !== null && _a !== void 0 ? _a : this.body) !== null && _b !== void 0 ? _b : this.target) !== null && _c !== void 0 ? _c : this.inToken) !== null && _d !== void 0 ? _d : this.item) !== null && _e !== void 0 ? _e : this.forEachToken).range.end);
726
+ this.kind = AstNode_1.AstNodeKind.ForEachStatement;
727
+ this.tokens = {
728
+ forEach: options.forEach,
729
+ item: options.item,
730
+ in: options.in,
731
+ endFor: options.endFor
732
+ };
733
+ this.body = options.body;
734
+ this.target = options.target;
735
+ this.range = util_1.util.createBoundingRange(this.tokens.forEach, this.tokens.item, this.tokens.in, this.target, this.body, this.tokens.endFor);
655
736
  }
656
737
  transpile(state) {
657
738
  let result = [];
658
739
  //for each
659
- result.push(state.transpileToken(this.forEachToken), ' ');
740
+ result.push(state.transpileToken(this.tokens.forEach, 'for each'), ' ');
660
741
  //item
661
- result.push(state.transpileToken(this.item), ' ');
742
+ result.push(state.transpileToken(this.tokens.item), ' ');
662
743
  //in
663
- result.push(state.transpileToken(this.inToken), ' ');
744
+ result.push(state.transpileToken(this.tokens.in, 'in'), ' ');
664
745
  //target
665
746
  result.push(...this.target.transpile(state));
666
747
  //body
667
748
  state.lineage.unshift(this);
668
749
  result.push(...this.body.transpile(state));
669
750
  state.lineage.shift();
670
- if (this.body.statements.length > 0) {
671
- result.push('\n');
672
- }
673
751
  //end for
674
- result.push(state.indent(), state.transpileToken(this.endForToken));
752
+ result.push(...state.transpileEndBlockToken(this.body, this.tokens.endFor, 'end for'));
675
753
  return result;
676
754
  }
677
755
  walk(visitor, options) {
678
756
  if (options.walkMode & visitors_1.InternalWalkMode.walkExpressions) {
679
- visitors_1.walk(this, 'target', visitor, options);
757
+ (0, visitors_1.walk)(this, 'target', visitor, options);
680
758
  }
681
759
  if (options.walkMode & visitors_1.InternalWalkMode.walkStatements) {
682
- visitors_1.walk(this, 'body', visitor, options);
760
+ (0, visitors_1.walk)(this, 'body', visitor, options);
683
761
  }
684
762
  }
763
+ getType(options) {
764
+ return this.getSymbolTable().getSymbolType(this.tokens.item.text, options);
765
+ }
766
+ getLeadingTrivia() {
767
+ var _a, _b;
768
+ return (_b = (_a = this.tokens.forEach) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
769
+ }
770
+ getEndTrivia() {
771
+ var _a, _b;
772
+ return (_b = (_a = this.tokens.endFor) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
773
+ }
685
774
  }
686
775
  exports.ForEachStatement = ForEachStatement;
687
- class WhileStatement extends Statement {
688
- constructor(tokens, condition, body) {
689
- var _a, _b;
776
+ class WhileStatement extends AstNode_2.Statement {
777
+ constructor(options) {
690
778
  super();
691
- this.tokens = tokens;
692
- this.condition = condition;
693
- this.body = body;
694
- const lastRange = (_b = (_a = this.tokens.endWhile) === null || _a === void 0 ? void 0 : _a.range) !== null && _b !== void 0 ? _b : body.range;
695
- this.range = util_1.util.createRangeFromPositions(this.tokens.while.range.start, lastRange.end);
779
+ this.kind = AstNode_1.AstNodeKind.WhileStatement;
780
+ this.tokens = {
781
+ while: options.while,
782
+ endWhile: options.endWhile
783
+ };
784
+ this.body = options.body;
785
+ this.condition = options.condition;
786
+ this.range = util_1.util.createBoundingRange(this.tokens.while, this.condition, this.body, this.tokens.endWhile);
696
787
  }
697
788
  transpile(state) {
698
789
  let result = [];
699
790
  //while
700
- result.push(state.transpileToken(this.tokens.while), ' ');
791
+ result.push(state.transpileToken(this.tokens.while, 'while'), ' ');
701
792
  //condition
702
793
  result.push(...this.condition.transpile(state));
703
794
  state.lineage.unshift(this);
704
795
  //body
705
796
  result.push(...this.body.transpile(state));
706
797
  state.lineage.shift();
707
- //trailing newline only if we have body statements
708
- result.push('\n');
709
798
  //end while
710
- result.push(state.indent(), state.transpileToken(this.tokens.endWhile));
799
+ result.push(...state.transpileEndBlockToken(this.body, this.tokens.endWhile, 'end while'));
711
800
  return result;
712
801
  }
713
802
  walk(visitor, options) {
714
803
  if (options.walkMode & visitors_1.InternalWalkMode.walkExpressions) {
715
- visitors_1.walk(this, 'condition', visitor, options);
804
+ (0, visitors_1.walk)(this, 'condition', visitor, options);
716
805
  }
717
806
  if (options.walkMode & visitors_1.InternalWalkMode.walkStatements) {
718
- visitors_1.walk(this, 'body', visitor, options);
807
+ (0, visitors_1.walk)(this, 'body', visitor, options);
719
808
  }
720
809
  }
810
+ getLeadingTrivia() {
811
+ var _a, _b;
812
+ return (_b = (_a = this.tokens.while) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
813
+ }
814
+ getEndTrivia() {
815
+ var _a, _b;
816
+ return (_b = (_a = this.tokens.endWhile) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
817
+ }
721
818
  }
722
819
  exports.WhileStatement = WhileStatement;
723
- class DottedSetStatement extends Statement {
724
- constructor(obj, name, value) {
820
+ class DottedSetStatement extends AstNode_2.Statement {
821
+ constructor(options) {
725
822
  super();
726
- this.obj = obj;
727
- this.name = name;
728
- this.value = value;
729
- this.range = util_1.util.createRangeFromPositions(this.obj.range.start, this.value.range.end);
823
+ this.kind = AstNode_1.AstNodeKind.DottedSetStatement;
824
+ this.tokens = {
825
+ name: options.name,
826
+ dot: options.dot
827
+ };
828
+ this.obj = options.obj;
829
+ this.value = options.value;
830
+ this.range = util_1.util.createBoundingRange(this.obj, this.tokens.dot, this.tokens.name, this.value);
730
831
  }
731
832
  transpile(state) {
732
- var _a, _b;
833
+ var _a, _b, _c;
733
834
  //if the value is a compound assignment, don't add the obj, dot, name, or operator...the expression will handle that
734
- if (lexer_1.CompoundAssignmentOperators.includes((_b = (_a = this.value) === null || _a === void 0 ? void 0 : _a.operator) === null || _b === void 0 ? void 0 : _b.kind)) {
835
+ if (TokenKind_1.CompoundAssignmentOperators.includes((_c = (_b = (_a = this.value) === null || _a === void 0 ? void 0 : _a.tokens) === null || _b === void 0 ? void 0 : _b.operator) === null || _c === void 0 ? void 0 : _c.kind)) {
735
836
  return this.value.transpile(state);
736
837
  }
737
838
  else {
738
839
  return [
739
840
  //object
740
841
  ...this.obj.transpile(state),
741
- '.',
842
+ this.tokens.dot ? state.tokenToSourceNode(this.tokens.dot) : '.',
742
843
  //name
743
- state.transpileToken(this.name),
844
+ state.transpileToken(this.tokens.name),
744
845
  ' = ',
745
846
  //right-hand-side of assignment
746
847
  ...this.value.transpile(state)
@@ -749,59 +850,86 @@ class DottedSetStatement extends Statement {
749
850
  }
750
851
  walk(visitor, options) {
751
852
  if (options.walkMode & visitors_1.InternalWalkMode.walkExpressions) {
752
- visitors_1.walk(this, 'obj', visitor, options);
753
- visitors_1.walk(this, 'value', visitor, options);
853
+ (0, visitors_1.walk)(this, 'obj', visitor, options);
854
+ (0, visitors_1.walk)(this, 'value', visitor, options);
754
855
  }
755
856
  }
857
+ getType(options) {
858
+ var _a, _b, _c, _d, _e;
859
+ const objType = (_a = this.obj) === null || _a === void 0 ? void 0 : _a.getType(options);
860
+ const result = objType === null || objType === void 0 ? void 0 : objType.getMemberType((_b = this.tokens.name) === null || _b === void 0 ? void 0 : _b.text, options);
861
+ (_c = options.typeChain) === null || _c === void 0 ? void 0 : _c.push(new interfaces_1.TypeChainEntry({
862
+ name: (_d = this.tokens.name) === null || _d === void 0 ? void 0 : _d.text,
863
+ type: result, data: options.data,
864
+ range: (_e = this.tokens.name) === null || _e === void 0 ? void 0 : _e.range,
865
+ astNode: this
866
+ }));
867
+ return result;
868
+ }
869
+ getLeadingTrivia() {
870
+ return this.obj.getLeadingTrivia();
871
+ }
756
872
  }
757
873
  exports.DottedSetStatement = DottedSetStatement;
758
- class IndexedSetStatement extends Statement {
759
- constructor(obj, index, value, openingSquare, closingSquare) {
874
+ class IndexedSetStatement extends AstNode_2.Statement {
875
+ constructor(options) {
760
876
  super();
761
- this.obj = obj;
762
- this.index = index;
763
- this.value = value;
764
- this.openingSquare = openingSquare;
765
- this.closingSquare = closingSquare;
766
- this.range = util_1.util.createRangeFromPositions(this.obj.range.start, this.value.range.end);
877
+ this.kind = AstNode_1.AstNodeKind.IndexedSetStatement;
878
+ this.tokens = {
879
+ openingSquare: options.openingSquare,
880
+ closingSquare: options.closingSquare
881
+ };
882
+ this.obj = options.obj;
883
+ this.indexes = options.indexes;
884
+ this.value = options.value;
885
+ this.range = util_1.util.createBoundingRange(this.obj, this.tokens.openingSquare, ...this.indexes, this.tokens.closingSquare, this.value);
767
886
  }
768
887
  transpile(state) {
769
- var _a, _b;
888
+ var _a, _b, _c, _d;
770
889
  //if the value is a component assignment, don't add the obj, index or operator...the expression will handle that
771
- if (lexer_1.CompoundAssignmentOperators.includes((_b = (_a = this.value) === null || _a === void 0 ? void 0 : _a.operator) === null || _b === void 0 ? void 0 : _b.kind)) {
890
+ if (TokenKind_1.CompoundAssignmentOperators.includes((_c = (_b = (_a = this.value) === null || _a === void 0 ? void 0 : _a.tokens) === null || _b === void 0 ? void 0 : _b.operator) === null || _c === void 0 ? void 0 : _c.kind)) {
772
891
  return this.value.transpile(state);
773
892
  }
774
893
  else {
775
- return [
776
- //obj
777
- ...this.obj.transpile(state),
778
- // [
779
- state.transpileToken(this.openingSquare),
780
- // index
781
- ...this.index.transpile(state),
782
- // ]
783
- state.transpileToken(this.closingSquare),
784
- // =
785
- ' = ',
786
- // value
787
- ...this.value.transpile(state)
788
- ];
894
+ const result = [];
895
+ result.push(
896
+ //obj
897
+ ...this.obj.transpile(state),
898
+ // [
899
+ state.transpileToken(this.tokens.openingSquare));
900
+ for (let i = 0; i < this.indexes.length; i++) {
901
+ //add comma between indexes
902
+ if (i > 0) {
903
+ result.push(', ');
904
+ }
905
+ let index = this.indexes[i];
906
+ result.push(...((_d = index === null || index === void 0 ? void 0 : index.transpile(state)) !== null && _d !== void 0 ? _d : []));
907
+ }
908
+ result.push(state.transpileToken(this.tokens.closingSquare), ' = ', ...this.value.transpile(state));
909
+ return result;
789
910
  }
790
911
  }
791
912
  walk(visitor, options) {
792
913
  if (options.walkMode & visitors_1.InternalWalkMode.walkExpressions) {
793
- visitors_1.walk(this, 'obj', visitor, options);
794
- visitors_1.walk(this, 'index', visitor, options);
795
- visitors_1.walk(this, 'value', visitor, options);
914
+ (0, visitors_1.walk)(this, 'obj', visitor, options);
915
+ (0, visitors_1.walkArray)(this.indexes, visitor, options, this);
916
+ (0, visitors_1.walk)(this, 'value', visitor, options);
796
917
  }
797
918
  }
919
+ getLeadingTrivia() {
920
+ return this.obj.getLeadingTrivia();
921
+ }
798
922
  }
799
923
  exports.IndexedSetStatement = IndexedSetStatement;
800
- class LibraryStatement extends Statement {
801
- constructor(tokens) {
924
+ class LibraryStatement extends AstNode_2.Statement {
925
+ constructor(options) {
802
926
  super();
803
- this.tokens = tokens;
804
- this.range = util_1.util.createRangeFromPositions(this.tokens.library.range.start, this.tokens.filePath ? this.tokens.filePath.range.end : this.tokens.library.range.end);
927
+ this.kind = AstNode_1.AstNodeKind.LibraryStatement;
928
+ this.tokens = {
929
+ library: options.library,
930
+ filePath: options.filePath
931
+ };
932
+ this.range = util_1.util.createBoundingRange(this.tokens.library, this.tokens.filePath);
805
933
  }
806
934
  transpile(state) {
807
935
  let result = [];
@@ -818,38 +946,70 @@ class LibraryStatement extends Statement {
818
946
  walk(visitor, options) {
819
947
  //nothing to walk
820
948
  }
949
+ getLeadingTrivia() {
950
+ var _a, _b;
951
+ return (_b = (_a = this.tokens.library) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
952
+ }
821
953
  }
822
954
  exports.LibraryStatement = LibraryStatement;
823
- class NamespaceStatement extends Statement {
824
- constructor(keyword,
825
- //this should technically only be a VariableExpression or DottedGetExpression, but that can be enforced elsewhere
826
- nameExpression, body, endKeyword, parentSymbolTable) {
955
+ class NamespaceStatement extends AstNode_2.Statement {
956
+ constructor(options) {
827
957
  super();
828
- this.keyword = keyword;
829
- this.nameExpression = nameExpression;
830
- this.body = body;
831
- this.endKeyword = endKeyword;
832
- this.parentSymbolTable = parentSymbolTable;
833
- this.name = this.nameExpression.getName(Parser_1.ParseMode.BrighterScript);
834
- this.symbolTable = new SymbolTable_1.SymbolTable(parentSymbolTable);
958
+ this.kind = AstNode_1.AstNodeKind.NamespaceStatement;
959
+ this.tokens = {
960
+ namespace: options.namespace,
961
+ endNamespace: options.endNamespace
962
+ };
963
+ this.nameExpression = options.nameExpression;
964
+ this.body = options.body;
965
+ this.name = this.getName(Parser_1.ParseMode.BrighterScript);
966
+ this.symbolTable = new SymbolTable_1.SymbolTable(`NamespaceStatement: '${this.name}'`, () => { var _a; return (_a = this.parent) === null || _a === void 0 ? void 0 : _a.getSymbolTable(); });
835
967
  }
836
968
  get range() {
837
- var _a, _b, _c;
838
- return util_1.util.createRangeFromPositions(this.keyword.range.start, ((_c = (_b = (_a = this.endKeyword) !== null && _a !== void 0 ? _a : this.body) !== null && _b !== void 0 ? _b : this.nameExpression) !== null && _c !== void 0 ? _c : this.keyword).range.end);
969
+ return this.cacheRange();
970
+ }
971
+ cacheRange() {
972
+ if (!this._range) {
973
+ this._range = util_1.util.createBoundingRange(this.tokens.namespace, this.nameExpression, this.body, this.tokens.endNamespace);
974
+ }
975
+ return this._range;
839
976
  }
840
977
  getName(parseMode) {
841
- return this.nameExpression.getName(parseMode);
978
+ var _a, _b;
979
+ const sep = parseMode === Parser_1.ParseMode.BrighterScript ? '.' : '_';
980
+ let name = util_1.util.getAllDottedGetPartsAsString(this.nameExpression, parseMode);
981
+ if (((_b = (_a = this.parent) === null || _a === void 0 ? void 0 : _a.parent) === null || _b === void 0 ? void 0 : _b.kind) === AstNode_1.AstNodeKind.NamespaceStatement) {
982
+ name = this.parent.parent.getName(parseMode) + sep + name;
983
+ }
984
+ return name;
985
+ }
986
+ getLeadingTrivia() {
987
+ var _a;
988
+ return util_1.util.concatAnnotationLeadingTrivia(this, (_a = this.tokens.namespace) === null || _a === void 0 ? void 0 : _a.leadingTrivia);
989
+ }
990
+ getEndTrivia() {
991
+ var _a, _b;
992
+ return (_b = (_a = this.tokens.endNamespace) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
993
+ }
994
+ getNameParts() {
995
+ var _a, _b;
996
+ let parts = util_1.util.getAllDottedGetParts(this.nameExpression);
997
+ if (((_b = (_a = this.parent) === null || _a === void 0 ? void 0 : _a.parent) === null || _b === void 0 ? void 0 : _b.kind) === AstNode_1.AstNodeKind.NamespaceStatement) {
998
+ parts = this.parent.parent.getNameParts().concat(parts);
999
+ }
1000
+ return parts;
842
1001
  }
843
1002
  transpile(state) {
844
1003
  //namespaces don't actually have any real content, so just transpile their bodies
845
1004
  return this.body.transpile(state);
846
1005
  }
847
1006
  getTypedef(state) {
848
- let result = [
849
- 'namespace ',
850
- ...this.nameExpression.getName(Parser_1.ParseMode.BrighterScript),
851
- state.newline
852
- ];
1007
+ var _a;
1008
+ let result = [];
1009
+ for (let comment of (_a = util_1.util.getLeadingComments(this)) !== null && _a !== void 0 ? _a : []) {
1010
+ result.push(comment.text, state.newline, state.indent());
1011
+ }
1012
+ result.push('namespace ', ...this.getName(Parser_1.ParseMode.BrighterScript), state.newline);
853
1013
  state.blockDepth++;
854
1014
  result.push(...this.body.getTypedef(state));
855
1015
  state.blockDepth--;
@@ -858,25 +1018,35 @@ class NamespaceStatement extends Statement {
858
1018
  }
859
1019
  walk(visitor, options) {
860
1020
  if (options.walkMode & visitors_1.InternalWalkMode.walkExpressions) {
861
- visitors_1.walk(this, 'nameExpression', visitor, options);
1021
+ (0, visitors_1.walk)(this, 'nameExpression', visitor, options);
862
1022
  }
863
1023
  if (this.body.statements.length > 0 && options.walkMode & visitors_1.InternalWalkMode.walkStatements) {
864
- visitors_1.walk(this, 'body', visitor, options);
1024
+ (0, visitors_1.walk)(this, 'body', visitor, options);
865
1025
  }
866
1026
  }
1027
+ getType(options) {
1028
+ const resultType = new NamespaceType_1.NamespaceType(this.name);
1029
+ return resultType;
1030
+ }
867
1031
  }
868
1032
  exports.NamespaceStatement = NamespaceStatement;
869
- class ImportStatement extends Statement {
870
- constructor(importToken, filePathToken) {
1033
+ class ImportStatement extends AstNode_2.Statement {
1034
+ constructor(options) {
1035
+ var _a;
871
1036
  super();
872
- this.importToken = importToken;
873
- this.filePathToken = filePathToken;
874
- this.range = util_1.util.createRangeFromPositions(importToken.range.start, (filePathToken !== null && filePathToken !== void 0 ? filePathToken : importToken).range.end);
875
- if (this.filePathToken) {
1037
+ this.kind = AstNode_1.AstNodeKind.ImportStatement;
1038
+ this.tokens = {
1039
+ import: options.import,
1040
+ path: options.path
1041
+ };
1042
+ this.range = util_1.util.createBoundingRange(this.tokens.import, this.tokens.path);
1043
+ if (this.tokens.path) {
876
1044
  //remove quotes
877
- this.filePath = this.filePathToken.text.replace(/"/g, '');
878
- //adjust the range to exclude the quotes
879
- this.filePathToken.range = util_1.util.createRange(this.filePathToken.range.start.line, this.filePathToken.range.start.character + 1, this.filePathToken.range.end.line, this.filePathToken.range.end.character - 1);
1045
+ this.filePath = this.tokens.path.text.replace(/"/g, '');
1046
+ if ((_a = this.tokens.path) === null || _a === void 0 ? void 0 : _a.range) {
1047
+ //adjust the range to exclude the quotes
1048
+ this.tokens.path.range = util_1.util.createRange(this.tokens.path.range.start.line, this.tokens.path.range.start.character + 1, this.tokens.path.range.end.line, this.tokens.path.range.end.character - 1);
1049
+ }
880
1050
  }
881
1051
  }
882
1052
  transpile(state) {
@@ -884,177 +1054,499 @@ class ImportStatement extends Statement {
884
1054
  //add the import statement as a comment just for debugging purposes
885
1055
  return [
886
1056
  `'`,
887
- state.transpileToken(this.importToken),
1057
+ state.transpileToken(this.tokens.import, 'import'),
888
1058
  ' ',
889
- state.transpileToken(this.filePathToken)
1059
+ state.transpileToken(this.tokens.path)
890
1060
  ];
891
1061
  }
892
1062
  /**
893
1063
  * Get the typedef for this statement
894
1064
  */
895
1065
  getTypedef(state) {
1066
+ var _a, _b;
896
1067
  return [
897
- this.importToken.text,
1068
+ (_b = (_a = this.tokens.import) === null || _a === void 0 ? void 0 : _a.text) !== null && _b !== void 0 ? _b : 'import',
898
1069
  ' ',
899
1070
  //replace any `.bs` extension with `.brs`
900
- this.filePathToken.text.replace(/\.bs"?$/i, '.brs"')
1071
+ this.tokens.path.text.replace(/\.bs"?$/i, '.brs"')
901
1072
  ];
902
1073
  }
903
1074
  walk(visitor, options) {
904
1075
  //nothing to walk
905
1076
  }
1077
+ getLeadingTrivia() {
1078
+ var _a, _b;
1079
+ return (_b = (_a = this.tokens.import) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
1080
+ }
906
1081
  }
907
1082
  exports.ImportStatement = ImportStatement;
908
- class ClassStatement extends Statement {
909
- constructor(classKeyword,
910
- /**
911
- * The name of the class (without namespace prefix)
912
- */
913
- name, body, end, extendsKeyword, parentClassName, namespaceName) {
914
- var _a, _b, _c;
1083
+ class InterfaceStatement extends AstNode_2.Statement {
1084
+ constructor(options) {
915
1085
  super();
916
- this.classKeyword = classKeyword;
917
- this.name = name;
918
- this.body = body;
919
- this.end = end;
920
- this.extendsKeyword = extendsKeyword;
921
- this.parentClassName = parentClassName;
922
- this.namespaceName = namespaceName;
923
- this.memberMap = {};
924
- this.methods = [];
925
- this.fields = [];
926
- this.body = (_a = this.body) !== null && _a !== void 0 ? _a : [];
927
- for (let statement of this.body) {
928
- if (reflection_1.isClassMethodStatement(statement)) {
929
- this.methods.push(statement);
930
- this.memberMap[(_b = statement === null || statement === void 0 ? void 0 : statement.name) === null || _b === void 0 ? void 0 : _b.text.toLowerCase()] = statement;
931
- }
932
- else if (reflection_1.isClassFieldStatement(statement)) {
933
- this.fields.push(statement);
934
- this.memberMap[(_c = statement === null || statement === void 0 ? void 0 : statement.name) === null || _c === void 0 ? void 0 : _c.text.toLowerCase()] = statement;
935
- }
936
- }
937
- this.range = util_1.util.createRangeFromPositions(this.classKeyword.range.start, this.end.range.end);
1086
+ this.kind = AstNode_1.AstNodeKind.InterfaceStatement;
1087
+ this.tokens = {};
1088
+ this.tokens = {
1089
+ interface: options.interface,
1090
+ name: options.name,
1091
+ extends: options.extends,
1092
+ endInterface: options.endInterface
1093
+ };
1094
+ this.parentInterfaceName = options.parentInterfaceName;
1095
+ this.body = options.body;
1096
+ this.range = util_1.util.createBoundingRange(this.tokens.interface, this.tokens.name, this.tokens.extends, this.parentInterfaceName, ...this.body, this.tokens.endInterface);
1097
+ }
1098
+ get fields() {
1099
+ return this.body.filter(x => (0, reflection_1.isInterfaceFieldStatement)(x));
1100
+ }
1101
+ get methods() {
1102
+ return this.body.filter(x => (0, reflection_1.isInterfaceMethodStatement)(x));
1103
+ }
1104
+ hasParentInterface() {
1105
+ return !!this.parentInterfaceName;
1106
+ }
1107
+ getLeadingTrivia() {
1108
+ var _a;
1109
+ return util_1.util.concatAnnotationLeadingTrivia(this, (_a = this.tokens.interface) === null || _a === void 0 ? void 0 : _a.leadingTrivia);
938
1110
  }
939
- getName(parseMode) {
1111
+ getEndTrivia() {
1112
+ var _a, _b;
1113
+ return (_b = (_a = this.tokens.endInterface) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
1114
+ }
1115
+ /**
1116
+ * The name of the interface WITH its leading namespace (if applicable)
1117
+ */
1118
+ get fullName() {
940
1119
  var _a;
941
- const name = (_a = this.name) === null || _a === void 0 ? void 0 : _a.text;
1120
+ const name = (_a = this.tokens.name) === null || _a === void 0 ? void 0 : _a.text;
942
1121
  if (name) {
943
- if (this.namespaceName) {
944
- let namespaceName = this.namespaceName.getName(parseMode);
945
- let separator = parseMode === Parser_1.ParseMode.BrighterScript ? '.' : '_';
946
- return namespaceName + separator + name;
1122
+ const namespace = this.findAncestor(reflection_1.isNamespaceStatement);
1123
+ if (namespace) {
1124
+ let namespaceName = namespace.getName(Parser_1.ParseMode.BrighterScript);
1125
+ return `${namespaceName}.${name}`;
947
1126
  }
948
1127
  else {
949
1128
  return name;
950
1129
  }
951
1130
  }
952
1131
  else {
953
- //return undefined which will allow outside callers to know that this class doesn't have a name
1132
+ //return undefined which will allow outside callers to know that this interface doesn't have a name
954
1133
  return undefined;
955
1134
  }
956
1135
  }
1136
+ /**
1137
+ * The name of the interface (without the namespace prefix)
1138
+ */
1139
+ get name() {
1140
+ var _a;
1141
+ return (_a = this.tokens.name) === null || _a === void 0 ? void 0 : _a.text;
1142
+ }
1143
+ /**
1144
+ * Get the name of this expression based on the parse mode
1145
+ */
1146
+ getName(parseMode) {
1147
+ const namespace = this.findAncestor(reflection_1.isNamespaceStatement);
1148
+ if (namespace) {
1149
+ let delimiter = parseMode === Parser_1.ParseMode.BrighterScript ? '.' : '_';
1150
+ let namespaceName = namespace.getName(parseMode);
1151
+ return namespaceName + delimiter + this.name;
1152
+ }
1153
+ else {
1154
+ return this.name;
1155
+ }
1156
+ }
957
1157
  transpile(state) {
958
- let result = [];
959
- //make the builder
960
- result.push(...this.getTranspiledBuilder(state));
961
- result.push('\n', state.indent());
962
- //make the class assembler (i.e. the public-facing class creator method)
963
- result.push(...this.getTranspiledClassFunction(state));
964
- return result;
1158
+ //interfaces should completely disappear at runtime
1159
+ return [];
965
1160
  }
966
1161
  getTypedef(state) {
967
- var _a, _b;
1162
+ var _a, _b, _c, _d;
968
1163
  const result = [];
969
- for (let annotation of (_a = this.annotations) !== null && _a !== void 0 ? _a : []) {
1164
+ for (let comment of (_a = util_1.util.getLeadingComments(this)) !== null && _a !== void 0 ? _a : []) {
1165
+ result.push(comment.text, state.newline, state.indent());
1166
+ }
1167
+ for (let annotation of (_b = this.annotations) !== null && _b !== void 0 ? _b : []) {
970
1168
  result.push(...annotation.getTypedef(state), state.newline, state.indent());
971
1169
  }
972
- result.push('class ', this.name.text);
973
- if (this.extendsKeyword && this.parentClassName) {
974
- const fqName = util_1.util.getFullyQualifiedClassName(this.parentClassName.getName(Parser_1.ParseMode.BrighterScript), (_b = this.namespaceName) === null || _b === void 0 ? void 0 : _b.getName(Parser_1.ParseMode.BrighterScript));
975
- result.push(` extends ${fqName}`);
1170
+ result.push(this.tokens.interface.text, ' ', this.tokens.name.text);
1171
+ const parentInterfaceName = (_c = this.parentInterfaceName) === null || _c === void 0 ? void 0 : _c.getName();
1172
+ if (parentInterfaceName) {
1173
+ result.push(' extends ', parentInterfaceName);
976
1174
  }
977
- result.push(state.newline);
978
- state.blockDepth++;
979
- for (const member of this.body) {
980
- if ('getTypedef' in member) {
981
- result.push(state.indent(), ...member.getTypedef(state), state.newline);
982
- }
1175
+ const body = (_d = this.body) !== null && _d !== void 0 ? _d : [];
1176
+ if (body.length > 0) {
1177
+ state.blockDepth++;
983
1178
  }
984
- state.blockDepth--;
985
- result.push(state.indent(), 'end class');
986
- return result;
987
- }
988
- /**
989
- * Find the parent index for this class's parent.
990
- * For class inheritance, every class is given an index.
991
- * The base class is index 0, its child is index 1, and so on.
992
- */
993
- getParentClassIndex(state) {
994
- var _a, _b;
995
- let myIndex = 0;
996
- let stmt = this;
997
- while (stmt) {
998
- if (stmt.parentClassName) {
999
- //find the parent class
1000
- stmt = (_b = state.file.getClassFileLink(stmt.parentClassName.getName(Parser_1.ParseMode.BrighterScript), (_a = stmt.namespaceName) === null || _a === void 0 ? void 0 : _a.getName(Parser_1.ParseMode.BrighterScript))) === null || _b === void 0 ? void 0 : _b.item;
1001
- myIndex++;
1179
+ for (const statement of body) {
1180
+ if ((0, reflection_1.isInterfaceMethodStatement)(statement) || (0, reflection_1.isInterfaceFieldStatement)(statement)) {
1181
+ result.push(state.newline, state.indent(), ...statement.getTypedef(state));
1002
1182
  }
1003
1183
  else {
1004
- break;
1184
+ result.push(state.newline, state.indent(), ...statement.transpile(state));
1005
1185
  }
1006
1186
  }
1007
- return myIndex - 1;
1008
- }
1009
- hasParentClass() {
1010
- return !!this.parentClassName;
1011
- }
1012
- /**
1013
- * Get all ancestor classes, in closest-to-furthest order (i.e. 0 is parent, 1 is grandparent, etc...).
1014
- * This will return an empty array if no ancestors were found
1015
- */
1016
- getAncestors(state) {
1017
- var _a, _b;
1018
- let ancestors = [];
1019
- let stmt = this;
1020
- while (stmt) {
1021
- if (stmt.parentClassName) {
1022
- stmt = (_b = state.file.getClassFileLink(stmt.parentClassName.getName(Parser_1.ParseMode.BrighterScript), (_a = this.namespaceName) === null || _a === void 0 ? void 0 : _a.getName(Parser_1.ParseMode.BrighterScript))) === null || _b === void 0 ? void 0 : _b.item;
1023
- ancestors.push(stmt);
1024
- }
1025
- else {
1026
- break;
1027
- }
1187
+ if (body.length > 0) {
1188
+ state.blockDepth--;
1028
1189
  }
1029
- return ancestors;
1190
+ result.push(state.newline, state.indent(), 'end interface', state.newline);
1191
+ return result;
1030
1192
  }
1031
- getBuilderName(name) {
1032
- if (name.includes('.')) {
1033
- name = name.replace(/\./gi, '_');
1193
+ walk(visitor, options) {
1194
+ //visitor-less walk function to do parent linking
1195
+ (0, visitors_1.walk)(this, 'parentInterfaceName', null, options);
1196
+ if (options.walkMode & visitors_1.InternalWalkMode.walkStatements) {
1197
+ (0, visitors_1.walkArray)(this.body, visitor, options, this);
1034
1198
  }
1035
- return `__${name}_builder`;
1036
1199
  }
1037
- /**
1038
- * Get the constructor function for this class (if exists), or undefined if not exist
1200
+ getType(options) {
1201
+ var _a, _b, _c, _d;
1202
+ const superIface = (_a = this.parentInterfaceName) === null || _a === void 0 ? void 0 : _a.getType(options);
1203
+ const resultType = new InterfaceType_1.InterfaceType(this.getName(Parser_1.ParseMode.BrighterScript), superIface);
1204
+ for (const statement of this.methods) {
1205
+ const memberType = statement === null || statement === void 0 ? void 0 : statement.getType(Object.assign(Object.assign({}, options), { typeChain: undefined })); // no typechain info needed
1206
+ const flag = statement.isOptional ? 1 /* SymbolTypeFlag.runtime */ | 4 /* SymbolTypeFlag.optional */ : 1 /* SymbolTypeFlag.runtime */;
1207
+ resultType.addMember((_b = statement === null || statement === void 0 ? void 0 : statement.tokens.name) === null || _b === void 0 ? void 0 : _b.text, { definingNode: statement }, memberType, flag);
1208
+ }
1209
+ for (const statement of this.fields) {
1210
+ const memberType = statement === null || statement === void 0 ? void 0 : statement.getType(Object.assign(Object.assign({}, options), { typeChain: undefined })); // no typechain info needed
1211
+ const flag = statement.isOptional ? 1 /* SymbolTypeFlag.runtime */ | 4 /* SymbolTypeFlag.optional */ : 1 /* SymbolTypeFlag.runtime */;
1212
+ resultType.addMember((_c = statement === null || statement === void 0 ? void 0 : statement.tokens.name) === null || _c === void 0 ? void 0 : _c.text, { definingNode: statement, isInstance: true }, memberType, flag);
1213
+ }
1214
+ (_d = options.typeChain) === null || _d === void 0 ? void 0 : _d.push(new interfaces_1.TypeChainEntry({
1215
+ name: this.getName(Parser_1.ParseMode.BrighterScript),
1216
+ type: resultType,
1217
+ data: options.data,
1218
+ astNode: this
1219
+ }));
1220
+ return resultType;
1221
+ }
1222
+ }
1223
+ exports.InterfaceStatement = InterfaceStatement;
1224
+ class InterfaceFieldStatement extends AstNode_2.Statement {
1225
+ constructor(options) {
1226
+ super();
1227
+ this.kind = AstNode_1.AstNodeKind.InterfaceFieldStatement;
1228
+ this.tokens = {
1229
+ optional: options.optional,
1230
+ name: options.name,
1231
+ as: options.as
1232
+ };
1233
+ this.typeExpression = options.typeExpression;
1234
+ this.range = util_1.util.createBoundingRange(this.tokens.optional, this.tokens.name, this.tokens.as, this.typeExpression);
1235
+ }
1236
+ transpile(state) {
1237
+ throw new Error('Method not implemented.');
1238
+ }
1239
+ getLeadingTrivia() {
1240
+ var _a, _b;
1241
+ return util_1.util.concatAnnotationLeadingTrivia(this, (_b = (_a = this.tokens.optional) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : this.tokens.name.leadingTrivia);
1242
+ }
1243
+ get name() {
1244
+ return this.tokens.name.text;
1245
+ }
1246
+ get isOptional() {
1247
+ return !!this.tokens.optional;
1248
+ }
1249
+ walk(visitor, options) {
1250
+ if (options.walkMode & visitors_1.InternalWalkMode.walkExpressions) {
1251
+ (0, visitors_1.walk)(this, 'typeExpression', visitor, options);
1252
+ }
1253
+ }
1254
+ getTypedef(state) {
1255
+ var _a, _b;
1256
+ const result = [];
1257
+ for (let comment of (_a = util_1.util.getLeadingComments(this)) !== null && _a !== void 0 ? _a : []) {
1258
+ result.push(comment.text, state.newline, state.indent());
1259
+ }
1260
+ for (let annotation of (_b = this.annotations) !== null && _b !== void 0 ? _b : []) {
1261
+ result.push(...annotation.getTypedef(state), state.newline, state.indent());
1262
+ }
1263
+ if (this.isOptional) {
1264
+ result.push(this.tokens.optional.text, ' ');
1265
+ }
1266
+ result.push(this.tokens.name.text);
1267
+ if (this.typeExpression) {
1268
+ result.push(' as ', ...this.typeExpression.getTypedef(state));
1269
+ }
1270
+ return result;
1271
+ }
1272
+ getType(options) {
1273
+ var _a, _b;
1274
+ return (_b = (_a = this.typeExpression) === null || _a === void 0 ? void 0 : _a.getType(options)) !== null && _b !== void 0 ? _b : DynamicType_1.DynamicType.instance;
1275
+ }
1276
+ }
1277
+ exports.InterfaceFieldStatement = InterfaceFieldStatement;
1278
+ //TODO: there is much that is similar with this and FunctionExpression.
1279
+ //It would be nice to refactor this so there is less duplicated code
1280
+ class InterfaceMethodStatement extends AstNode_2.Statement {
1281
+ constructor(options) {
1282
+ var _a;
1283
+ super();
1284
+ this.kind = AstNode_1.AstNodeKind.InterfaceMethodStatement;
1285
+ this.tokens = {
1286
+ optional: options.optional,
1287
+ functionType: options.functionType,
1288
+ name: options.name,
1289
+ leftParen: options.leftParen,
1290
+ rightParen: options.rightParen,
1291
+ as: options.as
1292
+ };
1293
+ this.params = (_a = options.params) !== null && _a !== void 0 ? _a : [];
1294
+ this.returnTypeExpression = options.returnTypeExpression;
1295
+ }
1296
+ transpile(state) {
1297
+ throw new Error('Method not implemented.');
1298
+ }
1299
+ get range() {
1300
+ var _a;
1301
+ return util_1.util.createBoundingRange(this.tokens.optional, this.tokens.functionType, this.tokens.name, this.tokens.leftParen, ...((_a = this.params) !== null && _a !== void 0 ? _a : []), this.tokens.rightParen, this.tokens.as, this.returnTypeExpression);
1302
+ }
1303
+ /**
1304
+ * Get the name of this method.
1039
1305
  */
1040
- getConstructorFunction() {
1306
+ getName(parseMode) {
1307
+ return this.tokens.name.text;
1308
+ }
1309
+ get isOptional() {
1310
+ return !!this.tokens.optional;
1311
+ }
1312
+ getLeadingTrivia() {
1041
1313
  var _a, _b;
1042
- for (let key in this.memberMap) {
1043
- let member = this.memberMap[key];
1044
- if (((_b = (_a = member.name) === null || _a === void 0 ? void 0 : _a.text) === null || _b === void 0 ? void 0 : _b.toLowerCase()) === 'new') {
1045
- return member;
1314
+ return util_1.util.concatAnnotationLeadingTrivia(this, (_b = (_a = this.tokens.optional) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : this.tokens.functionType.leadingTrivia);
1315
+ }
1316
+ walk(visitor, options) {
1317
+ if (options.walkMode & visitors_1.InternalWalkMode.walkExpressions) {
1318
+ (0, visitors_1.walk)(this, 'returnTypeExpression', visitor, options);
1319
+ }
1320
+ }
1321
+ getTypedef(state) {
1322
+ var _a, _b, _c, _d, _e;
1323
+ const result = [];
1324
+ for (let comment of (_a = util_1.util.getLeadingComments(this)) !== null && _a !== void 0 ? _a : []) {
1325
+ result.push(comment.text, state.newline, state.indent());
1326
+ }
1327
+ for (let annotation of (_b = this.annotations) !== null && _b !== void 0 ? _b : []) {
1328
+ result.push(...annotation.getTypedef(state), state.newline, state.indent());
1329
+ }
1330
+ if (this.isOptional) {
1331
+ result.push(this.tokens.optional.text, ' ');
1332
+ }
1333
+ result.push((_d = (_c = this.tokens.functionType) === null || _c === void 0 ? void 0 : _c.text) !== null && _d !== void 0 ? _d : 'function', ' ', this.tokens.name.text, '(');
1334
+ const params = (_e = this.params) !== null && _e !== void 0 ? _e : [];
1335
+ for (let i = 0; i < params.length; i++) {
1336
+ if (i > 0) {
1337
+ result.push(', ');
1046
1338
  }
1339
+ const param = params[i];
1340
+ result.push(param.tokens.name.text);
1341
+ if (param.typeExpression) {
1342
+ result.push(' as ', ...param.typeExpression.getTypedef(state));
1343
+ }
1344
+ }
1345
+ result.push(')');
1346
+ if (this.returnTypeExpression) {
1347
+ result.push(' as ', ...this.returnTypeExpression.getTypedef(state));
1047
1348
  }
1349
+ return result;
1048
1350
  }
1049
- getEmptyNewFunction() {
1050
- let stmt = Parser_1.Parser.parse(`
1051
- class UtilClass
1052
- sub new()
1053
- end sub
1054
- end class
1055
- `, { mode: Parser_1.ParseMode.BrighterScript }).statements[0].memberMap.new;
1056
- //TODO make locations point to 0,0 (might not matter?)
1057
- return stmt;
1351
+ getType(options) {
1352
+ var _a, _b, _c, _d;
1353
+ //if there's a defined return type, use that
1354
+ let returnType = (_a = this.returnTypeExpression) === null || _a === void 0 ? void 0 : _a.getType(options);
1355
+ const isSub = ((_b = this.tokens.functionType) === null || _b === void 0 ? void 0 : _b.kind) === TokenKind_1.TokenKind.Sub || !returnType;
1356
+ //if we don't have a return type and this is a sub, set the return type to `void`. else use `dynamic`
1357
+ if (!returnType) {
1358
+ returnType = isSub ? VoidType_1.VoidType.instance : DynamicType_1.DynamicType.instance;
1359
+ }
1360
+ const resultType = new TypedFunctionType_1.TypedFunctionType(returnType);
1361
+ resultType.isSub = isSub;
1362
+ for (let param of this.params) {
1363
+ resultType.addParameter(param.tokens.name.text, param.getType(options), !!param.defaultValue);
1364
+ }
1365
+ if (options.typeChain) {
1366
+ // need Interface type for type chain
1367
+ (_c = this.parent) === null || _c === void 0 ? void 0 : _c.getType(options);
1368
+ }
1369
+ let funcName = this.getName(Parser_1.ParseMode.BrighterScript);
1370
+ resultType.setName(funcName);
1371
+ (_d = options.typeChain) === null || _d === void 0 ? void 0 : _d.push(new interfaces_1.TypeChainEntry({ name: resultType.name, type: resultType, data: options.data, astNode: this }));
1372
+ return resultType;
1373
+ }
1374
+ }
1375
+ exports.InterfaceMethodStatement = InterfaceMethodStatement;
1376
+ class ClassStatement extends AstNode_2.Statement {
1377
+ constructor(options) {
1378
+ var _a, _b, _c, _d, _e;
1379
+ super();
1380
+ this.kind = AstNode_1.AstNodeKind.ClassStatement;
1381
+ this.memberMap = {};
1382
+ this.methods = [];
1383
+ this.fields = [];
1384
+ this.body = (_a = options.body) !== null && _a !== void 0 ? _a : [];
1385
+ this.tokens = {
1386
+ name: options.name,
1387
+ class: options.class,
1388
+ endClass: options.endClass,
1389
+ extends: options.extends
1390
+ };
1391
+ this.parentClassName = options.parentClassName;
1392
+ this.symbolTable = new SymbolTable_1.SymbolTable(`ClassStatement: '${(_b = this.tokens.name) === null || _b === void 0 ? void 0 : _b.text}'`, () => { var _a; return (_a = this.parent) === null || _a === void 0 ? void 0 : _a.getSymbolTable(); });
1393
+ for (let statement of this.body) {
1394
+ if ((0, reflection_1.isMethodStatement)(statement)) {
1395
+ this.methods.push(statement);
1396
+ this.memberMap[(_c = statement === null || statement === void 0 ? void 0 : statement.tokens.name) === null || _c === void 0 ? void 0 : _c.text.toLowerCase()] = statement;
1397
+ }
1398
+ else if ((0, reflection_1.isFieldStatement)(statement)) {
1399
+ this.fields.push(statement);
1400
+ this.memberMap[(_d = statement === null || statement === void 0 ? void 0 : statement.tokens.name) === null || _d === void 0 ? void 0 : _d.text.toLowerCase()] = statement;
1401
+ }
1402
+ }
1403
+ this.range = util_1.util.createBoundingRange(this.parentClassName, ...((_e = this.body) !== null && _e !== void 0 ? _e : []), util_1.util.createBoundingRangeFromTokens(this.tokens));
1404
+ }
1405
+ getName(parseMode) {
1406
+ var _a;
1407
+ const name = (_a = this.tokens.name) === null || _a === void 0 ? void 0 : _a.text;
1408
+ if (name) {
1409
+ const namespace = this.findAncestor(reflection_1.isNamespaceStatement);
1410
+ if (namespace) {
1411
+ let namespaceName = namespace.getName(parseMode);
1412
+ let separator = parseMode === Parser_1.ParseMode.BrighterScript ? '.' : '_';
1413
+ return namespaceName + separator + name;
1414
+ }
1415
+ else {
1416
+ return name;
1417
+ }
1418
+ }
1419
+ else {
1420
+ //return undefined which will allow outside callers to know that this class doesn't have a name
1421
+ return undefined;
1422
+ }
1423
+ }
1424
+ getLeadingTrivia() {
1425
+ var _a;
1426
+ return util_1.util.concatAnnotationLeadingTrivia(this, (_a = this.tokens.class) === null || _a === void 0 ? void 0 : _a.leadingTrivia);
1427
+ }
1428
+ getEndTrivia() {
1429
+ var _a, _b;
1430
+ return (_b = (_a = this.tokens.endClass) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
1431
+ }
1432
+ transpile(state) {
1433
+ let result = [];
1434
+ //make the builder
1435
+ result.push(...this.getTranspiledBuilder(state));
1436
+ result.push('\n', state.indent());
1437
+ //make the class assembler (i.e. the public-facing class creator method)
1438
+ result.push(...this.getTranspiledClassFunction(state));
1439
+ return result;
1440
+ }
1441
+ getTypedef(state) {
1442
+ var _a, _b;
1443
+ const result = [];
1444
+ for (let comment of (_a = util_1.util.getLeadingComments(this)) !== null && _a !== void 0 ? _a : []) {
1445
+ result.push(comment.text, state.newline, state.indent());
1446
+ }
1447
+ for (let annotation of (_b = this.annotations) !== null && _b !== void 0 ? _b : []) {
1448
+ result.push(...annotation.getTypedef(state), state.newline, state.indent());
1449
+ }
1450
+ result.push('class ', this.tokens.name.text);
1451
+ if (this.parentClassName) {
1452
+ const namespace = this.findAncestor(reflection_1.isNamespaceStatement);
1453
+ const fqName = util_1.util.getFullyQualifiedClassName(this.parentClassName.getName(), namespace === null || namespace === void 0 ? void 0 : namespace.getName(Parser_1.ParseMode.BrighterScript));
1454
+ result.push(` extends ${fqName}`);
1455
+ }
1456
+ result.push(state.newline);
1457
+ state.blockDepth++;
1458
+ let body = this.body;
1459
+ //inject an empty "new" method if missing
1460
+ if (!this.getConstructorFunction()) {
1461
+ const constructor = (0, creators_1.createMethodStatement)('new', TokenKind_1.TokenKind.Sub);
1462
+ constructor.parent = this;
1463
+ //walk the constructor to set up parent links
1464
+ constructor.link();
1465
+ body = [
1466
+ constructor,
1467
+ ...this.body
1468
+ ];
1469
+ }
1470
+ for (const member of body) {
1471
+ if ((0, reflection_1.isTypedefProvider)(member)) {
1472
+ result.push(state.indent(), ...member.getTypedef(state), state.newline);
1473
+ }
1474
+ }
1475
+ state.blockDepth--;
1476
+ result.push(state.indent(), 'end class');
1477
+ return result;
1478
+ }
1479
+ /**
1480
+ * Find the parent index for this class's parent.
1481
+ * For class inheritance, every class is given an index.
1482
+ * The base class is index 0, its child is index 1, and so on.
1483
+ */
1484
+ getParentClassIndex(state) {
1485
+ var _a;
1486
+ let myIndex = 0;
1487
+ let stmt = this;
1488
+ while (stmt) {
1489
+ if (stmt.parentClassName) {
1490
+ const namespace = stmt.findAncestor(reflection_1.isNamespaceStatement);
1491
+ //find the parent class
1492
+ stmt = (_a = state.file.getClassFileLink(stmt.parentClassName.getName(), namespace === null || namespace === void 0 ? void 0 : namespace.getName(Parser_1.ParseMode.BrighterScript))) === null || _a === void 0 ? void 0 : _a.item;
1493
+ myIndex++;
1494
+ }
1495
+ else {
1496
+ break;
1497
+ }
1498
+ }
1499
+ const result = myIndex - 1;
1500
+ if (result >= 0) {
1501
+ return result;
1502
+ }
1503
+ else {
1504
+ return null;
1505
+ }
1506
+ }
1507
+ hasParentClass() {
1508
+ return !!this.parentClassName;
1509
+ }
1510
+ /**
1511
+ * Get all ancestor classes, in closest-to-furthest order (i.e. 0 is parent, 1 is grandparent, etc...).
1512
+ * This will return an empty array if no ancestors were found
1513
+ */
1514
+ getAncestors(state) {
1515
+ var _a;
1516
+ let ancestors = [];
1517
+ let stmt = this;
1518
+ while (stmt) {
1519
+ if (stmt.parentClassName) {
1520
+ const namespace = this.findAncestor(reflection_1.isNamespaceStatement);
1521
+ stmt = (_a = state.file.getClassFileLink(stmt.parentClassName.getName(), namespace === null || namespace === void 0 ? void 0 : namespace.getName(Parser_1.ParseMode.BrighterScript))) === null || _a === void 0 ? void 0 : _a.item;
1522
+ ancestors.push(stmt);
1523
+ }
1524
+ else {
1525
+ break;
1526
+ }
1527
+ }
1528
+ return ancestors;
1529
+ }
1530
+ getBuilderName(name) {
1531
+ if (name.includes('.')) {
1532
+ name = name.replace(/\./gi, '_');
1533
+ }
1534
+ return `__${name}_builder`;
1535
+ }
1536
+ getConstructorType() {
1537
+ var _a, _b;
1538
+ const constructorType = (_b = (_a = this.getConstructorFunction()) === null || _a === void 0 ? void 0 : _a.getType({ flags: 1 /* SymbolTypeFlag.runtime */ })) !== null && _b !== void 0 ? _b : new TypedFunctionType_1.TypedFunctionType(null);
1539
+ constructorType.returnType = this.getType({ flags: 1 /* SymbolTypeFlag.runtime */ });
1540
+ return constructorType;
1541
+ }
1542
+ /**
1543
+ * Get the constructor function for this class (if exists), or undefined if not exist
1544
+ */
1545
+ getConstructorFunction() {
1546
+ return this.body.find((stmt) => {
1547
+ var _a, _b;
1548
+ return ((_b = (_a = stmt === null || stmt === void 0 ? void 0 : stmt.tokens.name) === null || _a === void 0 ? void 0 : _a.text) === null || _b === void 0 ? void 0 : _b.toLowerCase()) === 'new';
1549
+ });
1058
1550
  }
1059
1551
  /**
1060
1552
  * Determine if the specified field was declared in one of the ancestor classes
@@ -1074,7 +1566,6 @@ class ClassStatement extends Statement {
1074
1566
  * without instantiating the parent constructor at that point in time.
1075
1567
  */
1076
1568
  getTranspiledBuilder(state) {
1077
- var _a;
1078
1569
  let result = [];
1079
1570
  result.push(`function ${this.getBuilderName(this.getName(Parser_1.ParseMode.BrightScript))}()\n`);
1080
1571
  state.blockDepth++;
@@ -1086,7 +1577,8 @@ class ClassStatement extends Statement {
1086
1577
  let ancestors = this.getAncestors(state);
1087
1578
  //construct parent class or empty object
1088
1579
  if (ancestors[0]) {
1089
- let fullyQualifiedClassName = util_1.util.getFullyQualifiedClassName(ancestors[0].getName(Parser_1.ParseMode.BrighterScript), (_a = ancestors[0].namespaceName) === null || _a === void 0 ? void 0 : _a.getName(Parser_1.ParseMode.BrighterScript));
1580
+ const ancestorNamespace = ancestors[0].findAncestor(reflection_1.isNamespaceStatement);
1581
+ let fullyQualifiedClassName = util_1.util.getFullyQualifiedClassName(ancestors[0].getName(Parser_1.ParseMode.BrighterScript), ancestorNamespace === null || ancestorNamespace === void 0 ? void 0 : ancestorNamespace.getName(Parser_1.ParseMode.BrighterScript));
1090
1582
  result.push('instance = ', this.getBuilderName(fullyQualifiedClassName), '()');
1091
1583
  }
1092
1584
  else {
@@ -1095,29 +1587,32 @@ class ClassStatement extends Statement {
1095
1587
  }
1096
1588
  result.push(state.newline, state.indent());
1097
1589
  let parentClassIndex = this.getParentClassIndex(state);
1098
- //create empty `new` function if class is missing it (simplifies transpile logic)
1590
+ let body = this.body;
1591
+ //inject an empty "new" method if missing
1099
1592
  if (!this.getConstructorFunction()) {
1100
- this.memberMap.new = this.getEmptyNewFunction();
1101
- this.body = [this.memberMap.new, ...this.body];
1593
+ body = [
1594
+ (0, creators_1.createMethodStatement)('new', TokenKind_1.TokenKind.Sub),
1595
+ ...this.body
1596
+ ];
1102
1597
  }
1103
- for (let statement of this.body) {
1598
+ for (let statement of body) {
1104
1599
  //is field statement
1105
- if (reflection_1.isClassFieldStatement(statement)) {
1600
+ if ((0, reflection_1.isFieldStatement)(statement)) {
1106
1601
  //do nothing with class fields in this situation, they are handled elsewhere
1107
1602
  continue;
1108
1603
  //methods
1109
1604
  }
1110
- else if (reflection_1.isClassMethodStatement(statement)) {
1605
+ else if ((0, reflection_1.isMethodStatement)(statement)) {
1111
1606
  //store overridden parent methods as super{parentIndex}_{methodName}
1112
1607
  if (
1113
1608
  //is override method
1114
- statement.override ||
1609
+ statement.tokens.override ||
1115
1610
  //is constructor function in child class
1116
- (statement.name.text.toLowerCase() === 'new' && ancestors[0])) {
1117
- result.push(`instance.super${parentClassIndex}_${statement.name.text} = instance.${statement.name.text}`, state.newline, state.indent());
1611
+ (statement.tokens.name.text.toLowerCase() === 'new' && ancestors[0])) {
1612
+ result.push(`instance.super${parentClassIndex}_${statement.tokens.name.text} = instance.${statement.tokens.name.text}`, state.newline, state.indent());
1118
1613
  }
1119
1614
  state.classStatement = this;
1120
- result.push('instance.', state.transpileToken(statement.name), ' = ', ...statement.transpile(state), state.newline, state.indent());
1615
+ result.push('instance.', state.transpileToken(statement.tokens.name), ' = ', ...statement.transpile(state), state.newline, state.indent());
1121
1616
  delete state.classStatement;
1122
1617
  }
1123
1618
  else {
@@ -1141,7 +1636,7 @@ class ClassStatement extends Statement {
1141
1636
  let result = [];
1142
1637
  const constructorFunction = this.getConstructorFunction();
1143
1638
  const constructorParams = constructorFunction ? constructorFunction.func.parameters : [];
1144
- result.push(state.sourceNode(this.classKeyword, 'function'), state.sourceNode(this.classKeyword, ' '), state.sourceNode(this.name, this.getName(Parser_1.ParseMode.BrightScript)), `(`);
1639
+ result.push(state.sourceNode(this.tokens.class, 'function'), state.sourceNode(this.tokens.class, ' '), state.sourceNode(this.tokens.name, this.getName(Parser_1.ParseMode.BrightScript)), `(`);
1145
1640
  let i = 0;
1146
1641
  for (let param of constructorParams) {
1147
1642
  if (i > 0) {
@@ -1162,7 +1657,7 @@ class ClassStatement extends Statement {
1162
1657
  if (i > 0) {
1163
1658
  result.push(', ');
1164
1659
  }
1165
- result.push(state.transpileToken(param.name));
1660
+ result.push(state.transpileToken(param.tokens.name));
1166
1661
  i++;
1167
1662
  }
1168
1663
  result.push(')', '\n');
@@ -1174,24 +1669,81 @@ class ClassStatement extends Statement {
1174
1669
  return result;
1175
1670
  }
1176
1671
  walk(visitor, options) {
1672
+ //visitor-less walk function to do parent linking
1673
+ (0, visitors_1.walk)(this, 'parentClassName', null, options);
1177
1674
  if (options.walkMode & visitors_1.InternalWalkMode.walkStatements) {
1178
- for (let i = 0; i < this.body.length; i++) {
1179
- visitors_1.walk(this.body, i, visitor, options, this);
1675
+ (0, visitors_1.walkArray)(this.body, visitor, options, this);
1676
+ }
1677
+ }
1678
+ getType(options) {
1679
+ var _a, _b, _c, _d, _e, _f, _g, _h;
1680
+ const superClass = (_a = this.parentClassName) === null || _a === void 0 ? void 0 : _a.getType(options);
1681
+ const resultType = new ClassType_1.ClassType(this.getName(Parser_1.ParseMode.BrighterScript), superClass);
1682
+ for (const statement of this.methods) {
1683
+ const funcType = statement === null || statement === void 0 ? void 0 : statement.func.getType(Object.assign(Object.assign({}, options), { typeChain: undefined })); //no typechain needed
1684
+ let flag = 1 /* SymbolTypeFlag.runtime */;
1685
+ if (((_b = statement.accessModifier) === null || _b === void 0 ? void 0 : _b.kind) === TokenKind_1.TokenKind.Private) {
1686
+ flag |= 8 /* SymbolTypeFlag.private */;
1687
+ }
1688
+ if (((_c = statement.accessModifier) === null || _c === void 0 ? void 0 : _c.kind) === TokenKind_1.TokenKind.Protected) {
1689
+ flag |= 16 /* SymbolTypeFlag.protected */;
1180
1690
  }
1691
+ resultType.addMember((_d = statement === null || statement === void 0 ? void 0 : statement.tokens.name) === null || _d === void 0 ? void 0 : _d.text, { definingNode: statement }, funcType, flag);
1181
1692
  }
1693
+ for (const statement of this.fields) {
1694
+ const fieldType = statement.getType(Object.assign(Object.assign({}, options), { typeChain: undefined })); //no typechain needed
1695
+ let flag = 1 /* SymbolTypeFlag.runtime */;
1696
+ if (statement.isOptional) {
1697
+ flag |= 4 /* SymbolTypeFlag.optional */;
1698
+ }
1699
+ if (((_e = statement.tokens.accessModifier) === null || _e === void 0 ? void 0 : _e.kind) === TokenKind_1.TokenKind.Private) {
1700
+ flag |= 8 /* SymbolTypeFlag.private */;
1701
+ }
1702
+ if (((_f = statement.tokens.accessModifier) === null || _f === void 0 ? void 0 : _f.kind) === TokenKind_1.TokenKind.Protected) {
1703
+ flag |= 16 /* SymbolTypeFlag.protected */;
1704
+ }
1705
+ resultType.addMember((_g = statement === null || statement === void 0 ? void 0 : statement.tokens.name) === null || _g === void 0 ? void 0 : _g.text, { definingNode: statement, isInstance: true }, fieldType, flag);
1706
+ }
1707
+ (_h = options.typeChain) === null || _h === void 0 ? void 0 : _h.push(new interfaces_1.TypeChainEntry({ name: resultType.name, type: resultType, data: options.data, astNode: this }));
1708
+ return resultType;
1182
1709
  }
1183
1710
  }
1184
1711
  exports.ClassStatement = ClassStatement;
1185
- class ClassMethodStatement extends FunctionStatement {
1186
- constructor(accessModifier, name, func, override) {
1187
- var _a;
1188
- super(name, func, undefined);
1189
- this.accessModifier = accessModifier;
1190
- this.override = override;
1191
- this.range = util_1.util.createRangeFromPositions(((_a = this.accessModifier) !== null && _a !== void 0 ? _a : this.func).range.start, this.func.range.end);
1712
+ const accessModifiers = [
1713
+ TokenKind_1.TokenKind.Public,
1714
+ TokenKind_1.TokenKind.Protected,
1715
+ TokenKind_1.TokenKind.Private
1716
+ ];
1717
+ class MethodStatement extends FunctionStatement {
1718
+ constructor(options) {
1719
+ super(options);
1720
+ this.kind = AstNode_1.AstNodeKind.MethodStatement;
1721
+ this.modifiers = [];
1722
+ if (options.modifiers) {
1723
+ if (Array.isArray(options.modifiers)) {
1724
+ this.modifiers.push(...options.modifiers);
1725
+ }
1726
+ else {
1727
+ this.modifiers.push(options.modifiers);
1728
+ }
1729
+ }
1730
+ this.tokens = Object.assign(Object.assign({}, this.tokens), { override: options.override });
1731
+ this.range = util_1.util.createBoundingRange(...(this.modifiers), util_1.util.createBoundingRangeFromTokens(this.tokens), this.func);
1732
+ }
1733
+ get accessModifier() {
1734
+ return this.modifiers.find(x => accessModifiers.includes(x.kind));
1735
+ }
1736
+ /**
1737
+ * Get the name of this method.
1738
+ */
1739
+ getName(parseMode) {
1740
+ return this.tokens.name.text;
1741
+ }
1742
+ getLeadingTrivia() {
1743
+ return util_1.util.concatAnnotationLeadingTrivia(this, this.func.getLeadingTrivia());
1192
1744
  }
1193
1745
  transpile(state) {
1194
- if (this.name.text.toLowerCase() === 'new') {
1746
+ if (this.tokens.name.text.toLowerCase() === 'new') {
1195
1747
  this.ensureSuperConstructorCall(state);
1196
1748
  //TODO we need to undo this at the bottom of this method
1197
1749
  this.injectFieldInitializersForConstructor(state);
@@ -1199,18 +1751,18 @@ class ClassMethodStatement extends FunctionStatement {
1199
1751
  //TODO - remove type information from these methods because that doesn't work
1200
1752
  //convert the `super` calls into the proper methods
1201
1753
  const parentClassIndex = state.classStatement.getParentClassIndex(state);
1202
- const visitor = visitors_1.createVisitor({
1754
+ const visitor = (0, visitors_1.createVisitor)({
1203
1755
  VariableExpression: e => {
1204
- if (e.name.text.toLocaleLowerCase() === 'super') {
1205
- e.name.text = `m.super${parentClassIndex}_new`;
1756
+ if (e.tokens.name.text.toLocaleLowerCase() === 'super') {
1757
+ state.editor.setProperty(e.tokens.name, 'text', `m.super${parentClassIndex}_new`);
1206
1758
  }
1207
1759
  },
1208
1760
  DottedGetExpression: e => {
1209
1761
  const beginningVariable = util_1.util.findBeginningVariableExpression(e);
1210
1762
  const lowerName = beginningVariable === null || beginningVariable === void 0 ? void 0 : beginningVariable.getName(Parser_1.ParseMode.BrighterScript).toLowerCase();
1211
1763
  if (lowerName === 'super') {
1212
- beginningVariable.name.text = 'm';
1213
- e.name.text = `super${parentClassIndex}_${e.name.text}`;
1764
+ state.editor.setProperty(beginningVariable.tokens.name, 'text', 'm');
1765
+ state.editor.setProperty(e.tokens.name, 'text', `super${parentClassIndex}_${e.tokens.name.text}`);
1214
1766
  }
1215
1767
  }
1216
1768
  });
@@ -1222,18 +1774,21 @@ class ClassMethodStatement extends FunctionStatement {
1222
1774
  return this.func.transpile(state);
1223
1775
  }
1224
1776
  getTypedef(state) {
1225
- var _a;
1777
+ var _a, _b;
1226
1778
  const result = [];
1227
- for (let annotation of (_a = this.annotations) !== null && _a !== void 0 ? _a : []) {
1779
+ for (let comment of (_a = util_1.util.getLeadingComments(this)) !== null && _a !== void 0 ? _a : []) {
1780
+ result.push(comment.text, state.newline, state.indent());
1781
+ }
1782
+ for (let annotation of (_b = this.annotations) !== null && _b !== void 0 ? _b : []) {
1228
1783
  result.push(...annotation.getTypedef(state), state.newline, state.indent());
1229
1784
  }
1230
1785
  if (this.accessModifier) {
1231
1786
  result.push(this.accessModifier.text, ' ');
1232
1787
  }
1233
- if (this.override) {
1788
+ if (this.tokens.override) {
1234
1789
  result.push('override ');
1235
1790
  }
1236
- result.push(...this.func.getTypedef(state, this.name));
1791
+ result.push(...this.func.getTypedef(state));
1237
1792
  return result;
1238
1793
  }
1239
1794
  /**
@@ -1245,163 +1800,236 @@ class ClassMethodStatement extends FunctionStatement {
1245
1800
  if (state.classStatement.getAncestors(state).length === 0) {
1246
1801
  return;
1247
1802
  }
1248
- //if the first statement is a call to super, quit here
1249
- let firstStatement = this.func.body.statements[0];
1250
- if (
1251
- //is a call statement
1252
- reflection_1.isExpressionStatement(firstStatement) && reflection_1.isCallExpression(firstStatement.expression) &&
1253
- //is a call to super
1254
- util_1.util.findBeginningVariableExpression(firstStatement === null || firstStatement === void 0 ? void 0 : firstStatement.expression.callee).name.text.toLowerCase() === 'super') {
1803
+ //check whether any calls to super exist
1804
+ let containsSuperCall = this.func.body.statements.findIndex((x) => {
1805
+ var _a;
1806
+ //is a call statement
1807
+ return (0, reflection_1.isExpressionStatement)(x) && (0, reflection_1.isCallExpression)(x.expression) &&
1808
+ //is a call to super
1809
+ ((_a = util_1.util.findBeginningVariableExpression(x.expression.callee).tokens.name) === null || _a === void 0 ? void 0 : _a.text.toLowerCase()) === 'super';
1810
+ }) !== -1;
1811
+ //if a call to super exists, quit here
1812
+ if (containsSuperCall) {
1255
1813
  return;
1256
1814
  }
1257
- //this is a child class, and the first statement isn't a call to super. Inject one
1258
- this.func.body.statements.unshift(new ExpressionStatement(new Expression_1.CallExpression(new Expression_1.VariableExpression({
1259
- kind: lexer_1.TokenKind.Identifier,
1260
- text: 'super',
1261
- isReserved: false,
1262
- range: state.classStatement.name.range,
1263
- leadingWhitespace: ''
1264
- }, null), {
1265
- kind: lexer_1.TokenKind.LeftParen,
1266
- text: '(',
1267
- isReserved: false,
1268
- range: state.classStatement.name.range,
1269
- leadingWhitespace: ''
1270
- }, {
1271
- kind: lexer_1.TokenKind.RightParen,
1272
- text: ')',
1273
- isReserved: false,
1274
- range: state.classStatement.name.range,
1275
- leadingWhitespace: ''
1276
- }, [], null)));
1815
+ //this is a child class, and the constructor doesn't contain a call to super. Inject one
1816
+ const superCall = new ExpressionStatement({
1817
+ expression: new Expression_1.CallExpression({
1818
+ callee: new Expression_1.VariableExpression({
1819
+ name: {
1820
+ kind: TokenKind_1.TokenKind.Identifier,
1821
+ text: 'super',
1822
+ isReserved: false,
1823
+ range: state.classStatement.tokens.name.range,
1824
+ leadingWhitespace: '',
1825
+ leadingTrivia: []
1826
+ }
1827
+ }),
1828
+ openingParen: {
1829
+ kind: TokenKind_1.TokenKind.LeftParen,
1830
+ text: '(',
1831
+ isReserved: false,
1832
+ range: state.classStatement.tokens.name.range,
1833
+ leadingWhitespace: '',
1834
+ leadingTrivia: []
1835
+ },
1836
+ closingParen: {
1837
+ kind: TokenKind_1.TokenKind.RightParen,
1838
+ text: ')',
1839
+ isReserved: false,
1840
+ range: state.classStatement.tokens.name.range,
1841
+ leadingWhitespace: '',
1842
+ leadingTrivia: []
1843
+ },
1844
+ args: []
1845
+ })
1846
+ });
1847
+ state.editor.arrayUnshift(this.func.body.statements, superCall);
1277
1848
  }
1278
1849
  /**
1279
1850
  * Inject field initializers at the top of the `new` function (after any present `super()` call)
1280
1851
  */
1281
1852
  injectFieldInitializersForConstructor(state) {
1853
+ var _a;
1282
1854
  let startingIndex = state.classStatement.hasParentClass() ? 1 : 0;
1283
1855
  let newStatements = [];
1284
1856
  //insert the field initializers in order
1285
1857
  for (let field of state.classStatement.fields) {
1286
- let thisQualifiedName = Object.assign({}, field.name);
1287
- thisQualifiedName.text = 'm.' + field.name.text;
1288
- if (field.initialValue) {
1289
- newStatements.push(new AssignmentStatement(thisQualifiedName, field.equal, field.initialValue, this.func));
1290
- }
1291
- else {
1292
- //if there is no initial value, set the initial value to `invalid`
1293
- newStatements.push(new AssignmentStatement(thisQualifiedName, creators_1.createToken(lexer_1.TokenKind.Equal, '=', field.name.range), creators_1.createInvalidLiteral('invalid', field.name.range), this.func));
1294
- }
1295
- }
1296
- this.func.body.statements.splice(startingIndex, 0, ...newStatements);
1858
+ let thisQualifiedName = Object.assign({}, field.tokens.name);
1859
+ thisQualifiedName.text = 'm.' + ((_a = field.tokens.name) === null || _a === void 0 ? void 0 : _a.text);
1860
+ const fieldAssignment = field.initialValue
1861
+ ? new AssignmentStatement({
1862
+ equals: field.tokens.equals,
1863
+ name: thisQualifiedName,
1864
+ value: field.initialValue
1865
+ })
1866
+ : new AssignmentStatement({
1867
+ equals: (0, creators_1.createToken)(TokenKind_1.TokenKind.Equal, '=', field.tokens.name.range),
1868
+ name: thisQualifiedName,
1869
+ //if there is no initial value, set the initial value to `invalid`
1870
+ value: (0, creators_1.createInvalidLiteral)('invalid', field.tokens.name.range)
1871
+ });
1872
+ // Add parent so namespace lookups work
1873
+ fieldAssignment.parent = state.classStatement;
1874
+ newStatements.push(fieldAssignment);
1875
+ }
1876
+ state.editor.arraySplice(this.func.body.statements, startingIndex, 0, ...newStatements);
1297
1877
  }
1298
1878
  walk(visitor, options) {
1299
1879
  if (options.walkMode & visitors_1.InternalWalkMode.walkExpressions) {
1300
- visitors_1.walk(this, 'func', visitor, options);
1880
+ (0, visitors_1.walk)(this, 'func', visitor, options);
1301
1881
  }
1302
1882
  }
1303
1883
  }
1304
- exports.ClassMethodStatement = ClassMethodStatement;
1305
- class ClassFieldStatement extends Statement {
1306
- constructor(accessModifier, name, as, type, equal, initialValue) {
1307
- var _a, _b, _c, _d;
1884
+ exports.MethodStatement = MethodStatement;
1885
+ class FieldStatement extends AstNode_2.Statement {
1886
+ constructor(options) {
1308
1887
  super();
1309
- this.accessModifier = accessModifier;
1310
- this.name = name;
1311
- this.as = as;
1312
- this.type = type;
1313
- this.equal = equal;
1314
- this.initialValue = initialValue;
1315
- this.range = util_1.util.createRangeFromPositions(((_a = this.accessModifier) !== null && _a !== void 0 ? _a : this.name).range.start, ((_d = (_c = (_b = this.initialValue) !== null && _b !== void 0 ? _b : this.type) !== null && _c !== void 0 ? _c : this.as) !== null && _d !== void 0 ? _d : this.name).range.end);
1888
+ this.kind = AstNode_1.AstNodeKind.FieldStatement;
1889
+ this.tokens = {
1890
+ accessModifier: options.accessModifier,
1891
+ name: options.name,
1892
+ as: options.as,
1893
+ equals: options.equals,
1894
+ optional: options.optional
1895
+ };
1896
+ this.typeExpression = options.typeExpression;
1897
+ this.initialValue = options.initialValue;
1898
+ this.range = util_1.util.createBoundingRange(util_1.util.createBoundingRangeFromTokens(this.tokens), this.typeExpression, this.initialValue);
1316
1899
  }
1317
1900
  /**
1318
1901
  * Derive a ValueKind from the type token, or the initial value.
1319
1902
  * Defaults to `DynamicType`
1320
1903
  */
1321
- getType() {
1322
- if (this.type) {
1323
- return util_1.util.tokenToBscType(this.type);
1324
- }
1325
- else if (reflection_1.isLiteralExpression(this.initialValue)) {
1326
- return this.initialValue.type;
1327
- }
1328
- else {
1329
- return new DynamicType_1.DynamicType();
1330
- }
1904
+ getType(options) {
1905
+ var _a, _b, _c, _d;
1906
+ return (_d = (_b = (_a = this.typeExpression) === null || _a === void 0 ? void 0 : _a.getType(Object.assign(Object.assign({}, options), { flags: 2 /* SymbolTypeFlag.typetime */ }))) !== null && _b !== void 0 ? _b : (_c = this.initialValue) === null || _c === void 0 ? void 0 : _c.getType(Object.assign(Object.assign({}, options), { flags: 1 /* SymbolTypeFlag.runtime */ }))) !== null && _d !== void 0 ? _d : DynamicType_1.DynamicType.instance;
1907
+ }
1908
+ getLeadingTrivia() {
1909
+ var _a, _b, _c, _d, _e, _f;
1910
+ return util_1.util.concatAnnotationLeadingTrivia(this, (_f = (_d = (_b = (_a = this.tokens.accessModifier) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : (_c = this.tokens.optional) === null || _c === void 0 ? void 0 : _c.leadingTrivia) !== null && _d !== void 0 ? _d : (_e = this.tokens.name) === null || _e === void 0 ? void 0 : _e.leadingTrivia) !== null && _f !== void 0 ? _f : []);
1911
+ }
1912
+ get isOptional() {
1913
+ return !!this.tokens.optional;
1331
1914
  }
1332
1915
  transpile(state) {
1333
1916
  throw new Error('transpile not implemented for ' + Object.getPrototypeOf(this).constructor.name);
1334
1917
  }
1335
1918
  getTypedef(state) {
1336
- var _a, _b, _c, _d;
1919
+ var _a, _b, _c, _d, _e;
1337
1920
  const result = [];
1338
- if (this.name) {
1339
- for (let annotation of (_a = this.annotations) !== null && _a !== void 0 ? _a : []) {
1921
+ if (this.tokens.name) {
1922
+ for (let comment of (_a = util_1.util.getLeadingComments(this)) !== null && _a !== void 0 ? _a : []) {
1923
+ result.push(comment.text, state.newline, state.indent());
1924
+ }
1925
+ for (let annotation of (_b = this.annotations) !== null && _b !== void 0 ? _b : []) {
1340
1926
  result.push(...annotation.getTypedef(state), state.newline, state.indent());
1341
1927
  }
1342
- let type = this.getType();
1343
- if (reflection_1.isInvalidType(type) || reflection_1.isVoidType(type)) {
1928
+ let type = this.getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
1929
+ if ((0, reflection_1.isInvalidType)(type) || (0, reflection_1.isVoidType)(type)) {
1344
1930
  type = new DynamicType_1.DynamicType();
1345
1931
  }
1346
- result.push((_c = (_b = this.accessModifier) === null || _b === void 0 ? void 0 : _b.text) !== null && _c !== void 0 ? _c : 'public', ' ', (_d = this.name) === null || _d === void 0 ? void 0 : _d.text, ' as ', type.toTypeString());
1932
+ result.push((_d = (_c = this.tokens.accessModifier) === null || _c === void 0 ? void 0 : _c.text) !== null && _d !== void 0 ? _d : 'public', ' ');
1933
+ if (this.isOptional) {
1934
+ result.push(this.tokens.optional.text, ' ');
1935
+ }
1936
+ result.push((_e = this.tokens.name) === null || _e === void 0 ? void 0 : _e.text, ' as ', type.toTypeString());
1347
1937
  }
1348
1938
  return result;
1349
1939
  }
1350
1940
  walk(visitor, options) {
1351
- if (this.initialValue && options.walkMode & visitors_1.InternalWalkMode.walkExpressions) {
1352
- visitors_1.walk(this, 'initialValue', visitor, options);
1941
+ if (options.walkMode & visitors_1.InternalWalkMode.walkExpressions) {
1942
+ (0, visitors_1.walk)(this, 'typeExpression', visitor, options);
1943
+ (0, visitors_1.walk)(this, 'initialValue', visitor, options);
1353
1944
  }
1354
1945
  }
1355
1946
  }
1356
- exports.ClassFieldStatement = ClassFieldStatement;
1357
- class TryCatchStatement extends Statement {
1358
- constructor(tryToken, tryBranch, catchToken, exceptionVariable, catchBranch, endTryToken) {
1947
+ exports.FieldStatement = FieldStatement;
1948
+ class TryCatchStatement extends AstNode_2.Statement {
1949
+ constructor(options) {
1359
1950
  super();
1360
- this.tryToken = tryToken;
1361
- this.tryBranch = tryBranch;
1362
- this.catchToken = catchToken;
1363
- this.exceptionVariable = exceptionVariable;
1364
- this.catchBranch = catchBranch;
1365
- this.endTryToken = endTryToken;
1366
- }
1367
- get range() {
1368
- var _a, _b, _c, _d, _e;
1369
- return util_1.util.createRangeFromPositions(this.tryToken.range.start, ((_e = (_d = (_c = (_b = (_a = this.endTryToken) !== null && _a !== void 0 ? _a : this.catchBranch) !== null && _b !== void 0 ? _b : this.exceptionVariable) !== null && _c !== void 0 ? _c : this.catchToken) !== null && _d !== void 0 ? _d : this.tryBranch) !== null && _e !== void 0 ? _e : this.tryToken).range.end);
1951
+ this.kind = AstNode_1.AstNodeKind.TryCatchStatement;
1952
+ this.tokens = {
1953
+ try: options.try,
1954
+ endTry: options.endTry
1955
+ };
1956
+ this.tryBranch = options.tryBranch;
1957
+ this.catchStatement = options.catchStatement;
1958
+ this.range = util_1.util.createBoundingRange(this.tokens.try, this.tryBranch, this.catchStatement, this.tokens.endTry);
1370
1959
  }
1371
1960
  transpile(state) {
1961
+ var _a, _b;
1372
1962
  return [
1373
- state.transpileToken(this.tryToken),
1963
+ state.transpileToken(this.tokens.try, 'try'),
1374
1964
  ...this.tryBranch.transpile(state),
1375
1965
  state.newline,
1376
1966
  state.indent(),
1377
- state.transpileToken(this.catchToken),
1378
- ' ',
1379
- state.transpileToken(this.exceptionVariable),
1380
- ...this.catchBranch.transpile(state),
1967
+ ...((_b = (_a = this.catchStatement) === null || _a === void 0 ? void 0 : _a.transpile(state)) !== null && _b !== void 0 ? _b : ['catch']),
1381
1968
  state.newline,
1382
1969
  state.indent(),
1383
- state.transpileToken(this.endTryToken)
1970
+ state.transpileToken(this.tokens.endTry, 'end try')
1384
1971
  ];
1385
1972
  }
1386
1973
  walk(visitor, options) {
1387
1974
  if (this.tryBranch && options.walkMode & visitors_1.InternalWalkMode.walkStatements) {
1388
- visitors_1.walk(this, 'tryBranch', visitor, options);
1389
- visitors_1.walk(this, 'catchBranch', visitor, options);
1975
+ (0, visitors_1.walk)(this, 'tryBranch', visitor, options);
1976
+ (0, visitors_1.walk)(this, 'catchStatement', visitor, options);
1390
1977
  }
1391
1978
  }
1979
+ getLeadingTrivia() {
1980
+ var _a, _b;
1981
+ return (_b = (_a = this.tokens.try) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
1982
+ }
1983
+ getEndTrivia() {
1984
+ var _a, _b;
1985
+ return (_b = (_a = this.tokens.endTry) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
1986
+ }
1392
1987
  }
1393
1988
  exports.TryCatchStatement = TryCatchStatement;
1394
- class ThrowStatement extends Statement {
1395
- constructor(throwToken, expression) {
1396
- var _a;
1989
+ class CatchStatement extends AstNode_2.Statement {
1990
+ constructor(options) {
1397
1991
  super();
1398
- this.throwToken = throwToken;
1399
- this.expression = expression;
1400
- this.range = util_1.util.createRangeFromPositions(this.throwToken.range.start, ((_a = this.expression) !== null && _a !== void 0 ? _a : this.throwToken).range.end);
1992
+ this.kind = AstNode_1.AstNodeKind.CatchStatement;
1993
+ this.tokens = {
1994
+ catch: options === null || options === void 0 ? void 0 : options.catch,
1995
+ exceptionVariable: options === null || options === void 0 ? void 0 : options.exceptionVariable
1996
+ };
1997
+ this.catchBranch = options === null || options === void 0 ? void 0 : options.catchBranch;
1998
+ this.range = util_1.util.createBoundingRange(this.tokens.catch, this.tokens.exceptionVariable, this.catchBranch);
1999
+ }
2000
+ transpile(state) {
2001
+ var _a, _b, _c, _d;
2002
+ return [
2003
+ state.transpileToken(this.tokens.catch, 'catch'),
2004
+ ' ',
2005
+ (_b = (_a = this.tokens.exceptionVariable) === null || _a === void 0 ? void 0 : _a.text) !== null && _b !== void 0 ? _b : 'e',
2006
+ ...((_d = (_c = this.catchBranch) === null || _c === void 0 ? void 0 : _c.transpile(state)) !== null && _d !== void 0 ? _d : [])
2007
+ ];
2008
+ }
2009
+ walk(visitor, options) {
2010
+ if (this.catchBranch && options.walkMode & visitors_1.InternalWalkMode.walkStatements) {
2011
+ (0, visitors_1.walk)(this, 'catchBranch', visitor, options);
2012
+ }
2013
+ }
2014
+ getLeadingTrivia() {
2015
+ var _a, _b;
2016
+ return (_b = (_a = this.tokens.catch) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
2017
+ }
2018
+ }
2019
+ exports.CatchStatement = CatchStatement;
2020
+ class ThrowStatement extends AstNode_2.Statement {
2021
+ constructor(options) {
2022
+ super();
2023
+ this.kind = AstNode_1.AstNodeKind.ThrowStatement;
2024
+ this.tokens = {
2025
+ throw: options.throw
2026
+ };
2027
+ this.expression = options.expression;
2028
+ this.range = util_1.util.createBoundingRange(this.tokens.throw, this.expression);
1401
2029
  }
1402
2030
  transpile(state) {
1403
2031
  const result = [
1404
- state.transpileToken(this.throwToken),
2032
+ state.transpileToken(this.tokens.throw, 'throw'),
1405
2033
  ' '
1406
2034
  ];
1407
2035
  //if we have an expression, transpile it
@@ -1410,15 +2038,534 @@ class ThrowStatement extends Statement {
1410
2038
  //no expression found. Rather than emit syntax errors, provide a generic error message
1411
2039
  }
1412
2040
  else {
1413
- result.push('"An error has occurred"');
2041
+ result.push('"User-specified exception"');
1414
2042
  }
1415
2043
  return result;
1416
2044
  }
1417
2045
  walk(visitor, options) {
1418
2046
  if (this.expression && options.walkMode & visitors_1.InternalWalkMode.walkExpressions) {
1419
- visitors_1.walk(this, 'expression', visitor, options);
2047
+ (0, visitors_1.walk)(this, 'expression', visitor, options);
1420
2048
  }
1421
2049
  }
2050
+ getLeadingTrivia() {
2051
+ var _a, _b;
2052
+ return (_b = (_a = this.tokens.throw) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
2053
+ }
1422
2054
  }
1423
2055
  exports.ThrowStatement = ThrowStatement;
2056
+ class EnumStatement extends AstNode_2.Statement {
2057
+ constructor(options) {
2058
+ var _a;
2059
+ super();
2060
+ this.kind = AstNode_1.AstNodeKind.EnumStatement;
2061
+ this.tokens = {
2062
+ enum: options.enum,
2063
+ name: options.name,
2064
+ endEnum: options.endEnum
2065
+ };
2066
+ this.symbolTable = new SymbolTable_1.SymbolTable('Enum');
2067
+ this.body = (_a = options.body) !== null && _a !== void 0 ? _a : [];
2068
+ }
2069
+ get range() {
2070
+ return util_1.util.createBoundingRange(this.tokens.enum, this.tokens.name, ...this.body, this.tokens.endEnum);
2071
+ }
2072
+ getMembers() {
2073
+ const result = [];
2074
+ for (const statement of this.body) {
2075
+ if ((0, reflection_1.isEnumMemberStatement)(statement)) {
2076
+ result.push(statement);
2077
+ }
2078
+ }
2079
+ return result;
2080
+ }
2081
+ getLeadingTrivia() {
2082
+ var _a;
2083
+ return util_1.util.concatAnnotationLeadingTrivia(this, (_a = this.tokens.enum) === null || _a === void 0 ? void 0 : _a.leadingTrivia);
2084
+ }
2085
+ getEndTrivia() {
2086
+ var _a, _b;
2087
+ return (_b = (_a = this.tokens.endEnum) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
2088
+ }
2089
+ /**
2090
+ * Get a map of member names and their values.
2091
+ * All values are stored as their AST LiteralExpression representation (i.e. string enum values include the wrapping quotes)
2092
+ */
2093
+ getMemberValueMap() {
2094
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
2095
+ const result = new Map();
2096
+ const members = this.getMembers();
2097
+ let currentIntValue = 0;
2098
+ for (const member of members) {
2099
+ //if there is no value, assume an integer and increment the int counter
2100
+ if (!member.value) {
2101
+ result.set((_a = member.name) === null || _a === void 0 ? void 0 : _a.toLowerCase(), currentIntValue.toString());
2102
+ currentIntValue++;
2103
+ //if explicit integer value, use it and increment the int counter
2104
+ }
2105
+ else if ((0, reflection_1.isLiteralExpression)(member.value) && member.value.tokens.value.kind === TokenKind_1.TokenKind.IntegerLiteral) {
2106
+ //try parsing as integer literal, then as hex integer literal.
2107
+ let tokenIntValue = (_b = util_1.util.parseInt(member.value.tokens.value.text)) !== null && _b !== void 0 ? _b : util_1.util.parseInt(member.value.tokens.value.text.replace(/&h/i, '0x'));
2108
+ if (tokenIntValue !== undefined) {
2109
+ currentIntValue = tokenIntValue;
2110
+ currentIntValue++;
2111
+ }
2112
+ result.set((_c = member.name) === null || _c === void 0 ? void 0 : _c.toLowerCase(), member.value.tokens.value.text);
2113
+ //simple unary expressions (like `-1`)
2114
+ }
2115
+ else if ((0, reflection_1.isUnaryExpression)(member.value) && (0, reflection_1.isLiteralExpression)(member.value.right)) {
2116
+ result.set((_d = member.name) === null || _d === void 0 ? void 0 : _d.toLowerCase(), member.value.tokens.operator.text + member.value.right.tokens.value.text);
2117
+ //all other values
2118
+ }
2119
+ else {
2120
+ result.set((_e = member.name) === null || _e === void 0 ? void 0 : _e.toLowerCase(), (_j = (_h = (_g = (_f = member.value) === null || _f === void 0 ? void 0 : _f.tokens) === null || _g === void 0 ? void 0 : _g.value) === null || _h === void 0 ? void 0 : _h.text) !== null && _j !== void 0 ? _j : 'invalid');
2121
+ }
2122
+ }
2123
+ return result;
2124
+ }
2125
+ getMemberValue(name) {
2126
+ return this.getMemberValueMap().get(name.toLowerCase());
2127
+ }
2128
+ /**
2129
+ * The name of the enum (without the namespace prefix)
2130
+ */
2131
+ get name() {
2132
+ var _a;
2133
+ return (_a = this.tokens.name) === null || _a === void 0 ? void 0 : _a.text;
2134
+ }
2135
+ /**
2136
+ * The name of the enum WITH its leading namespace (if applicable)
2137
+ */
2138
+ get fullName() {
2139
+ var _a;
2140
+ const name = (_a = this.tokens.name) === null || _a === void 0 ? void 0 : _a.text;
2141
+ if (name) {
2142
+ const namespace = this.findAncestor(reflection_1.isNamespaceStatement);
2143
+ if (namespace) {
2144
+ let namespaceName = namespace.getName(Parser_1.ParseMode.BrighterScript);
2145
+ return `${namespaceName}.${name}`;
2146
+ }
2147
+ else {
2148
+ return name;
2149
+ }
2150
+ }
2151
+ else {
2152
+ //return undefined which will allow outside callers to know that this doesn't have a name
2153
+ return undefined;
2154
+ }
2155
+ }
2156
+ transpile(state) {
2157
+ //enum declarations do not exist at runtime, so don't transpile anything...
2158
+ return [];
2159
+ }
2160
+ getTypedef(state) {
2161
+ var _a, _b, _c, _d, _e, _f;
2162
+ const result = [];
2163
+ for (let comment of (_a = util_1.util.getLeadingComments(this)) !== null && _a !== void 0 ? _a : []) {
2164
+ result.push(comment.text, state.newline, state.indent());
2165
+ }
2166
+ for (let annotation of (_b = this.annotations) !== null && _b !== void 0 ? _b : []) {
2167
+ result.push(...annotation.getTypedef(state), state.newline, state.indent());
2168
+ }
2169
+ result.push((_d = (_c = this.tokens.enum) === null || _c === void 0 ? void 0 : _c.text) !== null && _d !== void 0 ? _d : 'enum', ' ', this.tokens.name.text);
2170
+ result.push(state.newline);
2171
+ state.blockDepth++;
2172
+ for (const member of this.body) {
2173
+ if ((0, reflection_1.isTypedefProvider)(member)) {
2174
+ result.push(state.indent(), ...member.getTypedef(state), state.newline);
2175
+ }
2176
+ }
2177
+ state.blockDepth--;
2178
+ result.push(state.indent(), (_f = (_e = this.tokens.endEnum) === null || _e === void 0 ? void 0 : _e.text) !== null && _f !== void 0 ? _f : 'end enum');
2179
+ return result;
2180
+ }
2181
+ walk(visitor, options) {
2182
+ if (options.walkMode & visitors_1.InternalWalkMode.walkStatements) {
2183
+ (0, visitors_1.walkArray)(this.body, visitor, options, this);
2184
+ }
2185
+ }
2186
+ getType(options) {
2187
+ var _a, _b, _c;
2188
+ const members = this.getMembers();
2189
+ const resultType = new EnumType_1.EnumType(this.fullName, (_a = members[0]) === null || _a === void 0 ? void 0 : _a.getType(options).underlyingType);
2190
+ resultType.pushMemberProvider(() => this.getSymbolTable());
2191
+ for (const statement of members) {
2192
+ resultType.addMember((_c = (_b = statement === null || statement === void 0 ? void 0 : statement.tokens) === null || _b === void 0 ? void 0 : _b.name) === null || _c === void 0 ? void 0 : _c.text, { definingNode: statement }, statement.getType(options), 1 /* SymbolTypeFlag.runtime */);
2193
+ }
2194
+ return resultType;
2195
+ }
2196
+ }
2197
+ exports.EnumStatement = EnumStatement;
2198
+ class EnumMemberStatement extends AstNode_2.Statement {
2199
+ constructor(options) {
2200
+ super();
2201
+ this.kind = AstNode_1.AstNodeKind.EnumMemberStatement;
2202
+ this.tokens = {
2203
+ name: options.name,
2204
+ equals: options.equals
2205
+ };
2206
+ this.value = options.value;
2207
+ }
2208
+ get range() {
2209
+ return util_1.util.createBoundingRange(this.tokens.name, this.tokens.equals, this.value);
2210
+ }
2211
+ /**
2212
+ * The name of the member
2213
+ */
2214
+ get name() {
2215
+ return this.tokens.name.text;
2216
+ }
2217
+ getLeadingTrivia() {
2218
+ return util_1.util.concatAnnotationLeadingTrivia(this, this.tokens.name.leadingTrivia);
2219
+ }
2220
+ transpile(state) {
2221
+ return [];
2222
+ }
2223
+ getTypedef(state) {
2224
+ var _a;
2225
+ const result = [];
2226
+ for (let comment of (_a = util_1.util.getLeadingComments(this)) !== null && _a !== void 0 ? _a : []) {
2227
+ result.push(comment.text, state.newline, state.indent());
2228
+ }
2229
+ result.push(this.tokens.name.text);
2230
+ if (this.tokens.equals) {
2231
+ result.push(' ', this.tokens.equals.text, ' ');
2232
+ if (this.value) {
2233
+ result.push(...this.value.transpile(state));
2234
+ }
2235
+ }
2236
+ return result;
2237
+ }
2238
+ walk(visitor, options) {
2239
+ if (this.value && options.walkMode & visitors_1.InternalWalkMode.walkExpressions) {
2240
+ (0, visitors_1.walk)(this, 'value', visitor, options);
2241
+ }
2242
+ }
2243
+ getType(options) {
2244
+ var _a, _b, _c, _d;
2245
+ return new EnumType_1.EnumMemberType((_a = this.parent) === null || _a === void 0 ? void 0 : _a.fullName, (_c = (_b = this.tokens) === null || _b === void 0 ? void 0 : _b.name) === null || _c === void 0 ? void 0 : _c.text, (_d = this.value) === null || _d === void 0 ? void 0 : _d.getType(options));
2246
+ }
2247
+ }
2248
+ exports.EnumMemberStatement = EnumMemberStatement;
2249
+ class ConstStatement extends AstNode_2.Statement {
2250
+ constructor(options) {
2251
+ super();
2252
+ this.kind = AstNode_1.AstNodeKind.ConstStatement;
2253
+ this.tokens = {
2254
+ const: options.const,
2255
+ name: options.name,
2256
+ equals: options.equals
2257
+ };
2258
+ this.value = options.value;
2259
+ this.range = util_1.util.createBoundingRange(this.tokens.const, this.tokens.name, this.tokens.equals, this.value);
2260
+ }
2261
+ get name() {
2262
+ return this.tokens.name.text;
2263
+ }
2264
+ getLeadingTrivia() {
2265
+ var _a;
2266
+ return util_1.util.concatAnnotationLeadingTrivia(this, (_a = this.tokens.const) === null || _a === void 0 ? void 0 : _a.leadingTrivia);
2267
+ }
2268
+ /**
2269
+ * The name of the statement WITH its leading namespace (if applicable)
2270
+ */
2271
+ get fullName() {
2272
+ var _a;
2273
+ const name = (_a = this.tokens.name) === null || _a === void 0 ? void 0 : _a.text;
2274
+ if (name) {
2275
+ const namespace = this.findAncestor(reflection_1.isNamespaceStatement);
2276
+ if (namespace) {
2277
+ let namespaceName = namespace.getName(Parser_1.ParseMode.BrighterScript);
2278
+ return `${namespaceName}.${name}`;
2279
+ }
2280
+ else {
2281
+ return name;
2282
+ }
2283
+ }
2284
+ else {
2285
+ //return undefined which will allow outside callers to know that this doesn't have a name
2286
+ return undefined;
2287
+ }
2288
+ }
2289
+ transpile(state) {
2290
+ //const declarations don't exist at runtime, so just transpile empty
2291
+ return [];
2292
+ }
2293
+ getTypedef(state) {
2294
+ var _a;
2295
+ const result = [];
2296
+ for (let comment of (_a = util_1.util.getLeadingComments(this)) !== null && _a !== void 0 ? _a : []) {
2297
+ result.push(comment.text, state.newline, state.indent());
2298
+ }
2299
+ result.push(this.tokens.const ? state.tokenToSourceNode(this.tokens.const) : 'const', ' ', state.tokenToSourceNode(this.tokens.name), ' ', this.tokens.equals ? state.tokenToSourceNode(this.tokens.equals) : '=', ' ', ...this.value.transpile(state));
2300
+ return result;
2301
+ }
2302
+ walk(visitor, options) {
2303
+ if (this.value && options.walkMode & visitors_1.InternalWalkMode.walkExpressions) {
2304
+ (0, visitors_1.walk)(this, 'value', visitor, options);
2305
+ }
2306
+ }
2307
+ getType(options) {
2308
+ return this.value.getType(options);
2309
+ }
2310
+ }
2311
+ exports.ConstStatement = ConstStatement;
2312
+ class ContinueStatement extends AstNode_2.Statement {
2313
+ constructor(options) {
2314
+ super();
2315
+ this.kind = AstNode_1.AstNodeKind.ContinueStatement;
2316
+ this.tokens = {
2317
+ continue: options.continue,
2318
+ loopType: options.loopType
2319
+ };
2320
+ this.range = util_1.util.createBoundingRange(this.tokens.continue, this.tokens.loopType);
2321
+ }
2322
+ transpile(state) {
2323
+ var _a, _b, _c, _d, _e;
2324
+ return [
2325
+ state.sourceNode(this.tokens.continue, (_b = (_a = this.tokens.continue) === null || _a === void 0 ? void 0 : _a.text) !== null && _b !== void 0 ? _b : 'continue'),
2326
+ (_d = (_c = this.tokens.loopType) === null || _c === void 0 ? void 0 : _c.leadingWhitespace) !== null && _d !== void 0 ? _d : ' ',
2327
+ state.sourceNode(this.tokens.continue, (_e = this.tokens.loopType) === null || _e === void 0 ? void 0 : _e.text)
2328
+ ];
2329
+ }
2330
+ walk(visitor, options) {
2331
+ //nothing to walk
2332
+ }
2333
+ getLeadingTrivia() {
2334
+ var _a, _b;
2335
+ return (_b = (_a = this.tokens.continue) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
2336
+ }
2337
+ }
2338
+ exports.ContinueStatement = ContinueStatement;
2339
+ class TypecastStatement extends AstNode_2.Statement {
2340
+ constructor(options) {
2341
+ super();
2342
+ this.kind = AstNode_1.AstNodeKind.TypecastStatement;
2343
+ this.tokens = {
2344
+ typecast: options.typecast
2345
+ };
2346
+ this.typecastExpression = options.typecastExpression;
2347
+ this.range = util_1.util.createBoundingRange(this.tokens.typecast, this.typecastExpression);
2348
+ }
2349
+ transpile(state) {
2350
+ //the typecast statement is a comment just for debugging purposes
2351
+ return [
2352
+ `'`,
2353
+ state.transpileToken(this.tokens.typecast, 'typecast'),
2354
+ ' ',
2355
+ this.typecastExpression.obj.transpile(state),
2356
+ ' ',
2357
+ state.transpileToken(this.typecastExpression.tokens.as, 'as'),
2358
+ ' ',
2359
+ this.typecastExpression.typeExpression.transpile(state)
2360
+ ];
2361
+ }
2362
+ walk(visitor, options) {
2363
+ if (options.walkMode & visitors_1.InternalWalkMode.walkExpressions) {
2364
+ (0, visitors_1.walk)(this, 'typecastExpression', visitor, options);
2365
+ }
2366
+ }
2367
+ getLeadingTrivia() {
2368
+ var _a, _b;
2369
+ return (_b = (_a = this.tokens.typecast) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
2370
+ }
2371
+ getType(options) {
2372
+ return this.typecastExpression.getType(options);
2373
+ }
2374
+ }
2375
+ exports.TypecastStatement = TypecastStatement;
2376
+ class ConditionalCompileErrorStatement extends AstNode_2.Statement {
2377
+ constructor(options) {
2378
+ super();
2379
+ this.kind = AstNode_1.AstNodeKind.ConditionalCompileErrorStatement;
2380
+ this.tokens = {
2381
+ hashError: options.hashError,
2382
+ message: options.message
2383
+ };
2384
+ this.range = util_1.util.createBoundingRange(util_1.util.createBoundingRangeFromTokens(this.tokens));
2385
+ }
2386
+ transpile(state) {
2387
+ return [
2388
+ state.transpileToken(this.tokens.hashError, '#error'),
2389
+ ' ',
2390
+ state.transpileToken(this.tokens.message)
2391
+ ];
2392
+ }
2393
+ walk(visitor, options) {
2394
+ // nothing to walk
2395
+ }
2396
+ getLeadingTrivia() {
2397
+ var _a;
2398
+ return (_a = this.tokens.hashError.leadingTrivia) !== null && _a !== void 0 ? _a : [];
2399
+ }
2400
+ }
2401
+ exports.ConditionalCompileErrorStatement = ConditionalCompileErrorStatement;
2402
+ class AliasStatement extends AstNode_2.Statement {
2403
+ constructor(options) {
2404
+ super();
2405
+ this.kind = AstNode_1.AstNodeKind.AliasStatement;
2406
+ this.tokens = {
2407
+ alias: options.alias,
2408
+ name: options.name,
2409
+ equals: options.equals
2410
+ };
2411
+ this.value = options.value;
2412
+ this.range = util_1.util.createBoundingRange(this.tokens.alias, this.tokens.name, this.tokens.equals, this.value);
2413
+ }
2414
+ transpile(state) {
2415
+ //the alias statement is a comment just for debugging purposes
2416
+ return [
2417
+ `'`,
2418
+ state.transpileToken(this.tokens.alias, 'alias'),
2419
+ ' ',
2420
+ state.transpileToken(this.tokens.name),
2421
+ ' ',
2422
+ state.transpileToken(this.tokens.equals, '='),
2423
+ ' ',
2424
+ this.value.transpile(state)
2425
+ ];
2426
+ }
2427
+ walk(visitor, options) {
2428
+ if (options.walkMode & visitors_1.InternalWalkMode.walkExpressions) {
2429
+ (0, visitors_1.walk)(this, 'value', visitor, options);
2430
+ }
2431
+ }
2432
+ getLeadingTrivia() {
2433
+ var _a, _b;
2434
+ return (_b = (_a = this.tokens.alias) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
2435
+ }
2436
+ getType(options) {
2437
+ return this.value.getType(options);
2438
+ }
2439
+ }
2440
+ exports.AliasStatement = AliasStatement;
2441
+ class ConditionalCompileStatement extends AstNode_2.Statement {
2442
+ constructor(options) {
2443
+ super();
2444
+ this.kind = AstNode_1.AstNodeKind.ConditionalCompileStatement;
2445
+ this.thenBranch = options.thenBranch;
2446
+ this.elseBranch = options.elseBranch;
2447
+ this.tokens = {
2448
+ hashIf: options.hashIf,
2449
+ not: options.not,
2450
+ condition: options.condition,
2451
+ hashElse: options.hashElse,
2452
+ hashEndIf: options.hashEndIf
2453
+ };
2454
+ this.range = util_1.util.createBoundingRange(util_1.util.createBoundingRangeFromTokens(this.tokens), this.thenBranch, this.elseBranch);
2455
+ }
2456
+ transpile(state) {
2457
+ var _a, _b, _c;
2458
+ let results = [];
2459
+ //if (already indented by block)
2460
+ if (!state.conditionalCompileStatement) {
2461
+ // only transpile the #if in the case when we're not in a conditionalCompileStatement already
2462
+ results.push(state.transpileToken((_a = this.tokens.hashIf) !== null && _a !== void 0 ? _a : (0, creators_1.createToken)(TokenKind_1.TokenKind.HashIf)));
2463
+ }
2464
+ results.push(' ');
2465
+ //conditions
2466
+ if (this.tokens.not) {
2467
+ results.push('not');
2468
+ results.push(' ');
2469
+ }
2470
+ results.push(state.transpileToken(this.tokens.condition));
2471
+ state.lineage.unshift(this);
2472
+ //if statement body
2473
+ let thenNodes = this.thenBranch.transpile(state);
2474
+ state.lineage.shift();
2475
+ if (thenNodes.length > 0) {
2476
+ results.push(thenNodes);
2477
+ }
2478
+ //else branch
2479
+ if (this.elseBranch) {
2480
+ const elseIsCC = (0, reflection_1.isConditionalCompileStatement)(this.elseBranch);
2481
+ const endBlockToken = elseIsCC ? (_b = this.elseBranch.tokens.hashIf) !== null && _b !== void 0 ? _b : (0, creators_1.createToken)(TokenKind_1.TokenKind.HashElseIf) : this.tokens.hashElse;
2482
+ //else
2483
+ results.push(...state.transpileEndBlockToken(this.thenBranch, endBlockToken, (0, creators_1.createToken)(TokenKind_1.TokenKind.HashElse).text));
2484
+ if (elseIsCC) {
2485
+ //chained else if
2486
+ state.lineage.unshift(this.elseBranch);
2487
+ // transpile following #if with knowledge of current
2488
+ const existingCCStmt = state.conditionalCompileStatement;
2489
+ state.conditionalCompileStatement = this;
2490
+ let body = this.elseBranch.transpile(state);
2491
+ state.conditionalCompileStatement = existingCCStmt;
2492
+ state.lineage.shift();
2493
+ if (body.length > 0) {
2494
+ //zero or more spaces between the `else` and the `if`
2495
+ results.push(...body);
2496
+ // stop here because chained if will transpile the rest
2497
+ return results;
2498
+ }
2499
+ else {
2500
+ results.push('\n');
2501
+ }
2502
+ }
2503
+ else {
2504
+ //else body
2505
+ state.lineage.unshift(this.tokens.hashElse);
2506
+ let body = this.elseBranch.transpile(state);
2507
+ state.lineage.shift();
2508
+ if (body.length > 0) {
2509
+ results.push(...body);
2510
+ }
2511
+ }
2512
+ }
2513
+ //end if
2514
+ results.push(...state.transpileEndBlockToken((_c = this.elseBranch) !== null && _c !== void 0 ? _c : this.thenBranch, this.tokens.hashEndIf, '#end if'));
2515
+ return results;
2516
+ }
2517
+ walk(visitor, options) {
2518
+ var _a;
2519
+ if (options.walkMode & visitors_1.InternalWalkMode.walkStatements) {
2520
+ const bsConsts = (_a = options.bsConsts) !== null && _a !== void 0 ? _a : this.getBsConsts();
2521
+ let conditionTrue = bsConsts === null || bsConsts === void 0 ? void 0 : bsConsts.get(this.tokens.condition.text.toLowerCase());
2522
+ if (this.tokens.not) {
2523
+ // flips the boolean value
2524
+ conditionTrue = !conditionTrue;
2525
+ }
2526
+ const walkFalseBlocks = options.walkMode & visitors_1.InternalWalkMode.visitFalseConditionalCompilationBlocks;
2527
+ if (conditionTrue || walkFalseBlocks) {
2528
+ (0, visitors_1.walk)(this, 'thenBranch', visitor, options);
2529
+ }
2530
+ if (this.elseBranch && (!conditionTrue || walkFalseBlocks)) {
2531
+ (0, visitors_1.walk)(this, 'elseBranch', visitor, options);
2532
+ }
2533
+ }
2534
+ }
2535
+ getLeadingTrivia() {
2536
+ var _a, _b;
2537
+ return (_b = (_a = this.tokens.hashIf) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
2538
+ }
2539
+ }
2540
+ exports.ConditionalCompileStatement = ConditionalCompileStatement;
2541
+ class ConditionalCompileConstStatement extends AstNode_2.Statement {
2542
+ constructor(options) {
2543
+ super();
2544
+ this.kind = AstNode_1.AstNodeKind.ConditionalCompileConstStatement;
2545
+ this.tokens = {
2546
+ hashConst: options.hashConst
2547
+ };
2548
+ this.assignment = options.assignment;
2549
+ this.range = util_1.util.createBoundingRange(util_1.util.createBoundingRangeFromTokens(this.tokens), this.assignment);
2550
+ }
2551
+ transpile(state) {
2552
+ return [
2553
+ state.transpileToken(this.tokens.hashConst, '#const'),
2554
+ ' ',
2555
+ state.transpileToken(this.assignment.tokens.name),
2556
+ ' ',
2557
+ state.transpileToken(this.assignment.tokens.equals, '='),
2558
+ ' ',
2559
+ ...this.assignment.value.transpile(state)
2560
+ ];
2561
+ }
2562
+ walk(visitor, options) {
2563
+ // nothing to walk
2564
+ }
2565
+ getLeadingTrivia() {
2566
+ var _a;
2567
+ return (_a = this.tokens.hashConst.leadingTrivia) !== null && _a !== void 0 ? _a : [];
2568
+ }
2569
+ }
2570
+ exports.ConditionalCompileConstStatement = ConditionalCompileConstStatement;
1424
2571
  //# sourceMappingURL=Statement.js.map