brighterscript 1.0.0-alpha.2 → 1.0.0-alpha.22

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 (388) hide show
  1. package/CHANGELOG.md +643 -253
  2. package/README.md +33 -9
  3. package/bsconfig.schema.json +22 -2
  4. package/dist/BsConfig.d.ts +9 -0
  5. package/dist/Cache.d.ts +5 -6
  6. package/dist/Cache.js +12 -11
  7. package/dist/Cache.js.map +1 -1
  8. package/dist/CodeActionUtil.d.ts +11 -2
  9. package/dist/CodeActionUtil.js +17 -3
  10. package/dist/CodeActionUtil.js.map +1 -1
  11. package/dist/CommentFlagProcessor.d.ts +4 -4
  12. package/dist/CommentFlagProcessor.js +5 -3
  13. package/dist/CommentFlagProcessor.js.map +1 -1
  14. package/dist/DependencyGraph.d.ts +2 -2
  15. package/dist/DependencyGraph.js +20 -7
  16. package/dist/DependencyGraph.js.map +1 -1
  17. package/dist/DiagnosticCollection.d.ts +3 -3
  18. package/dist/DiagnosticCollection.js +11 -11
  19. package/dist/DiagnosticCollection.js.map +1 -1
  20. package/dist/DiagnosticFilterer.js +5 -4
  21. package/dist/DiagnosticFilterer.js.map +1 -1
  22. package/dist/DiagnosticMessages.d.ts +59 -4
  23. package/dist/DiagnosticMessages.js +65 -7
  24. package/dist/DiagnosticMessages.js.map +1 -1
  25. package/dist/LanguageServer.d.ts +51 -39
  26. package/dist/LanguageServer.js +316 -232
  27. package/dist/LanguageServer.js.map +1 -1
  28. package/dist/Logger.d.ts +2 -0
  29. package/dist/Logger.js +10 -8
  30. package/dist/Logger.js.map +1 -1
  31. package/dist/PluginInterface.d.ts +7 -3
  32. package/dist/PluginInterface.js +9 -0
  33. package/dist/PluginInterface.js.map +1 -1
  34. package/dist/Program.d.ts +43 -25
  35. package/dist/Program.js +212 -95
  36. package/dist/Program.js.map +1 -1
  37. package/dist/ProgramBuilder.d.ts +4 -0
  38. package/dist/ProgramBuilder.js +36 -20
  39. package/dist/ProgramBuilder.js.map +1 -1
  40. package/dist/Scope.d.ts +126 -29
  41. package/dist/Scope.js +433 -156
  42. package/dist/Scope.js.map +1 -1
  43. package/dist/SemanticTokenUtils.d.ts +14 -0
  44. package/dist/SemanticTokenUtils.js +81 -0
  45. package/dist/SemanticTokenUtils.js.map +1 -0
  46. package/dist/SymbolTable.d.ts +10 -4
  47. package/dist/SymbolTable.js +55 -13
  48. package/dist/SymbolTable.js.map +1 -1
  49. package/dist/XmlScope.d.ts +7 -2
  50. package/dist/XmlScope.js +65 -27
  51. package/dist/XmlScope.js.map +1 -1
  52. package/dist/astUtils/AstEditor.d.ts +65 -0
  53. package/dist/astUtils/AstEditor.js +239 -0
  54. package/dist/astUtils/AstEditor.js.map +1 -0
  55. package/dist/{types/FunctionType.spec.d.ts → astUtils/AstEditor.spec.d.ts} +0 -0
  56. package/dist/astUtils/AstEditor.spec.js +254 -0
  57. package/dist/astUtils/AstEditor.spec.js.map +1 -0
  58. package/dist/astUtils/creators.d.ts +28 -6
  59. package/dist/astUtils/creators.js +137 -19
  60. package/dist/astUtils/creators.js.map +1 -1
  61. package/dist/astUtils/creators.spec.js +14 -4
  62. package/dist/astUtils/creators.spec.js.map +1 -1
  63. package/dist/astUtils/reflection.d.ts +32 -10
  64. package/dist/astUtils/reflection.js +82 -7
  65. package/dist/astUtils/reflection.js.map +1 -1
  66. package/dist/astUtils/reflection.spec.js +130 -119
  67. package/dist/astUtils/reflection.spec.js.map +1 -1
  68. package/dist/astUtils/stackedVisitor.js.map +1 -1
  69. package/dist/astUtils/stackedVisitor.spec.js +13 -13
  70. package/dist/astUtils/stackedVisitor.spec.js.map +1 -1
  71. package/dist/astUtils/visitors.d.ts +76 -51
  72. package/dist/astUtils/visitors.js +31 -11
  73. package/dist/astUtils/visitors.js.map +1 -1
  74. package/dist/astUtils/visitors.spec.js +126 -32
  75. package/dist/astUtils/visitors.spec.js.map +1 -1
  76. package/dist/astUtils/xml.d.ts +4 -3
  77. package/dist/astUtils/xml.js +8 -3
  78. package/dist/astUtils/xml.js.map +1 -1
  79. package/dist/bscPlugin/BscPlugin.d.ts +7 -1
  80. package/dist/bscPlugin/BscPlugin.js +28 -0
  81. package/dist/bscPlugin/BscPlugin.js.map +1 -1
  82. package/dist/bscPlugin/codeActions/CodeActionsProcessor.js +4 -4
  83. package/dist/bscPlugin/codeActions/CodeActionsProcessor.js.map +1 -1
  84. package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js +26 -26
  85. package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js.map +1 -1
  86. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.d.ts +9 -0
  87. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js +108 -0
  88. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js.map +1 -0
  89. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.d.ts +1 -0
  90. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js +130 -0
  91. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js.map +1 -0
  92. package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.d.ts +8 -0
  93. package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.js +52 -0
  94. package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.js.map +1 -0
  95. package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.d.ts +1 -0
  96. package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.js +32 -0
  97. package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.js.map +1 -0
  98. package/dist/bscPlugin/validation/BrsFileValidator.d.ts +9 -0
  99. package/dist/bscPlugin/validation/BrsFileValidator.js +66 -0
  100. package/dist/bscPlugin/validation/BrsFileValidator.js.map +1 -0
  101. package/dist/bscPlugin/validation/ScopeValidator.d.ts +29 -0
  102. package/dist/bscPlugin/validation/ScopeValidator.js +183 -0
  103. package/dist/bscPlugin/validation/ScopeValidator.js.map +1 -0
  104. package/dist/cli.js +10 -3
  105. package/dist/cli.js.map +1 -1
  106. package/dist/diagnosticUtils.d.ts +1 -0
  107. package/dist/diagnosticUtils.js +15 -8
  108. package/dist/diagnosticUtils.js.map +1 -1
  109. package/dist/examples/plugins/removePrint.js +12 -14
  110. package/dist/examples/plugins/removePrint.js.map +1 -1
  111. package/dist/files/BrsFile.Class.spec.js +717 -147
  112. package/dist/files/BrsFile.Class.spec.js.map +1 -1
  113. package/dist/files/BrsFile.d.ts +70 -30
  114. package/dist/files/BrsFile.js +719 -353
  115. package/dist/files/BrsFile.js.map +1 -1
  116. package/dist/files/BrsFile.spec.js +1238 -449
  117. package/dist/files/BrsFile.spec.js.map +1 -1
  118. package/dist/files/XmlFile.d.ts +6 -5
  119. package/dist/files/XmlFile.js +38 -30
  120. package/dist/files/XmlFile.js.map +1 -1
  121. package/dist/files/XmlFile.spec.js +302 -237
  122. package/dist/files/XmlFile.spec.js.map +1 -1
  123. package/dist/files/tests/imports.spec.js +44 -42
  124. package/dist/files/tests/imports.spec.js.map +1 -1
  125. package/dist/files/tests/optionalChaning.spec.d.ts +1 -0
  126. package/dist/files/tests/optionalChaning.spec.js +88 -0
  127. package/dist/files/tests/optionalChaning.spec.js.map +1 -0
  128. package/dist/globalCallables.d.ts +3 -1
  129. package/dist/globalCallables.js +424 -152
  130. package/dist/globalCallables.js.map +1 -1
  131. package/dist/index.d.ts +13 -3
  132. package/dist/index.js +28 -5
  133. package/dist/index.js.map +1 -1
  134. package/dist/interfaces.d.ts +133 -16
  135. package/dist/lexer/Lexer.d.ts +19 -1
  136. package/dist/lexer/Lexer.js +127 -21
  137. package/dist/lexer/Lexer.js.map +1 -1
  138. package/dist/lexer/Lexer.spec.js +657 -536
  139. package/dist/lexer/Lexer.spec.js.map +1 -1
  140. package/dist/lexer/Token.d.ts +2 -2
  141. package/dist/lexer/TokenKind.d.ts +13 -1
  142. package/dist/lexer/TokenKind.js +60 -3
  143. package/dist/lexer/TokenKind.js.map +1 -1
  144. package/dist/parser/BrsTranspileState.d.ts +9 -0
  145. package/dist/parser/BrsTranspileState.js +14 -0
  146. package/dist/parser/BrsTranspileState.js.map +1 -1
  147. package/dist/parser/Expression.d.ts +150 -34
  148. package/dist/parser/Expression.js +335 -165
  149. package/dist/parser/Expression.js.map +1 -1
  150. package/dist/parser/Parser.Class.spec.js +189 -89
  151. package/dist/parser/Parser.Class.spec.js.map +1 -1
  152. package/dist/parser/Parser.d.ts +153 -30
  153. package/dist/parser/Parser.js +1100 -503
  154. package/dist/parser/Parser.js.map +1 -1
  155. package/dist/parser/Parser.spec.js +687 -266
  156. package/dist/parser/Parser.spec.js.map +1 -1
  157. package/dist/parser/SGParser.d.ts +41 -4
  158. package/dist/parser/SGParser.js +186 -175
  159. package/dist/parser/SGParser.js.map +1 -1
  160. package/dist/parser/SGParser.spec.js +35 -22
  161. package/dist/parser/SGParser.spec.js.map +1 -1
  162. package/dist/parser/SGTypes.d.ts +206 -38
  163. package/dist/parser/SGTypes.js +470 -161
  164. package/dist/parser/SGTypes.js.map +1 -1
  165. package/dist/parser/SGTypes.spec.d.ts +1 -0
  166. package/dist/parser/SGTypes.spec.js +351 -0
  167. package/dist/parser/SGTypes.spec.js.map +1 -0
  168. package/dist/parser/Statement.d.ts +202 -48
  169. package/dist/parser/Statement.js +648 -193
  170. package/dist/parser/Statement.js.map +1 -1
  171. package/dist/parser/Statement.spec.js +11 -11
  172. package/dist/parser/Statement.spec.js.map +1 -1
  173. package/dist/parser/TranspileState.d.ts +1 -1
  174. package/dist/parser/TranspileState.js +15 -7
  175. package/dist/parser/TranspileState.js.map +1 -1
  176. package/dist/parser/tests/Parser.spec.d.ts +10 -9
  177. package/dist/parser/tests/Parser.spec.js +15 -11
  178. package/dist/parser/tests/Parser.spec.js.map +1 -1
  179. package/dist/parser/tests/controlFlow/For.spec.js +60 -60
  180. package/dist/parser/tests/controlFlow/For.spec.js.map +1 -1
  181. package/dist/parser/tests/controlFlow/ForEach.spec.js +40 -39
  182. package/dist/parser/tests/controlFlow/ForEach.spec.js.map +1 -1
  183. package/dist/parser/tests/controlFlow/If.spec.js +213 -194
  184. package/dist/parser/tests/controlFlow/If.spec.js.map +1 -1
  185. package/dist/parser/tests/controlFlow/While.spec.js +37 -37
  186. package/dist/parser/tests/controlFlow/While.spec.js.map +1 -1
  187. package/dist/parser/tests/expression/Additive.spec.js +30 -30
  188. package/dist/parser/tests/expression/Additive.spec.js.map +1 -1
  189. package/dist/parser/tests/expression/ArrayLiterals.spec.js +119 -119
  190. package/dist/parser/tests/expression/ArrayLiterals.spec.js.map +1 -1
  191. package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js +162 -138
  192. package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js.map +1 -1
  193. package/dist/parser/tests/expression/Boolean.spec.js +24 -24
  194. package/dist/parser/tests/expression/Boolean.spec.js.map +1 -1
  195. package/dist/parser/tests/expression/Call.spec.js +41 -40
  196. package/dist/parser/tests/expression/Call.spec.js.map +1 -1
  197. package/dist/parser/tests/expression/Exponential.spec.js +17 -17
  198. package/dist/parser/tests/expression/Exponential.spec.js.map +1 -1
  199. package/dist/parser/tests/expression/Function.spec.js +256 -256
  200. package/dist/parser/tests/expression/Function.spec.js.map +1 -1
  201. package/dist/parser/tests/expression/Indexing.spec.js +87 -87
  202. package/dist/parser/tests/expression/Indexing.spec.js.map +1 -1
  203. package/dist/parser/tests/expression/Multiplicative.spec.js +37 -37
  204. package/dist/parser/tests/expression/Multiplicative.spec.js.map +1 -1
  205. package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js +75 -63
  206. package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js.map +1 -1
  207. package/dist/parser/tests/expression/PrefixUnary.spec.js +41 -41
  208. package/dist/parser/tests/expression/PrefixUnary.spec.js.map +1 -1
  209. package/dist/parser/tests/expression/Primary.spec.js +41 -41
  210. package/dist/parser/tests/expression/Primary.spec.js.map +1 -1
  211. package/dist/parser/tests/expression/RegexLiteralExpression.spec.d.ts +1 -0
  212. package/dist/parser/tests/expression/RegexLiteralExpression.spec.js +171 -0
  213. package/dist/parser/tests/expression/RegexLiteralExpression.spec.js.map +1 -0
  214. package/dist/parser/tests/expression/Relational.spec.js +43 -43
  215. package/dist/parser/tests/expression/Relational.spec.js.map +1 -1
  216. package/dist/parser/tests/expression/SourceLiteralExpression.spec.js +9 -9
  217. package/dist/parser/tests/expression/SourceLiteralExpression.spec.js.map +1 -1
  218. package/dist/parser/tests/expression/TemplateStringExpression.spec.js +28 -28
  219. package/dist/parser/tests/expression/TemplateStringExpression.spec.js.map +1 -1
  220. package/dist/parser/tests/expression/TernaryExpression.spec.js +102 -102
  221. package/dist/parser/tests/expression/TernaryExpression.spec.js.map +1 -1
  222. package/dist/parser/tests/statement/AssignmentOperators.spec.js +36 -36
  223. package/dist/parser/tests/statement/AssignmentOperators.spec.js.map +1 -1
  224. package/dist/parser/tests/statement/Declaration.spec.js +44 -44
  225. package/dist/parser/tests/statement/Declaration.spec.js.map +1 -1
  226. package/dist/parser/tests/statement/Dim.spec.js +21 -21
  227. package/dist/parser/tests/statement/Dim.spec.js.map +1 -1
  228. package/dist/parser/tests/statement/Enum.spec.d.ts +1 -0
  229. package/dist/parser/tests/statement/Enum.spec.js +840 -0
  230. package/dist/parser/tests/statement/Enum.spec.js.map +1 -0
  231. package/dist/parser/tests/statement/For.spec.d.ts +1 -0
  232. package/dist/parser/tests/statement/For.spec.js +46 -0
  233. package/dist/parser/tests/statement/For.spec.js.map +1 -0
  234. package/dist/parser/tests/statement/ForEach.spec.d.ts +1 -0
  235. package/dist/parser/tests/statement/ForEach.spec.js +37 -0
  236. package/dist/parser/tests/statement/ForEach.spec.js.map +1 -0
  237. package/dist/parser/tests/statement/Function.spec.js +198 -197
  238. package/dist/parser/tests/statement/Function.spec.js.map +1 -1
  239. package/dist/parser/tests/statement/Goto.spec.js +15 -14
  240. package/dist/parser/tests/statement/Goto.spec.js.map +1 -1
  241. package/dist/parser/tests/statement/Increment.spec.js +50 -50
  242. package/dist/parser/tests/statement/Increment.spec.js.map +1 -1
  243. package/dist/parser/tests/statement/InterfaceStatement.spec.d.ts +1 -0
  244. package/dist/parser/tests/statement/InterfaceStatement.spec.js +254 -0
  245. package/dist/parser/tests/statement/InterfaceStatement.spec.js.map +1 -0
  246. package/dist/parser/tests/statement/LibraryStatement.spec.js +17 -17
  247. package/dist/parser/tests/statement/LibraryStatement.spec.js.map +1 -1
  248. package/dist/parser/tests/statement/Misc.spec.js +108 -106
  249. package/dist/parser/tests/statement/Misc.spec.js.map +1 -1
  250. package/dist/parser/tests/statement/PrintStatement.spec.js +40 -40
  251. package/dist/parser/tests/statement/PrintStatement.spec.js.map +1 -1
  252. package/dist/parser/tests/statement/ReturnStatement.spec.js +46 -46
  253. package/dist/parser/tests/statement/ReturnStatement.spec.js.map +1 -1
  254. package/dist/parser/tests/statement/Set.spec.js +83 -83
  255. package/dist/parser/tests/statement/Set.spec.js.map +1 -1
  256. package/dist/parser/tests/statement/Stop.spec.js +12 -11
  257. package/dist/parser/tests/statement/Stop.spec.js.map +1 -1
  258. package/dist/parser/tests/statement/Throw.spec.js +5 -5
  259. package/dist/parser/tests/statement/Throw.spec.js.map +1 -1
  260. package/dist/parser/tests/statement/TryCatch.spec.js +15 -13
  261. package/dist/parser/tests/statement/TryCatch.spec.js.map +1 -1
  262. package/dist/preprocessor/Chunk.d.ts +1 -1
  263. package/dist/preprocessor/Chunk.js.map +1 -1
  264. package/dist/preprocessor/Manifest.d.ts +5 -5
  265. package/dist/preprocessor/Manifest.js +14 -35
  266. package/dist/preprocessor/Manifest.js.map +1 -1
  267. package/dist/preprocessor/Manifest.spec.d.ts +1 -0
  268. package/dist/preprocessor/Manifest.spec.js +78 -103
  269. package/dist/preprocessor/Manifest.spec.js.map +1 -1
  270. package/dist/preprocessor/Preprocessor.d.ts +1 -1
  271. package/dist/preprocessor/Preprocessor.js +8 -8
  272. package/dist/preprocessor/Preprocessor.js.map +1 -1
  273. package/dist/preprocessor/Preprocessor.spec.js +49 -49
  274. package/dist/preprocessor/Preprocessor.spec.js.map +1 -1
  275. package/dist/preprocessor/PreprocessorParser.spec.js +72 -72
  276. package/dist/preprocessor/PreprocessorParser.spec.js.map +1 -1
  277. package/dist/roku-types/data.json +21891 -0
  278. package/dist/roku-types/index.d.ts +6776 -0
  279. package/dist/roku-types/index.js +11 -0
  280. package/dist/roku-types/index.js.map +1 -0
  281. package/dist/types/ArrayType.d.ts +8 -5
  282. package/dist/types/ArrayType.js +52 -12
  283. package/dist/types/ArrayType.js.map +1 -1
  284. package/dist/types/ArrayType.spec.js +72 -11
  285. package/dist/types/ArrayType.spec.js.map +1 -1
  286. package/dist/types/BooleanType.d.ts +4 -2
  287. package/dist/types/BooleanType.js +9 -4
  288. package/dist/types/BooleanType.js.map +1 -1
  289. package/dist/types/BooleanType.spec.js +5 -3
  290. package/dist/types/BooleanType.spec.js.map +1 -1
  291. package/dist/types/BscType.d.ts +20 -5
  292. package/dist/types/BscType.js +24 -0
  293. package/dist/types/BscType.js.map +1 -1
  294. package/dist/types/CustomType.d.ts +8 -6
  295. package/dist/types/CustomType.js +20 -11
  296. package/dist/types/CustomType.js.map +1 -1
  297. package/dist/types/DoubleType.d.ts +2 -0
  298. package/dist/types/DoubleType.js +14 -9
  299. package/dist/types/DoubleType.js.map +1 -1
  300. package/dist/types/DoubleType.spec.js +5 -3
  301. package/dist/types/DoubleType.spec.js.map +1 -1
  302. package/dist/types/DynamicType.d.ts +2 -0
  303. package/dist/types/DynamicType.js +6 -2
  304. package/dist/types/DynamicType.js.map +1 -1
  305. package/dist/types/DynamicType.spec.js +2 -2
  306. package/dist/types/DynamicType.spec.js.map +1 -1
  307. package/dist/types/EnumType.d.ts +22 -0
  308. package/dist/types/EnumType.js +55 -0
  309. package/dist/types/EnumType.js.map +1 -0
  310. package/dist/types/FloatType.d.ts +2 -0
  311. package/dist/types/FloatType.js +14 -9
  312. package/dist/types/FloatType.js.map +1 -1
  313. package/dist/types/FloatType.spec.js +4 -2
  314. package/dist/types/FloatType.spec.js.map +1 -1
  315. package/dist/types/FunctionType.d.ts +7 -31
  316. package/dist/types/FunctionType.js +11 -57
  317. package/dist/types/FunctionType.js.map +1 -1
  318. package/dist/types/IntegerType.d.ts +2 -0
  319. package/dist/types/IntegerType.js +14 -9
  320. package/dist/types/IntegerType.js.map +1 -1
  321. package/dist/types/IntegerType.spec.js +5 -3
  322. package/dist/types/IntegerType.spec.js.map +1 -1
  323. package/dist/types/InterfaceType.d.ts +13 -4
  324. package/dist/types/InterfaceType.js +48 -8
  325. package/dist/types/InterfaceType.js.map +1 -1
  326. package/dist/types/InterfaceType.spec.d.ts +1 -0
  327. package/dist/types/InterfaceType.spec.js +194 -0
  328. package/dist/types/InterfaceType.spec.js.map +1 -0
  329. package/dist/types/InvalidType.d.ts +4 -2
  330. package/dist/types/InvalidType.js +10 -5
  331. package/dist/types/InvalidType.js.map +1 -1
  332. package/dist/types/InvalidType.spec.js +4 -2
  333. package/dist/types/InvalidType.spec.js.map +1 -1
  334. package/dist/types/LazyType.d.ts +8 -7
  335. package/dist/types/LazyType.js +22 -10
  336. package/dist/types/LazyType.js.map +1 -1
  337. package/dist/types/LongIntegerType.d.ts +2 -0
  338. package/dist/types/LongIntegerType.js +14 -9
  339. package/dist/types/LongIntegerType.js.map +1 -1
  340. package/dist/types/LongIntegerType.spec.js +4 -2
  341. package/dist/types/LongIntegerType.spec.js.map +1 -1
  342. package/dist/types/ObjectType.d.ts +8 -4
  343. package/dist/types/ObjectType.js +9 -4
  344. package/dist/types/ObjectType.js.map +1 -1
  345. package/dist/types/ObjectType.spec.js +2 -2
  346. package/dist/types/ObjectType.spec.js.map +1 -1
  347. package/dist/types/StringType.d.ts +4 -2
  348. package/dist/types/StringType.js +9 -4
  349. package/dist/types/StringType.js.map +1 -1
  350. package/dist/types/StringType.spec.js +4 -2
  351. package/dist/types/StringType.spec.js.map +1 -1
  352. package/dist/types/TypedFunctionType.d.ts +28 -0
  353. package/dist/types/TypedFunctionType.js +88 -0
  354. package/dist/types/TypedFunctionType.js.map +1 -0
  355. package/dist/types/TypedFunctionType.spec.d.ts +1 -0
  356. package/dist/types/TypedFunctionType.spec.js +37 -0
  357. package/dist/types/TypedFunctionType.spec.js.map +1 -0
  358. package/dist/types/UninitializedType.js +3 -3
  359. package/dist/types/UninitializedType.js.map +1 -1
  360. package/dist/types/VoidType.d.ts +4 -2
  361. package/dist/types/VoidType.js +8 -4
  362. package/dist/types/VoidType.js.map +1 -1
  363. package/dist/types/VoidType.spec.js +2 -2
  364. package/dist/types/VoidType.spec.js.map +1 -1
  365. package/dist/types/helpers.d.ts +42 -0
  366. package/dist/types/helpers.js +118 -0
  367. package/dist/types/helpers.js.map +1 -0
  368. package/dist/util.d.ts +91 -21
  369. package/dist/util.js +364 -114
  370. package/dist/util.js.map +1 -1
  371. package/dist/validators/ClassValidator.d.ts +19 -2
  372. package/dist/validators/ClassValidator.js +164 -103
  373. package/dist/validators/ClassValidator.js.map +1 -1
  374. package/package.json +30 -19
  375. package/dist/astUtils/index.d.ts +0 -7
  376. package/dist/astUtils/index.js +0 -26
  377. package/dist/astUtils/index.js.map +0 -1
  378. package/dist/lexer/index.d.ts +0 -3
  379. package/dist/lexer/index.js +0 -17
  380. package/dist/lexer/index.js.map +0 -1
  381. package/dist/parser/index.d.ts +0 -3
  382. package/dist/parser/index.js +0 -16
  383. package/dist/parser/index.js.map +0 -1
  384. package/dist/preprocessor/index.d.ts +0 -3
  385. package/dist/preprocessor/index.js +0 -16
  386. package/dist/preprocessor/index.js.map +0 -1
  387. package/dist/types/FunctionType.spec.js +0 -23
  388. package/dist/types/FunctionType.spec.js.map +0 -1
