brighterscript 1.0.0-alpha.5 → 1.0.0-alpha.51

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (652) hide show
  1. package/README.md +79 -138
  2. package/bsconfig.schema.json +196 -5
  3. package/dist/ActionPipeline.d.ts +10 -0
  4. package/dist/ActionPipeline.js +40 -0
  5. package/dist/ActionPipeline.js.map +1 -0
  6. package/dist/AstValidationSegmenter.d.ts +45 -0
  7. package/dist/AstValidationSegmenter.js +322 -0
  8. package/dist/AstValidationSegmenter.js.map +1 -0
  9. package/dist/BsConfig.d.ts +161 -43
  10. package/dist/BusyStatusTracker.d.ts +61 -0
  11. package/dist/BusyStatusTracker.js +148 -0
  12. package/dist/BusyStatusTracker.js.map +1 -0
  13. package/dist/Cache.d.ts +3 -8
  14. package/dist/Cache.js +9 -14
  15. package/dist/Cache.js.map +1 -1
  16. package/dist/CacheVerifier.d.ts +7 -0
  17. package/dist/CacheVerifier.js +20 -0
  18. package/dist/CacheVerifier.js.map +1 -0
  19. package/dist/CodeActionUtil.d.ts +29 -4
  20. package/dist/CodeActionUtil.js +22 -5
  21. package/dist/CodeActionUtil.js.map +1 -1
  22. package/dist/CommentFlagProcessor.d.ts +20 -15
  23. package/dist/CommentFlagProcessor.js +143 -58
  24. package/dist/CommentFlagProcessor.js.map +1 -1
  25. package/dist/CrossScopeValidator.d.ts +68 -0
  26. package/dist/CrossScopeValidator.js +650 -0
  27. package/dist/CrossScopeValidator.js.map +1 -0
  28. package/dist/DependencyGraph.d.ts +8 -3
  29. package/dist/DependencyGraph.js +49 -16
  30. package/dist/DependencyGraph.js.map +1 -1
  31. package/dist/DiagnosticCollection.d.ts +21 -5
  32. package/dist/DiagnosticCollection.js +77 -24
  33. package/dist/DiagnosticCollection.js.map +1 -1
  34. package/dist/DiagnosticFilterer.d.ts +27 -6
  35. package/dist/DiagnosticFilterer.js +273 -60
  36. package/dist/DiagnosticFilterer.js.map +1 -1
  37. package/dist/DiagnosticManager.d.ts +83 -0
  38. package/dist/DiagnosticManager.js +422 -0
  39. package/dist/DiagnosticManager.js.map +1 -0
  40. package/dist/DiagnosticMessages.d.ts +602 -196
  41. package/dist/DiagnosticMessages.js +926 -342
  42. package/dist/DiagnosticMessages.js.map +1 -1
  43. package/dist/DiagnosticSeverityAdjuster.d.ts +7 -0
  44. package/dist/DiagnosticSeverityAdjuster.js +45 -0
  45. package/dist/DiagnosticSeverityAdjuster.js.map +1 -0
  46. package/dist/FunctionScope.d.ts +28 -0
  47. package/dist/FunctionScope.js +52 -0
  48. package/dist/FunctionScope.js.map +1 -0
  49. package/dist/KeyedThrottler.d.ts +3 -3
  50. package/dist/KeyedThrottler.js +3 -3
  51. package/dist/KeyedThrottler.js.map +1 -1
  52. package/dist/LanguageServer.d.ts +136 -104
  53. package/dist/LanguageServer.js +577 -741
  54. package/dist/LanguageServer.js.map +1 -1
  55. package/dist/Logger.d.ts +17 -13
  56. package/dist/Logger.js +64 -34
  57. package/dist/Logger.js.map +1 -1
  58. package/dist/PluginInterface.d.ts +32 -10
  59. package/dist/PluginInterface.js +117 -7
  60. package/dist/PluginInterface.js.map +1 -1
  61. package/dist/Program.d.ts +302 -98
  62. package/dist/Program.js +1613 -726
  63. package/dist/Program.js.map +1 -1
  64. package/dist/ProgramBuilder.d.ts +39 -22
  65. package/dist/ProgramBuilder.js +245 -179
  66. package/dist/ProgramBuilder.js.map +1 -1
  67. package/dist/Scope.d.ts +227 -106
  68. package/dist/Scope.js +609 -557
  69. package/dist/Scope.js.map +1 -1
  70. package/dist/ScopeNamespaceLookup.d.ts +73 -0
  71. package/dist/ScopeNamespaceLookup.js +242 -0
  72. package/dist/ScopeNamespaceLookup.js.map +1 -0
  73. package/dist/SemanticTokenUtils.js +5 -1
  74. package/dist/SemanticTokenUtils.js.map +1 -1
  75. package/dist/Stopwatch.d.ts +4 -0
  76. package/dist/Stopwatch.js +8 -1
  77. package/dist/Stopwatch.js.map +1 -1
  78. package/dist/SymbolTable.d.ts +145 -26
  79. package/dist/SymbolTable.js +575 -64
  80. package/dist/SymbolTable.js.map +1 -1
  81. package/dist/SymbolTypeFlag.d.ts +9 -0
  82. package/dist/SymbolTypeFlag.js +14 -0
  83. package/dist/SymbolTypeFlag.js.map +1 -0
  84. package/dist/Throttler.d.ts +12 -0
  85. package/dist/Throttler.js +39 -0
  86. package/dist/Throttler.js.map +1 -1
  87. package/dist/Watcher.d.ts +0 -3
  88. package/dist/Watcher.js +0 -3
  89. package/dist/Watcher.js.map +1 -1
  90. package/dist/XmlScope.d.ts +5 -15
  91. package/dist/XmlScope.js +34 -90
  92. package/dist/XmlScope.js.map +1 -1
  93. package/dist/astUtils/CachedLookups.d.ts +50 -0
  94. package/dist/astUtils/CachedLookups.js +337 -0
  95. package/dist/astUtils/CachedLookups.js.map +1 -0
  96. package/dist/astUtils/Editor.d.ts +69 -0
  97. package/dist/astUtils/Editor.js +245 -0
  98. package/dist/astUtils/Editor.js.map +1 -0
  99. package/dist/astUtils/creators.d.ts +54 -19
  100. package/dist/astUtils/creators.js +242 -42
  101. package/dist/astUtils/creators.js.map +1 -1
  102. package/dist/astUtils/reflection.d.ts +199 -85
  103. package/dist/astUtils/reflection.js +518 -145
  104. package/dist/astUtils/reflection.js.map +1 -1
  105. package/dist/astUtils/stackedVisitor.js.map +1 -1
  106. package/dist/astUtils/visitors.d.ts +117 -53
  107. package/dist/astUtils/visitors.js +95 -15
  108. package/dist/astUtils/visitors.js.map +1 -1
  109. package/dist/astUtils/xml.d.ts +9 -8
  110. package/dist/astUtils/xml.js +12 -7
  111. package/dist/astUtils/xml.js.map +1 -1
  112. package/dist/bscPlugin/BscPlugin.d.ts +26 -4
  113. package/dist/bscPlugin/BscPlugin.js +96 -4
  114. package/dist/bscPlugin/BscPlugin.js.map +1 -1
  115. package/dist/bscPlugin/CallExpressionInfo.d.ts +36 -0
  116. package/dist/bscPlugin/CallExpressionInfo.js +142 -0
  117. package/dist/bscPlugin/CallExpressionInfo.js.map +1 -0
  118. package/dist/bscPlugin/FileWriter.d.ts +19 -0
  119. package/dist/bscPlugin/FileWriter.js +79 -0
  120. package/dist/bscPlugin/FileWriter.js.map +1 -0
  121. package/dist/bscPlugin/SignatureHelpUtil.d.ts +10 -0
  122. package/dist/bscPlugin/SignatureHelpUtil.js +137 -0
  123. package/dist/bscPlugin/SignatureHelpUtil.js.map +1 -0
  124. package/dist/bscPlugin/codeActions/CodeActionsProcessor.d.ts +109 -7
  125. package/dist/bscPlugin/codeActions/CodeActionsProcessor.js +676 -26
  126. package/dist/bscPlugin/codeActions/CodeActionsProcessor.js.map +1 -1
  127. package/dist/bscPlugin/codeActions/FixAllCodeActionsProcessor.d.ts +17 -0
  128. package/dist/bscPlugin/codeActions/FixAllCodeActionsProcessor.js +66 -0
  129. package/dist/bscPlugin/codeActions/FixAllCodeActionsProcessor.js.map +1 -0
  130. package/dist/bscPlugin/codeActions/codeActionHelpers.d.ts +18 -0
  131. package/dist/bscPlugin/codeActions/codeActionHelpers.js +31 -0
  132. package/dist/bscPlugin/codeActions/codeActionHelpers.js.map +1 -0
  133. package/dist/bscPlugin/completions/CompletionsProcessor.d.ts +65 -0
  134. package/dist/bscPlugin/completions/CompletionsProcessor.js +633 -0
  135. package/dist/bscPlugin/completions/CompletionsProcessor.js.map +1 -0
  136. package/dist/bscPlugin/definition/DefinitionProvider.d.ts +13 -0
  137. package/dist/bscPlugin/definition/DefinitionProvider.js +220 -0
  138. package/dist/bscPlugin/definition/DefinitionProvider.js.map +1 -0
  139. package/dist/bscPlugin/fileProviders/FileProvider.d.ts +9 -0
  140. package/dist/bscPlugin/fileProviders/FileProvider.js +51 -0
  141. package/dist/bscPlugin/fileProviders/FileProvider.js.map +1 -0
  142. package/dist/bscPlugin/hover/HoverProcessor.d.ts +18 -0
  143. package/dist/bscPlugin/hover/HoverProcessor.js +238 -0
  144. package/dist/bscPlugin/hover/HoverProcessor.js.map +1 -0
  145. package/dist/bscPlugin/references/ReferencesProvider.d.ts +12 -0
  146. package/dist/bscPlugin/references/ReferencesProvider.js +57 -0
  147. package/dist/bscPlugin/references/ReferencesProvider.js.map +1 -0
  148. package/dist/bscPlugin/selectionRanges/SelectionRangesProcessor.d.ts +7 -0
  149. package/dist/bscPlugin/selectionRanges/SelectionRangesProcessor.js +77 -0
  150. package/dist/bscPlugin/selectionRanges/SelectionRangesProcessor.js.map +1 -0
  151. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.d.ts +14 -0
  152. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js +164 -0
  153. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js.map +1 -0
  154. package/dist/bscPlugin/serialize/BslibManager.d.ts +12 -0
  155. package/dist/bscPlugin/serialize/BslibManager.js +46 -0
  156. package/dist/bscPlugin/serialize/BslibManager.js.map +1 -0
  157. package/dist/bscPlugin/serialize/FileSerializer.d.ts +9 -0
  158. package/dist/bscPlugin/serialize/FileSerializer.js +80 -0
  159. package/dist/bscPlugin/serialize/FileSerializer.js.map +1 -0
  160. package/dist/bscPlugin/symbols/DocumentSymbolProcessor.d.ts +7 -0
  161. package/dist/bscPlugin/symbols/DocumentSymbolProcessor.js +22 -0
  162. package/dist/bscPlugin/symbols/DocumentSymbolProcessor.js.map +1 -0
  163. package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.d.ts +7 -0
  164. package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.js +26 -0
  165. package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.js.map +1 -0
  166. package/dist/bscPlugin/symbols/symbolUtils.d.ts +5 -0
  167. package/dist/bscPlugin/symbols/symbolUtils.js +141 -0
  168. package/dist/bscPlugin/symbols/symbolUtils.js.map +1 -0
  169. package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.d.ts +34 -0
  170. package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.js +504 -0
  171. package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.js.map +1 -0
  172. package/dist/bscPlugin/transpile/XmlFilePreTranspileProcessor.d.ts +12 -0
  173. package/dist/bscPlugin/transpile/XmlFilePreTranspileProcessor.js +99 -0
  174. package/dist/bscPlugin/transpile/XmlFilePreTranspileProcessor.js.map +1 -0
  175. package/dist/bscPlugin/validation/BrsFileAfterValidator.d.ts +7 -0
  176. package/dist/bscPlugin/validation/BrsFileAfterValidator.js +18 -0
  177. package/dist/bscPlugin/validation/BrsFileAfterValidator.js.map +1 -0
  178. package/dist/bscPlugin/validation/BrsFileValidator.d.ts +51 -0
  179. package/dist/bscPlugin/validation/BrsFileValidator.js +714 -0
  180. package/dist/bscPlugin/validation/BrsFileValidator.js.map +1 -0
  181. package/dist/bscPlugin/validation/ProgramValidator.d.ts +11 -0
  182. package/dist/bscPlugin/validation/ProgramValidator.js +33 -0
  183. package/dist/bscPlugin/validation/ProgramValidator.js.map +1 -0
  184. package/dist/bscPlugin/validation/ScopeValidator.d.ts +158 -0
  185. package/dist/bscPlugin/validation/ScopeValidator.js +1481 -0
  186. package/dist/bscPlugin/validation/ScopeValidator.js.map +1 -0
  187. package/dist/bscPlugin/validation/XmlFileValidator.d.ts +8 -0
  188. package/dist/bscPlugin/validation/XmlFileValidator.js +50 -0
  189. package/dist/bscPlugin/validation/XmlFileValidator.js.map +1 -0
  190. package/dist/cli.js +140 -28
  191. package/dist/cli.js.map +1 -1
  192. package/dist/common/Sequencer.d.ts +53 -0
  193. package/dist/common/Sequencer.js +233 -0
  194. package/dist/common/Sequencer.js.map +1 -0
  195. package/dist/deferred.d.ts +5 -3
  196. package/dist/deferred.js +10 -0
  197. package/dist/deferred.js.map +1 -1
  198. package/dist/diagnosticUtils.d.ts +61 -4
  199. package/dist/diagnosticUtils.js +285 -25
  200. package/dist/diagnosticUtils.js.map +1 -1
  201. package/dist/examples/plugins/removePrint.d.ts +2 -2
  202. package/dist/examples/plugins/removePrint.js +8 -12
  203. package/dist/examples/plugins/removePrint.js.map +1 -1
  204. package/dist/files/AssetFile.d.ts +24 -0
  205. package/dist/files/AssetFile.js +25 -0
  206. package/dist/files/AssetFile.js.map +1 -0
  207. package/dist/files/BrsFile.d.ts +161 -87
  208. package/dist/files/BrsFile.js +919 -936
  209. package/dist/files/BrsFile.js.map +1 -1
  210. package/dist/files/BscFile.d.ts +102 -0
  211. package/dist/files/BscFile.js +15 -0
  212. package/dist/files/BscFile.js.map +1 -0
  213. package/dist/files/Factory.d.ts +25 -0
  214. package/dist/files/Factory.js +22 -0
  215. package/dist/files/Factory.js.map +1 -0
  216. package/dist/files/LazyFileData.d.ts +21 -0
  217. package/dist/files/LazyFileData.js +54 -0
  218. package/dist/files/LazyFileData.js.map +1 -0
  219. package/dist/files/XmlFile.d.ts +80 -41
  220. package/dist/files/XmlFile.js +162 -137
  221. package/dist/files/XmlFile.js.map +1 -1
  222. package/dist/globalCallables.d.ts +3 -1
  223. package/dist/globalCallables.js +424 -184
  224. package/dist/globalCallables.js.map +1 -1
  225. package/dist/index.d.ts +32 -4
  226. package/dist/index.js +54 -7
  227. package/dist/index.js.map +1 -1
  228. package/dist/interfaces.d.ts +987 -125
  229. package/dist/interfaces.js +21 -0
  230. package/dist/interfaces.js.map +1 -1
  231. package/dist/lexer/Lexer.d.ts +51 -12
  232. package/dist/lexer/Lexer.js +214 -65
  233. package/dist/lexer/Lexer.js.map +1 -1
  234. package/dist/lexer/Token.d.ts +27 -11
  235. package/dist/lexer/Token.js +10 -2
  236. package/dist/lexer/Token.js.map +1 -1
  237. package/dist/lexer/TokenKind.d.ts +48 -2
  238. package/dist/lexer/TokenKind.js +167 -10
  239. package/dist/lexer/TokenKind.js.map +1 -1
  240. package/dist/logging.d.ts +14 -0
  241. package/dist/logging.js +29 -0
  242. package/dist/logging.js.map +1 -0
  243. package/dist/lsp/ActionQueue.d.ts +35 -0
  244. package/dist/lsp/ActionQueue.js +115 -0
  245. package/dist/lsp/ActionQueue.js.map +1 -0
  246. package/dist/lsp/DocumentManager.d.ts +63 -0
  247. package/dist/lsp/DocumentManager.js +122 -0
  248. package/dist/lsp/DocumentManager.js.map +1 -0
  249. package/dist/lsp/LspProject.d.ts +287 -0
  250. package/dist/lsp/LspProject.js +3 -0
  251. package/dist/lsp/LspProject.js.map +1 -0
  252. package/dist/lsp/PathFilterer.d.ts +75 -0
  253. package/dist/lsp/PathFilterer.js +196 -0
  254. package/dist/lsp/PathFilterer.js.map +1 -0
  255. package/dist/lsp/Project.d.ts +200 -0
  256. package/dist/lsp/Project.js +562 -0
  257. package/dist/lsp/Project.js.map +1 -0
  258. package/dist/lsp/ProjectManager.d.ts +288 -0
  259. package/dist/lsp/ProjectManager.js +967 -0
  260. package/dist/lsp/ProjectManager.js.map +1 -0
  261. package/dist/lsp/ReaderWriterManager.d.ts +21 -0
  262. package/dist/lsp/ReaderWriterManager.js +60 -0
  263. package/dist/lsp/ReaderWriterManager.js.map +1 -0
  264. package/dist/lsp/worker/MessageHandler.d.ts +99 -0
  265. package/dist/lsp/worker/MessageHandler.js +138 -0
  266. package/dist/lsp/worker/MessageHandler.js.map +1 -0
  267. package/dist/lsp/worker/WorkerPool.d.ts +38 -0
  268. package/dist/lsp/worker/WorkerPool.js +78 -0
  269. package/dist/lsp/worker/WorkerPool.js.map +1 -0
  270. package/dist/lsp/worker/WorkerThreadProject.d.ts +168 -0
  271. package/dist/lsp/worker/WorkerThreadProject.js +205 -0
  272. package/dist/lsp/worker/WorkerThreadProject.js.map +1 -0
  273. package/dist/lsp/worker/WorkerThreadProjectRunner.d.ts +15 -0
  274. package/dist/lsp/worker/WorkerThreadProjectRunner.js +58 -0
  275. package/dist/lsp/worker/WorkerThreadProjectRunner.js.map +1 -0
  276. package/dist/lsp/worker/run.js +14 -0
  277. package/dist/lsp/worker/run.js.map +1 -0
  278. package/dist/parser/AstNode.d.ts +205 -0
  279. package/dist/parser/AstNode.js +305 -0
  280. package/dist/parser/AstNode.js.map +1 -0
  281. package/dist/parser/BrightScriptDocParser.d.ts +56 -0
  282. package/dist/parser/BrightScriptDocParser.js +294 -0
  283. package/dist/parser/BrightScriptDocParser.js.map +1 -0
  284. package/dist/parser/BrsTranspileState.d.ts +22 -3
  285. package/dist/parser/BrsTranspileState.js +19 -0
  286. package/dist/parser/BrsTranspileState.js.map +1 -1
  287. package/dist/parser/Expression.d.ts +601 -220
  288. package/dist/parser/Expression.js +1516 -502
  289. package/dist/parser/Expression.js.map +1 -1
  290. package/dist/parser/Parser.d.ts +137 -121
  291. package/dist/parser/Parser.js +1808 -982
  292. package/dist/parser/Parser.js.map +1 -1
  293. package/dist/parser/SGParser.d.ts +30 -13
  294. package/dist/parser/SGParser.js +94 -56
  295. package/dist/parser/SGParser.js.map +1 -1
  296. package/dist/parser/SGTypes.d.ts +134 -46
  297. package/dist/parser/SGTypes.js +206 -115
  298. package/dist/parser/SGTypes.js.map +1 -1
  299. package/dist/parser/Statement.d.ts +854 -267
  300. package/dist/parser/Statement.js +2416 -621
  301. package/dist/parser/Statement.js.map +1 -1
  302. package/dist/parser/TranspileState.d.ts +30 -14
  303. package/dist/parser/TranspileState.js +124 -27
  304. package/dist/parser/TranspileState.js.map +1 -1
  305. package/dist/preprocessor/Manifest.d.ts +6 -6
  306. package/dist/preprocessor/Manifest.js +17 -38
  307. package/dist/preprocessor/Manifest.js.map +1 -1
  308. package/dist/roku-types/data.json +20554 -0
  309. package/dist/roku-types/index.d.ts +5726 -0
  310. package/dist/roku-types/index.js +11 -0
  311. package/dist/roku-types/index.js.map +1 -0
  312. package/dist/types/ArrayType.d.ts +12 -5
  313. package/dist/types/ArrayType.js +95 -25
  314. package/dist/types/ArrayType.js.map +1 -1
  315. package/dist/types/AssociativeArrayType.d.ts +15 -0
  316. package/dist/types/AssociativeArrayType.js +64 -0
  317. package/dist/types/AssociativeArrayType.js.map +1 -0
  318. package/dist/types/BaseFunctionType.d.ts +10 -0
  319. package/dist/types/BaseFunctionType.js +26 -0
  320. package/dist/types/BaseFunctionType.js.map +1 -0
  321. package/dist/types/BooleanType.d.ts +9 -5
  322. package/dist/types/BooleanType.js +19 -8
  323. package/dist/types/BooleanType.js.map +1 -1
  324. package/dist/types/BscType.d.ts +41 -3
  325. package/dist/types/BscType.js +152 -0
  326. package/dist/types/BscType.js.map +1 -1
  327. package/dist/types/BscTypeKind.d.ts +28 -0
  328. package/dist/types/BscTypeKind.js +33 -0
  329. package/dist/types/BscTypeKind.js.map +1 -0
  330. package/dist/types/BuiltInInterfaceAdder.d.ts +28 -0
  331. package/dist/types/BuiltInInterfaceAdder.js +212 -0
  332. package/dist/types/BuiltInInterfaceAdder.js.map +1 -0
  333. package/dist/types/CallFuncableType.d.ts +24 -0
  334. package/dist/types/CallFuncableType.js +91 -0
  335. package/dist/types/CallFuncableType.js.map +1 -0
  336. package/dist/types/ClassType.d.ts +17 -0
  337. package/dist/types/ClassType.js +63 -0
  338. package/dist/types/ClassType.js.map +1 -0
  339. package/dist/types/ComponentType.d.ts +22 -0
  340. package/dist/types/ComponentType.js +110 -0
  341. package/dist/types/ComponentType.js.map +1 -0
  342. package/dist/types/DoubleType.d.ts +10 -5
  343. package/dist/types/DoubleType.js +21 -17
  344. package/dist/types/DoubleType.js.map +1 -1
  345. package/dist/types/DynamicType.d.ts +13 -5
  346. package/dist/types/DynamicType.js +26 -5
  347. package/dist/types/DynamicType.js.map +1 -1
  348. package/dist/types/EnumType.d.ts +42 -0
  349. package/dist/types/EnumType.js +101 -0
  350. package/dist/types/EnumType.js.map +1 -0
  351. package/dist/types/FloatType.d.ts +10 -5
  352. package/dist/types/FloatType.js +21 -17
  353. package/dist/types/FloatType.js.map +1 -1
  354. package/dist/types/FunctionType.d.ts +8 -22
  355. package/dist/types/FunctionType.js +25 -63
  356. package/dist/types/FunctionType.js.map +1 -1
  357. package/dist/types/InheritableType.d.ts +29 -0
  358. package/dist/types/InheritableType.js +173 -0
  359. package/dist/types/InheritableType.js.map +1 -0
  360. package/dist/types/InlineInterfaceType.d.ts +5 -0
  361. package/dist/types/InlineInterfaceType.js +17 -0
  362. package/dist/types/InlineInterfaceType.js.map +1 -0
  363. package/dist/types/IntegerType.d.ts +10 -5
  364. package/dist/types/IntegerType.js +21 -17
  365. package/dist/types/IntegerType.js.map +1 -1
  366. package/dist/types/InterfaceType.d.ts +14 -6
  367. package/dist/types/InterfaceType.js +30 -15
  368. package/dist/types/InterfaceType.js.map +1 -1
  369. package/dist/types/IntersectionType.d.ts +29 -0
  370. package/dist/types/IntersectionType.js +256 -0
  371. package/dist/types/IntersectionType.js.map +1 -0
  372. package/dist/types/InvalidType.d.ts +10 -5
  373. package/dist/types/InvalidType.js +21 -9
  374. package/dist/types/InvalidType.js.map +1 -1
  375. package/dist/types/LongIntegerType.d.ts +10 -5
  376. package/dist/types/LongIntegerType.js +21 -17
  377. package/dist/types/LongIntegerType.js.map +1 -1
  378. package/dist/types/NamespaceType.d.ts +12 -0
  379. package/dist/types/NamespaceType.js +28 -0
  380. package/dist/types/NamespaceType.js.map +1 -0
  381. package/dist/types/ObjectType.d.ts +12 -5
  382. package/dist/types/ObjectType.js +25 -8
  383. package/dist/types/ObjectType.js.map +1 -1
  384. package/dist/types/ReferenceType.d.ts +123 -0
  385. package/dist/types/ReferenceType.js +726 -0
  386. package/dist/types/ReferenceType.js.map +1 -0
  387. package/dist/types/StringType.d.ts +12 -5
  388. package/dist/types/StringType.js +23 -8
  389. package/dist/types/StringType.js.map +1 -1
  390. package/dist/types/TypeStatementType.d.ts +19 -0
  391. package/dist/types/TypeStatementType.js +56 -0
  392. package/dist/types/TypeStatementType.js.map +1 -0
  393. package/dist/types/TypedFunctionType.d.ts +34 -0
  394. package/dist/types/TypedFunctionType.js +157 -0
  395. package/dist/types/TypedFunctionType.js.map +1 -0
  396. package/dist/types/UninitializedType.d.ts +11 -6
  397. package/dist/types/UninitializedType.js +20 -11
  398. package/dist/types/UninitializedType.js.map +1 -1
  399. package/dist/types/UnionType.d.ts +27 -0
  400. package/dist/types/UnionType.js +196 -0
  401. package/dist/types/UnionType.js.map +1 -0
  402. package/dist/types/VoidType.d.ts +11 -5
  403. package/dist/types/VoidType.js +22 -8
  404. package/dist/types/VoidType.js.map +1 -1
  405. package/dist/types/helpers.d.ts +51 -0
  406. package/dist/types/helpers.js +329 -0
  407. package/dist/types/helpers.js.map +1 -0
  408. package/dist/types/index.d.ts +22 -0
  409. package/dist/types/index.js +39 -0
  410. package/dist/types/index.js.map +1 -0
  411. package/dist/types/roFunctionType.d.ts +11 -0
  412. package/dist/types/roFunctionType.js +37 -0
  413. package/dist/types/roFunctionType.js.map +1 -0
  414. package/dist/util.d.ts +325 -185
  415. package/dist/util.js +2135 -568
  416. package/dist/util.js.map +1 -1
  417. package/dist/validators/ClassValidator.d.ts +9 -15
  418. package/dist/validators/ClassValidator.js +93 -138
  419. package/dist/validators/ClassValidator.js.map +1 -1
  420. package/package.json +183 -138
  421. package/CHANGELOG.md +0 -1188
  422. package/dist/astUtils/creators.spec.js +0 -21
  423. package/dist/astUtils/creators.spec.js.map +0 -1
  424. package/dist/astUtils/index.d.ts +0 -7
  425. package/dist/astUtils/index.js +0 -26
  426. package/dist/astUtils/index.js.map +0 -1
  427. package/dist/astUtils/reflection.spec.d.ts +0 -1
  428. package/dist/astUtils/reflection.spec.js +0 -292
  429. package/dist/astUtils/reflection.spec.js.map +0 -1
  430. package/dist/astUtils/stackedVisitor.spec.d.ts +0 -1
  431. package/dist/astUtils/stackedVisitor.spec.js +0 -79
  432. package/dist/astUtils/stackedVisitor.spec.js.map +0 -1
  433. package/dist/astUtils/visitors.spec.d.ts +0 -1
  434. package/dist/astUtils/visitors.spec.js +0 -854
  435. package/dist/astUtils/visitors.spec.js.map +0 -1
  436. package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.d.ts +0 -1
  437. package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js +0 -194
  438. package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js.map +0 -1
  439. package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.d.ts +0 -7
  440. package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.js +0 -63
  441. package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.js.map +0 -1
  442. package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.spec.d.ts +0 -1
  443. package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.spec.js +0 -45
  444. package/dist/bscPlugin/semanticTokens/SemanticTokensProcessor.spec.js.map +0 -1
  445. package/dist/files/BrsFile.Class.spec.d.ts +0 -1
  446. package/dist/files/BrsFile.Class.spec.js +0 -1081
  447. package/dist/files/BrsFile.Class.spec.js.map +0 -1
  448. package/dist/files/BrsFile.spec.d.ts +0 -1
  449. package/dist/files/BrsFile.spec.js +0 -2524
  450. package/dist/files/BrsFile.spec.js.map +0 -1
  451. package/dist/files/XmlFile.spec.d.ts +0 -1
  452. package/dist/files/XmlFile.spec.js +0 -1065
  453. package/dist/files/XmlFile.spec.js.map +0 -1
  454. package/dist/files/tests/imports.spec.d.ts +0 -1
  455. package/dist/files/tests/imports.spec.js +0 -241
  456. package/dist/files/tests/imports.spec.js.map +0 -1
  457. package/dist/lexer/Character.spec.d.ts +0 -1
  458. package/dist/lexer/Character.spec.js +0 -27
  459. package/dist/lexer/Character.spec.js.map +0 -1
  460. package/dist/lexer/Lexer.spec.d.ts +0 -1
  461. package/dist/lexer/Lexer.spec.js +0 -1101
  462. package/dist/lexer/Lexer.spec.js.map +0 -1
  463. package/dist/lexer/index.d.ts +0 -3
  464. package/dist/lexer/index.js +0 -17
  465. package/dist/lexer/index.js.map +0 -1
  466. package/dist/parser/Parser.Class.spec.d.ts +0 -1
  467. package/dist/parser/Parser.Class.spec.js +0 -390
  468. package/dist/parser/Parser.Class.spec.js.map +0 -1
  469. package/dist/parser/Parser.spec.d.ts +0 -4
  470. package/dist/parser/Parser.spec.js +0 -1216
  471. package/dist/parser/Parser.spec.js.map +0 -1
  472. package/dist/parser/SGParser.spec.d.ts +0 -1
  473. package/dist/parser/SGParser.spec.js +0 -145
  474. package/dist/parser/SGParser.spec.js.map +0 -1
  475. package/dist/parser/SGTypes.spec.d.ts +0 -1
  476. package/dist/parser/SGTypes.spec.js +0 -351
  477. package/dist/parser/SGTypes.spec.js.map +0 -1
  478. package/dist/parser/Statement.spec.d.ts +0 -1
  479. package/dist/parser/Statement.spec.js +0 -94
  480. package/dist/parser/Statement.spec.js.map +0 -1
  481. package/dist/parser/index.d.ts +0 -3
  482. package/dist/parser/index.js +0 -16
  483. package/dist/parser/index.js.map +0 -1
  484. package/dist/parser/tests/Parser.spec.d.ts +0 -18
  485. package/dist/parser/tests/Parser.spec.js +0 -35
  486. package/dist/parser/tests/Parser.spec.js.map +0 -1
  487. package/dist/parser/tests/controlFlow/For.spec.d.ts +0 -1
  488. package/dist/parser/tests/controlFlow/For.spec.js +0 -161
  489. package/dist/parser/tests/controlFlow/For.spec.js.map +0 -1
  490. package/dist/parser/tests/controlFlow/ForEach.spec.d.ts +0 -1
  491. package/dist/parser/tests/controlFlow/ForEach.spec.js +0 -106
  492. package/dist/parser/tests/controlFlow/ForEach.spec.js.map +0 -1
  493. package/dist/parser/tests/controlFlow/If.spec.d.ts +0 -1
  494. package/dist/parser/tests/controlFlow/If.spec.js +0 -551
  495. package/dist/parser/tests/controlFlow/If.spec.js.map +0 -1
  496. package/dist/parser/tests/controlFlow/While.spec.d.ts +0 -1
  497. package/dist/parser/tests/controlFlow/While.spec.js +0 -107
  498. package/dist/parser/tests/controlFlow/While.spec.js.map +0 -1
  499. package/dist/parser/tests/expression/Additive.spec.d.ts +0 -1
  500. package/dist/parser/tests/expression/Additive.spec.js +0 -99
  501. package/dist/parser/tests/expression/Additive.spec.js.map +0 -1
  502. package/dist/parser/tests/expression/ArrayLiterals.spec.d.ts +0 -1
  503. package/dist/parser/tests/expression/ArrayLiterals.spec.js +0 -254
  504. package/dist/parser/tests/expression/ArrayLiterals.spec.js.map +0 -1
  505. package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.d.ts +0 -1
  506. package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js +0 -266
  507. package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js.map +0 -1
  508. package/dist/parser/tests/expression/Boolean.spec.d.ts +0 -1
  509. package/dist/parser/tests/expression/Boolean.spec.js +0 -83
  510. package/dist/parser/tests/expression/Boolean.spec.js.map +0 -1
  511. package/dist/parser/tests/expression/Call.spec.d.ts +0 -1
  512. package/dist/parser/tests/expression/Call.spec.js +0 -134
  513. package/dist/parser/tests/expression/Call.spec.js.map +0 -1
  514. package/dist/parser/tests/expression/Exponential.spec.d.ts +0 -1
  515. package/dist/parser/tests/expression/Exponential.spec.js +0 -37
  516. package/dist/parser/tests/expression/Exponential.spec.js.map +0 -1
  517. package/dist/parser/tests/expression/Function.spec.d.ts +0 -1
  518. package/dist/parser/tests/expression/Function.spec.js +0 -403
  519. package/dist/parser/tests/expression/Function.spec.js.map +0 -1
  520. package/dist/parser/tests/expression/Indexing.spec.d.ts +0 -1
  521. package/dist/parser/tests/expression/Indexing.spec.js +0 -219
  522. package/dist/parser/tests/expression/Indexing.spec.js.map +0 -1
  523. package/dist/parser/tests/expression/Multiplicative.spec.d.ts +0 -1
  524. package/dist/parser/tests/expression/Multiplicative.spec.js +0 -67
  525. package/dist/parser/tests/expression/Multiplicative.spec.js.map +0 -1
  526. package/dist/parser/tests/expression/NullCoalescenceExpression.spec.d.ts +0 -1
  527. package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js +0 -201
  528. package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js.map +0 -1
  529. package/dist/parser/tests/expression/PrefixUnary.spec.d.ts +0 -1
  530. package/dist/parser/tests/expression/PrefixUnary.spec.js +0 -105
  531. package/dist/parser/tests/expression/PrefixUnary.spec.js.map +0 -1
  532. package/dist/parser/tests/expression/Primary.spec.d.ts +0 -1
  533. package/dist/parser/tests/expression/Primary.spec.js +0 -149
  534. package/dist/parser/tests/expression/Primary.spec.js.map +0 -1
  535. package/dist/parser/tests/expression/Relational.spec.d.ts +0 -1
  536. package/dist/parser/tests/expression/Relational.spec.js +0 -83
  537. package/dist/parser/tests/expression/Relational.spec.js.map +0 -1
  538. package/dist/parser/tests/expression/SourceLiteralExpression.spec.d.ts +0 -1
  539. package/dist/parser/tests/expression/SourceLiteralExpression.spec.js +0 -201
  540. package/dist/parser/tests/expression/SourceLiteralExpression.spec.js.map +0 -1
  541. package/dist/parser/tests/expression/TemplateStringExpression.spec.d.ts +0 -1
  542. package/dist/parser/tests/expression/TemplateStringExpression.spec.js +0 -202
  543. package/dist/parser/tests/expression/TemplateStringExpression.spec.js.map +0 -1
  544. package/dist/parser/tests/expression/TernaryExpression.spec.d.ts +0 -1
  545. package/dist/parser/tests/expression/TernaryExpression.spec.js +0 -323
  546. package/dist/parser/tests/expression/TernaryExpression.spec.js.map +0 -1
  547. package/dist/parser/tests/statement/AssignmentOperators.spec.d.ts +0 -1
  548. package/dist/parser/tests/statement/AssignmentOperators.spec.js +0 -79
  549. package/dist/parser/tests/statement/AssignmentOperators.spec.js.map +0 -1
  550. package/dist/parser/tests/statement/Declaration.spec.d.ts +0 -1
  551. package/dist/parser/tests/statement/Declaration.spec.js +0 -108
  552. package/dist/parser/tests/statement/Declaration.spec.js.map +0 -1
  553. package/dist/parser/tests/statement/Dim.spec.d.ts +0 -1
  554. package/dist/parser/tests/statement/Dim.spec.js +0 -73
  555. package/dist/parser/tests/statement/Dim.spec.js.map +0 -1
  556. package/dist/parser/tests/statement/Function.spec.d.ts +0 -1
  557. package/dist/parser/tests/statement/Function.spec.js +0 -332
  558. package/dist/parser/tests/statement/Function.spec.js.map +0 -1
  559. package/dist/parser/tests/statement/Goto.spec.d.ts +0 -1
  560. package/dist/parser/tests/statement/Goto.spec.js +0 -50
  561. package/dist/parser/tests/statement/Goto.spec.js.map +0 -1
  562. package/dist/parser/tests/statement/Increment.spec.d.ts +0 -1
  563. package/dist/parser/tests/statement/Increment.spec.js +0 -117
  564. package/dist/parser/tests/statement/Increment.spec.js.map +0 -1
  565. package/dist/parser/tests/statement/LibraryStatement.spec.d.ts +0 -1
  566. package/dist/parser/tests/statement/LibraryStatement.spec.js +0 -74
  567. package/dist/parser/tests/statement/LibraryStatement.spec.js.map +0 -1
  568. package/dist/parser/tests/statement/Misc.spec.d.ts +0 -1
  569. package/dist/parser/tests/statement/Misc.spec.js +0 -333
  570. package/dist/parser/tests/statement/Misc.spec.js.map +0 -1
  571. package/dist/parser/tests/statement/PrintStatement.spec.d.ts +0 -1
  572. package/dist/parser/tests/statement/PrintStatement.spec.js +0 -181
  573. package/dist/parser/tests/statement/PrintStatement.spec.js.map +0 -1
  574. package/dist/parser/tests/statement/ReturnStatement.spec.d.ts +0 -1
  575. package/dist/parser/tests/statement/ReturnStatement.spec.js +0 -94
  576. package/dist/parser/tests/statement/ReturnStatement.spec.js.map +0 -1
  577. package/dist/parser/tests/statement/Set.spec.d.ts +0 -1
  578. package/dist/parser/tests/statement/Set.spec.js +0 -218
  579. package/dist/parser/tests/statement/Set.spec.js.map +0 -1
  580. package/dist/parser/tests/statement/Stop.spec.d.ts +0 -1
  581. package/dist/parser/tests/statement/Stop.spec.js +0 -37
  582. package/dist/parser/tests/statement/Stop.spec.js.map +0 -1
  583. package/dist/parser/tests/statement/Throw.spec.d.ts +0 -1
  584. package/dist/parser/tests/statement/Throw.spec.js +0 -35
  585. package/dist/parser/tests/statement/Throw.spec.js.map +0 -1
  586. package/dist/parser/tests/statement/TryCatch.spec.d.ts +0 -1
  587. package/dist/parser/tests/statement/TryCatch.spec.js +0 -140
  588. package/dist/parser/tests/statement/TryCatch.spec.js.map +0 -1
  589. package/dist/preprocessor/Chunk.d.ts +0 -82
  590. package/dist/preprocessor/Chunk.js +0 -77
  591. package/dist/preprocessor/Chunk.js.map +0 -1
  592. package/dist/preprocessor/Manifest.spec.d.ts +0 -0
  593. package/dist/preprocessor/Manifest.spec.js +0 -105
  594. package/dist/preprocessor/Manifest.spec.js.map +0 -1
  595. package/dist/preprocessor/Preprocessor.d.ts +0 -60
  596. package/dist/preprocessor/Preprocessor.js +0 -156
  597. package/dist/preprocessor/Preprocessor.js.map +0 -1
  598. package/dist/preprocessor/Preprocessor.spec.d.ts +0 -1
  599. package/dist/preprocessor/Preprocessor.spec.js +0 -152
  600. package/dist/preprocessor/Preprocessor.spec.js.map +0 -1
  601. package/dist/preprocessor/PreprocessorParser.d.ts +0 -61
  602. package/dist/preprocessor/PreprocessorParser.js +0 -194
  603. package/dist/preprocessor/PreprocessorParser.js.map +0 -1
  604. package/dist/preprocessor/PreprocessorParser.spec.d.ts +0 -1
  605. package/dist/preprocessor/PreprocessorParser.spec.js +0 -116
  606. package/dist/preprocessor/PreprocessorParser.spec.js.map +0 -1
  607. package/dist/preprocessor/index.d.ts +0 -3
  608. package/dist/preprocessor/index.js +0 -16
  609. package/dist/preprocessor/index.js.map +0 -1
  610. package/dist/types/ArrayType.spec.d.ts +0 -1
  611. package/dist/types/ArrayType.spec.js +0 -30
  612. package/dist/types/ArrayType.spec.js.map +0 -1
  613. package/dist/types/BooleanType.spec.d.ts +0 -1
  614. package/dist/types/BooleanType.spec.js +0 -12
  615. package/dist/types/BooleanType.spec.js.map +0 -1
  616. package/dist/types/CustomType.d.ts +0 -10
  617. package/dist/types/CustomType.js +0 -35
  618. package/dist/types/CustomType.js.map +0 -1
  619. package/dist/types/DoubleType.spec.d.ts +0 -1
  620. package/dist/types/DoubleType.spec.js +0 -12
  621. package/dist/types/DoubleType.spec.js.map +0 -1
  622. package/dist/types/DynamicType.spec.d.ts +0 -1
  623. package/dist/types/DynamicType.spec.js +0 -12
  624. package/dist/types/DynamicType.spec.js.map +0 -1
  625. package/dist/types/FloatType.spec.d.ts +0 -1
  626. package/dist/types/FloatType.spec.js +0 -12
  627. package/dist/types/FloatType.spec.js.map +0 -1
  628. package/dist/types/FunctionType.spec.d.ts +0 -1
  629. package/dist/types/FunctionType.spec.js +0 -29
  630. package/dist/types/FunctionType.spec.js.map +0 -1
  631. package/dist/types/IntegerType.spec.d.ts +0 -1
  632. package/dist/types/IntegerType.spec.js +0 -12
  633. package/dist/types/IntegerType.spec.js.map +0 -1
  634. package/dist/types/InvalidType.spec.d.ts +0 -1
  635. package/dist/types/InvalidType.spec.js +0 -12
  636. package/dist/types/InvalidType.spec.js.map +0 -1
  637. package/dist/types/LazyType.d.ts +0 -15
  638. package/dist/types/LazyType.js +0 -32
  639. package/dist/types/LazyType.js.map +0 -1
  640. package/dist/types/LongIntegerType.spec.d.ts +0 -1
  641. package/dist/types/LongIntegerType.spec.js +0 -12
  642. package/dist/types/LongIntegerType.spec.js.map +0 -1
  643. package/dist/types/ObjectType.spec.d.ts +0 -1
  644. package/dist/types/ObjectType.spec.js +0 -12
  645. package/dist/types/ObjectType.spec.js.map +0 -1
  646. package/dist/types/StringType.spec.d.ts +0 -1
  647. package/dist/types/StringType.spec.js +0 -12
  648. package/dist/types/StringType.spec.js.map +0 -1
  649. package/dist/types/VoidType.spec.d.ts +0 -1
  650. package/dist/types/VoidType.spec.js +0 -12
  651. package/dist/types/VoidType.spec.js.map +0 -1
  652. /package/dist/{astUtils/creators.spec.d.ts → lsp/worker/run.d.ts} +0 -0
