brighterscript 1.0.0-alpha.24 → 1.0.0-alpha.26

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