@@ -1,150 +1,293 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SGAst = exports.SGComponent = exports.SGInterface = exports.SGFunction = exports.SGFieldTypes = exports.SGField = exports.SGScript = exports.SGChildren = exports.SGNode = exports.SGProlog = exports.SGTag = void 0;
3
+ exports.SGAst = exports.SGComponent = exports.SGInterface = exports.SGInterfaceFunction = exports.getBscTypeFromSGFieldType = exports.SGFieldTypes = exports.SGInterfaceField = exports.SGScript = exports.SGCustomization = exports.SGChildren = exports.SGNode = exports.SGProlog = exports.SGTag = exports.SGAttribute = void 0;
4
4
  const source_map_1 = require("source-map");
5
5
  const creators_1 = require("../astUtils/creators");
6
- const xml_1 = require("../astUtils/xml");
6
+ const BooleanType_1 = require("../types/BooleanType");
7
+ const DynamicType_1 = require("../types/DynamicType");
8
+ const FloatType_1 = require("../types/FloatType");
9
+ const TypedFunctionType_1 = require("../types/TypedFunctionType");
10
+ const IntegerType_1 = require("../types/IntegerType");
11
+ const LongIntegerType_1 = require("../types/LongIntegerType");
12
+ const StringType_1 = require("../types/StringType");
7
13
  const util_1 = require("../util");