@@ -1,36 +1,32 @@
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.TypeStatement = 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.ExitStatement = exports.ExpressionStatement = exports.Block = exports.AugmentedAssignmentStatement = exports.AssignmentStatement = exports.Body = exports.EmptyStatement = void 0;
4
+ const TokenKind_1 = require("../lexer/TokenKind");
5
5
  const Expression_1 = require("./Expression");
6
+ const Expression_2 = require("./Expression");
6
7
  const util_1 = require("../util");
7
- const vscode_languageserver_1 = require("vscode-languageserver");
8
8
  const Parser_1 = require("./Parser");
9
9
  const visitors_1 = require("../astUtils/visitors");
10
10
  const reflection_1 = require("../astUtils/reflection");
11
+ const interfaces_1 = require("../interfaces");
11
12
  const creators_1 = require("../astUtils/creators");
12
13
  const DynamicType_1 = require("../types/DynamicType");
13
14
  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) {
15
+ const AstNode_1 = 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
+ const BrightScriptDocParser_1 = require("./BrightScriptDocParser");
24
+ const ReferenceType_1 = require("../types/ReferenceType");
25
+ class EmptyStatement extends AstNode_1.Statement {
26
+ constructor(options) {
32
27
  super();
33
- this.range = range;
28
+ this.kind = AstNode_1.AstNodeKind.EmptyStatement;
29
+ this.location = undefined;
34
30
  }
35
31
  transpile(state) {
36
32
  return [];
@@ -38,22 +34,39 @@ class EmptyStatement extends Statement {
38
34
  walk(visitor, options) {
39
35
  //nothing to walk
40
36
  }
37
+ clone() {
38
+ return this.finalizeClone(new EmptyStatement({
39
+ range: util_1.util.cloneLocation(this.location)
40
+ }));
41
+ }
41
42
  }
42
43
  exports.EmptyStatement = EmptyStatement;
43
44
  /**
44
45
  * This is a top-level statement. Consider this the root of the AST
45
46
  */
46
- class Body extends Statement {
47
- constructor(statements = []) {
47
+ class Body extends AstNode_1.Statement {
48
+ constructor(options) {
49
+ var _a;
48
50
  super();
49
- this.statements = statements;
51
+ this.statements = [];
52
+ this.kind = AstNode_1.AstNodeKind.Body;
53
+ this.symbolTable = new SymbolTable_1.SymbolTable('Body', () => { var _a; return (_a = this.parent) === null || _a === void 0 ? void 0 : _a.getSymbolTable(); });
54
+ this.statements = (_a = options === null || options === void 0 ? void 0 : options.statements) !== null && _a !== void 0 ? _a : [];
50
55
  }
51
- 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));
56
+ get location() {
57
+ var _a;
58
+ if (!this._location) {
59
+ //this needs to be a getter because the body has its statements pushed to it after being constructed
60
+ this._location = util_1.util.createBoundingLocation(...((_a = this.statements) !== null && _a !== void 0 ? _a : []));
61
+ }
62
+ return this._location;
63
+ }
64
+ set location(value) {
65
+ this._location = value;
54
66
  }
55
67
  transpile(state) {
56
- let result = [];
68
+ var _a, _b, _c, _d, _e, _f;
69
+ let result = state.transpileAnnotations(this);
57
70
  for (let i = 0; i < this.statements.length; i++) {
58
71
  let statement = this.statements[i];
59
72
  let previousStatement = this.statements[i - 1];
@@ -62,20 +75,20 @@ class Body extends Statement {
62
75
  //this is the first statement. do nothing related to spacing and newlines
63
76
  //if comment is on same line as prior sibling
64
77
  }
65
- else if (reflection_1.isCommentStatement(statement) && previousStatement && statement.range.start.line === previousStatement.range.end.line) {
78
+ else if (util_1.util.hasLeadingComments(statement) && previousStatement && ((_d = (_c = (_b = (_a = util_1.util.getLeadingComments(statement)) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.location) === null || _c === void 0 ? void 0 : _c.range) === null || _d === void 0 ? void 0 : _d.start.line) === ((_f = (_e = previousStatement.location) === null || _e === void 0 ? void 0 : _e.range) === null || _f === void 0 ? void 0 : _f.end.line)) {
66
79
  result.push(' ');
67
80
  //add double newline if this is a comment, and next is a function
68
81
  }
69
- else if (reflection_1.isCommentStatement(statement) && nextStatement && reflection_1.isFunctionStatement(nextStatement)) {
70
- result.push('\n\n');
82
+ else if (util_1.util.hasLeadingComments(statement) && nextStatement && (0, reflection_1.isFunctionStatement)(nextStatement)) {
83
+ result.push(state.newline, state.newline);
71
84
  //add double newline if is function not preceeded by a comment
72
85
  }
73
- else if (reflection_1.isFunctionStatement(statement) && previousStatement && !(reflection_1.isCommentStatement(previousStatement))) {
74
- result.push('\n\n');
86
+ else if ((0, reflection_1.isFunctionStatement)(statement) && previousStatement && !util_1.util.hasLeadingComments(statement)) {
87
+ result.push(state.newline, state.newline);
75
88
  }
76
89
  else {
77
90
  //separate statements by a single newline
78
- result.push('\n');
91
+ result.push(state.newline);
79
92
  }
80
93
  result.push(...statement.transpile(state));
81
94
  }
@@ -85,7 +98,7 @@ class Body extends Statement {
85
98
  let result = [];
86
99
  for (const statement of this.statements) {
87
100
  //if the current statement supports generating typedef, call it
88
- if ('getTypedef' in statement) {
101
+ if ((0, reflection_1.isTypedefProvider)(statement)) {
89
102
  result.push(state.indent(), ...statement.getTypedef(state), state.newline);
90
103
  }
91
104
  }
@@ -93,63 +106,203 @@ class Body extends Statement {
93
106
  }
94
107
  walk(visitor, options) {
95
108
  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
- }
109
+ (0, visitors_1.walkArray)(this.statements, visitor, options, this);
99
110
  }
100
111
  }
112
+ clone() {
113
+ var _a;
114
+ return this.finalizeClone(new Body({
115
+ statements: (_a = this.statements) === null || _a === void 0 ? void 0 : _a.map(s => s === null || s === void 0 ? void 0 : s.clone())
116
+ }), ['statements']);
117
+ }
101
118
  }
102
119
  exports.Body = Body;
103
- class AssignmentStatement extends Statement {
104
- constructor(name, equals, value, containingFunction) {
120
+ class AssignmentStatement extends AstNode_1.Statement {
121
+ constructor(options) {
105
122
  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);
123
+ this.kind = AstNode_1.AstNodeKind.AssignmentStatement;
124
+ this.value = options.value;
125
+ this.tokens = {
126
+ equals: options.equals,
127
+ name: options.name,
128
+ as: options.as
129
+ };
130
+ this.typeExpression = options.typeExpression;
131
+ this.location = util_1.util.createBoundingLocation(util_1.util.createBoundingLocationFromTokens(this.tokens), this.value);
111
132
  }
112
133
  transpile(state) {
113
- var _a, _b;
114
- //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)) {
116
- return this.value.transpile(state);
117
- }
118
- else {
119
- return [
120
- state.transpileToken(this.name),
121
- ' ',
122
- state.transpileToken(this.equals),
123
- ' ',
124
- ...this.value.transpile(state)
125
- ];
126
- }
134
+ var _a;
135
+ return [
136
+ state.transpileToken(this.tokens.name),
137
+ ' ',
138
+ state.transpileToken((_a = this.tokens.equals) !== null && _a !== void 0 ? _a : (0, creators_1.createToken)(TokenKind_1.TokenKind.Equal), '='),
139
+ ' ',
140
+ ...this.value.transpile(state)
141
+ ];
127
142
  }
128
143
  walk(visitor, options) {
129
144
  if (options.walkMode & visitors_1.InternalWalkMode.walkExpressions) {
130
- visitors_1.walk(this, 'value', visitor, options);
145
+ (0, visitors_1.walk)(this, 'typeExpression', visitor, options);
146
+ (0, visitors_1.walk)(this, 'value', visitor, options);
131
147
  }
132
148
  }
149
+ getType(options) {
150
+ var _a, _b, _c, _d;
151
+ const variableTypeFromCode = (_a = this.typeExpression) === null || _a === void 0 ? void 0 : _a.getType(Object.assign(Object.assign({}, options), { typeChain: undefined }));
152
+ const docs = BrightScriptDocParser_1.default.parseNode(this);
153
+ const variableTypeFromDocs = docs === null || docs === void 0 ? void 0 : docs.getTypeTagBscType(options);
154
+ const variableType = (_b = util_1.util.chooseTypeFromCodeOrDocComment(variableTypeFromCode, variableTypeFromDocs, options)) !== null && _b !== void 0 ? _b : this.value.getType(Object.assign(Object.assign({}, options), { typeChain: undefined }));
155
+ // Note: compound assignments (eg. +=) are internally dealt with via the RHS being a BinaryExpression
156
+ // so this.value will be a BinaryExpression, and BinaryExpressions can figure out their own types
157
+ (_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, location: (_d = this.tokens.name) === null || _d === void 0 ? void 0 : _d.location, astNode: this }));
158
+ return variableType;
159
+ }
160
+ get leadingTrivia() {
161
+ return this.tokens.name.leadingTrivia;
162
+ }
163
+ clone() {
164
+ var _a, _b;
165
+ return this.finalizeClone(new AssignmentStatement({
166
+ name: util_1.util.cloneToken(this.tokens.name),
167
+ value: (_a = this.value) === null || _a === void 0 ? void 0 : _a.clone(),
168
+ as: util_1.util.cloneToken(this.tokens.as),
169
+ equals: util_1.util.cloneToken(this.tokens.equals),
170
+ typeExpression: (_b = this.typeExpression) === null || _b === void 0 ? void 0 : _b.clone()
171
+ }), ['value', 'typeExpression']);
172
+ }
133
173
  }
134
174
  exports.AssignmentStatement = AssignmentStatement;
135
- class Block extends Statement {
136
- constructor(statements, startingRange) {
175
+ class AugmentedAssignmentStatement extends AstNode_1.Statement {
176
+ constructor(options) {
177
+ super();
178
+ this.kind = AstNode_1.AstNodeKind.AugmentedAssignmentStatement;
179
+ this.value = options.value;
180
+ this.tokens = {
181
+ operator: options.operator
182
+ };
183
+ this.item = options.item;
184
+ this.value = options.value;
185
+ this.location = util_1.util.createBoundingLocation(this.item, util_1.util.createBoundingLocationFromTokens(this.tokens), this.value);
186
+ }
187
+ transpile(state) {
188
+ return [
189
+ this.item.transpile(state),
190
+ ' ',
191
+ state.transpileToken(this.tokens.operator),
192
+ ' ',
193
+ this.value.transpile(state)
194
+ ];
195
+ }
196
+ walk(visitor, options) {
197
+ if (options.walkMode & visitors_1.InternalWalkMode.walkExpressions) {
198
+ (0, visitors_1.walk)(this, 'item', visitor, options);
199
+ (0, visitors_1.walk)(this, 'value', visitor, options);
200
+ }
201
+ }
202
+ getType(options) {
203
+ const variableType = util_1.util.binaryOperatorResultType(this.item.getType(options), this.tokens.operator, this.value.getType(options));
204
+ //const variableType = this.typeExpression?.getType({ ...options, typeChain: undefined }) ?? this.value.getType({ ...options, typeChain: undefined });
205
+ // Note: compound assignments (eg. +=) are internally dealt with via the RHS being a BinaryExpression
206
+ // so this.value will be a BinaryExpression, and BinaryExpressions can figure out their own types
207
+ // options.typeChain?.push(new TypeChainEntry({ name: this.tokens.name.text, type: variableType, data: options.data, range: this.tokens.name.range, astNode: this }));
208
+ return variableType;
209
+ }
210
+ get leadingTrivia() {
211
+ return this.item.leadingTrivia;
212
+ }
213
+ clone() {
214
+ var _a, _b;
215
+ return this.finalizeClone(new AugmentedAssignmentStatement({
216
+ item: (_a = this.item) === null || _a === void 0 ? void 0 : _a.clone(),
217
+ operator: util_1.util.cloneToken(this.tokens.operator),
218
+ value: (_b = this.value) === null || _b === void 0 ? void 0 : _b.clone()
219
+ }), ['item', 'value']);
220
+ }
221
+ }
222
+ exports.AugmentedAssignmentStatement = AugmentedAssignmentStatement;
223
+ class Block extends AstNode_1.Statement {
224
+ constructor(options) {
137
225
  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);
226
+ this.kind = AstNode_1.AstNodeKind.Block;
227
+ this.statements = options.statements;
228
+ this.symbolTable = new SymbolTable_1.SymbolTable('Block', () => this.parent.getSymbolTable());
229
+ }
230
+ buildLocation() {
231
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
232
+ if (((_a = this.statements) === null || _a === void 0 ? void 0 : _a.length) > 0) {
233
+ return util_1.util.createBoundingLocation(...(_b = this.statements) !== null && _b !== void 0 ? _b : []);
234
+ }
235
+ let lastBitBefore;
236
+ let firstBitAfter;
237
+ if ((0, reflection_1.isFunctionExpression)(this.parent)) {
238
+ lastBitBefore = util_1.util.createBoundingLocation(this.parent.tokens.functionType, this.parent.tokens.leftParen, ...((_c = this.parent.parameters) !== null && _c !== void 0 ? _c : []), this.parent.tokens.rightParen, this.parent.tokens.as, this.parent.returnTypeExpression);
239
+ firstBitAfter = (_d = this.parent.tokens.endFunctionType) === null || _d === void 0 ? void 0 : _d.location;
240
+ }
241
+ else if ((0, reflection_1.isIfStatement)(this.parent)) {
242
+ if (this.parent.thenBranch === this) {
243
+ lastBitBefore = util_1.util.createBoundingLocation(this.parent.tokens.then, this.parent.condition);
244
+ firstBitAfter = util_1.util.createBoundingLocation(this.parent.tokens.else, this.parent.elseBranch, this.parent.tokens.endIf);
245
+ }
246
+ else if (this.parent.elseBranch === this) {
247
+ lastBitBefore = (_e = this.parent.tokens.else) === null || _e === void 0 ? void 0 : _e.location;
248
+ firstBitAfter = (_f = this.parent.tokens.endIf) === null || _f === void 0 ? void 0 : _f.location;
249
+ }
250
+ }
251
+ else if ((0, reflection_1.isConditionalCompileStatement)(this.parent)) {
252
+ if (this.parent.thenBranch === this) {
253
+ lastBitBefore = util_1.util.createBoundingLocation(this.parent.tokens.condition, this.parent.tokens.not, this.parent.tokens.hashIf);
254
+ firstBitAfter = util_1.util.createBoundingLocation(this.parent.tokens.hashElse, this.parent.elseBranch, this.parent.tokens.hashEndIf);
255
+ }
256
+ else if (this.parent.elseBranch === this) {
257
+ lastBitBefore = (_g = this.parent.tokens.hashElse) === null || _g === void 0 ? void 0 : _g.location;
258
+ firstBitAfter = (_h = this.parent.tokens.hashEndIf) === null || _h === void 0 ? void 0 : _h.location;
259
+ }
260
+ }
261
+ else if ((0, reflection_1.isForStatement)(this.parent)) {
262
+ lastBitBefore = util_1.util.createBoundingLocation(this.parent.increment, this.parent.tokens.step, this.parent.finalValue, this.parent.tokens.to, this.parent.counterDeclaration, this.parent.tokens.for);
263
+ firstBitAfter = (_j = this.parent.tokens.endFor) === null || _j === void 0 ? void 0 : _j.location;
264
+ }
265
+ else if ((0, reflection_1.isForEachStatement)(this.parent)) {
266
+ lastBitBefore = util_1.util.createBoundingLocation(this.parent.target, this.parent.tokens.in, this.parent.tokens.item, this.parent.tokens.forEach);
267
+ firstBitAfter = (_k = this.parent.tokens.endFor) === null || _k === void 0 ? void 0 : _k.location;
268
+ }
269
+ else if ((0, reflection_1.isWhileStatement)(this.parent)) {
270
+ lastBitBefore = util_1.util.createBoundingLocation(this.parent.condition, this.parent.tokens.while);
271
+ firstBitAfter = (_l = this.parent.tokens.endWhile) === null || _l === void 0 ? void 0 : _l.location;
272
+ }
273
+ else if ((0, reflection_1.isTryCatchStatement)(this.parent)) {
274
+ lastBitBefore = util_1.util.createBoundingLocation(this.parent.tokens.try);
275
+ firstBitAfter = util_1.util.createBoundingLocation(this.parent.tokens.endTry, this.parent.catchStatement);
276
+ }
277
+ else if ((0, reflection_1.isCatchStatement)(this.parent) && (0, reflection_1.isTryCatchStatement)((_m = this.parent) === null || _m === void 0 ? void 0 : _m.parent)) {
278
+ lastBitBefore = util_1.util.createBoundingLocation(this.parent.tokens.catch, this.parent.exceptionVariableExpression);
279
+ firstBitAfter = (_o = this.parent.parent.tokens.endTry) === null || _o === void 0 ? void 0 : _o.location;
280
+ }
281
+ if ((lastBitBefore === null || lastBitBefore === void 0 ? void 0 : lastBitBefore.range) && (firstBitAfter === null || firstBitAfter === void 0 ? void 0 : firstBitAfter.range)) {
282
+ return util_1.util.createLocation(lastBitBefore.range.end.line, lastBitBefore.range.end.character, firstBitAfter.range.start.line, firstBitAfter.range.start.character, (_p = lastBitBefore.uri) !== null && _p !== void 0 ? _p : firstBitAfter.uri);
283
+ }
284
+ }
285
+ get location() {
286
+ if (!this._location) {
287
+ //this needs to be a getter because the body has its statements pushed to it after being constructed
288
+ this._location = this.buildLocation();
289
+ }
290
+ return this._location;
291
+ }
292
+ set location(value) {
293
+ this._location = value;
143
294
  }
144
295
  transpile(state) {
296
+ var _a;
145
297
  state.blockDepth++;
146
298
  let results = [];
147
299
  for (let i = 0; i < this.statements.length; i++) {
148
300
  let previousStatement = this.statements[i - 1];
149
301
  let statement = this.statements[i];
302
+ //is not a comment
150
303
  //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))) {
304
+ if (util_1.util.isLeadingCommentOnSameLine((_a = state.lineage[0]) === null || _a === void 0 ? void 0 : _a.location, statement) ||
305
+ util_1.util.isLeadingCommentOnSameLine(previousStatement === null || previousStatement === void 0 ? void 0 : previousStatement.location, statement)) {
153
306
  results.push(' ');
154
307
  //is not a comment
155
308
  }
@@ -165,166 +318,200 @@ class Block extends Statement {
165
318
  state.blockDepth--;
166
319
  return results;
167
320
  }
321
+ get leadingTrivia() {
322
+ var _a, _b;
323
+ return (_b = (_a = this.statements[0]) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
324
+ }
168
325
  walk(visitor, options) {
169
326
  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
- }
327
+ (0, visitors_1.walkArray)(this.statements, visitor, options, this);
173
328
  }
174
329
  }
330
+ clone() {
331
+ var _a;
332
+ return this.finalizeClone(new Block({
333
+ statements: (_a = this.statements) === null || _a === void 0 ? void 0 : _a.map(s => s === null || s === void 0 ? void 0 : s.clone())
334
+ }), ['statements']);
335
+ }
175
336
  }
176
337
  exports.Block = Block;
177
- class ExpressionStatement extends Statement {
178
- constructor(expression) {
338
+ class ExpressionStatement extends AstNode_1.Statement {
339
+ constructor(options) {
340
+ var _a;
179
341
  super();
180
- this.expression = expression;
181
- this.range = this.expression.range;
342
+ this.kind = AstNode_1.AstNodeKind.ExpressionStatement;
343
+ this.expression = options.expression;
344
+ this.location = (_a = this.expression) === null || _a === void 0 ? void 0 : _a.location;
182
345
  }
183
346
  transpile(state) {
184
- return this.expression.transpile(state);
347
+ return [
348
+ state.transpileAnnotations(this),
349
+ this.expression.transpile(state)
350
+ ];
351
+ }
352
+ getTypedef(state) {
353
+ //ExpressionStatements should not be included in typedefs
354
+ //as they represent code execution which is not part of the type definition
355
+ return [];
185
356
  }
186
357
  walk(visitor, options) {
187
358
  if (options.walkMode & visitors_1.InternalWalkMode.walkExpressions) {
188
- visitors_1.walk(this, 'expression', visitor, options);
189
- }
190
- }
191
- }
192
- exports.ExpressionStatement = ExpressionStatement;
193
- class CommentStatement extends Statement {
194
- constructor(comments) {
195
- var _a;
196
- 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');
205
- }
206
- 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
- }
359
+ (0, visitors_1.walk)(this, 'expression', visitor, options);
218
360
  }
219
- return result;
220
361
  }
221
- getTypedef(state) {
222
- return this.transpile(state);
362
+ get leadingTrivia() {
363
+ return this.expression.leadingTrivia;
223
364
  }
224
- walk(visitor, options) {
225
- //nothing to walk
365
+ clone() {
366
+ var _a;
367
+ return this.finalizeClone(new ExpressionStatement({
368
+ expression: (_a = this.expression) === null || _a === void 0 ? void 0 : _a.clone()
369
+ }), ['expression']);
226
370
  }
227
371
  }
228
- exports.CommentStatement = CommentStatement;
229
- class ExitForStatement extends Statement {
230
- constructor(tokens) {
372
+ exports.ExpressionStatement = ExpressionStatement;
373
+ class ExitStatement extends AstNode_1.Statement {
374
+ constructor(options) {
231
375
  super();
232
- this.tokens = tokens;
233
- this.range = this.tokens.exitFor.range;
376
+ this.kind = AstNode_1.AstNodeKind.ExitStatement;
377
+ this.tokens = {
378
+ exit: options === null || options === void 0 ? void 0 : options.exit,
379
+ loopType: options.loopType
380
+ };
381
+ this.location = util_1.util.createBoundingLocation(this.tokens.exit, this.tokens.loopType);
234
382
  }
235
383
  transpile(state) {
384
+ var _a, _b;
236
385
  return [
237
- state.transpileToken(this.tokens.exitFor)
386
+ state.transpileToken(this.tokens.exit, 'exit'),
387
+ (_b = (_a = this.tokens.loopType) === null || _a === void 0 ? void 0 : _a.leadingWhitespace) !== null && _b !== void 0 ? _b : ' ',
388
+ state.transpileToken(this.tokens.loopType)
238
389
  ];
239
390
  }
240
391
  walk(visitor, options) {
241
392
  //nothing to walk
242
393
  }
243
- }
244
- exports.ExitForStatement = ExitForStatement;
245
- class ExitWhileStatement extends Statement {
246
- constructor(tokens) {
247
- super();
248
- this.tokens = tokens;
249
- this.range = this.tokens.exitWhile.range;
250
- }
251
- transpile(state) {
252
- return [
253
- state.transpileToken(this.tokens.exitWhile)
254
- ];
394
+ get leadingTrivia() {
395
+ var _a;
396
+ return (_a = this.tokens.exit) === null || _a === void 0 ? void 0 : _a.leadingTrivia;
255
397
  }
256
- walk(visitor, options) {
257
- //nothing to walk
398
+ clone() {
399
+ return this.finalizeClone(new ExitStatement({
400
+ loopType: util_1.util.cloneToken(this.tokens.loopType),
401
+ exit: util_1.util.cloneToken(this.tokens.exit)
402
+ }));
258
403
  }
259
404
  }
260
- exports.ExitWhileStatement = ExitWhileStatement;
261
- class FunctionStatement extends Statement {
262
- constructor(name, func, namespaceName) {
405
+ exports.ExitStatement = ExitStatement;
406
+ class FunctionStatement extends AstNode_1.Statement {
407
+ constructor(options) {
408
+ var _a, _b;
263
409
  super();
264
- this.name = name;
265
- this.func = func;
266
- this.namespaceName = namespaceName;
267
- this.range = this.func.range;
410
+ this.kind = AstNode_1.AstNodeKind.FunctionStatement;
411
+ this.tokens = {
412
+ name: options.name
413
+ };
414
+ this.func = options.func;
415
+ if (this.func) {
416
+ this.func.symbolTable.name += `: '${(_a = this.tokens.name) === null || _a === void 0 ? void 0 : _a.text}'`;
417
+ }
418
+ this.location = (_b = this.func) === null || _b === void 0 ? void 0 : _b.location;
268
419
  }
269
420
  /**
270
421
  * Get the name of this expression based on the parse mode
271
422
  */
272
423
  getName(parseMode) {
273
- if (this.namespaceName) {
424
+ var _a;
425
+ const namespace = this.findAncestor(reflection_1.isNamespaceStatement);
426
+ if (namespace) {
274
427
  let delimiter = parseMode === Parser_1.ParseMode.BrighterScript ? '.' : '_';
275
- let namespaceName = this.namespaceName.getName(parseMode);
276
- return namespaceName + delimiter + this.name.text;
428
+ let namespaceName = namespace.getName(parseMode);
429
+ return namespaceName + delimiter + ((_a = this.tokens.name) === null || _a === void 0 ? void 0 : _a.text);
277
430
  }
278
431
  else {
279
- return this.name.text;
432
+ return this.tokens.name.text;
280
433
  }
281
434
  }
435
+ get leadingTrivia() {
436
+ return this.func.leadingTrivia;
437
+ }
282
438
  transpile(state) {
283
439
  //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) });
285
- return this.func.transpile(state, nameToken);
440
+ let nameToken = Object.assign(Object.assign({}, this.tokens.name), { text: this.getName(Parser_1.ParseMode.BrightScript) });
441
+ return [
442
+ ...state.transpileAnnotations(this),
443
+ ...this.func.transpile(state, nameToken)
444
+ ];
286
445
  }
287
446
  getTypedef(state) {
288
- var _a;
447
+ var _a, _b;
289
448
  let result = [];
290
- for (let annotation of (_a = this.annotations) !== null && _a !== void 0 ? _a : []) {
449
+ for (let comment of (_a = util_1.util.getLeadingComments(this)) !== null && _a !== void 0 ? _a : []) {
450
+ result.push(comment.text, state.newline, state.indent());
451
+ }
452
+ for (let annotation of (_b = this.annotations) !== null && _b !== void 0 ? _b : []) {
291
453
  result.push(...annotation.getTypedef(state), state.newline, state.indent());
292
454
  }
293
- result.push(...this.func.getTypedef(state, this.name));
455
+ result.push(...this.func.getTypedef(state));
294
456
  return result;
295
457
  }
296
458
  walk(visitor, options) {
297
459
  if (options.walkMode & visitors_1.InternalWalkMode.walkExpressions) {
298
- visitors_1.walk(this, 'func', visitor, options);
460
+ (0, visitors_1.walk)(this, 'func', visitor, options);
299
461
  }
300
462
  }
463
+ getType(options) {
464
+ const funcExprType = this.func.getType(options);
465
+ funcExprType.setName(this.getName(Parser_1.ParseMode.BrighterScript));
466
+ return funcExprType;
467
+ }
468
+ clone() {
469
+ var _a;
470
+ return this.finalizeClone(new FunctionStatement({
471
+ func: (_a = this.func) === null || _a === void 0 ? void 0 : _a.clone(),
472
+ name: util_1.util.cloneToken(this.tokens.name)
473
+ }), ['func']);
474
+ }
301
475
  }
302
476
  exports.FunctionStatement = FunctionStatement;
303
- class IfStatement extends Statement {
304
- constructor(tokens, condition, thenBranch, elseBranch, isInline) {
305
- var _a, _b;
477
+ class IfStatement extends AstNode_1.Statement {
478
+ constructor(options) {
306
479
  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);
480
+ this.kind = AstNode_1.AstNodeKind.IfStatement;
481
+ this.condition = options.condition;
482
+ this.thenBranch = options.thenBranch;
483
+ this.elseBranch = options.elseBranch;
484
+ this.tokens = {
485
+ if: options.if,
486
+ then: options.then,
487
+ else: options.else,
488
+ endIf: options.endIf
489
+ };
490
+ this.location = util_1.util.createBoundingLocation(util_1.util.createBoundingLocationFromTokens(this.tokens), this.condition, this.thenBranch, this.elseBranch);
491
+ }
492
+ get isInline() {
493
+ var _a, _b, _c, _d;
494
+ const allLeadingTrivia = [
495
+ ...this.thenBranch.leadingTrivia,
496
+ ...this.thenBranch.statements.map(s => s.leadingTrivia).flat(),
497
+ ...((_b = (_a = this.tokens.else) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : []),
498
+ ...((_d = (_c = this.tokens.endIf) === null || _c === void 0 ? void 0 : _c.leadingTrivia) !== null && _d !== void 0 ? _d : [])
499
+ ];
500
+ const hasNewline = allLeadingTrivia.find(t => t.kind === TokenKind_1.TokenKind.Newline);
501
+ return !hasNewline;
313
502
  }
314
503
  transpile(state) {
504
+ var _a, _b;
315
505
  let results = [];
316
506
  //if (already indented by block)
317
- results.push(state.transpileToken(this.tokens.if));
507
+ results.push(state.transpileToken((_a = this.tokens.if) !== null && _a !== void 0 ? _a : (0, creators_1.createToken)(TokenKind_1.TokenKind.If)));
318
508
  results.push(' ');
319
509
  //conditions
320
510
  results.push(...this.condition.transpile(state));
321
- results.push(' ');
322
511
  //then
323
512
  if (this.tokens.then) {
324
- results.push(state.transpileToken(this.tokens.then));
325
- }
326
- else {
327
- results.push('then');
513
+ results.push(' ');
514
+ results.push(state.transpileToken(this.tokens.then, 'then'));
328
515
  }
329
516
  state.lineage.unshift(this);
330
517
  //if statement body
@@ -333,20 +520,18 @@ class IfStatement extends Statement {
333
520
  if (thenNodes.length > 0) {
334
521
  results.push(thenNodes);
335
522
  }
336
- results.push('\n');
337
523
  //else branch
338
- if (this.tokens.else) {
339
- //else
340
- results.push(state.indent(), state.transpileToken(this.tokens.else));
341
- }
342
524
  if (this.elseBranch) {
343
- if (reflection_1.isIfStatement(this.elseBranch)) {
525
+ //else
526
+ results.push(...state.transpileEndBlockToken(this.thenBranch, this.tokens.else, 'else'));
527
+ if ((0, reflection_1.isIfStatement)(this.elseBranch)) {
344
528
  //chained elseif
345
529
  state.lineage.unshift(this.elseBranch);
346
530
  let body = this.elseBranch.transpile(state);
347
531
  state.lineage.shift();
348
532
  if (body.length > 0) {
349
- results.push(' ');
533
+ //zero or more spaces between the `else` and the `if`
534
+ results.push(this.elseBranch.tokens.if.leadingWhitespace);
350
535
  results.push(...body);
351
536
  // stop here because chained if will transpile the rest
352
537
  return results;
@@ -357,125 +542,167 @@ class IfStatement extends Statement {
357
542
  }
358
543
  else {
359
544
  //else body
360
- state.lineage.unshift(this.elseBranch);
545
+ state.lineage.unshift(this.tokens.else);
361
546
  let body = this.elseBranch.transpile(state);
362
547
  state.lineage.shift();
363
548
  if (body.length > 0) {
364
549
  results.push(...body);
365
550
  }
366
- results.push('\n');
367
551
  }
368
552
  }
369
553
  //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
- }
554
+ results.push(...state.transpileEndBlockToken((_b = this.elseBranch) !== null && _b !== void 0 ? _b : this.thenBranch, this.tokens.endIf, 'end if'));
377
555
  return results;
378
556
  }
379
557
  walk(visitor, options) {
380
558
  if (options.walkMode & visitors_1.InternalWalkMode.walkExpressions) {
381
- visitors_1.walk(this, 'condition', visitor, options);
559
+ (0, visitors_1.walk)(this, 'condition', visitor, options);
382
560
  }
383
561
  if (options.walkMode & visitors_1.InternalWalkMode.walkStatements) {
384
- visitors_1.walk(this, 'thenBranch', visitor, options);
562
+ (0, visitors_1.walk)(this, 'thenBranch', visitor, options);
385
563
  }
386
564
  if (this.elseBranch && options.walkMode & visitors_1.InternalWalkMode.walkStatements) {
387
- visitors_1.walk(this, 'elseBranch', visitor, options);
565
+ (0, visitors_1.walk)(this, 'elseBranch', visitor, options);
388
566
  }
389
567
  }
568
+ get leadingTrivia() {
569
+ var _a, _b;
570
+ return (_b = (_a = this.tokens.if) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
571
+ }
572
+ get endTrivia() {
573
+ var _a, _b;
574
+ return (_b = (_a = this.tokens.endIf) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
575
+ }
576
+ clone() {
577
+ var _a, _b, _c;
578
+ return this.finalizeClone(new IfStatement({
579
+ if: util_1.util.cloneToken(this.tokens.if),
580
+ else: util_1.util.cloneToken(this.tokens.else),
581
+ endIf: util_1.util.cloneToken(this.tokens.endIf),
582
+ then: util_1.util.cloneToken(this.tokens.then),
583
+ condition: (_a = this.condition) === null || _a === void 0 ? void 0 : _a.clone(),
584
+ thenBranch: (_b = this.thenBranch) === null || _b === void 0 ? void 0 : _b.clone(),
585
+ elseBranch: (_c = this.elseBranch) === null || _c === void 0 ? void 0 : _c.clone()
586
+ }), ['condition', 'thenBranch', 'elseBranch']);
587
+ }
390
588
  }
391
589
  exports.IfStatement = IfStatement;
392
- class IncrementStatement extends Statement {
393
- constructor(value, operator) {
590
+ class IncrementStatement extends AstNode_1.Statement {
591
+ constructor(options) {
394
592
  super();
395
- this.value = value;
396
- this.operator = operator;
397
- this.range = util_1.util.createRangeFromPositions(this.value.range.start, this.operator.range.end);
593
+ this.kind = AstNode_1.AstNodeKind.IncrementStatement;
594
+ this.value = options.value;
595
+ this.tokens = {
596
+ operator: options.operator
597
+ };
598
+ this.location = util_1.util.createBoundingLocation(this.value, this.tokens.operator);
398
599
  }
399
600
  transpile(state) {
400
601
  return [
401
602
  ...this.value.transpile(state),
402
- state.transpileToken(this.operator)
603
+ state.transpileToken(this.tokens.operator)
403
604
  ];
404
605
  }
405
606
  walk(visitor, options) {
406
607
  if (options.walkMode & visitors_1.InternalWalkMode.walkExpressions) {
407
- visitors_1.walk(this, 'value', visitor, options);
608
+ (0, visitors_1.walk)(this, 'value', visitor, options);
408
609
  }
409
610
  }
611
+ get leadingTrivia() {
612
+ var _a, _b;
613
+ return (_b = (_a = this.value) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
614
+ }
615
+ clone() {
616
+ var _a;
617
+ return this.finalizeClone(new IncrementStatement({
618
+ value: (_a = this.value) === null || _a === void 0 ? void 0 : _a.clone(),
619
+ operator: util_1.util.cloneToken(this.tokens.operator)
620
+ }), ['value']);
621
+ }
410
622
  }
411
623
  exports.IncrementStatement = IncrementStatement;
412
624
  /**
413
625
  * Represents a `print` statement within BrightScript.
414
626
  */
415
- class PrintStatement extends Statement {
627
+ class PrintStatement extends AstNode_1.Statement {
416
628
  /**
417
629
  * 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.
630
+ * @param options the options for this statement
631
+ * @param options.print a print token
632
+ * @param options.expressions an array of expressions to be evaluated and printed. Wrap PrintSeparator tokens (`;` or `,`) in `PrintSeparatorExpression`
420
633
  */
421
- constructor(tokens, expressions) {
634
+ constructor(options) {
635
+ var _a;
422
636
  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);
637
+ this.kind = AstNode_1.AstNodeKind.PrintStatement;
638
+ this.tokens = {
639
+ print: options.print
640
+ };
641
+ this.expressions = options.expressions;
642
+ this.location = util_1.util.createBoundingLocation(this.tokens.print, ...((_a = this.expressions) !== null && _a !== void 0 ? _a : []));
428
643
  }
429
644
  transpile(state) {
430
- var _a;
645
+ var _a, _b, _c;
431
646
  let result = [
432
- state.transpileToken(this.tokens.print),
433
- ' '
647
+ state.transpileToken(this.tokens.print, 'print')
434
648
  ];
649
+ //if the first expression has no leading whitespace, add a single space between the `print` and the expression
650
+ if (this.expressions.length > 0 && !((_a = this.expressions[0].leadingTrivia) === null || _a === void 0 ? void 0 : _a.find(t => (t === null || t === void 0 ? void 0 : t.kind) === TokenKind_1.TokenKind.Whitespace))) {
651
+ result.push(' ');
652
+ }
653
+ // eslint-disable-next-line @typescript-eslint/prefer-for-of
435
654
  for (let i = 0; i < this.expressions.length; i++) {
436
- const expressionOrSeparator = this.expressions[i];
437
- if (expressionOrSeparator.transpile) {
438
- result.push(...expressionOrSeparator.transpile(state));
439
- }
440
- else {
441
- result.push(state.tokenToSourceNode(expressionOrSeparator));
655
+ const expression = this.expressions[i];
656
+ let leadingWhitespace = (_c = (_b = expression.leadingTrivia) === null || _b === void 0 ? void 0 : _b.find(t => (t === null || t === void 0 ? void 0 : t.kind) === TokenKind_1.TokenKind.Whitespace)) === null || _c === void 0 ? void 0 : _c.text;
657
+ if (leadingWhitespace) {
658
+ result.push(leadingWhitespace);
659
+ //if the previous expression was NOT a separator, and this one is not also, add a space between them
442
660
  }
443
- //if there's an expression after us, add a space
444
- if ((_a = this.expressions[i + 1]) === null || _a === void 0 ? void 0 : _a.transpile) {
661
+ else if (i > 0 && !(0, reflection_1.isPrintSeparatorExpression)(this.expressions[i - 1]) && !(0, reflection_1.isPrintSeparatorExpression)(expression) && !leadingWhitespace) {
445
662
  result.push(' ');
446
663
  }
664
+ result.push(...expression.transpile(state));
447
665
  }
448
666
  return result;
449
667
  }
450
668
  walk(visitor, options) {
451
669
  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
- }
670
+ (0, visitors_1.walkArray)(this.expressions, visitor, options, this);
458
671
  }
459
672
  }
673
+ get leadingTrivia() {
674
+ var _a, _b;
675
+ return (_b = (_a = this.tokens.print) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
676
+ }
677
+ clone() {
678
+ var _a;
679
+ return this.finalizeClone(new PrintStatement({
680
+ print: util_1.util.cloneToken(this.tokens.print),
681
+ expressions: (_a = this.expressions) === null || _a === void 0 ? void 0 : _a.map(e => e === null || e === void 0 ? void 0 : e.clone())
682
+ }), ['expressions']);
683
+ }
460
684
  }
461
685
  exports.PrintStatement = PrintStatement;
462
- class DimStatement extends Statement {
463
- constructor(dimToken, identifier, openingSquare, dimensions, closingSquare) {
464
- var _a, _b, _c, _d;
686
+ class DimStatement extends AstNode_1.Statement {
687
+ constructor(options) {
688
+ var _a;
465
689
  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);
690
+ this.kind = AstNode_1.AstNodeKind.DimStatement;
691
+ this.tokens = {
692
+ dim: options === null || options === void 0 ? void 0 : options.dim,
693
+ name: options.name,
694
+ openingSquare: options.openingSquare,
695
+ closingSquare: options.closingSquare
696
+ };
697
+ this.dimensions = options.dimensions;
698
+ this.location = util_1.util.createBoundingLocation(options.dim, options.name, options.openingSquare, ...((_a = this.dimensions) !== null && _a !== void 0 ? _a : []), options.closingSquare);
472
699
  }
473
700
  transpile(state) {
474
701
  let result = [
475
- state.transpileToken(this.dimToken),
702
+ state.transpileToken(this.tokens.dim, 'dim'),
476
703
  ' ',
477
- state.transpileToken(this.identifier),
478
- state.transpileToken(this.openingSquare)
704
+ state.transpileToken(this.tokens.name),
705
+ state.transpileToken(this.tokens.openingSquare, '[')
479
706
  ];
480
707
  for (let i = 0; i < this.dimensions.length; i++) {
481
708
  if (i > 0) {
@@ -483,28 +710,53 @@ class DimStatement extends Statement {
483
710
  }
484
711
  result.push(...this.dimensions[i].transpile(state));
485
712
  }
486
- result.push(state.transpileToken(this.closingSquare));
713
+ result.push(state.transpileToken(this.tokens.closingSquare, ']'));
487
714
  return result;
488
715
  }
489
716
  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
- }
717
+ var _a, _b;
718
+ 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) {
719
+ (0, visitors_1.walkArray)(this.dimensions, visitor, options, this);
720
+ }
721
+ }
722
+ getType(options) {
723
+ var _a, _b;
724
+ const numDimensions = (_b = (_a = this.dimensions) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 1;
725
+ let type = new ArrayType_1.ArrayType();
726
+ for (let i = 0; i < numDimensions - 1; i++) {
727
+ type = new ArrayType_1.ArrayType(type);
495
728
  }
729
+ return type;
730
+ }
731
+ get leadingTrivia() {
732
+ var _a, _b;
733
+ return (_b = (_a = this.tokens.dim) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
734
+ }
735
+ clone() {
736
+ var _a;
737
+ return this.finalizeClone(new DimStatement({
738
+ dim: util_1.util.cloneToken(this.tokens.dim),
739
+ name: util_1.util.cloneToken(this.tokens.name),
740
+ openingSquare: util_1.util.cloneToken(this.tokens.openingSquare),
741
+ dimensions: (_a = this.dimensions) === null || _a === void 0 ? void 0 : _a.map(e => e === null || e === void 0 ? void 0 : e.clone()),
742
+ closingSquare: util_1.util.cloneToken(this.tokens.closingSquare)
743
+ }), ['dimensions']);
496
744
  }
497
745
  }
498
746
  exports.DimStatement = DimStatement;
499
- class GotoStatement extends Statement {
500
- constructor(tokens) {
747
+ class GotoStatement extends AstNode_1.Statement {
748
+ constructor(options) {
501
749
  super();
502
- this.tokens = tokens;
503
- this.range = util_1.util.createRangeFromPositions(this.tokens.goto.range.start, this.tokens.label.range.end);
750
+ this.kind = AstNode_1.AstNodeKind.GotoStatement;
751
+ this.tokens = {
752
+ goto: options.goto,
753
+ label: options.label
754
+ };
755
+ this.location = util_1.util.createBoundingLocation(this.tokens.goto, this.tokens.label);
504
756
  }
505
757
  transpile(state) {
506
758
  return [
507
- state.transpileToken(this.tokens.goto),
759
+ state.transpileToken(this.tokens.goto, 'goto'),
508
760
  ' ',
509
761
  state.transpileToken(this.tokens.label)
510
762
  ];
@@ -512,36 +764,61 @@ class GotoStatement extends Statement {
512
764
  walk(visitor, options) {
513
765
  //nothing to walk
514
766
  }
767
+ get leadingTrivia() {
768
+ var _a, _b;
769
+ return (_b = (_a = this.tokens.goto) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
770
+ }
771
+ clone() {
772
+ return this.finalizeClone(new GotoStatement({
773
+ goto: util_1.util.cloneToken(this.tokens.goto),
774
+ label: util_1.util.cloneToken(this.tokens.label)
775
+ }));
776
+ }
515
777
  }
516
778
  exports.GotoStatement = GotoStatement;
517
- class LabelStatement extends Statement {
518
- constructor(tokens) {
779
+ class LabelStatement extends AstNode_1.Statement {
780
+ constructor(options) {
519
781
  super();
520
- this.tokens = tokens;
521
- this.range = util_1.util.createRangeFromPositions(this.tokens.identifier.range.start, this.tokens.colon.range.end);
782
+ this.kind = AstNode_1.AstNodeKind.LabelStatement;
783
+ this.tokens = {
784
+ name: options.name,
785
+ colon: options.colon
786
+ };
787
+ this.location = util_1.util.createBoundingLocation(this.tokens.name, this.tokens.colon);
788
+ }
789
+ get leadingTrivia() {
790
+ return this.tokens.name.leadingTrivia;
522
791
  }
523
792
  transpile(state) {
524
793
  return [
525
- state.transpileToken(this.tokens.identifier),
526
- state.transpileToken(this.tokens.colon)
794
+ state.transpileToken(this.tokens.name),
795
+ state.transpileToken(this.tokens.colon, ':')
527
796
  ];
528
797
  }
529
798
  walk(visitor, options) {
530
799
  //nothing to walk
531
800
  }
801
+ clone() {
802
+ return this.finalizeClone(new LabelStatement({
803
+ name: util_1.util.cloneToken(this.tokens.name),
804
+ colon: util_1.util.cloneToken(this.tokens.colon)
805
+ }));
806
+ }
532
807
  }
533
808
  exports.LabelStatement = LabelStatement;
534
- class ReturnStatement extends Statement {
535
- constructor(tokens, value) {
536
- var _a;
809
+ class ReturnStatement extends AstNode_1.Statement {
810
+ constructor(options) {
537
811
  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);
812
+ this.kind = AstNode_1.AstNodeKind.ReturnStatement;
813
+ this.tokens = {
814
+ return: options === null || options === void 0 ? void 0 : options.return
815
+ };
816
+ this.value = options === null || options === void 0 ? void 0 : options.value;
817
+ this.location = util_1.util.createBoundingLocation(this.tokens.return, this.value);
541
818
  }
542
819
  transpile(state) {
543
820
  let result = [];
544
- result.push(state.transpileToken(this.tokens.return));
821
+ result.push(state.transpileToken(this.tokens.return, 'return'));
545
822
  if (this.value) {
546
823
  result.push(' ');
547
824
  result.push(...this.value.transpile(state));
@@ -550,258 +827,409 @@ class ReturnStatement extends Statement {
550
827
  }
551
828
  walk(visitor, options) {
552
829
  if (options.walkMode & visitors_1.InternalWalkMode.walkExpressions) {
553
- visitors_1.walk(this, 'value', visitor, options);
830
+ (0, visitors_1.walk)(this, 'value', visitor, options);
554
831
  }
555
832
  }
833
+ get leadingTrivia() {
834
+ var _a, _b;
835
+ return (_b = (_a = this.tokens.return) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
836
+ }
837
+ clone() {
838
+ var _a;
839
+ return this.finalizeClone(new ReturnStatement({
840
+ return: util_1.util.cloneToken(this.tokens.return),
841
+ value: (_a = this.value) === null || _a === void 0 ? void 0 : _a.clone()
842
+ }), ['value']);
843
+ }
556
844
  }
557
845
  exports.ReturnStatement = ReturnStatement;
558
- class EndStatement extends Statement {
559
- constructor(tokens) {
846
+ class EndStatement extends AstNode_1.Statement {
847
+ constructor(options) {
848
+ var _a;
560
849
  super();
561
- this.tokens = tokens;
562
- this.range = util_1.util.createRangeFromPositions(this.tokens.end.range.start, this.tokens.end.range.end);
850
+ this.kind = AstNode_1.AstNodeKind.EndStatement;
851
+ this.tokens = {
852
+ end: options === null || options === void 0 ? void 0 : options.end
853
+ };
854
+ this.location = (_a = this.tokens.end) === null || _a === void 0 ? void 0 : _a.location;
563
855
  }
564
856
  transpile(state) {
565
857
  return [
566
- state.transpileToken(this.tokens.end)
858
+ state.transpileToken(this.tokens.end, 'end')
567
859
  ];
568
860
  }
569
861
  walk(visitor, options) {
570
862
  //nothing to walk
571
863
  }
864
+ get leadingTrivia() {
865
+ var _a, _b;
866
+ return (_b = (_a = this.tokens.end) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
867
+ }
868
+ clone() {
869
+ return this.finalizeClone(new EndStatement({
870
+ end: util_1.util.cloneToken(this.tokens.end)
871
+ }));
872
+ }
572
873
  }
573
874
  exports.EndStatement = EndStatement;
574
- class StopStatement extends Statement {
575
- constructor(tokens) {
875
+ class StopStatement extends AstNode_1.Statement {
876
+ constructor(options) {
877
+ var _a, _b;
576
878
  super();
577
- this.tokens = tokens;
578
- this.range = util_1.util.createRangeFromPositions(this.tokens.stop.range.start, this.tokens.stop.range.end);
879
+ this.kind = AstNode_1.AstNodeKind.StopStatement;
880
+ this.tokens = { stop: options === null || options === void 0 ? void 0 : options.stop };
881
+ this.location = (_b = (_a = this.tokens) === null || _a === void 0 ? void 0 : _a.stop) === null || _b === void 0 ? void 0 : _b.location;
579
882
  }
580
883
  transpile(state) {
581
884
  return [
582
- state.transpileToken(this.tokens.stop)
885
+ state.transpileToken(this.tokens.stop, 'stop')
583
886
  ];
584
887
  }
585
888
  walk(visitor, options) {
586
889
  //nothing to walk
587
890
  }
891
+ get leadingTrivia() {
892
+ var _a, _b;
893
+ return (_b = (_a = this.tokens.stop) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
894
+ }
895
+ clone() {
896
+ return this.finalizeClone(new StopStatement({
897
+ stop: util_1.util.cloneToken(this.tokens.stop)
898
+ }));
899
+ }
588
900
  }
589
901
  exports.StopStatement = StopStatement;
590
- class ForStatement extends Statement {
591
- constructor(forToken, counterDeclaration, toToken, finalValue, body, endForToken, stepToken, increment) {
592
- var _a, _b;
902
+ class ForStatement extends AstNode_1.Statement {
903
+ constructor(options) {
593
904
  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);
905
+ this.kind = AstNode_1.AstNodeKind.ForStatement;
906
+ this.tokens = {
907
+ for: options.for,
908
+ to: options.to,
909
+ endFor: options.endFor,
910
+ step: options.step
911
+ };
912
+ this.counterDeclaration = options.counterDeclaration;
913
+ this.finalValue = options.finalValue;
914
+ this.body = options.body;
915
+ this.increment = options.increment;
916
+ this.location = util_1.util.createBoundingLocation(this.tokens.for, this.counterDeclaration, this.tokens.to, this.finalValue, this.tokens.step, this.increment, this.body, this.tokens.endFor);
604
917
  }
605
918
  transpile(state) {
606
919
  let result = [];
607
920
  //for
608
- result.push(state.transpileToken(this.forToken), ' ');
921
+ result.push(state.transpileToken(this.tokens.for, 'for'), ' ');
609
922
  //i=1
610
923
  result.push(...this.counterDeclaration.transpile(state), ' ');
611
924
  //to
612
- result.push(state.transpileToken(this.toToken), ' ');
925
+ result.push(state.transpileToken(this.tokens.to, 'to'), ' ');
613
926
  //final value
614
927
  result.push(this.finalValue.transpile(state));
615
928
  //step
616
- if (this.stepToken) {
617
- result.push(' ', state.transpileToken(this.stepToken), ' ', this.increment.transpile(state));
929
+ if (this.increment) {
930
+ result.push(' ', state.transpileToken(this.tokens.step, 'step'), ' ', this.increment.transpile(state));
618
931
  }
619
932
  //loop body
620
933
  state.lineage.unshift(this);
621
934
  result.push(...this.body.transpile(state));
622
935
  state.lineage.shift();
623
- if (this.body.statements.length > 0) {
624
- result.push('\n');
625
- }
626
936
  //end for
627
- result.push(state.indent(), state.transpileToken(this.endForToken));
937
+ result.push(...state.transpileEndBlockToken(this.body, this.tokens.endFor, 'end for'));
628
938
  return result;
629
939
  }
630
940
  walk(visitor, options) {
631
941
  if (options.walkMode & visitors_1.InternalWalkMode.walkStatements) {
632
- visitors_1.walk(this, 'counterDeclaration', visitor, options);
942
+ (0, visitors_1.walk)(this, 'counterDeclaration', visitor, options);
633
943
  }
634
944
  if (options.walkMode & visitors_1.InternalWalkMode.walkExpressions) {
635
- visitors_1.walk(this, 'finalValue', visitor, options);
636
- visitors_1.walk(this, 'increment', visitor, options);
945
+ (0, visitors_1.walk)(this, 'finalValue', visitor, options);
946
+ (0, visitors_1.walk)(this, 'increment', visitor, options);
637
947
  }
638
948
  if (options.walkMode & visitors_1.InternalWalkMode.walkStatements) {
639
- visitors_1.walk(this, 'body', visitor, options);
949
+ (0, visitors_1.walk)(this, 'body', visitor, options);
640
950
  }
641
951
  }
952
+ get leadingTrivia() {
953
+ var _a, _b;
954
+ return (_b = (_a = this.tokens.for) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
955
+ }
956
+ get endTrivia() {
957
+ var _a, _b;
958
+ return (_b = (_a = this.tokens.endFor) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
959
+ }
960
+ clone() {
961
+ var _a, _b, _c, _d;
962
+ return this.finalizeClone(new ForStatement({
963
+ for: util_1.util.cloneToken(this.tokens.for),
964
+ counterDeclaration: (_a = this.counterDeclaration) === null || _a === void 0 ? void 0 : _a.clone(),
965
+ to: util_1.util.cloneToken(this.tokens.to),
966
+ finalValue: (_b = this.finalValue) === null || _b === void 0 ? void 0 : _b.clone(),
967
+ body: (_c = this.body) === null || _c === void 0 ? void 0 : _c.clone(),
968
+ endFor: util_1.util.cloneToken(this.tokens.endFor),
969
+ step: util_1.util.cloneToken(this.tokens.step),
970
+ increment: (_d = this.increment) === null || _d === void 0 ? void 0 : _d.clone()
971
+ }), ['counterDeclaration', 'finalValue', 'body', 'increment']);
972
+ }
642
973
  }
643
974
  exports.ForStatement = ForStatement;
644
- class ForEachStatement extends Statement {
645
- constructor(forEachToken, item, inToken, target, body, endForToken) {
646
- var _a, _b, _c, _d, _e;
975
+ class ForEachStatement extends AstNode_1.Statement {
976
+ constructor(options) {
647
977
  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);
978
+ this.kind = AstNode_1.AstNodeKind.ForEachStatement;
979
+ this.tokens = {
980
+ forEach: options.forEach,
981
+ item: options.item,
982
+ as: options.as,
983
+ in: options.in,
984
+ endFor: options.endFor
985
+ };
986
+ this.body = options.body;
987
+ this.target = options.target;
988
+ this.typeExpression = options.typeExpression;
989
+ this.location = util_1.util.createBoundingLocation(this.tokens.forEach, this.tokens.item, this.tokens.as, this.typeExpression, this.tokens.in, this.target, this.body, this.tokens.endFor);
655
990
  }
656
991
  transpile(state) {
657
992
  let result = [];
658
993
  //for each
659
- result.push(state.transpileToken(this.forEachToken), ' ');
994
+ result.push(state.transpileToken(this.tokens.forEach, 'for each'), ' ');
660
995
  //item
661
- result.push(state.transpileToken(this.item), ' ');
996
+ result.push(state.transpileToken(this.tokens.item), ' ');
662
997
  //in
663
- result.push(state.transpileToken(this.inToken), ' ');
998
+ result.push(state.transpileToken(this.tokens.in, 'in'), ' ');
664
999
  //target
665
1000
  result.push(...this.target.transpile(state));
666
1001
  //body
667
1002
  state.lineage.unshift(this);
668
1003
  result.push(...this.body.transpile(state));
669
1004
  state.lineage.shift();
670
- if (this.body.statements.length > 0) {
671
- result.push('\n');
672
- }
673
1005
  //end for
674
- result.push(state.indent(), state.transpileToken(this.endForToken));
1006
+ result.push(...state.transpileEndBlockToken(this.body, this.tokens.endFor, 'end for'));
675
1007
  return result;
676
1008
  }
677
1009
  walk(visitor, options) {
678
1010
  if (options.walkMode & visitors_1.InternalWalkMode.walkExpressions) {
679
- visitors_1.walk(this, 'target', visitor, options);
1011
+ (0, visitors_1.walk)(this, 'target', visitor, options);
680
1012
  }
681
1013
  if (options.walkMode & visitors_1.InternalWalkMode.walkStatements) {
682
- visitors_1.walk(this, 'body', visitor, options);
1014
+ (0, visitors_1.walk)(this, 'body', visitor, options);
1015
+ }
1016
+ }
1017
+ getType(options) {
1018
+ // Used for hovers on the statement 'item' token
1019
+ return this.getLoopVariableType(options);
1020
+ }
1021
+ getLoopVariableType(options) {
1022
+ if (this.typeExpression) {
1023
+ return this.typeExpression.getType(options);
683
1024
  }
1025
+ //register the for loop variable
1026
+ const loopTargetType = this.target.getType({ flags: 1 /* SymbolTypeFlag.runtime */ });
1027
+ const loopVarType = new ReferenceType_1.ArrayDefaultTypeReferenceType(loopTargetType);
1028
+ return loopVarType;
1029
+ }
1030
+ get leadingTrivia() {
1031
+ var _a, _b;
1032
+ return (_b = (_a = this.tokens.forEach) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
1033
+ }
1034
+ get endTrivia() {
1035
+ var _a, _b;
1036
+ return (_b = (_a = this.tokens.endFor) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
1037
+ }
1038
+ clone() {
1039
+ var _a, _b, _c;
1040
+ return this.finalizeClone(new ForEachStatement({
1041
+ forEach: util_1.util.cloneToken(this.tokens.forEach),
1042
+ in: util_1.util.cloneToken(this.tokens.in),
1043
+ as: util_1.util.cloneToken(this.tokens.as),
1044
+ typeExpression: (_a = this.typeExpression) === null || _a === void 0 ? void 0 : _a.clone(),
1045
+ endFor: util_1.util.cloneToken(this.tokens.endFor),
1046
+ item: util_1.util.cloneToken(this.tokens.item),
1047
+ target: (_b = this.target) === null || _b === void 0 ? void 0 : _b.clone(),
1048
+ body: (_c = this.body) === null || _c === void 0 ? void 0 : _c.clone()
1049
+ }), ['target', 'body']);
684
1050
  }
685
1051
  }
686
1052
  exports.ForEachStatement = ForEachStatement;
687
- class WhileStatement extends Statement {
688
- constructor(tokens, condition, body) {
689
- var _a, _b;
1053
+ class WhileStatement extends AstNode_1.Statement {
1054
+ constructor(options) {
690
1055
  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);
1056
+ this.kind = AstNode_1.AstNodeKind.WhileStatement;
1057
+ this.tokens = {
1058
+ while: options.while,
1059
+ endWhile: options.endWhile
1060
+ };
1061
+ this.body = options.body;
1062
+ this.condition = options.condition;
1063
+ this.location = util_1.util.createBoundingLocation(this.tokens.while, this.condition, this.body, this.tokens.endWhile);
696
1064
  }
697
1065
  transpile(state) {
698
1066
  let result = [];
699
1067
  //while
700
- result.push(state.transpileToken(this.tokens.while), ' ');
1068
+ result.push(state.transpileToken(this.tokens.while, 'while'), ' ');
701
1069
  //condition
702
1070
  result.push(...this.condition.transpile(state));
703
1071
  state.lineage.unshift(this);
704
1072
  //body
705
1073
  result.push(...this.body.transpile(state));
706
1074
  state.lineage.shift();
707
- //trailing newline only if we have body statements
708
- result.push('\n');
709
1075
  //end while
710
- result.push(state.indent(), state.transpileToken(this.tokens.endWhile));
1076
+ result.push(...state.transpileEndBlockToken(this.body, this.tokens.endWhile, 'end while'));
711
1077
  return result;
712
1078
  }
713
1079
  walk(visitor, options) {
714
1080
  if (options.walkMode & visitors_1.InternalWalkMode.walkExpressions) {
715
- visitors_1.walk(this, 'condition', visitor, options);
1081
+ (0, visitors_1.walk)(this, 'condition', visitor, options);
716
1082
  }
717
1083
  if (options.walkMode & visitors_1.InternalWalkMode.walkStatements) {
718
- visitors_1.walk(this, 'body', visitor, options);
1084
+ (0, visitors_1.walk)(this, 'body', visitor, options);
719
1085
  }
720
1086
  }
1087
+ get leadingTrivia() {
1088
+ var _a, _b;
1089
+ return (_b = (_a = this.tokens.while) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
1090
+ }
1091
+ get endTrivia() {
1092
+ var _a, _b;
1093
+ return (_b = (_a = this.tokens.endWhile) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
1094
+ }
1095
+ clone() {
1096
+ var _a, _b;
1097
+ return this.finalizeClone(new WhileStatement({
1098
+ while: util_1.util.cloneToken(this.tokens.while),
1099
+ endWhile: util_1.util.cloneToken(this.tokens.endWhile),
1100
+ condition: (_a = this.condition) === null || _a === void 0 ? void 0 : _a.clone(),
1101
+ body: (_b = this.body) === null || _b === void 0 ? void 0 : _b.clone()
1102
+ }), ['condition', 'body']);
1103
+ }
721
1104
  }
722
1105
  exports.WhileStatement = WhileStatement;
723
- class DottedSetStatement extends Statement {
724
- constructor(obj, name, value) {
1106
+ class DottedSetStatement extends AstNode_1.Statement {
1107
+ constructor(options) {
725
1108
  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);
1109
+ this.kind = AstNode_1.AstNodeKind.DottedSetStatement;
1110
+ this.tokens = {
1111
+ name: options.name,
1112
+ dot: options.dot,
1113
+ equals: options.equals
1114
+ };
1115
+ this.obj = options.obj;
1116
+ this.value = options.value;
1117
+ this.location = util_1.util.createBoundingLocation(this.obj, this.tokens.dot, this.tokens.equals, this.tokens.name, this.value);
730
1118
  }
731
1119
  transpile(state) {
732
- var _a, _b;
733
1120
  //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)) {
735
- return this.value.transpile(state);
736
- }
737
- else {
738
- return [
739
- //object
740
- ...this.obj.transpile(state),
741
- '.',
742
- //name
743
- state.transpileToken(this.name),
744
- ' = ',
745
- //right-hand-side of assignment
746
- ...this.value.transpile(state)
747
- ];
748
- }
1121
+ return [
1122
+ //object
1123
+ ...this.obj.transpile(state),
1124
+ this.tokens.dot ? state.tokenToSourceNode(this.tokens.dot) : '.',
1125
+ //name
1126
+ state.transpileToken(this.tokens.name),
1127
+ ' ',
1128
+ state.transpileToken(this.tokens.equals, '='),
1129
+ ' ',
1130
+ //right-hand-side of assignment
1131
+ ...this.value.transpile(state)
1132
+ ];
749
1133
  }
750
1134
  walk(visitor, options) {
751
1135
  if (options.walkMode & visitors_1.InternalWalkMode.walkExpressions) {
752
- visitors_1.walk(this, 'obj', visitor, options);
753
- visitors_1.walk(this, 'value', visitor, options);
1136
+ (0, visitors_1.walk)(this, 'obj', visitor, options);
1137
+ (0, visitors_1.walk)(this, 'value', visitor, options);
754
1138
  }
755
1139
  }
1140
+ getType(options) {
1141
+ var _a, _b, _c, _d, _e;
1142
+ const objType = (_a = this.obj) === null || _a === void 0 ? void 0 : _a.getType(options);
1143
+ const result = objType === null || objType === void 0 ? void 0 : objType.getMemberType((_b = this.tokens.name) === null || _b === void 0 ? void 0 : _b.text, options);
1144
+ (_c = options.typeChain) === null || _c === void 0 ? void 0 : _c.push(new interfaces_1.TypeChainEntry({
1145
+ name: (_d = this.tokens.name) === null || _d === void 0 ? void 0 : _d.text,
1146
+ type: result, data: options.data,
1147
+ location: (_e = this.tokens.name) === null || _e === void 0 ? void 0 : _e.location,
1148
+ astNode: this
1149
+ }));
1150
+ return result;
1151
+ }
1152
+ get leadingTrivia() {
1153
+ return this.obj.leadingTrivia;
1154
+ }
1155
+ clone() {
1156
+ var _a, _b;
1157
+ return this.finalizeClone(new DottedSetStatement({
1158
+ obj: (_a = this.obj) === null || _a === void 0 ? void 0 : _a.clone(),
1159
+ dot: util_1.util.cloneToken(this.tokens.dot),
1160
+ name: util_1.util.cloneToken(this.tokens.name),
1161
+ equals: util_1.util.cloneToken(this.tokens.equals),
1162
+ value: (_b = this.value) === null || _b === void 0 ? void 0 : _b.clone()
1163
+ }), ['obj', 'value']);
1164
+ }
756
1165
  }
757
1166
  exports.DottedSetStatement = DottedSetStatement;
758
- class IndexedSetStatement extends Statement {
759
- constructor(obj, index, value, openingSquare, closingSquare) {
1167
+ class IndexedSetStatement extends AstNode_1.Statement {
1168
+ constructor(options) {
1169
+ var _a;
760
1170
  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);
1171
+ this.kind = AstNode_1.AstNodeKind.IndexedSetStatement;
1172
+ this.tokens = {
1173
+ openingSquare: options.openingSquare,
1174
+ closingSquare: options.closingSquare,
1175
+ equals: options.equals
1176
+ };
1177
+ this.obj = options.obj;
1178
+ this.indexes = (_a = options.indexes) !== null && _a !== void 0 ? _a : [];
1179
+ this.value = options.value;
1180
+ this.location = util_1.util.createBoundingLocation(this.obj, this.tokens.openingSquare, ...this.indexes, this.tokens.closingSquare, this.value);
767
1181
  }
768
1182
  transpile(state) {
769
- var _a, _b;
770
- //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)) {
772
- return this.value.transpile(state);
773
- }
774
- 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
- ];
1183
+ var _a;
1184
+ const result = [];
1185
+ result.push(
1186
+ //obj
1187
+ ...this.obj.transpile(state),
1188
+ // [
1189
+ state.transpileToken(this.tokens.openingSquare, '['));
1190
+ for (let i = 0; i < this.indexes.length; i++) {
1191
+ //add comma between indexes
1192
+ if (i > 0) {
1193
+ result.push(', ');
1194
+ }
1195
+ let index = this.indexes[i];
1196
+ result.push(...((_a = index === null || index === void 0 ? void 0 : index.transpile(state)) !== null && _a !== void 0 ? _a : []));
789
1197
  }
1198
+ result.push(state.transpileToken(this.tokens.closingSquare, ']'), ' ', state.transpileToken(this.tokens.equals, '='), ' ', ...this.value.transpile(state));
1199
+ return result;
790
1200
  }
791
1201
  walk(visitor, options) {
792
1202
  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);
1203
+ (0, visitors_1.walk)(this, 'obj', visitor, options);
1204
+ (0, visitors_1.walkArray)(this.indexes, visitor, options, this);
1205
+ (0, visitors_1.walk)(this, 'value', visitor, options);
796
1206
  }
797
1207
  }
1208
+ get leadingTrivia() {
1209
+ return this.obj.leadingTrivia;
1210
+ }
1211
+ clone() {
1212
+ var _a, _b, _c;
1213
+ return this.finalizeClone(new IndexedSetStatement({
1214
+ obj: (_a = this.obj) === null || _a === void 0 ? void 0 : _a.clone(),
1215
+ openingSquare: util_1.util.cloneToken(this.tokens.openingSquare),
1216
+ indexes: (_b = this.indexes) === null || _b === void 0 ? void 0 : _b.map(x => x === null || x === void 0 ? void 0 : x.clone()),
1217
+ closingSquare: util_1.util.cloneToken(this.tokens.closingSquare),
1218
+ equals: util_1.util.cloneToken(this.tokens.equals),
1219
+ value: (_c = this.value) === null || _c === void 0 ? void 0 : _c.clone()
1220
+ }), ['obj', 'indexes', 'value']);
1221
+ }
798
1222
  }
799
1223
  exports.IndexedSetStatement = IndexedSetStatement;
800
- class LibraryStatement extends Statement {
801
- constructor(tokens) {
1224
+ class LibraryStatement extends AstNode_1.Statement {
1225
+ constructor(options) {
802
1226
  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);
1227
+ this.kind = AstNode_1.AstNodeKind.LibraryStatement;
1228
+ this.tokens = {
1229
+ library: options === null || options === void 0 ? void 0 : options.library,
1230
+ filePath: options === null || options === void 0 ? void 0 : options.filePath
1231
+ };
1232
+ this.location = util_1.util.createBoundingLocation(this.tokens.library, this.tokens.filePath);
805
1233
  }
806
1234
  transpile(state) {
807
1235
  let result = [];
@@ -818,38 +1246,87 @@ class LibraryStatement extends Statement {
818
1246
  walk(visitor, options) {
819
1247
  //nothing to walk
820
1248
  }
1249
+ get leadingTrivia() {
1250
+ var _a, _b;
1251
+ return (_b = (_a = this.tokens.library) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
1252
+ }
1253
+ clone() {
1254
+ var _a, _b;
1255
+ return this.finalizeClone(new LibraryStatement({
1256
+ library: util_1.util.cloneToken((_a = this.tokens) === null || _a === void 0 ? void 0 : _a.library),
1257
+ filePath: util_1.util.cloneToken((_b = this.tokens) === null || _b === void 0 ? void 0 : _b.filePath)
1258
+ }));
1259
+ }
821
1260
  }
822
1261
  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) {
1262
+ class NamespaceStatement extends AstNode_1.Statement {
1263
+ constructor(options) {
827
1264
  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);
835
- }
836
- 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);
1265
+ this.kind = AstNode_1.AstNodeKind.NamespaceStatement;
1266
+ this.tokens = {
1267
+ namespace: options.namespace,
1268
+ endNamespace: options.endNamespace
1269
+ };
1270
+ this.nameExpression = options.nameExpression;
1271
+ this.body = options.body;
1272
+ this.symbolTable = new SymbolTable_1.SymbolTable(`NamespaceStatement: '${this.name}'`, () => { var _a; return (_a = this.getRoot()) === null || _a === void 0 ? void 0 : _a.getSymbolTable(); });
1273
+ }
1274
+ /**
1275
+ * The string name for this namespace
1276
+ */
1277
+ get name() {
1278
+ return this.getName(Parser_1.ParseMode.BrighterScript);
1279
+ }
1280
+ get location() {
1281
+ return this.cacheLocation();
1282
+ }
1283
+ cacheLocation() {
1284
+ if (!this._location) {
1285
+ this._location = util_1.util.createBoundingLocation(this.tokens.namespace, this.nameExpression, this.body, this.tokens.endNamespace);
1286
+ }
1287
+ return this._location;
839
1288
  }
840
1289
  getName(parseMode) {
841
- return this.nameExpression.getName(parseMode);
1290
+ var _a, _b;
1291
+ const sep = parseMode === Parser_1.ParseMode.BrighterScript ? '.' : '_';
1292
+ let name = util_1.util.getAllDottedGetPartsAsString(this.nameExpression, parseMode);
1293
+ 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) {
1294
+ name = this.parent.parent.getName(parseMode) + sep + name;
1295
+ }
1296
+ return name;
842
1297
  }
843
- transpile(state) {
844
- //namespaces don't actually have any real content, so just transpile their bodies
845
- return this.body.transpile(state);
1298
+ get leadingTrivia() {
1299
+ var _a;
1300
+ return (_a = this.tokens.namespace) === null || _a === void 0 ? void 0 : _a.leadingTrivia;
846
1301
  }
847
- getTypedef(state) {
848
- let result = [
849
- 'namespace ',
850
- ...this.nameExpression.getName(Parser_1.ParseMode.BrighterScript),
851
- state.newline
1302
+ get endTrivia() {
1303
+ var _a;
1304
+ return (_a = this.tokens.endNamespace) === null || _a === void 0 ? void 0 : _a.leadingTrivia;
1305
+ }
1306
+ getNameParts() {
1307
+ var _a, _b;
1308
+ let parts = util_1.util.getAllDottedGetParts(this.nameExpression);
1309
+ 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) {
1310
+ parts = this.parent.parent.getNameParts().concat(parts);
1311
+ }
1312
+ return parts;
1313
+ }
1314
+ transpile(state) {
1315
+ //namespaces don't actually have any real content, so just transpile their bodies
1316
+ return [
1317
+ state.transpileAnnotations(this),
1318
+ state.transpileLeadingComments(this.tokens.namespace),
1319
+ this.body.transpile(state),
1320
+ state.transpileLeadingComments(this.tokens.endNamespace)
852
1321
  ];
1322
+ }
1323
+ getTypedef(state) {
1324
+ var _a;
1325
+ let result = [];
1326
+ for (let comment of (_a = util_1.util.getLeadingComments(this)) !== null && _a !== void 0 ? _a : []) {
1327
+ result.push(comment.text, state.newline, state.indent());
1328
+ }
1329
+ result.push('namespace ', ...this.getName(Parser_1.ParseMode.BrighterScript), state.newline);
853
1330
  state.blockDepth++;
854
1331
  result.push(...this.body.getTypedef(state));
855
1332
  state.blockDepth--;
@@ -858,90 +1335,449 @@ class NamespaceStatement extends Statement {
858
1335
  }
859
1336
  walk(visitor, options) {
860
1337
  if (options.walkMode & visitors_1.InternalWalkMode.walkExpressions) {
861
- visitors_1.walk(this, 'nameExpression', visitor, options);
1338
+ (0, visitors_1.walk)(this, 'nameExpression', visitor, options);
862
1339
  }
863
1340
  if (this.body.statements.length > 0 && options.walkMode & visitors_1.InternalWalkMode.walkStatements) {
864
- visitors_1.walk(this, 'body', visitor, options);
1341
+ (0, visitors_1.walk)(this, 'body', visitor, options);
865
1342
  }
866
1343
  }
1344
+ getType(options) {
1345
+ const resultType = new NamespaceType_1.NamespaceType(this.name);
1346
+ return resultType;
1347
+ }
1348
+ clone() {
1349
+ var _a, _b;
1350
+ const clone = this.finalizeClone(new NamespaceStatement({
1351
+ namespace: util_1.util.cloneToken(this.tokens.namespace),
1352
+ nameExpression: (_a = this.nameExpression) === null || _a === void 0 ? void 0 : _a.clone(),
1353
+ body: (_b = this.body) === null || _b === void 0 ? void 0 : _b.clone(),
1354
+ endNamespace: util_1.util.cloneToken(this.tokens.endNamespace)
1355
+ }), ['nameExpression', 'body']);
1356
+ clone.cacheLocation();
1357
+ return clone;
1358
+ }
867
1359
  }
868
1360
  exports.NamespaceStatement = NamespaceStatement;
869
- class ImportStatement extends Statement {
870
- constructor(importToken, filePathToken) {
1361
+ class ImportStatement extends AstNode_1.Statement {
1362
+ constructor(options) {
1363
+ var _a, _b;
871
1364
  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) {
1365
+ this.kind = AstNode_1.AstNodeKind.ImportStatement;
1366
+ this.tokens = {
1367
+ import: options.import,
1368
+ path: options.path
1369
+ };
1370
+ this.location = util_1.util.createBoundingLocation(this.tokens.import, this.tokens.path);
1371
+ if (this.tokens.path) {
876
1372
  //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);
1373
+ this.filePath = this.tokens.path.text.replace(/"/g, '');
1374
+ if ((_b = (_a = this.tokens.path) === null || _a === void 0 ? void 0 : _a.location) === null || _b === void 0 ? void 0 : _b.range) {
1375
+ //adjust the range to exclude the quotes
1376
+ this.tokens.path.location = util_1.util.createLocation(this.tokens.path.location.range.start.line, this.tokens.path.location.range.start.character + 1, this.tokens.path.location.range.end.line, this.tokens.path.location.range.end.character - 1, this.tokens.path.location.uri);
1377
+ }
880
1378
  }
881
1379
  }
882
1380
  transpile(state) {
883
1381
  //The xml files are responsible for adding the additional script imports, but
884
1382
  //add the import statement as a comment just for debugging purposes
885
1383
  return [
886
- `'`,
887
- state.transpileToken(this.importToken),
1384
+ state.transpileToken(this.tokens.import, 'import', true),
888
1385
  ' ',
889
- state.transpileToken(this.filePathToken)
1386
+ state.transpileToken(this.tokens.path)
890
1387
  ];
891
1388
  }
892
1389
  /**
893
1390
  * Get the typedef for this statement
894
1391
  */
895
1392
  getTypedef(state) {
1393
+ var _a, _b;
896
1394
  return [
897
- this.importToken.text,
1395
+ (_b = (_a = this.tokens.import) === null || _a === void 0 ? void 0 : _a.text) !== null && _b !== void 0 ? _b : 'import',
898
1396
  ' ',
899
1397
  //replace any `.bs` extension with `.brs`
900
- this.filePathToken.text.replace(/\.bs"?$/i, '.brs"')
1398
+ this.tokens.path.text.replace(/\.bs"?$/i, '.brs"')
901
1399
  ];
902
1400
  }
903
1401
  walk(visitor, options) {
904
1402
  //nothing to walk
905
1403
  }
1404
+ get leadingTrivia() {
1405
+ var _a, _b;
1406
+ return (_b = (_a = this.tokens.import) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
1407
+ }
1408
+ clone() {
1409
+ return this.finalizeClone(new ImportStatement({
1410
+ import: util_1.util.cloneToken(this.tokens.import),
1411
+ path: util_1.util.cloneToken(this.tokens.path)
1412
+ }));
1413
+ }
906
1414
  }
907
1415
  exports.ImportStatement = ImportStatement;
908
- class ClassStatement extends Statement {
909
- constructor(classKeyword,
1416
+ class InterfaceStatement extends AstNode_1.Statement {
1417
+ constructor(options) {
1418
+ var _a;
1419
+ super();
1420
+ this.kind = AstNode_1.AstNodeKind.InterfaceStatement;
1421
+ this.tokens = {};
1422
+ this.tokens = {
1423
+ interface: options.interface,
1424
+ name: options.name,
1425
+ extends: options.extends,
1426
+ endInterface: options.endInterface
1427
+ };
1428
+ this.parentInterfaceName = options.parentInterfaceName;
1429
+ this.body = options.body;
1430
+ this.location = util_1.util.createBoundingLocation(this.tokens.interface, this.tokens.name, this.tokens.extends, this.parentInterfaceName, ...(_a = this.body) !== null && _a !== void 0 ? _a : [], this.tokens.endInterface);
1431
+ }
1432
+ get fields() {
1433
+ return this.body.filter(x => (0, reflection_1.isInterfaceFieldStatement)(x));
1434
+ }
1435
+ get methods() {
1436
+ return this.body.filter(x => (0, reflection_1.isInterfaceMethodStatement)(x));
1437
+ }
1438
+ hasParentInterface() {
1439
+ return !!this.parentInterfaceName;
1440
+ }
1441
+ get leadingTrivia() {
1442
+ var _a;
1443
+ return (_a = this.tokens.interface) === null || _a === void 0 ? void 0 : _a.leadingTrivia;
1444
+ }
1445
+ get endTrivia() {
1446
+ var _a;
1447
+ return (_a = this.tokens.endInterface) === null || _a === void 0 ? void 0 : _a.leadingTrivia;
1448
+ }
910
1449
  /**
911
- * The name of the class (without namespace prefix)
1450
+ * The name of the interface WITH its leading namespace (if applicable)
912
1451
  */
913
- name, body, end, extendsKeyword, parentClassName, namespaceName) {
914
- var _a, _b, _c;
1452
+ get fullName() {
1453
+ var _a;
1454
+ const name = (_a = this.tokens.name) === null || _a === void 0 ? void 0 : _a.text;
1455
+ if (name) {
1456
+ const namespace = this.findAncestor(reflection_1.isNamespaceStatement);
1457
+ if (namespace) {
1458
+ let namespaceName = namespace.getName(Parser_1.ParseMode.BrighterScript);
1459
+ return `${namespaceName}.${name}`;
1460
+ }
1461
+ else {
1462
+ return name;
1463
+ }
1464
+ }
1465
+ else {
1466
+ //return undefined which will allow outside callers to know that this interface doesn't have a name
1467
+ return undefined;
1468
+ }
1469
+ }
1470
+ /**
1471
+ * The name of the interface (without the namespace prefix)
1472
+ */
1473
+ get name() {
1474
+ var _a;
1475
+ return (_a = this.tokens.name) === null || _a === void 0 ? void 0 : _a.text;
1476
+ }
1477
+ /**
1478
+ * Get the name of this expression based on the parse mode
1479
+ */
1480
+ getName(parseMode) {
1481
+ const namespace = this.findAncestor(reflection_1.isNamespaceStatement);
1482
+ if (namespace) {
1483
+ let delimiter = parseMode === Parser_1.ParseMode.BrighterScript ? '.' : '_';
1484
+ let namespaceName = namespace.getName(parseMode);
1485
+ return namespaceName + delimiter + this.name;
1486
+ }
1487
+ else {
1488
+ return this.name;
1489
+ }
1490
+ }
1491
+ transpile(state) {
1492
+ //interfaces should completely disappear at runtime
1493
+ return [
1494
+ state.transpileLeadingComments(this.tokens.interface)
1495
+ ];
1496
+ }
1497
+ getTypedef(state) {
1498
+ var _a, _b, _c, _d;
1499
+ const result = [];
1500
+ for (let comment of (_a = util_1.util.getLeadingComments(this)) !== null && _a !== void 0 ? _a : []) {
1501
+ result.push(comment.text, state.newline, state.indent());
1502
+ }
1503
+ for (let annotation of (_b = this.annotations) !== null && _b !== void 0 ? _b : []) {
1504
+ result.push(...annotation.getTypedef(state), state.newline, state.indent());
1505
+ }
1506
+ result.push(this.tokens.interface.text, ' ', this.tokens.name.text);
1507
+ const parentInterfaceName = (_c = this.parentInterfaceName) === null || _c === void 0 ? void 0 : _c.getName();
1508
+ if (parentInterfaceName) {
1509
+ result.push(' extends ', parentInterfaceName);
1510
+ }
1511
+ const body = (_d = this.body) !== null && _d !== void 0 ? _d : [];
1512
+ if (body.length > 0) {
1513
+ state.blockDepth++;
1514
+ }
1515
+ for (const statement of body) {
1516
+ if ((0, reflection_1.isInterfaceMethodStatement)(statement) || (0, reflection_1.isInterfaceFieldStatement)(statement)) {
1517
+ result.push(state.newline, state.indent(), ...statement.getTypedef(state));
1518
+ }
1519
+ else {
1520
+ result.push(state.newline, state.indent(), ...statement.transpile(state));
1521
+ }
1522
+ }
1523
+ if (body.length > 0) {
1524
+ state.blockDepth--;
1525
+ }
1526
+ result.push(state.newline, state.indent(), 'end interface', state.newline);
1527
+ return result;
1528
+ }
1529
+ walk(visitor, options) {
1530
+ //visitor-less walk function to do parent linking
1531
+ (0, visitors_1.walk)(this, 'parentInterfaceName', null, options);
1532
+ if (options.walkMode & visitors_1.InternalWalkMode.walkStatements) {
1533
+ (0, visitors_1.walkArray)(this.body, visitor, options, this);
1534
+ }
1535
+ }
1536
+ getType(options) {
1537
+ var _a, _b, _c, _d;
1538
+ const superIface = (_a = this.parentInterfaceName) === null || _a === void 0 ? void 0 : _a.getType(options);
1539
+ const resultType = new InterfaceType_1.InterfaceType(this.getName(Parser_1.ParseMode.BrighterScript), superIface);
1540
+ for (const statement of this.methods) {
1541
+ const memberType = statement === null || statement === void 0 ? void 0 : statement.getType(Object.assign(Object.assign({}, options), { typeChain: undefined })); // no typechain info needed
1542
+ const flag = statement.isOptional ? 1 /* SymbolTypeFlag.runtime */ | 4 /* SymbolTypeFlag.optional */ : 1 /* SymbolTypeFlag.runtime */;
1543
+ 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);
1544
+ }
1545
+ for (const statement of this.fields) {
1546
+ const memberType = statement === null || statement === void 0 ? void 0 : statement.getType(Object.assign(Object.assign({}, options), { typeChain: undefined })); // no typechain info needed
1547
+ const flag = statement.isOptional ? 1 /* SymbolTypeFlag.runtime */ | 4 /* SymbolTypeFlag.optional */ : 1 /* SymbolTypeFlag.runtime */;
1548
+ 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);
1549
+ }
1550
+ (_d = options.typeChain) === null || _d === void 0 ? void 0 : _d.push(new interfaces_1.TypeChainEntry({
1551
+ name: this.getName(Parser_1.ParseMode.BrighterScript),
1552
+ type: resultType,
1553
+ data: options.data,
1554
+ astNode: this
1555
+ }));
1556
+ return resultType;
1557
+ }
1558
+ clone() {
1559
+ var _a, _b;
1560
+ return this.finalizeClone(new InterfaceStatement({
1561
+ interface: util_1.util.cloneToken(this.tokens.interface),
1562
+ name: util_1.util.cloneToken(this.tokens.name),
1563
+ extends: util_1.util.cloneToken(this.tokens.extends),
1564
+ parentInterfaceName: (_a = this.parentInterfaceName) === null || _a === void 0 ? void 0 : _a.clone(),
1565
+ body: (_b = this.body) === null || _b === void 0 ? void 0 : _b.map(x => x === null || x === void 0 ? void 0 : x.clone()),
1566
+ endInterface: util_1.util.cloneToken(this.tokens.endInterface)
1567
+ }), ['parentInterfaceName', 'body']);
1568
+ }
1569
+ }
1570
+ exports.InterfaceStatement = InterfaceStatement;
1571
+ class InterfaceFieldStatement extends AstNode_1.Statement {
1572
+ constructor(options) {
1573
+ super();
1574
+ this.kind = AstNode_1.AstNodeKind.InterfaceFieldStatement;
1575
+ this.tokens = {
1576
+ optional: options.optional,
1577
+ name: options.name,
1578
+ as: options.as
1579
+ };
1580
+ this.typeExpression = options.typeExpression;
1581
+ this.location = util_1.util.createBoundingLocation(this.tokens.optional, this.tokens.name, this.tokens.as, this.typeExpression);
1582
+ }
1583
+ transpile(state) {
1584
+ throw new Error('Method not implemented.');
1585
+ }
1586
+ get leadingTrivia() {
1587
+ var _a, _b;
1588
+ return (_b = (_a = this.tokens.optional) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : this.tokens.name.leadingTrivia;
1589
+ }
1590
+ get name() {
1591
+ return this.tokens.name.text;
1592
+ }
1593
+ get isOptional() {
1594
+ return !!this.tokens.optional;
1595
+ }
1596
+ walk(visitor, options) {
1597
+ if (options.walkMode & visitors_1.InternalWalkMode.walkExpressions) {
1598
+ (0, visitors_1.walk)(this, 'typeExpression', visitor, options);
1599
+ }
1600
+ }
1601
+ getTypedef(state) {
1602
+ var _a, _b;
1603
+ const result = [];
1604
+ for (let comment of (_a = util_1.util.getLeadingComments(this)) !== null && _a !== void 0 ? _a : []) {
1605
+ result.push(comment.text, state.newline, state.indent());
1606
+ }
1607
+ for (let annotation of (_b = this.annotations) !== null && _b !== void 0 ? _b : []) {
1608
+ result.push(...annotation.getTypedef(state), state.newline, state.indent());
1609
+ }
1610
+ if (this.isOptional) {
1611
+ result.push(this.tokens.optional.text, ' ');
1612
+ }
1613
+ result.push(this.tokens.name.text);
1614
+ if (this.typeExpression) {
1615
+ result.push(' as ', ...this.typeExpression.getTypedef(state));
1616
+ }
1617
+ return result;
1618
+ }
1619
+ getType(options) {
1620
+ var _a, _b;
1621
+ return (_b = (_a = this.typeExpression) === null || _a === void 0 ? void 0 : _a.getType(options)) !== null && _b !== void 0 ? _b : DynamicType_1.DynamicType.instance;
1622
+ }
1623
+ clone() {
1624
+ var _a;
1625
+ return this.finalizeClone(new InterfaceFieldStatement({
1626
+ name: util_1.util.cloneToken(this.tokens.name),
1627
+ as: util_1.util.cloneToken(this.tokens.as),
1628
+ typeExpression: (_a = this.typeExpression) === null || _a === void 0 ? void 0 : _a.clone(),
1629
+ optional: util_1.util.cloneToken(this.tokens.optional)
1630
+ }));
1631
+ }
1632
+ }
1633
+ exports.InterfaceFieldStatement = InterfaceFieldStatement;
1634
+ //TODO: there is much that is similar with this and FunctionExpression.
1635
+ //It would be nice to refactor this so there is less duplicated code
1636
+ class InterfaceMethodStatement extends AstNode_1.Statement {
1637
+ constructor(options) {
1638
+ var _a;
1639
+ super();
1640
+ this.kind = AstNode_1.AstNodeKind.InterfaceMethodStatement;
1641
+ this.tokens = {
1642
+ optional: options.optional,
1643
+ functionType: options.functionType,
1644
+ name: options.name,
1645
+ leftParen: options.leftParen,
1646
+ rightParen: options.rightParen,
1647
+ as: options.as
1648
+ };
1649
+ this.params = (_a = options.params) !== null && _a !== void 0 ? _a : [];
1650
+ this.returnTypeExpression = options.returnTypeExpression;
1651
+ }
1652
+ transpile(state) {
1653
+ throw new Error('Method not implemented.');
1654
+ }
1655
+ get location() {
1656
+ var _a;
1657
+ return util_1.util.createBoundingLocation(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);
1658
+ }
1659
+ /**
1660
+ * Get the name of this method.
1661
+ */
1662
+ getName(parseMode) {
1663
+ return this.tokens.name.text;
1664
+ }
1665
+ get isOptional() {
1666
+ return !!this.tokens.optional;
1667
+ }
1668
+ get leadingTrivia() {
1669
+ var _a, _b;
1670
+ return (_b = (_a = this.tokens.optional) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : this.tokens.functionType.leadingTrivia;
1671
+ }
1672
+ walk(visitor, options) {
1673
+ if (options.walkMode & visitors_1.InternalWalkMode.walkExpressions) {
1674
+ (0, visitors_1.walk)(this, 'returnTypeExpression', visitor, options);
1675
+ }
1676
+ }
1677
+ getTypedef(state) {
1678
+ var _a, _b, _c, _d, _e;
1679
+ const result = [];
1680
+ for (let comment of (_a = util_1.util.getLeadingComments(this)) !== null && _a !== void 0 ? _a : []) {
1681
+ result.push(comment.text, state.newline, state.indent());
1682
+ }
1683
+ for (let annotation of (_b = this.annotations) !== null && _b !== void 0 ? _b : []) {
1684
+ result.push(...annotation.getTypedef(state), state.newline, state.indent());
1685
+ }
1686
+ if (this.isOptional) {
1687
+ result.push(this.tokens.optional.text, ' ');
1688
+ }
1689
+ 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, '(');
1690
+ const params = (_e = this.params) !== null && _e !== void 0 ? _e : [];
1691
+ for (let i = 0; i < params.length; i++) {
1692
+ if (i > 0) {
1693
+ result.push(', ');
1694
+ }
1695
+ const param = params[i];
1696
+ result.push(param.tokens.name.text);
1697
+ if (param.typeExpression) {
1698
+ result.push(' as ', ...param.typeExpression.getTypedef(state));
1699
+ }
1700
+ }
1701
+ result.push(')');
1702
+ if (this.returnTypeExpression) {
1703
+ result.push(' as ', ...this.returnTypeExpression.getTypedef(state));
1704
+ }
1705
+ return result;
1706
+ }
1707
+ getType(options) {
1708
+ var _a, _b, _c, _d;
1709
+ //if there's a defined return type, use that
1710
+ let returnType = (_a = this.returnTypeExpression) === null || _a === void 0 ? void 0 : _a.getType(options);
1711
+ const isSub = ((_b = this.tokens.functionType) === null || _b === void 0 ? void 0 : _b.kind) === TokenKind_1.TokenKind.Sub || !returnType;
1712
+ //if we don't have a return type and this is a sub, set the return type to `void`. else use `dynamic`
1713
+ if (!returnType) {
1714
+ returnType = isSub ? VoidType_1.VoidType.instance : DynamicType_1.DynamicType.instance;
1715
+ }
1716
+ const resultType = new TypedFunctionType_1.TypedFunctionType(returnType);
1717
+ resultType.isSub = isSub;
1718
+ for (let param of this.params) {
1719
+ resultType.addParameter(param.tokens.name.text, param.getType(options), !!param.defaultValue);
1720
+ }
1721
+ if (options.typeChain) {
1722
+ // need Interface type for type chain
1723
+ (_c = this.parent) === null || _c === void 0 ? void 0 : _c.getType(options);
1724
+ }
1725
+ let funcName = this.getName(Parser_1.ParseMode.BrighterScript);
1726
+ resultType.setName(funcName);
1727
+ (_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 }));
1728
+ return resultType;
1729
+ }
1730
+ clone() {
1731
+ var _a, _b;
1732
+ return this.finalizeClone(new InterfaceMethodStatement({
1733
+ optional: util_1.util.cloneToken(this.tokens.optional),
1734
+ functionType: util_1.util.cloneToken(this.tokens.functionType),
1735
+ name: util_1.util.cloneToken(this.tokens.name),
1736
+ leftParen: util_1.util.cloneToken(this.tokens.leftParen),
1737
+ params: (_a = this.params) === null || _a === void 0 ? void 0 : _a.map(p => p === null || p === void 0 ? void 0 : p.clone()),
1738
+ rightParen: util_1.util.cloneToken(this.tokens.rightParen),
1739
+ as: util_1.util.cloneToken(this.tokens.as),
1740
+ returnTypeExpression: (_b = this.returnTypeExpression) === null || _b === void 0 ? void 0 : _b.clone()
1741
+ }), ['params']);
1742
+ }
1743
+ }
1744
+ exports.InterfaceMethodStatement = InterfaceMethodStatement;
1745
+ class ClassStatement extends AstNode_1.Statement {
1746
+ constructor(options) {
1747
+ var _a, _b, _c, _d, _e;
915
1748
  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;
1749
+ this.kind = AstNode_1.AstNodeKind.ClassStatement;
923
1750
  this.memberMap = {};
924
1751
  this.methods = [];
925
1752
  this.fields = [];
926
- this.body = (_a = this.body) !== null && _a !== void 0 ? _a : [];
1753
+ this.body = (_a = options.body) !== null && _a !== void 0 ? _a : [];
1754
+ this.tokens = {
1755
+ name: options.name,
1756
+ class: options.class,
1757
+ endClass: options.endClass,
1758
+ extends: options.extends
1759
+ };
1760
+ this.parentClassName = options.parentClassName;
1761
+ 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(); });
927
1762
  for (let statement of this.body) {
928
- if (reflection_1.isClassMethodStatement(statement)) {
1763
+ if ((0, reflection_1.isMethodStatement)(statement)) {
929
1764
  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;
1765
+ this.memberMap[(_c = statement === null || statement === void 0 ? void 0 : statement.tokens.name) === null || _c === void 0 ? void 0 : _c.text.toLowerCase()] = statement;
931
1766
  }
932
- else if (reflection_1.isClassFieldStatement(statement)) {
1767
+ else if ((0, reflection_1.isFieldStatement)(statement)) {
933
1768
  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;
1769
+ this.memberMap[(_d = statement === null || statement === void 0 ? void 0 : statement.tokens.name) === null || _d === void 0 ? void 0 : _d.text.toLowerCase()] = statement;
935
1770
  }
936
1771
  }
937
- this.range = util_1.util.createRangeFromPositions(this.classKeyword.range.start, this.end.range.end);
1772
+ this.location = util_1.util.createBoundingLocation(this.parentClassName, ...((_e = this.body) !== null && _e !== void 0 ? _e : []), util_1.util.createBoundingLocationFromTokens(this.tokens));
938
1773
  }
939
1774
  getName(parseMode) {
940
1775
  var _a;
941
- const name = (_a = this.name) === null || _a === void 0 ? void 0 : _a.text;
1776
+ const name = (_a = this.tokens.name) === null || _a === void 0 ? void 0 : _a.text;
942
1777
  if (name) {
943
- if (this.namespaceName) {
944
- let namespaceName = this.namespaceName.getName(parseMode);
1778
+ const namespace = this.findAncestor(reflection_1.isNamespaceStatement);
1779
+ if (namespace) {
1780
+ let namespaceName = namespace.getName(parseMode);
945
1781
  let separator = parseMode === Parser_1.ParseMode.BrighterScript ? '.' : '_';
946
1782
  return namespaceName + separator + name;
947
1783
  }
@@ -954,30 +1790,59 @@ class ClassStatement extends Statement {
954
1790
  return undefined;
955
1791
  }
956
1792
  }
1793
+ get leadingTrivia() {
1794
+ var _a;
1795
+ return (_a = this.tokens.class) === null || _a === void 0 ? void 0 : _a.leadingTrivia;
1796
+ }
1797
+ get endTrivia() {
1798
+ var _a, _b;
1799
+ return (_b = (_a = this.tokens.endClass) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
1800
+ }
957
1801
  transpile(state) {
958
1802
  let result = [];
1803
+ const className = this.getName(Parser_1.ParseMode.BrightScript).replace(/\./g, '_');
1804
+ const ancestors = this.getAncestors(state);
1805
+ const body = this.getTranspiledClassBody(ancestors);
1806
+ //make the methods
1807
+ result.push(...this.getTranspiledMethods(state, className, body));
959
1808
  //make the builder
960
- result.push(...this.getTranspiledBuilder(state));
1809
+ result.push(...this.getTranspiledBuilder(state, className, ancestors, body));
961
1810
  result.push('\n', state.indent());
962
1811
  //make the class assembler (i.e. the public-facing class creator method)
963
- result.push(...this.getTranspiledClassFunction(state));
1812
+ result.push(...this.getTranspiledClassFunction(state, className));
964
1813
  return result;
965
1814
  }
966
1815
  getTypedef(state) {
967
1816
  var _a, _b;
968
1817
  const result = [];
969
- for (let annotation of (_a = this.annotations) !== null && _a !== void 0 ? _a : []) {
1818
+ for (let comment of (_a = util_1.util.getLeadingComments(this)) !== null && _a !== void 0 ? _a : []) {
1819
+ result.push(comment.text, state.newline, state.indent());
1820
+ }
1821
+ for (let annotation of (_b = this.annotations) !== null && _b !== void 0 ? _b : []) {
970
1822
  result.push(...annotation.getTypedef(state), state.newline, state.indent());
971
1823
  }
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));
1824
+ result.push('class ', this.tokens.name.text);
1825
+ if (this.parentClassName) {
1826
+ const namespace = this.findAncestor(reflection_1.isNamespaceStatement);
1827
+ const fqName = util_1.util.getFullyQualifiedClassName(this.parentClassName.getName(), namespace === null || namespace === void 0 ? void 0 : namespace.getName(Parser_1.ParseMode.BrighterScript));
975
1828
  result.push(` extends ${fqName}`);
976
1829
  }
977
1830
  result.push(state.newline);
978
1831
  state.blockDepth++;
979
- for (const member of this.body) {
980
- if ('getTypedef' in member) {
1832
+ let body = this.body;
1833
+ //inject an empty "new" method if missing
1834
+ if (!this.getConstructorFunction()) {
1835
+ const constructor = (0, creators_1.createMethodStatement)('new', TokenKind_1.TokenKind.Sub);
1836
+ constructor.parent = this;
1837
+ //walk the constructor to set up parent links
1838
+ constructor.link();
1839
+ body = [
1840
+ constructor,
1841
+ ...this.body
1842
+ ];
1843
+ }
1844
+ for (const member of body) {
1845
+ if ((0, reflection_1.isTypedefProvider)(member)) {
981
1846
  result.push(state.indent(), ...member.getTypedef(state), state.newline);
982
1847
  }
983
1848
  }
@@ -991,20 +1856,27 @@ class ClassStatement extends Statement {
991
1856
  * The base class is index 0, its child is index 1, and so on.
992
1857
  */
993
1858
  getParentClassIndex(state) {
994
- var _a, _b;
1859
+ var _a;
995
1860
  let myIndex = 0;
996
1861
  let stmt = this;
997
1862
  while (stmt) {
998
1863
  if (stmt.parentClassName) {
1864
+ const namespace = stmt.findAncestor(reflection_1.isNamespaceStatement);
999
1865
  //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;
1866
+ 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;
1001
1867
  myIndex++;
1002
1868
  }
1003
1869
  else {
1004
1870
  break;
1005
1871
  }
1006
1872
  }
1007
- return myIndex - 1;
1873
+ const result = myIndex - 1;
1874
+ if (result >= 0) {
1875
+ return result;
1876
+ }
1877
+ else {
1878
+ return null;
1879
+ }
1008
1880
  }
1009
1881
  hasParentClass() {
1010
1882
  return !!this.parentClassName;
@@ -1014,12 +1886,13 @@ class ClassStatement extends Statement {
1014
1886
  * This will return an empty array if no ancestors were found
1015
1887
  */
1016
1888
  getAncestors(state) {
1017
- var _a, _b;
1889
+ var _a;
1018
1890
  let ancestors = [];
1019
1891
  let stmt = this;
1020
1892
  while (stmt) {
1021
1893
  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;
1894
+ const namespace = stmt.findAncestor(reflection_1.isNamespaceStatement);
1895
+ 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;
1023
1896
  ancestors.push(stmt);
1024
1897
  }
1025
1898
  else {
@@ -1028,33 +1901,40 @@ class ClassStatement extends Statement {
1028
1901
  }
1029
1902
  return ancestors;
1030
1903
  }
1031
- getBuilderName(name) {
1032
- if (name.includes('.')) {
1033
- name = name.replace(/\./gi, '_');
1034
- }
1035
- return `__${name}_builder`;
1904
+ getBuilderName(transpiledClassName) {
1905
+ return `__${transpiledClassName}_builder`;
1906
+ }
1907
+ getMethodIdentifier(transpiledClassName, statement) {
1908
+ return Object.assign(Object.assign({}, statement.tokens.name), { text: `__${transpiledClassName}_method_${statement.tokens.name.text}` });
1909
+ }
1910
+ getConstructorType() {
1911
+ var _a, _b;
1912
+ 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);
1913
+ constructorType.returnType = this.getType({ flags: 1 /* SymbolTypeFlag.runtime */ });
1914
+ return constructorType;
1036
1915
  }
1037
1916
  /**
1038
1917
  * Get the constructor function for this class (if exists), or undefined if not exist
1039
1918
  */
1040
1919
  getConstructorFunction() {
1041
- 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;
1920
+ return this.body.find((stmt) => {
1921
+ var _a, _b;
1922
+ 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';
1923
+ });
1924
+ }
1925
+ /**
1926
+ * Return the parameters for the first constructor function for this class
1927
+ * @param ancestors The list of ancestors for this class
1928
+ * @returns The parameters for the first constructor function for this class
1929
+ */
1930
+ getConstructorParams(ancestors) {
1931
+ for (let ancestor of ancestors) {
1932
+ const ctor = ancestor === null || ancestor === void 0 ? void 0 : ancestor.getConstructorFunction();
1933
+ if (ctor) {
1934
+ return ctor.func.parameters;
1046
1935
  }
1047
1936
  }
1048
- }
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;
1937
+ return [];
1058
1938
  }
1059
1939
  /**
1060
1940
  * Determine if the specified field was declared in one of the ancestor classes
@@ -1073,21 +1953,18 @@ class ClassStatement extends Statement {
1073
1953
  * This needs to be a separate function so that child classes can call the builder from their parent
1074
1954
  * without instantiating the parent constructor at that point in time.
1075
1955
  */
1076
- getTranspiledBuilder(state) {
1077
- var _a;
1956
+ getTranspiledBuilder(state, transpiledClassName, ancestors, body) {
1957
+ var _a, _b;
1078
1958
  let result = [];
1079
- result.push(`function ${this.getBuilderName(this.getName(Parser_1.ParseMode.BrightScript))}()\n`);
1959
+ result.push(`function ${this.getBuilderName(transpiledClassName)}()\n`);
1080
1960
  state.blockDepth++;
1081
1961
  //indent
1082
1962
  result.push(state.indent());
1083
- /**
1084
- * The lineage of this class. index 0 is a direct parent, index 1 is index 0's parent, etc...
1085
- */
1086
- let ancestors = this.getAncestors(state);
1087
1963
  //construct parent class or empty object
1088
1964
  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));
1090
- result.push('instance = ', this.getBuilderName(fullyQualifiedClassName), '()');
1965
+ const ancestorNamespace = ancestors[0].findAncestor(reflection_1.isNamespaceStatement);
1966
+ 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));
1967
+ result.push(`instance = ${this.getBuilderName(fullyQualifiedClassName.replace(/\./g, '_'))}()`);
1091
1968
  }
1092
1969
  else {
1093
1970
  //use an empty object.
@@ -1095,29 +1972,30 @@ class ClassStatement extends Statement {
1095
1972
  }
1096
1973
  result.push(state.newline, state.indent());
1097
1974
  let parentClassIndex = this.getParentClassIndex(state);
1098
- //create empty `new` function if class is missing it (simplifies transpile logic)
1099
- if (!this.getConstructorFunction()) {
1100
- this.memberMap.new = this.getEmptyNewFunction();
1101
- this.body = [this.memberMap.new, ...this.body];
1102
- }
1103
- for (let statement of this.body) {
1975
+ for (let statement of body) {
1104
1976
  //is field statement
1105
- if (reflection_1.isClassFieldStatement(statement)) {
1977
+ if ((0, reflection_1.isFieldStatement)(statement)) {
1106
1978
  //do nothing with class fields in this situation, they are handled elsewhere
1107
1979
  continue;
1108
1980
  //methods
1109
1981
  }
1110
- else if (reflection_1.isClassMethodStatement(statement)) {
1982
+ else if ((0, reflection_1.isMethodStatement)(statement)) {
1111
1983
  //store overridden parent methods as super{parentIndex}_{methodName}
1112
1984
  if (
1113
1985
  //is override method
1114
- statement.override ||
1986
+ statement.tokens.override ||
1115
1987
  //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());
1988
+ (statement.tokens.name.text.toLowerCase() === 'new' && ancestors[0])) {
1989
+ result.push(`instance.super${parentClassIndex}_${statement.tokens.name.text} = instance.${statement.tokens.name.text}`, state.newline, state.indent());
1118
1990
  }
1119
1991
  state.classStatement = this;
1120
- result.push('instance.', state.transpileToken(statement.name), ' = ', ...statement.transpile(state), state.newline, state.indent());
1992
+ state.skipLeadingComments = true;
1993
+ //add leading comments
1994
+ if (((_b = (_a = statement.leadingTrivia) === null || _a === void 0 ? void 0 : _a.filter(token => token.kind === TokenKind_1.TokenKind.Comment)) !== null && _b !== void 0 ? _b : []).length > 0) {
1995
+ result.push(...state.transpileComments(statement.leadingTrivia), state.indent());
1996
+ }
1997
+ result.push('instance.', state.transpileToken(statement.tokens.name), ' = ', state.transpileToken(this.getMethodIdentifier(transpiledClassName, statement)), state.newline, state.indent());
1998
+ state.skipLeadingComments = false;
1121
1999
  delete state.classStatement;
1122
2000
  }
1123
2001
  else {
@@ -1132,16 +2010,79 @@ class ClassStatement extends Statement {
1132
2010
  result.push(`end function`);
1133
2011
  return result;
1134
2012
  }
2013
+ /**
2014
+ * Returns a copy of the class' body, with the constructor function added if it doesn't exist.
2015
+ */
2016
+ getTranspiledClassBody(ancestors) {
2017
+ const body = [];
2018
+ body.push(...this.body);
2019
+ //inject an empty "new" method if missing
2020
+ if (!this.getConstructorFunction()) {
2021
+ if (ancestors.length === 0) {
2022
+ body.unshift((0, creators_1.createMethodStatement)('new', TokenKind_1.TokenKind.Sub));
2023
+ }
2024
+ else {
2025
+ const params = this.getConstructorParams(ancestors);
2026
+ const call = new ExpressionStatement({
2027
+ expression: new Expression_2.CallExpression({
2028
+ callee: new Expression_2.VariableExpression({
2029
+ name: (0, creators_1.createToken)(TokenKind_1.TokenKind.Identifier, 'super')
2030
+ }),
2031
+ openingParen: (0, creators_1.createToken)(TokenKind_1.TokenKind.LeftParen),
2032
+ args: params.map(x => new Expression_2.VariableExpression({
2033
+ name: x.tokens.name
2034
+ })),
2035
+ closingParen: (0, creators_1.createToken)(TokenKind_1.TokenKind.RightParen)
2036
+ })
2037
+ });
2038
+ body.unshift(new MethodStatement({
2039
+ modifiers: [],
2040
+ name: (0, creators_1.createIdentifier)('new'),
2041
+ func: new Expression_1.FunctionExpression({
2042
+ parameters: params.map(x => x.clone()),
2043
+ body: new Block({ statements: [call] }),
2044
+ functionType: (0, creators_1.createToken)(TokenKind_1.TokenKind.Sub),
2045
+ endFunctionType: (0, creators_1.createToken)(TokenKind_1.TokenKind.EndSub),
2046
+ leftParen: (0, creators_1.createToken)(TokenKind_1.TokenKind.LeftParen),
2047
+ rightParen: (0, creators_1.createToken)(TokenKind_1.TokenKind.RightParen)
2048
+ }),
2049
+ override: null
2050
+ }));
2051
+ }
2052
+ }
2053
+ return body;
2054
+ }
2055
+ /**
2056
+ * These are the methods that are defined in this class. They are transpiled outside of the class body
2057
+ * to ensure they don't appear as "$anon_#" in stack traces and crash logs.
2058
+ */
2059
+ getTranspiledMethods(state, transpiledClassName, body) {
2060
+ let result = [];
2061
+ for (let statement of body) {
2062
+ if ((0, reflection_1.isMethodStatement)(statement)) {
2063
+ state.classStatement = this;
2064
+ result.push(...statement.transpile(state, this.getMethodIdentifier(transpiledClassName, statement)), state.newline, state.indent());
2065
+ delete state.classStatement;
2066
+ }
2067
+ }
2068
+ return result;
2069
+ }
1135
2070
  /**
1136
2071
  * The class function is the function with the same name as the class. This is the function that
1137
2072
  * consumers should call to create a new instance of that class.
1138
2073
  * This invokes the builder, gets an instance of the class, then invokes the "new" function on that class.
1139
2074
  */
1140
- getTranspiledClassFunction(state) {
1141
- let result = [];
2075
+ getTranspiledClassFunction(state, transpiledClassName) {
2076
+ let result = state.transpileAnnotations(this);
1142
2077
  const constructorFunction = this.getConstructorFunction();
1143
- 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)), `(`);
2078
+ let constructorParams = [];
2079
+ if (constructorFunction) {
2080
+ constructorParams = constructorFunction.func.parameters;
2081
+ }
2082
+ else {
2083
+ constructorParams = this.getConstructorParams(this.getAncestors(state));
2084
+ }
2085
+ result.push(state.transpileLeadingComments(this.tokens.class), state.sourceNode(this.tokens.class, 'function'), state.sourceNode(this.tokens.class, ' '), state.sourceNode(this.tokens.name, this.getName(Parser_1.ParseMode.BrightScript)), `(`);
1145
2086
  let i = 0;
1146
2087
  for (let param of constructorParams) {
1147
2088
  if (i > 0) {
@@ -1153,7 +2094,7 @@ class ClassStatement extends Statement {
1153
2094
  result.push(')', '\n');
1154
2095
  state.blockDepth++;
1155
2096
  result.push(state.indent());
1156
- result.push(`instance = ${this.getBuilderName(this.getName(Parser_1.ParseMode.BrightScript))}()\n`);
2097
+ result.push(`instance = ${this.getBuilderName(transpiledClassName)}()\n`);
1157
2098
  result.push(state.indent());
1158
2099
  result.push(`instance.new(`);
1159
2100
  //append constructor arguments
@@ -1162,7 +2103,7 @@ class ClassStatement extends Statement {
1162
2103
  if (i > 0) {
1163
2104
  result.push(', ');
1164
2105
  }
1165
- result.push(state.transpileToken(param.name));
2106
+ result.push(state.transpileToken(param.tokens.name));
1166
2107
  i++;
1167
2108
  }
1168
2109
  result.push(')', '\n');
@@ -1174,24 +2115,92 @@ class ClassStatement extends Statement {
1174
2115
  return result;
1175
2116
  }
1176
2117
  walk(visitor, options) {
2118
+ //visitor-less walk function to do parent linking
2119
+ (0, visitors_1.walk)(this, 'parentClassName', null, options);
1177
2120
  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);
2121
+ (0, visitors_1.walkArray)(this.body, visitor, options, this);
2122
+ }
2123
+ }
2124
+ getType(options) {
2125
+ var _a, _b, _c, _d, _e, _f, _g, _h;
2126
+ const superClass = (_a = this.parentClassName) === null || _a === void 0 ? void 0 : _a.getType(options);
2127
+ const resultType = new ClassType_1.ClassType(this.getName(Parser_1.ParseMode.BrighterScript), superClass);
2128
+ for (const statement of this.methods) {
2129
+ const funcType = statement === null || statement === void 0 ? void 0 : statement.func.getType(Object.assign(Object.assign({}, options), { typeChain: undefined })); //no typechain needed
2130
+ let flag = 1 /* SymbolTypeFlag.runtime */;
2131
+ if (((_b = statement.accessModifier) === null || _b === void 0 ? void 0 : _b.kind) === TokenKind_1.TokenKind.Private) {
2132
+ flag |= 8 /* SymbolTypeFlag.private */;
2133
+ }
2134
+ if (((_c = statement.accessModifier) === null || _c === void 0 ? void 0 : _c.kind) === TokenKind_1.TokenKind.Protected) {
2135
+ flag |= 16 /* SymbolTypeFlag.protected */;
2136
+ }
2137
+ 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);
2138
+ }
2139
+ for (const statement of this.fields) {
2140
+ const fieldType = statement.getType(Object.assign(Object.assign({}, options), { typeChain: undefined })); //no typechain needed
2141
+ let flag = 1 /* SymbolTypeFlag.runtime */;
2142
+ if (statement.isOptional) {
2143
+ flag |= 4 /* SymbolTypeFlag.optional */;
1180
2144
  }
2145
+ if (((_e = statement.tokens.accessModifier) === null || _e === void 0 ? void 0 : _e.kind) === TokenKind_1.TokenKind.Private) {
2146
+ flag |= 8 /* SymbolTypeFlag.private */;
2147
+ }
2148
+ if (((_f = statement.tokens.accessModifier) === null || _f === void 0 ? void 0 : _f.kind) === TokenKind_1.TokenKind.Protected) {
2149
+ flag |= 16 /* SymbolTypeFlag.protected */;
2150
+ }
2151
+ 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);
1181
2152
  }
2153
+ (_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 }));
2154
+ return resultType;
2155
+ }
2156
+ clone() {
2157
+ var _a, _b;
2158
+ return this.finalizeClone(new ClassStatement({
2159
+ class: util_1.util.cloneToken(this.tokens.class),
2160
+ name: util_1.util.cloneToken(this.tokens.name),
2161
+ body: (_a = this.body) === null || _a === void 0 ? void 0 : _a.map(x => x === null || x === void 0 ? void 0 : x.clone()),
2162
+ endClass: util_1.util.cloneToken(this.tokens.endClass),
2163
+ extends: util_1.util.cloneToken(this.tokens.extends),
2164
+ parentClassName: (_b = this.parentClassName) === null || _b === void 0 ? void 0 : _b.clone()
2165
+ }), ['body', 'parentClassName']);
1182
2166
  }
1183
2167
  }
1184
2168
  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);
2169
+ const accessModifiers = [
2170
+ TokenKind_1.TokenKind.Public,
2171
+ TokenKind_1.TokenKind.Protected,
2172
+ TokenKind_1.TokenKind.Private
2173
+ ];
2174
+ class MethodStatement extends FunctionStatement {
2175
+ constructor(options) {
2176
+ super(options);
2177
+ this.kind = AstNode_1.AstNodeKind.MethodStatement;
2178
+ this.modifiers = [];
2179
+ if (options.modifiers) {
2180
+ if (Array.isArray(options.modifiers)) {
2181
+ this.modifiers.push(...options.modifiers);
2182
+ }
2183
+ else {
2184
+ this.modifiers.push(options.modifiers);
2185
+ }
2186
+ }
2187
+ this.tokens = Object.assign(Object.assign({}, this.tokens), { override: options.override });
2188
+ this.location = util_1.util.createBoundingLocation(...(this.modifiers), util_1.util.createBoundingLocationFromTokens(this.tokens), this.func);
1192
2189
  }
1193
- transpile(state) {
1194
- if (this.name.text.toLowerCase() === 'new') {
2190
+ get accessModifier() {
2191
+ return this.modifiers.find(x => accessModifiers.includes(x.kind));
2192
+ }
2193
+ /**
2194
+ * Get the name of this method.
2195
+ */
2196
+ getName(parseMode) {
2197
+ return this.tokens.name.text;
2198
+ }
2199
+ get leadingTrivia() {
2200
+ return this.func.leadingTrivia;
2201
+ }
2202
+ transpile(state, name) {
2203
+ if (this.tokens.name.text.toLowerCase() === 'new') {
1195
2204
  this.ensureSuperConstructorCall(state);
1196
2205
  //TODO we need to undo this at the bottom of this method
1197
2206
  this.injectFieldInitializersForConstructor(state);
@@ -1199,18 +2208,18 @@ class ClassMethodStatement extends FunctionStatement {
1199
2208
  //TODO - remove type information from these methods because that doesn't work
1200
2209
  //convert the `super` calls into the proper methods
1201
2210
  const parentClassIndex = state.classStatement.getParentClassIndex(state);
1202
- const visitor = visitors_1.createVisitor({
2211
+ const visitor = (0, visitors_1.createVisitor)({
1203
2212
  VariableExpression: e => {
1204
- if (e.name.text.toLocaleLowerCase() === 'super') {
1205
- e.name.text = `m.super${parentClassIndex}_new`;
2213
+ if (e.tokens.name.text.toLocaleLowerCase() === 'super') {
2214
+ state.editor.setProperty(e.tokens.name, 'text', `m.super${parentClassIndex}_new`);
1206
2215
  }
1207
2216
  },
1208
2217
  DottedGetExpression: e => {
1209
2218
  const beginningVariable = util_1.util.findBeginningVariableExpression(e);
1210
2219
  const lowerName = beginningVariable === null || beginningVariable === void 0 ? void 0 : beginningVariable.getName(Parser_1.ParseMode.BrighterScript).toLowerCase();
1211
2220
  if (lowerName === 'super') {
1212
- beginningVariable.name.text = 'm';
1213
- e.name.text = `super${parentClassIndex}_${e.name.text}`;
2221
+ state.editor.setProperty(beginningVariable.tokens.name, 'text', 'm');
2222
+ state.editor.setProperty(e.tokens.name, 'text', `super${parentClassIndex}_${e.tokens.name.text}`);
1214
2223
  }
1215
2224
  }
1216
2225
  });
@@ -1219,21 +2228,24 @@ class ClassMethodStatement extends FunctionStatement {
1219
2228
  visitor(statement, undefined);
1220
2229
  statement.walk(visitor, walkOptions);
1221
2230
  }
1222
- return this.func.transpile(state);
2231
+ return this.func.transpile(state, name);
1223
2232
  }
1224
2233
  getTypedef(state) {
1225
- var _a;
2234
+ var _a, _b;
1226
2235
  const result = [];
1227
- for (let annotation of (_a = this.annotations) !== null && _a !== void 0 ? _a : []) {
2236
+ for (let comment of (_a = util_1.util.getLeadingComments(this)) !== null && _a !== void 0 ? _a : []) {
2237
+ result.push(comment.text, state.newline, state.indent());
2238
+ }
2239
+ for (let annotation of (_b = this.annotations) !== null && _b !== void 0 ? _b : []) {
1228
2240
  result.push(...annotation.getTypedef(state), state.newline, state.indent());
1229
2241
  }
1230
2242
  if (this.accessModifier) {
1231
2243
  result.push(this.accessModifier.text, ' ');
1232
2244
  }
1233
- if (this.override) {
2245
+ if (this.tokens.override) {
1234
2246
  result.push('override ');
1235
2247
  }
1236
- result.push(...this.func.getTypedef(state, this.name));
2248
+ result.push(...this.func.getTypedef(state));
1237
2249
  return result;
1238
2250
  }
1239
2251
  /**
@@ -1245,163 +2257,283 @@ class ClassMethodStatement extends FunctionStatement {
1245
2257
  if (state.classStatement.getAncestors(state).length === 0) {
1246
2258
  return;
1247
2259
  }
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') {
2260
+ //check whether any calls to super exist
2261
+ let containsSuperCall = this.func.body.statements.findIndex((x) => {
2262
+ var _a;
2263
+ //is a call statement
2264
+ return (0, reflection_1.isExpressionStatement)(x) && (0, reflection_1.isCallExpression)(x.expression) &&
2265
+ //is a call to super
2266
+ ((_a = util_1.util.findBeginningVariableExpression(x.expression.callee).tokens.name) === null || _a === void 0 ? void 0 : _a.text.toLowerCase()) === 'super';
2267
+ }) !== -1;
2268
+ //if a call to super exists, quit here
2269
+ if (containsSuperCall) {
1255
2270
  return;
1256
2271
  }
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)));
2272
+ //this is a child class, and the constructor doesn't contain a call to super. Inject one
2273
+ const superCall = new ExpressionStatement({
2274
+ expression: new Expression_2.CallExpression({
2275
+ callee: new Expression_2.VariableExpression({
2276
+ name: {
2277
+ kind: TokenKind_1.TokenKind.Identifier,
2278
+ text: 'super',
2279
+ isReserved: false,
2280
+ location: state.classStatement.tokens.name.location,
2281
+ leadingWhitespace: '',
2282
+ leadingTrivia: []
2283
+ }
2284
+ }),
2285
+ openingParen: {
2286
+ kind: TokenKind_1.TokenKind.LeftParen,
2287
+ text: '(',
2288
+ isReserved: false,
2289
+ location: state.classStatement.tokens.name.location,
2290
+ leadingWhitespace: '',
2291
+ leadingTrivia: []
2292
+ },
2293
+ closingParen: {
2294
+ kind: TokenKind_1.TokenKind.RightParen,
2295
+ text: ')',
2296
+ isReserved: false,
2297
+ location: state.classStatement.tokens.name.location,
2298
+ leadingWhitespace: '',
2299
+ leadingTrivia: []
2300
+ },
2301
+ args: []
2302
+ })
2303
+ });
2304
+ state.editor.arrayUnshift(this.func.body.statements, superCall);
1277
2305
  }
1278
2306
  /**
1279
2307
  * Inject field initializers at the top of the `new` function (after any present `super()` call)
1280
2308
  */
1281
2309
  injectFieldInitializersForConstructor(state) {
2310
+ var _a;
1282
2311
  let startingIndex = state.classStatement.hasParentClass() ? 1 : 0;
1283
2312
  let newStatements = [];
1284
2313
  //insert the field initializers in order
1285
2314
  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);
2315
+ let thisQualifiedName = Object.assign({}, field.tokens.name);
2316
+ thisQualifiedName.text = 'm.' + ((_a = field.tokens.name) === null || _a === void 0 ? void 0 : _a.text);
2317
+ const fieldAssignment = field.initialValue
2318
+ ? new AssignmentStatement({
2319
+ equals: field.tokens.equals,
2320
+ name: thisQualifiedName,
2321
+ value: field.initialValue
2322
+ })
2323
+ : new AssignmentStatement({
2324
+ equals: (0, creators_1.createToken)(TokenKind_1.TokenKind.Equal, '=', field.tokens.name.location),
2325
+ name: thisQualifiedName,
2326
+ //if there is no initial value, set the initial value to `invalid`
2327
+ value: (0, creators_1.createInvalidLiteral)('invalid', field.tokens.name.location)
2328
+ });
2329
+ // Add parent so namespace lookups work
2330
+ fieldAssignment.parent = state.classStatement;
2331
+ newStatements.push(fieldAssignment);
2332
+ }
2333
+ state.editor.arraySplice(this.func.body.statements, startingIndex, 0, ...newStatements);
1297
2334
  }
1298
2335
  walk(visitor, options) {
1299
2336
  if (options.walkMode & visitors_1.InternalWalkMode.walkExpressions) {
1300
- visitors_1.walk(this, 'func', visitor, options);
2337
+ (0, visitors_1.walk)(this, 'func', visitor, options);
1301
2338
  }
1302
2339
  }
2340
+ clone() {
2341
+ var _a, _b;
2342
+ return this.finalizeClone(new MethodStatement({
2343
+ modifiers: (_a = this.modifiers) === null || _a === void 0 ? void 0 : _a.map(m => util_1.util.cloneToken(m)),
2344
+ name: util_1.util.cloneToken(this.tokens.name),
2345
+ func: (_b = this.func) === null || _b === void 0 ? void 0 : _b.clone(),
2346
+ override: util_1.util.cloneToken(this.tokens.override)
2347
+ }), ['func']);
2348
+ }
1303
2349
  }
1304
- exports.ClassMethodStatement = ClassMethodStatement;
1305
- class ClassFieldStatement extends Statement {
1306
- constructor(accessModifier, name, as, type, equal, initialValue) {
1307
- var _a, _b, _c, _d;
2350
+ exports.MethodStatement = MethodStatement;
2351
+ class FieldStatement extends AstNode_1.Statement {
2352
+ constructor(options) {
1308
2353
  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);
2354
+ this.kind = AstNode_1.AstNodeKind.FieldStatement;
2355
+ this.tokens = {
2356
+ accessModifier: options.accessModifier,
2357
+ name: options.name,
2358
+ as: options.as,
2359
+ equals: options.equals,
2360
+ optional: options.optional
2361
+ };
2362
+ this.typeExpression = options.typeExpression;
2363
+ this.initialValue = options.initialValue;
2364
+ this.location = util_1.util.createBoundingLocation(util_1.util.createBoundingLocationFromTokens(this.tokens), this.typeExpression, this.initialValue);
1316
2365
  }
1317
2366
  /**
1318
2367
  * Derive a ValueKind from the type token, or the initial value.
1319
2368
  * Defaults to `DynamicType`
1320
2369
  */
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();
2370
+ getType(options) {
2371
+ var _a, _b, _c, _d;
2372
+ let initialValueType = (_a = this.initialValue) === null || _a === void 0 ? void 0 : _a.getType(Object.assign(Object.assign({}, options), { flags: 1 /* SymbolTypeFlag.runtime */ }));
2373
+ if ((0, reflection_1.isInvalidType)(initialValueType) || (0, reflection_1.isVoidType)(initialValueType) || (0, reflection_1.isUninitializedType)(initialValueType)) {
2374
+ initialValueType = undefined;
1330
2375
  }
2376
+ return (_d = (_c = (_b = this.typeExpression) === null || _b === void 0 ? void 0 : _b.getType(Object.assign(Object.assign({}, options), { flags: 2 /* SymbolTypeFlag.typetime */ }))) !== null && _c !== void 0 ? _c : util_1.util.getDefaultTypeFromValueType(initialValueType)) !== null && _d !== void 0 ? _d : DynamicType_1.DynamicType.instance;
2377
+ }
2378
+ get leadingTrivia() {
2379
+ var _a, _b, _c, _d;
2380
+ return (_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 : this.tokens.name.leadingTrivia;
2381
+ }
2382
+ get isOptional() {
2383
+ return !!this.tokens.optional;
1331
2384
  }
1332
2385
  transpile(state) {
1333
2386
  throw new Error('transpile not implemented for ' + Object.getPrototypeOf(this).constructor.name);
1334
2387
  }
1335
2388
  getTypedef(state) {
1336
- var _a, _b, _c, _d;
2389
+ var _a, _b, _c, _d, _e;
1337
2390
  const result = [];
1338
- if (this.name) {
1339
- for (let annotation of (_a = this.annotations) !== null && _a !== void 0 ? _a : []) {
2391
+ if (this.tokens.name) {
2392
+ for (let comment of (_a = util_1.util.getLeadingComments(this)) !== null && _a !== void 0 ? _a : []) {
2393
+ result.push(comment.text, state.newline, state.indent());
2394
+ }
2395
+ for (let annotation of (_b = this.annotations) !== null && _b !== void 0 ? _b : []) {
1340
2396
  result.push(...annotation.getTypedef(state), state.newline, state.indent());
1341
2397
  }
1342
- let type = this.getType();
1343
- if (reflection_1.isInvalidType(type) || reflection_1.isVoidType(type)) {
1344
- type = new DynamicType_1.DynamicType();
2398
+ let type = this.getType({ flags: 2 /* SymbolTypeFlag.typetime */ });
2399
+ if ((0, reflection_1.isInvalidType)(type) || (0, reflection_1.isVoidType)(type) || (0, reflection_1.isUninitializedType)(type)) {
2400
+ type = DynamicType_1.DynamicType.instance;
1345
2401
  }
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());
2402
+ result.push((_d = (_c = this.tokens.accessModifier) === null || _c === void 0 ? void 0 : _c.text) !== null && _d !== void 0 ? _d : 'public', ' ');
2403
+ if (this.isOptional) {
2404
+ result.push(this.tokens.optional.text, ' ');
2405
+ }
2406
+ result.push((_e = this.tokens.name) === null || _e === void 0 ? void 0 : _e.text, ' as ', type.toTypeString());
1347
2407
  }
1348
2408
  return result;
1349
2409
  }
1350
2410
  walk(visitor, options) {
1351
- if (this.initialValue && options.walkMode & visitors_1.InternalWalkMode.walkExpressions) {
1352
- visitors_1.walk(this, 'initialValue', visitor, options);
2411
+ if (options.walkMode & visitors_1.InternalWalkMode.walkExpressions) {
2412
+ (0, visitors_1.walk)(this, 'typeExpression', visitor, options);
2413
+ (0, visitors_1.walk)(this, 'initialValue', visitor, options);
1353
2414
  }
1354
2415
  }
2416
+ clone() {
2417
+ var _a, _b;
2418
+ return this.finalizeClone(new FieldStatement({
2419
+ accessModifier: util_1.util.cloneToken(this.tokens.accessModifier),
2420
+ name: util_1.util.cloneToken(this.tokens.name),
2421
+ as: util_1.util.cloneToken(this.tokens.as),
2422
+ typeExpression: (_a = this.typeExpression) === null || _a === void 0 ? void 0 : _a.clone(),
2423
+ equals: util_1.util.cloneToken(this.tokens.equals),
2424
+ initialValue: (_b = this.initialValue) === null || _b === void 0 ? void 0 : _b.clone(),
2425
+ optional: util_1.util.cloneToken(this.tokens.optional)
2426
+ }), ['initialValue']);
2427
+ }
1355
2428
  }
1356
- exports.ClassFieldStatement = ClassFieldStatement;
1357
- class TryCatchStatement extends Statement {
1358
- constructor(tryToken, tryBranch, catchToken, exceptionVariable, catchBranch, endTryToken) {
2429
+ exports.FieldStatement = FieldStatement;
2430
+ class TryCatchStatement extends AstNode_1.Statement {
2431
+ constructor(options) {
1359
2432
  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);
2433
+ this.kind = AstNode_1.AstNodeKind.TryCatchStatement;
2434
+ this.tokens = {
2435
+ try: options.try,
2436
+ endTry: options.endTry
2437
+ };
2438
+ this.tryBranch = options.tryBranch;
2439
+ this.catchStatement = options.catchStatement;
2440
+ this.location = util_1.util.createBoundingLocation(this.tokens.try, this.tryBranch, this.catchStatement, this.tokens.endTry);
1370
2441
  }
1371
2442
  transpile(state) {
2443
+ var _a, _b;
1372
2444
  return [
1373
- state.transpileToken(this.tryToken),
2445
+ state.transpileToken(this.tokens.try, 'try'),
1374
2446
  ...this.tryBranch.transpile(state),
1375
2447
  state.newline,
1376
2448
  state.indent(),
1377
- state.transpileToken(this.catchToken),
1378
- ' ',
1379
- state.transpileToken(this.exceptionVariable),
1380
- ...this.catchBranch.transpile(state),
2449
+ ...((_b = (_a = this.catchStatement) === null || _a === void 0 ? void 0 : _a.transpile(state)) !== null && _b !== void 0 ? _b : ['catch']),
1381
2450
  state.newline,
1382
2451
  state.indent(),
1383
- state.transpileToken(this.endTryToken)
2452
+ state.transpileToken(this.tokens.endTry, 'end try')
1384
2453
  ];
1385
2454
  }
1386
2455
  walk(visitor, options) {
1387
2456
  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);
2457
+ (0, visitors_1.walk)(this, 'tryBranch', visitor, options);
2458
+ (0, visitors_1.walk)(this, 'catchStatement', visitor, options);
1390
2459
  }
1391
2460
  }
2461
+ get leadingTrivia() {
2462
+ var _a, _b;
2463
+ return (_b = (_a = this.tokens.try) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
2464
+ }
2465
+ get endTrivia() {
2466
+ var _a, _b;
2467
+ return (_b = (_a = this.tokens.endTry) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
2468
+ }
2469
+ clone() {
2470
+ var _a, _b;
2471
+ return this.finalizeClone(new TryCatchStatement({
2472
+ try: util_1.util.cloneToken(this.tokens.try),
2473
+ endTry: util_1.util.cloneToken(this.tokens.endTry),
2474
+ tryBranch: (_a = this.tryBranch) === null || _a === void 0 ? void 0 : _a.clone(),
2475
+ catchStatement: (_b = this.catchStatement) === null || _b === void 0 ? void 0 : _b.clone()
2476
+ }), ['tryBranch', 'catchStatement']);
2477
+ }
1392
2478
  }
1393
2479
  exports.TryCatchStatement = TryCatchStatement;
1394
- class ThrowStatement extends Statement {
1395
- constructor(throwToken, expression) {
1396
- var _a;
2480
+ class CatchStatement extends AstNode_1.Statement {
2481
+ constructor(options) {
1397
2482
  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);
2483
+ this.kind = AstNode_1.AstNodeKind.CatchStatement;
2484
+ this.tokens = {
2485
+ catch: options === null || options === void 0 ? void 0 : options.catch
2486
+ };
2487
+ this.exceptionVariableExpression = options === null || options === void 0 ? void 0 : options.exceptionVariableExpression;
2488
+ this.catchBranch = options === null || options === void 0 ? void 0 : options.catchBranch;
2489
+ this.location = util_1.util.createBoundingLocation(this.tokens.catch, this.exceptionVariableExpression, this.catchBranch);
2490
+ }
2491
+ transpile(state) {
2492
+ var _a, _b, _c, _d, _e;
2493
+ return [
2494
+ state.transpileToken(this.tokens.catch, 'catch'),
2495
+ ' ',
2496
+ (_b = (_a = this.exceptionVariableExpression) === null || _a === void 0 ? void 0 : _a.transpile(state)) !== null && _b !== void 0 ? _b : [
2497
+ //use the variable named `e` if it doesn't exist in this function body. otherwise use '__bsc_error' just to make sure we're out of the way
2498
+ ((_c = this.getSymbolTable()) === null || _c === void 0 ? void 0 : _c.hasSymbol('e', 1 /* SymbolTypeFlag.runtime */))
2499
+ ? '__bsc_error'
2500
+ : 'e'
2501
+ ],
2502
+ ...((_e = (_d = this.catchBranch) === null || _d === void 0 ? void 0 : _d.transpile(state)) !== null && _e !== void 0 ? _e : [])
2503
+ ];
2504
+ }
2505
+ walk(visitor, options) {
2506
+ if (this.catchBranch && options.walkMode & visitors_1.InternalWalkMode.walkStatements) {
2507
+ (0, visitors_1.walk)(this, 'catchBranch', visitor, options);
2508
+ }
2509
+ }
2510
+ get leadingTrivia() {
2511
+ var _a, _b;
2512
+ return (_b = (_a = this.tokens.catch) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
2513
+ }
2514
+ clone() {
2515
+ var _a, _b;
2516
+ return this.finalizeClone(new CatchStatement({
2517
+ catch: util_1.util.cloneToken(this.tokens.catch),
2518
+ exceptionVariableExpression: (_a = this.exceptionVariableExpression) === null || _a === void 0 ? void 0 : _a.clone(),
2519
+ catchBranch: (_b = this.catchBranch) === null || _b === void 0 ? void 0 : _b.clone()
2520
+ }), ['catchBranch']);
2521
+ }
2522
+ }
2523
+ exports.CatchStatement = CatchStatement;
2524
+ class ThrowStatement extends AstNode_1.Statement {
2525
+ constructor(options) {
2526
+ super();
2527
+ this.kind = AstNode_1.AstNodeKind.ThrowStatement;
2528
+ this.tokens = {
2529
+ throw: options.throw
2530
+ };
2531
+ this.expression = options.expression;
2532
+ this.location = util_1.util.createBoundingLocation(this.tokens.throw, this.expression);
1401
2533
  }
1402
2534
  transpile(state) {
1403
2535
  const result = [
1404
- state.transpileToken(this.throwToken),
2536
+ state.transpileToken(this.tokens.throw, 'throw'),
1405
2537
  ' '
1406
2538
  ];
1407
2539
  //if we have an expression, transpile it
@@ -1410,15 +2542,678 @@ class ThrowStatement extends Statement {
1410
2542
  //no expression found. Rather than emit syntax errors, provide a generic error message
1411
2543
  }
1412
2544
  else {
1413
- result.push('"An error has occurred"');
2545
+ result.push('"User-specified exception"');
1414
2546
  }
1415
2547
  return result;
1416
2548
  }
1417
2549
  walk(visitor, options) {
1418
2550
  if (this.expression && options.walkMode & visitors_1.InternalWalkMode.walkExpressions) {
1419
- visitors_1.walk(this, 'expression', visitor, options);
2551
+ (0, visitors_1.walk)(this, 'expression', visitor, options);
1420
2552
  }
1421
2553
  }
2554
+ get leadingTrivia() {
2555
+ var _a, _b;
2556
+ return (_b = (_a = this.tokens.throw) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
2557
+ }
2558
+ clone() {
2559
+ var _a;
2560
+ return this.finalizeClone(new ThrowStatement({
2561
+ throw: util_1.util.cloneToken(this.tokens.throw),
2562
+ expression: (_a = this.expression) === null || _a === void 0 ? void 0 : _a.clone()
2563
+ }), ['expression']);
2564
+ }
1422
2565
  }
1423
2566
  exports.ThrowStatement = ThrowStatement;
2567
+ class EnumStatement extends AstNode_1.Statement {
2568
+ constructor(options) {
2569
+ var _a;
2570
+ super();
2571
+ this.kind = AstNode_1.AstNodeKind.EnumStatement;
2572
+ this.tokens = {
2573
+ enum: options.enum,
2574
+ name: options.name,
2575
+ endEnum: options.endEnum
2576
+ };
2577
+ this.symbolTable = new SymbolTable_1.SymbolTable('Enum');
2578
+ this.body = (_a = options.body) !== null && _a !== void 0 ? _a : [];
2579
+ }
2580
+ get location() {
2581
+ return util_1.util.createBoundingLocation(this.tokens.enum, this.tokens.name, ...this.body, this.tokens.endEnum);
2582
+ }
2583
+ getMembers() {
2584
+ const result = [];
2585
+ for (const statement of this.body) {
2586
+ if ((0, reflection_1.isEnumMemberStatement)(statement)) {
2587
+ result.push(statement);
2588
+ }
2589
+ }
2590
+ return result;
2591
+ }
2592
+ get leadingTrivia() {
2593
+ var _a;
2594
+ return (_a = this.tokens.enum) === null || _a === void 0 ? void 0 : _a.leadingTrivia;
2595
+ }
2596
+ get endTrivia() {
2597
+ var _a, _b;
2598
+ return (_b = (_a = this.tokens.endEnum) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
2599
+ }
2600
+ /**
2601
+ * Get a map of member names and their values.
2602
+ * All values are stored as their AST LiteralExpression representation (i.e. string enum values include the wrapping quotes)
2603
+ */
2604
+ getMemberValueMap() {
2605
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
2606
+ const result = new Map();
2607
+ const members = this.getMembers();
2608
+ let currentIntValue = 0;
2609
+ for (const member of members) {
2610
+ //if there is no value, assume an integer and increment the int counter
2611
+ if (!member.value) {
2612
+ result.set((_a = member.name) === null || _a === void 0 ? void 0 : _a.toLowerCase(), currentIntValue.toString());
2613
+ currentIntValue++;
2614
+ //if explicit integer value, use it and increment the int counter
2615
+ }
2616
+ else if ((0, reflection_1.isLiteralExpression)(member.value) && member.value.tokens.value.kind === TokenKind_1.TokenKind.IntegerLiteral) {
2617
+ //try parsing as integer literal, then as hex integer literal.
2618
+ 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'));
2619
+ if (tokenIntValue !== undefined) {
2620
+ currentIntValue = tokenIntValue;
2621
+ currentIntValue++;
2622
+ }
2623
+ result.set((_c = member.name) === null || _c === void 0 ? void 0 : _c.toLowerCase(), member.value.tokens.value.text);
2624
+ //simple unary expressions (like `-1`)
2625
+ }
2626
+ else if ((0, reflection_1.isUnaryExpression)(member.value) && (0, reflection_1.isLiteralExpression)(member.value.right)) {
2627
+ result.set((_d = member.name) === null || _d === void 0 ? void 0 : _d.toLowerCase(), member.value.tokens.operator.text + member.value.right.tokens.value.text);
2628
+ //all other values
2629
+ }
2630
+ else {
2631
+ 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');
2632
+ }
2633
+ }
2634
+ return result;
2635
+ }
2636
+ getMemberValue(name) {
2637
+ return this.getMemberValueMap().get(name.toLowerCase());
2638
+ }
2639
+ /**
2640
+ * The name of the enum (without the namespace prefix)
2641
+ */
2642
+ get name() {
2643
+ var _a;
2644
+ return (_a = this.tokens.name) === null || _a === void 0 ? void 0 : _a.text;
2645
+ }
2646
+ /**
2647
+ * The name of the enum WITH its leading namespace (if applicable)
2648
+ */
2649
+ get fullName() {
2650
+ var _a;
2651
+ const name = (_a = this.tokens.name) === null || _a === void 0 ? void 0 : _a.text;
2652
+ if (name) {
2653
+ const namespace = this.findAncestor(reflection_1.isNamespaceStatement);
2654
+ if (namespace) {
2655
+ let namespaceName = namespace.getName(Parser_1.ParseMode.BrighterScript);
2656
+ return `${namespaceName}.${name}`;
2657
+ }
2658
+ else {
2659
+ return name;
2660
+ }
2661
+ }
2662
+ else {
2663
+ //return undefined which will allow outside callers to know that this doesn't have a name
2664
+ return undefined;
2665
+ }
2666
+ }
2667
+ transpile(state) {
2668
+ //enum declarations don't exist at runtime, so just transpile comments and trivia
2669
+ return [
2670
+ state.transpileAnnotations(this),
2671
+ state.transpileLeadingComments(this.tokens.enum)
2672
+ ];
2673
+ }
2674
+ getTypedef(state) {
2675
+ var _a, _b, _c, _d, _e, _f;
2676
+ const result = [];
2677
+ for (let comment of (_a = util_1.util.getLeadingComments(this)) !== null && _a !== void 0 ? _a : []) {
2678
+ result.push(comment.text, state.newline, state.indent());
2679
+ }
2680
+ for (let annotation of (_b = this.annotations) !== null && _b !== void 0 ? _b : []) {
2681
+ result.push(...annotation.getTypedef(state), state.newline, state.indent());
2682
+ }
2683
+ 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);
2684
+ result.push(state.newline);
2685
+ state.blockDepth++;
2686
+ for (const member of this.body) {
2687
+ if ((0, reflection_1.isTypedefProvider)(member)) {
2688
+ result.push(state.indent(), ...member.getTypedef(state), state.newline);
2689
+ }
2690
+ }
2691
+ state.blockDepth--;
2692
+ result.push(state.indent(), (_f = (_e = this.tokens.endEnum) === null || _e === void 0 ? void 0 : _e.text) !== null && _f !== void 0 ? _f : 'end enum');
2693
+ return result;
2694
+ }
2695
+ walk(visitor, options) {
2696
+ if (options.walkMode & visitors_1.InternalWalkMode.walkStatements) {
2697
+ (0, visitors_1.walkArray)(this.body, visitor, options, this);
2698
+ }
2699
+ }
2700
+ getType(options) {
2701
+ var _a, _b, _c;
2702
+ const members = this.getMembers();
2703
+ const resultType = new EnumType_1.EnumType(this.fullName, (_a = members[0]) === null || _a === void 0 ? void 0 : _a.getType(options).underlyingType);
2704
+ resultType.pushMemberProvider(() => this.getSymbolTable());
2705
+ for (const statement of members) {
2706
+ const memberType = statement.getType(Object.assign(Object.assign({}, options), { typeChain: undefined }));
2707
+ memberType.parentEnumType = resultType;
2708
+ 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 }, memberType, 1 /* SymbolTypeFlag.runtime */);
2709
+ }
2710
+ return resultType;
2711
+ }
2712
+ clone() {
2713
+ var _a;
2714
+ return this.finalizeClone(new EnumStatement({
2715
+ enum: util_1.util.cloneToken(this.tokens.enum),
2716
+ name: util_1.util.cloneToken(this.tokens.name),
2717
+ endEnum: util_1.util.cloneToken(this.tokens.endEnum),
2718
+ body: (_a = this.body) === null || _a === void 0 ? void 0 : _a.map(x => x === null || x === void 0 ? void 0 : x.clone())
2719
+ }), ['body']);
2720
+ }
2721
+ }
2722
+ exports.EnumStatement = EnumStatement;
2723
+ class EnumMemberStatement extends AstNode_1.Statement {
2724
+ constructor(options) {
2725
+ super();
2726
+ this.kind = AstNode_1.AstNodeKind.EnumMemberStatement;
2727
+ this.tokens = {
2728
+ name: options.name,
2729
+ equals: options.equals
2730
+ };
2731
+ this.value = options.value;
2732
+ }
2733
+ get location() {
2734
+ return util_1.util.createBoundingLocation(this.tokens.name, this.tokens.equals, this.value);
2735
+ }
2736
+ /**
2737
+ * The name of the member
2738
+ */
2739
+ get name() {
2740
+ return this.tokens.name.text;
2741
+ }
2742
+ get leadingTrivia() {
2743
+ return this.tokens.name.leadingTrivia;
2744
+ }
2745
+ /**
2746
+ * Get the value of this enum. Requires that `.parent` is set
2747
+ */
2748
+ getValue() {
2749
+ var _a;
2750
+ if ((0, reflection_1.isEnumStatement)(this.parent)) {
2751
+ return (_a = this.parent) === null || _a === void 0 ? void 0 : _a.getMemberValue(this.name);
2752
+ }
2753
+ return undefined;
2754
+ }
2755
+ transpile(state) {
2756
+ return [];
2757
+ }
2758
+ getTypedef(state) {
2759
+ var _a;
2760
+ const result = [];
2761
+ for (let comment of (_a = util_1.util.getLeadingComments(this)) !== null && _a !== void 0 ? _a : []) {
2762
+ result.push(comment.text, state.newline, state.indent());
2763
+ }
2764
+ result.push(this.tokens.name.text);
2765
+ if (this.tokens.equals) {
2766
+ result.push(' ', this.tokens.equals.text, ' ');
2767
+ if (this.value) {
2768
+ result.push(...this.value.transpile(state));
2769
+ }
2770
+ }
2771
+ return result;
2772
+ }
2773
+ walk(visitor, options) {
2774
+ if (this.value && options.walkMode & visitors_1.InternalWalkMode.walkExpressions) {
2775
+ (0, visitors_1.walk)(this, 'value', visitor, options);
2776
+ }
2777
+ }
2778
+ getType(options) {
2779
+ var _a, _b, _c, _d;
2780
+ 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));
2781
+ }
2782
+ clone() {
2783
+ var _a;
2784
+ return this.finalizeClone(new EnumMemberStatement({
2785
+ name: util_1.util.cloneToken(this.tokens.name),
2786
+ equals: util_1.util.cloneToken(this.tokens.equals),
2787
+ value: (_a = this.value) === null || _a === void 0 ? void 0 : _a.clone()
2788
+ }), ['value']);
2789
+ }
2790
+ }
2791
+ exports.EnumMemberStatement = EnumMemberStatement;
2792
+ class ConstStatement extends AstNode_1.Statement {
2793
+ constructor(options) {
2794
+ super();
2795
+ this.kind = AstNode_1.AstNodeKind.ConstStatement;
2796
+ this.tokens = {
2797
+ const: options.const,
2798
+ name: options.name,
2799
+ equals: options.equals
2800
+ };
2801
+ this.value = options.value;
2802
+ this.location = util_1.util.createBoundingLocation(this.tokens.const, this.tokens.name, this.tokens.equals, this.value);
2803
+ }
2804
+ get name() {
2805
+ return this.tokens.name.text;
2806
+ }
2807
+ get leadingTrivia() {
2808
+ var _a;
2809
+ return (_a = this.tokens.const) === null || _a === void 0 ? void 0 : _a.leadingTrivia;
2810
+ }
2811
+ /**
2812
+ * The name of the statement WITH its leading namespace (if applicable)
2813
+ */
2814
+ get fullName() {
2815
+ var _a;
2816
+ const name = (_a = this.tokens.name) === null || _a === void 0 ? void 0 : _a.text;
2817
+ if (name) {
2818
+ const namespace = this.findAncestor(reflection_1.isNamespaceStatement);
2819
+ if (namespace) {
2820
+ let namespaceName = namespace.getName(Parser_1.ParseMode.BrighterScript);
2821
+ return `${namespaceName}.${name}`;
2822
+ }
2823
+ else {
2824
+ return name;
2825
+ }
2826
+ }
2827
+ else {
2828
+ //return undefined which will allow outside callers to know that this doesn't have a name
2829
+ return undefined;
2830
+ }
2831
+ }
2832
+ transpile(state) {
2833
+ //const declarations don't exist at runtime, so just transpile comments and trivia
2834
+ return [
2835
+ state.transpileAnnotations(this),
2836
+ state.transpileLeadingComments(this.tokens.const)
2837
+ ];
2838
+ }
2839
+ getTypedef(state) {
2840
+ var _a;
2841
+ const result = [];
2842
+ for (let comment of (_a = util_1.util.getLeadingComments(this)) !== null && _a !== void 0 ? _a : []) {
2843
+ result.push(comment.text, state.newline, state.indent());
2844
+ }
2845
+ 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));
2846
+ return result;
2847
+ }
2848
+ walk(visitor, options) {
2849
+ if (this.value && options.walkMode & visitors_1.InternalWalkMode.walkExpressions) {
2850
+ (0, visitors_1.walk)(this, 'value', visitor, options);
2851
+ }
2852
+ }
2853
+ getType(options) {
2854
+ return this.value.getType(options);
2855
+ }
2856
+ clone() {
2857
+ var _a;
2858
+ return this.finalizeClone(new ConstStatement({
2859
+ const: util_1.util.cloneToken(this.tokens.const),
2860
+ name: util_1.util.cloneToken(this.tokens.name),
2861
+ equals: util_1.util.cloneToken(this.tokens.equals),
2862
+ value: (_a = this.value) === null || _a === void 0 ? void 0 : _a.clone()
2863
+ }), ['value']);
2864
+ }
2865
+ }
2866
+ exports.ConstStatement = ConstStatement;
2867
+ class ContinueStatement extends AstNode_1.Statement {
2868
+ constructor(options) {
2869
+ super();
2870
+ this.kind = AstNode_1.AstNodeKind.ContinueStatement;
2871
+ this.tokens = {
2872
+ continue: options.continue,
2873
+ loopType: options.loopType
2874
+ };
2875
+ this.location = util_1.util.createBoundingLocation(this.tokens.continue, this.tokens.loopType);
2876
+ }
2877
+ transpile(state) {
2878
+ var _a, _b, _c, _d, _e;
2879
+ return [
2880
+ state.sourceNode(this.tokens.continue, (_b = (_a = this.tokens.continue) === null || _a === void 0 ? void 0 : _a.text) !== null && _b !== void 0 ? _b : 'continue'),
2881
+ (_d = (_c = this.tokens.loopType) === null || _c === void 0 ? void 0 : _c.leadingWhitespace) !== null && _d !== void 0 ? _d : ' ',
2882
+ state.sourceNode(this.tokens.continue, (_e = this.tokens.loopType) === null || _e === void 0 ? void 0 : _e.text)
2883
+ ];
2884
+ }
2885
+ walk(visitor, options) {
2886
+ //nothing to walk
2887
+ }
2888
+ get leadingTrivia() {
2889
+ var _a, _b;
2890
+ return (_b = (_a = this.tokens.continue) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
2891
+ }
2892
+ clone() {
2893
+ return this.finalizeClone(new ContinueStatement({
2894
+ continue: util_1.util.cloneToken(this.tokens.continue),
2895
+ loopType: util_1.util.cloneToken(this.tokens.loopType)
2896
+ }));
2897
+ }
2898
+ }
2899
+ exports.ContinueStatement = ContinueStatement;
2900
+ class TypecastStatement extends AstNode_1.Statement {
2901
+ constructor(options) {
2902
+ super();
2903
+ this.kind = AstNode_1.AstNodeKind.TypecastStatement;
2904
+ this.tokens = {
2905
+ typecast: options.typecast
2906
+ };
2907
+ this.typecastExpression = options.typecastExpression;
2908
+ this.location = util_1.util.createBoundingLocation(this.tokens.typecast, this.typecastExpression);
2909
+ }
2910
+ transpile(state) {
2911
+ //the typecast statement is a comment just for debugging purposes
2912
+ return [
2913
+ state.transpileToken(this.tokens.typecast, 'typecast', true),
2914
+ ' ',
2915
+ this.typecastExpression.obj.transpile(state),
2916
+ ' ',
2917
+ state.transpileToken(this.typecastExpression.tokens.as, 'as'),
2918
+ ' ',
2919
+ this.typecastExpression.typeExpression.getName(Parser_1.ParseMode.BrighterScript)
2920
+ ];
2921
+ }
2922
+ walk(visitor, options) {
2923
+ if (options.walkMode & visitors_1.InternalWalkMode.walkExpressions) {
2924
+ (0, visitors_1.walk)(this, 'typecastExpression', visitor, options);
2925
+ }
2926
+ }
2927
+ get leadingTrivia() {
2928
+ var _a, _b;
2929
+ return (_b = (_a = this.tokens.typecast) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
2930
+ }
2931
+ getType(options) {
2932
+ return this.typecastExpression.getType(options);
2933
+ }
2934
+ clone() {
2935
+ var _a;
2936
+ return this.finalizeClone(new TypecastStatement({
2937
+ typecast: util_1.util.cloneToken(this.tokens.typecast),
2938
+ typecastExpression: (_a = this.typecastExpression) === null || _a === void 0 ? void 0 : _a.clone()
2939
+ }), ['typecastExpression']);
2940
+ }
2941
+ }
2942
+ exports.TypecastStatement = TypecastStatement;
2943
+ class ConditionalCompileErrorStatement extends AstNode_1.Statement {
2944
+ constructor(options) {
2945
+ super();
2946
+ this.kind = AstNode_1.AstNodeKind.ConditionalCompileErrorStatement;
2947
+ this.tokens = {
2948
+ hashError: options.hashError,
2949
+ message: options.message
2950
+ };
2951
+ this.location = util_1.util.createBoundingLocation(util_1.util.createBoundingLocationFromTokens(this.tokens));
2952
+ }
2953
+ transpile(state) {
2954
+ return [
2955
+ state.transpileToken(this.tokens.hashError, '#error'),
2956
+ ' ',
2957
+ state.transpileToken(this.tokens.message)
2958
+ ];
2959
+ }
2960
+ walk(visitor, options) {
2961
+ // nothing to walk
2962
+ }
2963
+ get leadingTrivia() {
2964
+ var _a;
2965
+ return (_a = this.tokens.hashError.leadingTrivia) !== null && _a !== void 0 ? _a : [];
2966
+ }
2967
+ clone() {
2968
+ return this.finalizeClone(new ConditionalCompileErrorStatement({
2969
+ hashError: util_1.util.cloneToken(this.tokens.hashError),
2970
+ message: util_1.util.cloneToken(this.tokens.message)
2971
+ }));
2972
+ }
2973
+ }
2974
+ exports.ConditionalCompileErrorStatement = ConditionalCompileErrorStatement;
2975
+ class AliasStatement extends AstNode_1.Statement {
2976
+ constructor(options) {
2977
+ super();
2978
+ this.kind = AstNode_1.AstNodeKind.AliasStatement;
2979
+ this.tokens = {
2980
+ alias: options.alias,
2981
+ name: options.name,
2982
+ equals: options.equals
2983
+ };
2984
+ this.value = options.value;
2985
+ this.location = util_1.util.createBoundingLocation(this.tokens.alias, this.tokens.name, this.tokens.equals, this.value);
2986
+ }
2987
+ transpile(state) {
2988
+ //transpile to a comment just for debugging purposes
2989
+ return [
2990
+ state.transpileToken(this.tokens.alias, 'alias', true),
2991
+ ' ',
2992
+ state.transpileToken(this.tokens.name),
2993
+ ' ',
2994
+ state.transpileToken(this.tokens.equals, '='),
2995
+ ' ',
2996
+ this.value.transpile(state)
2997
+ ];
2998
+ }
2999
+ walk(visitor, options) {
3000
+ if (options.walkMode & visitors_1.InternalWalkMode.walkExpressions) {
3001
+ (0, visitors_1.walk)(this, 'value', visitor, options);
3002
+ }
3003
+ }
3004
+ get leadingTrivia() {
3005
+ var _a, _b;
3006
+ return (_b = (_a = this.tokens.alias) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
3007
+ }
3008
+ getType(options) {
3009
+ return this.value.getType(options);
3010
+ }
3011
+ clone() {
3012
+ var _a;
3013
+ return this.finalizeClone(new AliasStatement({
3014
+ alias: util_1.util.cloneToken(this.tokens.alias),
3015
+ name: util_1.util.cloneToken(this.tokens.name),
3016
+ equals: util_1.util.cloneToken(this.tokens.equals),
3017
+ value: (_a = this.value) === null || _a === void 0 ? void 0 : _a.clone()
3018
+ }), ['value']);
3019
+ }
3020
+ }
3021
+ exports.AliasStatement = AliasStatement;
3022
+ class ConditionalCompileStatement extends AstNode_1.Statement {
3023
+ constructor(options) {
3024
+ super();
3025
+ this.kind = AstNode_1.AstNodeKind.ConditionalCompileStatement;
3026
+ this.thenBranch = options.thenBranch;
3027
+ this.elseBranch = options.elseBranch;
3028
+ this.tokens = {
3029
+ hashIf: options.hashIf,
3030
+ not: options.not,
3031
+ condition: options.condition,
3032
+ hashElse: options.hashElse,
3033
+ hashEndIf: options.hashEndIf
3034
+ };
3035
+ this.location = util_1.util.createBoundingLocation(util_1.util.createBoundingLocationFromTokens(this.tokens), this.thenBranch, this.elseBranch);
3036
+ }
3037
+ transpile(state) {
3038
+ var _a, _b, _c;
3039
+ let results = [];
3040
+ //if (already indented by block)
3041
+ if (!state.conditionalCompileStatement) {
3042
+ // only transpile the #if in the case when we're not in a conditionalCompileStatement already
3043
+ results.push(state.transpileToken((_a = this.tokens.hashIf) !== null && _a !== void 0 ? _a : (0, creators_1.createToken)(TokenKind_1.TokenKind.HashIf)));
3044
+ }
3045
+ results.push(' ');
3046
+ //conditions
3047
+ if (this.tokens.not) {
3048
+ results.push('not');
3049
+ results.push(' ');
3050
+ }
3051
+ results.push(state.transpileToken(this.tokens.condition));
3052
+ state.lineage.unshift(this);
3053
+ //if statement body
3054
+ let thenNodes = this.thenBranch.transpile(state);
3055
+ state.lineage.shift();
3056
+ if (thenNodes.length > 0) {
3057
+ results.push(thenNodes);
3058
+ }
3059
+ //else branch
3060
+ if (this.elseBranch) {
3061
+ const elseIsCC = (0, reflection_1.isConditionalCompileStatement)(this.elseBranch);
3062
+ const endBlockToken = elseIsCC ? (_b = this.elseBranch.tokens.hashIf) !== null && _b !== void 0 ? _b : (0, creators_1.createToken)(TokenKind_1.TokenKind.HashElseIf) : this.tokens.hashElse;
3063
+ //else
3064
+ results.push(...state.transpileEndBlockToken(this.thenBranch, endBlockToken, (0, creators_1.createToken)(TokenKind_1.TokenKind.HashElse).text));
3065
+ if (elseIsCC) {
3066
+ //chained else if
3067
+ state.lineage.unshift(this.elseBranch);
3068
+ // transpile following #if with knowledge of current
3069
+ const existingCCStmt = state.conditionalCompileStatement;
3070
+ state.conditionalCompileStatement = this;
3071
+ let body = this.elseBranch.transpile(state);
3072
+ state.conditionalCompileStatement = existingCCStmt;
3073
+ state.lineage.shift();
3074
+ if (body.length > 0) {
3075
+ //zero or more spaces between the `else` and the `if`
3076
+ results.push(...body);
3077
+ // stop here because chained if will transpile the rest
3078
+ return results;
3079
+ }
3080
+ else {
3081
+ results.push('\n');
3082
+ }
3083
+ }
3084
+ else {
3085
+ //else body
3086
+ state.lineage.unshift(this.tokens.hashElse);
3087
+ let body = this.elseBranch.transpile(state);
3088
+ state.lineage.shift();
3089
+ if (body.length > 0) {
3090
+ results.push(...body);
3091
+ }
3092
+ }
3093
+ }
3094
+ //end if
3095
+ results.push(...state.transpileEndBlockToken((_c = this.elseBranch) !== null && _c !== void 0 ? _c : this.thenBranch, this.tokens.hashEndIf, '#end if'));
3096
+ return results;
3097
+ }
3098
+ walk(visitor, options) {
3099
+ var _a;
3100
+ if (options.walkMode & visitors_1.InternalWalkMode.walkStatements) {
3101
+ const bsConsts = (_a = options.bsConsts) !== null && _a !== void 0 ? _a : this.getBsConsts();
3102
+ let conditionTrue = bsConsts === null || bsConsts === void 0 ? void 0 : bsConsts.get(this.tokens.condition.text.toLowerCase());
3103
+ if (this.tokens.not) {
3104
+ // flips the boolean value
3105
+ conditionTrue = !conditionTrue;
3106
+ }
3107
+ const walkFalseBlocks = options.walkMode & visitors_1.InternalWalkMode.visitFalseConditionalCompilationBlocks;
3108
+ if (conditionTrue || walkFalseBlocks) {
3109
+ (0, visitors_1.walk)(this, 'thenBranch', visitor, options);
3110
+ }
3111
+ if (this.elseBranch && (!conditionTrue || walkFalseBlocks)) {
3112
+ (0, visitors_1.walk)(this, 'elseBranch', visitor, options);
3113
+ }
3114
+ }
3115
+ }
3116
+ get leadingTrivia() {
3117
+ var _a, _b;
3118
+ return (_b = (_a = this.tokens.hashIf) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
3119
+ }
3120
+ clone() {
3121
+ var _a, _b;
3122
+ return this.finalizeClone(new ConditionalCompileStatement({
3123
+ hashIf: util_1.util.cloneToken(this.tokens.hashIf),
3124
+ not: util_1.util.cloneToken(this.tokens.not),
3125
+ condition: util_1.util.cloneToken(this.tokens.condition),
3126
+ hashElse: util_1.util.cloneToken(this.tokens.hashElse),
3127
+ hashEndIf: util_1.util.cloneToken(this.tokens.hashEndIf),
3128
+ thenBranch: (_a = this.thenBranch) === null || _a === void 0 ? void 0 : _a.clone(),
3129
+ elseBranch: (_b = this.elseBranch) === null || _b === void 0 ? void 0 : _b.clone()
3130
+ }), ['thenBranch', 'elseBranch']);
3131
+ }
3132
+ getBranchStatementIndex(stmt) {
3133
+ if (this.thenBranch === stmt) {
3134
+ return 0;
3135
+ }
3136
+ else if (this.elseBranch === stmt) {
3137
+ return 1;
3138
+ }
3139
+ return -1;
3140
+ }
3141
+ }
3142
+ exports.ConditionalCompileStatement = ConditionalCompileStatement;
3143
+ class ConditionalCompileConstStatement extends AstNode_1.Statement {
3144
+ constructor(options) {
3145
+ super();
3146
+ this.kind = AstNode_1.AstNodeKind.ConditionalCompileConstStatement;
3147
+ this.tokens = {
3148
+ hashConst: options.hashConst
3149
+ };
3150
+ this.assignment = options.assignment;
3151
+ this.location = util_1.util.createBoundingLocation(util_1.util.createBoundingLocationFromTokens(this.tokens), this.assignment);
3152
+ }
3153
+ transpile(state) {
3154
+ return [
3155
+ state.transpileToken(this.tokens.hashConst, '#const'),
3156
+ ' ',
3157
+ state.transpileToken(this.assignment.tokens.name),
3158
+ ' ',
3159
+ state.transpileToken(this.assignment.tokens.equals, '='),
3160
+ ' ',
3161
+ ...this.assignment.value.transpile(state)
3162
+ ];
3163
+ }
3164
+ walk(visitor, options) {
3165
+ // nothing to walk
3166
+ }
3167
+ get leadingTrivia() {
3168
+ var _a;
3169
+ return (_a = this.tokens.hashConst.leadingTrivia) !== null && _a !== void 0 ? _a : [];
3170
+ }
3171
+ clone() {
3172
+ var _a;
3173
+ return this.finalizeClone(new ConditionalCompileConstStatement({
3174
+ hashConst: util_1.util.cloneToken(this.tokens.hashConst),
3175
+ assignment: (_a = this.assignment) === null || _a === void 0 ? void 0 : _a.clone()
3176
+ }), ['assignment']);
3177
+ }
3178
+ }
3179
+ exports.ConditionalCompileConstStatement = ConditionalCompileConstStatement;
3180
+ class TypeStatement extends AstNode_1.Statement {
3181
+ constructor(options) {
3182
+ super();
3183
+ this.kind = AstNode_1.AstNodeKind.TypeStatement;
3184
+ this.tokens = {
3185
+ type: options.type,
3186
+ name: options.name,
3187
+ equals: options.equals
3188
+ };
3189
+ this.value = options.value;
3190
+ this.location = util_1.util.createBoundingLocation(this.tokens.type, this.tokens.name, this.tokens.equals, this.value);
3191
+ }
3192
+ transpile(state) {
3193
+ //type statements have no runtime representation, so they're stripped entirely
3194
+ return [];
3195
+ }
3196
+ walk(visitor, options) {
3197
+ if (options.walkMode & visitors_1.InternalWalkMode.walkExpressions) {
3198
+ (0, visitors_1.walk)(this, 'value', visitor, options);
3199
+ }
3200
+ }
3201
+ get leadingTrivia() {
3202
+ var _a, _b;
3203
+ return (_b = (_a = this.tokens.type) === null || _a === void 0 ? void 0 : _a.leadingTrivia) !== null && _b !== void 0 ? _b : [];
3204
+ }
3205
+ getType(options) {
3206
+ return this.value.getType(options);
3207
+ }
3208
+ clone() {
3209
+ var _a;
3210
+ return this.finalizeClone(new TypeStatement({
3211
+ type: util_1.util.cloneToken(this.tokens.type),
3212
+ name: util_1.util.cloneToken(this.tokens.name),
3213
+ equals: util_1.util.cloneToken(this.tokens.equals),
3214
+ value: (_a = this.value) === null || _a === void 0 ? void 0 : _a.clone()
3215
+ }), ['value']);
3216
+ }
3217
+ }
3218
+ exports.TypeStatement = TypeStatement;
1424
3219
  //# sourceMappingURL=Statement.js.map