14
+ class SGAttribute {
15
+ constructor(key, equals, openingQuote, value, closingQuote) {
16
+ this.tokens = {};
17
+ this._range = null;
18
+ this.tokens.key = key;
19
+ this.tokens.equals = equals;
20
+ this.tokens.openingQuote = openingQuote;
21
+ this.tokens.value = value;
22
+ this.tokens.closingQuote = closingQuote;
23
+ }
24
+ get key() {
25
+ return this.tokens.key.text;
26
+ }
27
+ /**
28
+ * The value of this attribute. This does not including the opening or closing quote
29
+ */
30
+ get value() {
31
+ var _a;
32
+ return (_a = this.tokens.value) === null || _a === void 0 ? void 0 : _a.text;
33
+ }
34
+ set value(val) {
35
+ if (val === null || val === undefined) {
36
+ val = '';
37
+ }
38
+ if (!this.tokens.equals) {
39
+ this.tokens.equals = { text: '=' };
40
+ }
41
+ if (this.tokens.value) {
42
+ this.tokens.value.text = val;
43
+ }
44
+ else {
45
+ this.tokens.value = { text: val };
46
+ }
47
+ }
48
+ get range() {
49
+ if (!this._range) {
50
+ this._range = util_1.default.createBoundingRange(this.tokens.key, this.tokens.equals, this.tokens.openingQuote, this.tokens.value, this.tokens.closingQuote);
51
+ }
52
+ return this._range;
53
+ }
54
+ transpile(state) {
55
+ const result = [
56
+ state.transpileToken(this.tokens.key)
57
+ ];
58
+ if (this.tokens.value) {
59
+ result.push(state.transpileToken(this.tokens.equals, '='), state.transpileToken(this.tokens.openingQuote, '"'), state.transpileToken(this.tokens.value), state.transpileToken(this.tokens.closingQuote, '"'));
60
+ }
61
+ return new source_map_1.SourceNode(null, null, null, result);
62
+ }
63
+ }
64
+ exports.SGAttribute = SGAttribute;
8
65
  class SGTag {
9
- constructor(tag, attributes = [], range) {
10
- this.tag = tag;
66
+ constructor(startTagOpen, startTagName, attributes = [], startTagClose, childNodes = [], endTagOpen, endTagName, endTagClose) {
67
+ this.tokens = {};
68
+ /**
69
+ * Array of attributes found on this tag
70
+ */
71
+ this.attributes = [];
72
+ /**
73
+ * The array of direct children AST elements of this AST node
74
+ */
75
+ this.childNodes = [];
76
+ this._range = null;
77
+ this.tokens.startTagOpen = startTagOpen;
78
+ this.tokens.startTagName = startTagName;
11
79
  this.attributes = attributes;
12
- this.range = range;
80
+ this.tokens.startTagClose = startTagClose;
81
+ this.childNodes = childNodes;
82
+ this.tokens.endTagOpen = endTagOpen;
83
+ this.tokens.endTagName = endTagName;
84
+ this.tokens.endTagClose = endTagClose;
85
+ }
86
+ get range() {
87
+ var _a, _b, _c, _d;
88
+ if (!this._range) {
89
+ this._range = util_1.default.createBoundingRange(this.tokens.startTagOpen, this.tokens.startTagName, (_a = this.attributes) === null || _a === void 0 ? void 0 : _a[((_b = this.attributes) === null || _b === void 0 ? void 0 : _b.length) - 1], this.tokens.startTagClose, (_c = this.childNodes) === null || _c === void 0 ? void 0 : _c[((_d = this.childNodes) === null || _d === void 0 ? void 0 : _d.length) - 1], this.tokens.endTagOpen, this.tokens.endTagName, this.tokens.endTagClose);
90
+ }
91
+ return this._range;
92
+ }
93
+ /**
94
+ * Is this a self-closing tag?
95
+ */
96
+ get isSelfClosing() {
97
+ return !this.tokens.endTagName;
13
98
  }
14
99
  get id() {
15
100
  return this.getAttributeValue('id');
16
101
  }
17
102
  set id(value) {
18
- this.setAttribute('id', value);
103
+ this.setAttributeValue('id', value);
104
+ }
105
+ /**
106
+ * Get the lower-case name of this tag.
107
+ */
108
+ get tagName() {
109
+ var _a;
110
+ return (_a = this.tokens.startTagName) === null || _a === void 0 ? void 0 : _a.text;
111
+ }
112
+ /**
113
+ * Find all direct children by their tag name (case insensitive).
114
+ * This does not step into children's children.
115
+ *
116
+ */
117
+ getChildNodesByTagName(tagName) {
118
+ const result = [];
119
+ const lowerTagName = tagName.toLowerCase();
120
+ for (const el of this.childNodes) {
121
+ if (el.tokens.startTagName.text.toLowerCase() === lowerTagName) {
122
+ result.push(el);
123
+ }
124
+ }
125
+ return result;
19
126
  }
127
+ /**
128
+ * Add a child to the end of the children array
129
+ */
130
+ addChild(tag) {
131
+ this.childNodes.push(tag);
132
+ return tag;
133
+ }
134
+ /**
135
+ * Remove a child from the children array.
136
+ * @returns true if node was found and removed, false if the node wasn't there and thus nothing was done
137
+ */
138
+ removeChild(tag) {
139
+ const idx = this.childNodes.indexOf(tag);
140
+ if (idx > -1) {
141
+ this.childNodes.splice(idx, 1);
142
+ return true;
143
+ }
144
+ return false;
145
+ }
146
+ /**
147
+ * Does this node have the specified attribute?
148
+ */
149
+ hasAttribute(name) {
150
+ return !!this.getAttribute(name);
151
+ }
152
+ /**
153
+ * Get an SGAttribute by its name
154
+ */
20
155
  getAttribute(name) {
21
- return this.attributes.find(att => att.key.text.toLowerCase() === name);
156
+ var _a;
157
+ const nameLower = name.toLowerCase();
158
+ for (const attr of this.attributes) {
159
+ if (((_a = attr.tokens.key) === null || _a === void 0 ? void 0 : _a.text.toLowerCase()) === nameLower) {
160
+ return attr;
161
+ }
162
+ }
22
163
  }
164
+ /**
165
+ * Get an attribute value by its name
166
+ */
23
167
  getAttributeValue(name) {
24
168
  var _a, _b;
25
- return (_b = (_a = this.getAttribute(name)) === null || _a === void 0 ? void 0 : _a.value) === null || _b === void 0 ? void 0 : _b.text;
26
- }
27
- setAttribute(name, value) {
28
- const attr = this.getAttribute(name);
29
- if (attr) {
30
- if (value) {
31
- attr.value = { text: value };
32
- attr.range = undefined;
33
- }
34
- else {
35
- this.attributes.splice(this.attributes.indexOf(attr), 1);
36
- }
169
+ return (_b = (_a = this.getAttribute(name)) === null || _a === void 0 ? void 0 : _a.tokens.value) === null || _b === void 0 ? void 0 : _b.text;
170
+ }
171
+ /**
172
+ * Set an attribute value by its name. If no attribute exists with this name, it is created
173
+ */
174
+ setAttributeValue(name, value) {
175
+ let attr = this.getAttribute(name);
176
+ //create an attribute with this name if we don't have one yet
177
+ if (!attr) {
178
+ attr = (0, creators_1.createSGAttribute)(name, value);
179
+ this.attributes.push(attr);
37
180
  }
38
- else if (value) {
39
- this.attributes.push({
40
- key: { text: name },
41
- value: { text: value }
42
- });
181
+ attr.value = value;
182
+ }
183
+ /**
184
+ * Remove an attribute by its name
185
+ * @returns true if an attribute was found and removed. False if no attribute was found
186
+ */
187
+ removeAttribute(name) {
188
+ var _a;
189
+ const nameLower = name.toLowerCase();
190
+ for (let i = 0; i < this.attributes.length; i++) {
191
+ if (((_a = this.attributes[i].key) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === nameLower) {
192
+ this.attributes.splice(i, 1);
193
+ return true;
194
+ }
43
195
  }
196
+ return false;
44
197
  }
45
198
  transpile(state) {
46
- return new source_map_1.SourceNode(null, null, state.srcPath, [
47
- state.indentText,
48
- '<',
49
- state.transpileToken(this.tag),
50
- ...this.transpileAttributes(state, this.attributes),
51
- ...this.transpileBody(state)
199
+ return new source_map_1.SourceNode(null, null, null, [
200
+ state.transpileToken(this.tokens.startTagOpen, '<'),
201
+ state.transpileToken(this.tokens.startTagName),
202
+ this.transpileAttributes(state, this.attributes),
203
+ this.transpileBody(state)
52
204
  ]);
53
205
  }
54
206
  transpileBody(state) {
55
- return [' />\n'];
207
+ var _a;
208
+ if (this.isSelfClosing) {
209
+ return new source_map_1.SourceNode(null, null, null, [
210
+ ' ',
211
+ state.transpileToken(this.tokens.startTagClose, '/>'),
212
+ state.newline
213
+ ]);
214
+ }
215
+ else {
216
+ const chunks = [
217
+ state.transpileToken(this.tokens.startTagClose, '>'),
218
+ state.newline
219
+ ];
220
+ state.blockDepth++;
221
+ for (const child of this.childNodes) {
222
+ chunks.push(state.indentText, child.transpile(state));
223
+ }
224
+ state.blockDepth--;
225
+ chunks.push(state.indentText, state.transpileToken(this.tokens.endTagOpen, '</'), state.transpileToken((_a = this.tokens.endTagName) !== null && _a !== void 0 ? _a : this.tokens.startTagName), state.transpileToken(this.tokens.endTagClose, '>'), state.newline);
226
+ return new source_map_1.SourceNode(null, null, null, chunks);
227
+ }
56
228
  }
57
229
  transpileAttributes(state, attributes) {
58
- const result = [];
230
+ const chunks = [];
59
231
  for (const attr of attributes) {
60
- result.push(' ', state.transpileToken(attr.key), '="', state.transpileToken(attr.value), '"');
232
+ chunks.push(' ', attr.transpile(state));
61
233
  }
62
- return result;
234
+ return new source_map_1.SourceNode(null, null, null, chunks);
63
235
  }
64
236
  }
65
237
  exports.SGTag = SGTag;
66
238
  class SGProlog extends SGTag {
67
- transpile(state) {
68
- return new source_map_1.SourceNode(null, null, state.srcPath, [
69
- '<?xml',
70
- ...this.transpileAttributes(state, this.attributes),
71
- ' ?>\n'
72
- ]);
73
- }
74
239
  }
75
240
  exports.SGProlog = SGProlog;
76
241
  class SGNode extends SGTag {
77
- constructor(tag, attributes, children = [], range) {
78
- super(tag, attributes, range);
79
- this.children = children;
80
- }
81
- transpileBody(state) {
82
- if (this.children.length > 0) {
83
- const body = ['>\n'];
84
- state.blockDepth++;
85
- body.push(...this.children.map(node => node.transpile(state)));
86
- state.blockDepth--;
87
- body.push(state.indentText, '</', this.tag.text, '>\n');
88
- return body;
89
- }
90
- else {
91
- return super.transpileBody(state);
92
- }
93
- }
94
242
  }
95
243
  exports.SGNode = SGNode;
96
- class SGChildren extends SGNode {
97
- constructor(tag = { text: 'children' }, children = [], range) {
98
- super(tag, [], children, range);
99
- }
244
+ class SGChildren extends SGTag {
100
245
  }
101
246
  exports.SGChildren = SGChildren;
247
+ class SGCustomization extends SGTag {
248
+ }
249
+ exports.SGCustomization = SGCustomization;
102
250
  class SGScript extends SGTag {
103
- constructor(tag = { text: 'script' }, attributes, cdata, range) {
104
- super(tag, attributes, range);
105
- this.cdata = cdata;
106
- if (!attributes) {
107
- this.type = 'text/brightscript';
108
- }
109
- }
110
251
  get type() {
111
252
  return this.getAttributeValue('type');
112
253
  }
113
254
  set type(value) {
114
- this.setAttribute('type', value);
255
+ this.setAttributeValue('type', value);
115
256
  }
116
257
  get uri() {
117
258
  return this.getAttributeValue('uri');
118
259
  }
119
260
  set uri(value) {
120
- this.setAttribute('uri', value);
261
+ this.setAttributeValue('uri', value);
121
262
  }
122
263
  transpileBody(state) {
123
264
  if (this.cdata) {
124
- return [
265
+ return new source_map_1.SourceNode(null, null, null, [
125
266
  '>',
126
267
  state.transpileToken(this.cdata),
127
268
  '</',
128
- this.tag.text,
129
- '>\n'
130
- ];
269
+ this.tokens.startTagName.text,
270
+ '>',
271
+ state.newline
272
+ ]);
131
273
  }
132
274
  else {
133
275
  return super.transpileBody(state);
134
276
  }
135
277
  }
136
278
  transpileAttributes(state, attributes) {
279
+ var _a, _b, _c;
137
280
  const modifiedAttributes = [];
138
281
  let foundType = false;
139
282
  const bsExtensionRegexp = /\.bs$/i;
140
283
  for (const attr of attributes) {
141
- const lowerKey = attr.key.text.toLowerCase();
142
- if (lowerKey === 'uri' && bsExtensionRegexp.exec(attr.value.text)) {
143
- modifiedAttributes.push(util_1.default.cloneSGAttribute(attr, attr.value.text.replace(bsExtensionRegexp, '.brs')));
284
+ const lowerKey = (_a = attr.tokens.key) === null || _a === void 0 ? void 0 : _a.text.toLowerCase();
285
+ if (lowerKey === 'uri' && bsExtensionRegexp.exec((_b = attr.tokens.value) === null || _b === void 0 ? void 0 : _b.text)) {
286
+ modifiedAttributes.push(util_1.default.cloneSGAttribute(attr, attr.tokens.value.text.replace(bsExtensionRegexp, '.brs')));
144
287
  }
145
288
  else if (lowerKey === 'type') {
146
289
  foundType = true;
147
- if (attr.value.text.toLowerCase().endsWith('brighterscript')) {
290
+ if ((_c = attr.tokens.value) === null || _c === void 0 ? void 0 : _c.text.toLowerCase().endsWith('brighterscript')) {
148
291
  modifiedAttributes.push(util_1.default.cloneSGAttribute(attr, 'text/brightscript'));
149
292
  }
150
293
  else {
@@ -156,94 +299,152 @@ class SGScript extends SGTag {
156
299
  }
157
300
  }
158
301
  if (!foundType) {
159
- modifiedAttributes.push(creators_1.createSGAttribute('type', 'text/brightscript'));
302
+ modifiedAttributes.push((0, creators_1.createSGAttribute)('type', 'text/brightscript'));
160
303
  }
161
304
  return super.transpileAttributes(state, modifiedAttributes);
162
305
  }
163
306
  }
164
307
  exports.SGScript = SGScript;
165
- class SGField extends SGTag {
166
- constructor(tag = { text: 'field' }, attributes = [], range) {
167
- super(tag, attributes, range);
168
- }
308
+ class SGInterfaceField extends SGTag {
169
309
  get type() {
170
310
  return this.getAttributeValue('type');
171
311
  }
172
312
  set type(value) {
173
- this.setAttribute('type', value);
313
+ this.setAttributeValue('type', value);
174
314
  }
175
315
  get alias() {
176
316
  return this.getAttributeValue('alias');
177
317
  }
178
318
  set alias(value) {
179
- this.setAttribute('alias', value);
319
+ this.setAttributeValue('alias', value);
180
320
  }
181
321
  get value() {
182
322
  return this.getAttributeValue('value');
183
323
  }
184
324
  set value(value) {
185
- this.setAttribute('value', value);
325
+ this.setAttributeValue('value', value);
186
326
  }
187
327
  get onChange() {
188
328
  return this.getAttributeValue('onChange');
189
329
  }
190
330
  set onChange(value) {
191
- this.setAttribute('onChange', value);
331
+ this.setAttributeValue('onChange', value);
192
332
  }
193
333
  get alwaysNotify() {
194
334
  return this.getAttributeValue('alwaysNotify');
195
335
  }
196
336
  set alwaysNotify(value) {
197
- this.setAttribute('alwaysNotify', value);
337
+ this.setAttributeValue('alwaysNotify', value);
338
+ }
339
+ get bscType() {
340
+ return getBscTypeFromSGFieldType(this.type);
198
341
  }
199
342
  }
200
- exports.SGField = SGField;
343
+ exports.SGInterfaceField = SGInterfaceField;
201
344
  exports.SGFieldTypes = [
202
345
  'integer', 'int', 'longinteger', 'float', 'string', 'str', 'boolean', 'bool',
203
346
  'vector2d', 'color', 'time', 'uri', 'node', 'floatarray', 'intarray', 'boolarray',
204
347
  'stringarray', 'vector2darray', 'colorarray', 'timearray', 'nodearray', 'assocarray',
205
348
  'array', 'roarray', 'rect2d', 'rect2darray'
206
349
  ];
207
- class SGFunction extends SGTag {
208
- constructor(tag = { text: 'function' }, attributes = [], range) {
209
- super(tag, attributes, range);
350
+ function getBscTypeFromSGFieldType(sgFieldType) {
351
+ switch (sgFieldType) {
352
+ case 'integer':
353
+ case 'int': {
354
+ return new IntegerType_1.IntegerType();
355
+ }
356
+ case 'longinteger': {
357
+ return new LongIntegerType_1.LongIntegerType();
358
+ }
359
+ case 'float': {
360
+ return new FloatType_1.FloatType();
361
+ }
362
+ case 'string':
363
+ case 'str': {
364
+ return new StringType_1.StringType();
365
+ }
366
+ case 'boolean':
367
+ case 'bool': {
368
+ return new BooleanType_1.BooleanType();
369
+ }
370
+ default: {
371
+ return new DynamicType_1.DynamicType();
372
+ }
210
373
  }
374
+ }
375
+ exports.getBscTypeFromSGFieldType = getBscTypeFromSGFieldType;
376
+ class SGInterfaceFunction extends SGTag {
211
377
  get name() {
212
378
  return this.getAttributeValue('name');
213
379
  }
214
380
  set name(value) {
215
- this.setAttribute('name', value);
381
+ this.setAttributeValue('name', value);
382
+ }
383
+ get functionType() {
384
+ const funcType = new TypedFunctionType_1.TypedFunctionType(new DynamicType_1.DynamicType());
385
+ funcType.name = this.name;
386
+ // TODO TYPES: Need to get parameter count/type for these functions for @callFunc usage
387
+ return funcType;
216
388
  }
217
389
  }
218
- exports.SGFunction = SGFunction;
390
+ exports.SGInterfaceFunction = SGInterfaceFunction;
219
391
  class SGInterface extends SGTag {
220
- constructor(tag = { text: 'interface' }, content, range) {
221
- super(tag, [], range);
222
- this.fields = [];
223
- this.functions = [];
224
- if (content) {
225
- for (const tag of content) {
226
- if (xml_1.isSGField(tag)) {
227
- this.fields.push(tag);
228
- }
229
- else if (xml_1.isSGFunction(tag)) {
230
- this.functions.push(tag);
231
- }
232
- else {
233
- throw new Error(`Unexpected tag ${tag.tag.text}`);
234
- }
392
+ get fields() {
393
+ return this.getChildNodesByTagName('field');
394
+ }
395
+ get functions() {
396
+ return this.getChildNodesByTagName('function');
397
+ }
398
+ get members() {
399
+ var _a;
400
+ const result = [];
401
+ for (const node of this.childNodes) {
402
+ const tagName = (_a = node.tagName) === null || _a === void 0 ? void 0 : _a.toLowerCase();
403
+ if (tagName === 'field' || tagName === 'function') {
404
+ result.push(node);
235
405
  }
236
406
  }
407
+ return result;
237
408
  }
409
+ /**
410
+ * Check if there's an SGField with the specified name
411
+ */
412
+ hasField(id) {
413
+ var _a;
414
+ for (const node of this.childNodes) {
415
+ const tagName = (_a = node.tagName) === null || _a === void 0 ? void 0 : _a.toLowerCase();
416
+ if (tagName === 'field' && node.id === id) {
417
+ return true;
418
+ }
419
+ }
420
+ return false;
421
+ }
422
+ /**
423
+ * Check if there's an SGFunction with the specified name
424
+ */
425
+ hasFunction(name) {
426
+ var _a;
427
+ for (const node of this.childNodes) {
428
+ const tagName = (_a = node.tagName) === null || _a === void 0 ? void 0 : _a.toLowerCase();
429
+ if (tagName === 'function' && node.name === name) {
430
+ return true;
431
+ }
432
+ }
433
+ return false;
434
+ }
435
+ /**
436
+ * Find a field by its ID
437
+ */
238
438
  getField(id) {
239
439
  return this.fields.find(field => field.id === id);
240
440
  }
441
+ /**
442
+ * Set the value of a field. Creates a new field if one does not already exist with this ID
443
+ */
241
444
  setField(id, type, onChange, alwaysNotify, alias) {
242
445
  let field = this.getField(id);
243
446
  if (!field) {
244
- field = new SGField();
245
- field.id = id;
246
- this.fields.push(field);
447
+ field = this.addChild((0, creators_1.createSGInterfaceField)(id));
247
448
  }
248
449
  field.type = type;
249
450
  field.onChange = onChange;
@@ -254,81 +455,189 @@ class SGInterface extends SGTag {
254
455
  field.alwaysNotify = alwaysNotify ? 'true' : 'false';
255
456
  }
256
457
  field.alias = alias;
458
+ return field;
459
+ }
460
+ /**
461
+ * Remove a field from the interface
462
+ * @returns true if a field was found and removed. Returns false if no field was found with that name
463
+ */
464
+ removeField(id) {
465
+ var _a;
466
+ for (let i = 0; i < this.childNodes.length; i++) {
467
+ const node = this.childNodes[i];
468
+ const tagName = (_a = node.tagName) === null || _a === void 0 ? void 0 : _a.toLowerCase();
469
+ if (tagName === 'field' && node.id === id) {
470
+ this.childNodes.splice(i, 1);
471
+ return true;
472
+ }
473
+ }
474
+ return false;
257
475
  }
476
+ /**
477
+ * Get the interface function with the specified name
478
+ */
258
479
  getFunction(name) {
259
480
  return this.functions.find(field => field.name === name);
260
481
  }
482
+ /**
483
+ * Add or replace a function on the interface
484
+ */
261
485
  setFunction(name) {
262
486
  let func = this.getFunction(name);
263
487
  if (!func) {
264
- func = new SGFunction();
265
- func.name = name;
266
- this.functions.push(func);
267
- }
268
- }
269
- transpileBody(state) {
270
- const body = ['>\n'];
271
- state.blockDepth++;
272
- if (this.fields.length > 0) {
273
- body.push(...this.fields.map(node => node.transpile(state)));
488
+ func = this.addChild((0, creators_1.createSGInterfaceFunction)(name));
274
489
  }
275
- if (this.functions.length > 0) {
276
- body.push(...this.functions.map(node => node.transpile(state)));
490
+ return func;
491
+ }
492
+ /**
493
+ * Remove a function from the interface
494
+ * @returns true if a function was found and removed. Returns false if no function was found with that name
495
+ */
496
+ removeFunction(name) {
497
+ var _a;
498
+ for (let i = 0; i < this.childNodes.length; i++) {
499
+ const node = this.childNodes[i];
500
+ const tagName = (_a = node.tagName) === null || _a === void 0 ? void 0 : _a.toLowerCase();
501
+ if (tagName === 'function' && node.getAttributeValue('name') === name) {
502
+ this.childNodes.splice(i, 1);
503
+ return true;
504
+ }
277
505
  }
278
- state.blockDepth--;
279
- body.push(state.indentText, '</', this.tag.text, '>\n');
280
- return body;
506
+ return false;
281
507
  }
282
508
  }
283
509
  exports.SGInterface = SGInterface;
284
510
  class SGComponent extends SGTag {
285
- constructor(tag = { text: 'component' }, attributes, content, range) {
286
- super(tag, attributes, range);
287
- this.scripts = [];
288
- if (content) {
289
- for (const tag of content) {
290
- if (xml_1.isSGInterface(tag)) {
291
- this.api = tag;
292
- }
293
- else if (xml_1.isSGScript(tag)) {
294
- this.scripts.push(tag);
295
- }
296
- else if (xml_1.isSGChildren(tag)) {
297
- this.children = tag;
298
- }
299
- else {
300
- throw new Error(`Unexpected tag ${tag.tag.text}`);
301
- }
302
- }
511
+ /**
512
+ * Get all the <Field> and <Function> elements across all <Interface> nodes in this component
513
+ */
514
+ get interfaceMembers() {
515
+ const members = [];
516
+ for (const ifaceNode of this.getChildNodesByTagName('interface')) {
517
+ members.push(...ifaceNode.members);
303
518
  }
519
+ return members;
520
+ }
521
+ get scripts() {
522
+ return this.getChildNodesByTagName('script');
523
+ }
524
+ /**
525
+ * Get the `<children>` element of this component. (not to be confused with the AST `childNodes` property).
526
+ * If there are multiope `<children>` elements, this function will return the last `<children>` tag because that's what Roku devices do.
527
+ */
528
+ get children() {
529
+ const children = this.getChildNodesByTagName('children');
530
+ return children[children.length - 1];
531
+ }
532
+ get customizations() {
533
+ return this.getChildNodesByTagName('customization');
304
534
  }
305
535
  get name() {
306
536
  return this.getAttributeValue('name');
307
537
  }
308
538
  set name(value) {
309
- this.setAttribute('name', value);
539
+ this.setAttributeValue('name', value);
310
540
  }
311
541
  get extends() {
312
542
  return this.getAttributeValue('extends');
313
543
  }
314
544
  set extends(value) {
315
- this.setAttribute('extends', value);
545
+ this.setAttributeValue('extends', value);
546
+ }
547
+ /**
548
+ * Does the specified field exist in the component interface?
549
+ */
550
+ hasInterfaceField(id) {
551
+ for (const ifaceNode of this.getChildNodesByTagName('interface')) {
552
+ if (ifaceNode.hasField(id)) {
553
+ return true;
554
+ }
555
+ }
556
+ return false;
557
+ }
558
+ /**
559
+ * Does the specified function exist in the component interface?
560
+ */
561
+ hasInterfaceFunction(name) {
562
+ for (const ifaceNode of this.getChildNodesByTagName('interface')) {
563
+ if (ifaceNode.hasFunction(name)) {
564
+ return true;
565
+ }
566
+ }
567
+ return false;
568
+ }
569
+ /**
570
+ * Get an interface field with the specified name
571
+ */
572
+ getInterfaceField(name) {
573
+ for (const ifaceNode of this.getChildNodesByTagName('interface')) {
574
+ const field = ifaceNode.getField(name);
575
+ if (field) {
576
+ return field;
577
+ }
578
+ }
316
579
  }
317
- transpileBody(state) {
318
- const body = ['>\n'];
319
- state.blockDepth++;
320
- if (this.api) {
321
- body.push(this.api.transpile(state));
580
+ /**
581
+ * Return the first SGInterface node found, or insert a new one then return it
582
+ */
583
+ ensureInterfaceNode() {
584
+ for (const el of this.childNodes) {
585
+ if (el.tokens.startTagName.text.toLowerCase() === 'interface') {
586
+ return el;
587
+ }
588
+ }
589
+ return this.addChild((0, creators_1.createSGInterface)());
590
+ }
591
+ /**
592
+ * Create or update a <field> interface element.
593
+ * This will create a new `<interface>` element if there are none on the component already
594
+ */
595
+ setInterfaceField(id, type, onChange, alwaysNotify, alias) {
596
+ let ifaceNode = this.ensureInterfaceNode();
597
+ return ifaceNode.setField(id, type, onChange, alwaysNotify, alias);
598
+ }
599
+ /**
600
+ * Create or update a <function> interface element.
601
+ * This will create a new `<interface>` element if there are none on the component already
602
+ */
603
+ setInterfaceFunction(name) {
604
+ let ifaceNode = this.ensureInterfaceNode();
605
+ return ifaceNode.setFunction(name);
606
+ }
607
+ /**
608
+ * Remove an interface field.
609
+ * @returns true if a field was found and removed. Returns false if no field was found with that name
610
+ */
611
+ removeInterfaceField(id) {
612
+ for (const ifaceNode of this.getChildNodesByTagName('interface')) {
613
+ if (ifaceNode.removeField(id)) {
614
+ return true;
615
+ }
322
616
  }
323
- if (this.scripts.length > 0) {
324
- body.push(...this.scripts.map(node => node.transpile(state)));
617
+ return false;
618
+ }
619
+ /**
620
+ * Get an interface field with the specified name
621
+ */
622
+ getInterfaceFunction(name) {
623
+ for (const ifaceNode of this.getChildNodesByTagName('interface')) {
624
+ const func = ifaceNode.getFunction(name);
625
+ if (func) {
626
+ return func;
627
+ }
325
628
  }
326
- if (this.children) {
327
- body.push(this.children.transpile(state));
629
+ }
630
+ /**
631
+ * Remove an interface function.
632
+ * @returns true if a function was found and removed. Returns false if no function was found with that name
633
+ */
634
+ removeInterfaceFunction(name) {
635
+ for (const ifaceNode of this.getChildNodesByTagName('interface')) {
636
+ if (ifaceNode.removeFunction(name)) {
637
+ return true;
638
+ }
328
639
  }
329
- state.blockDepth--;
330
- body.push(state.indentText, '</', this.tag.text, '>\n');
331
- return body;
640
+ return false;
332
641
  }
333
642
  }
334
643
  exports.SGComponent = SGComponent;
@@ -348,7 +657,7 @@ class SGAst {
348
657
  //write content
349
658
  chunks.push(this.component.transpile(state));
350
659
  }
351
- return chunks;
660
+ return new source_map_1.SourceNode(null, null, null, chunks);
352
661
  }
353
662
  }
354
663
  exports.SGAst = SGAst;