brighterscript 0.66.0-alpha.0 → 0.66.0-alpha.10

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 (383) hide show
  1. package/CHANGELOG.md +223 -10
  2. package/README.md +13 -3
  3. package/bsconfig.schema.json +15 -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 +150 -0
  9. package/dist/AstValidationSegmenter.js.map +1 -0
  10. package/dist/BsConfig.d.ts +13 -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 +0 -1
  17. package/dist/CodeActionUtil.d.ts +2 -2
  18. package/dist/CommentFlagProcessor.d.ts +4 -3
  19. package/dist/CommentFlagProcessor.js.map +1 -1
  20. package/dist/DiagnosticCollection.js +8 -5
  21. package/dist/DiagnosticCollection.js.map +1 -1
  22. package/dist/DiagnosticMessages.d.ts +34 -4
  23. package/dist/DiagnosticMessages.js +59 -4
  24. package/dist/DiagnosticMessages.js.map +1 -1
  25. package/dist/FunctionScope.d.ts +1 -1
  26. package/dist/LanguageServer.d.ts +23 -1
  27. package/dist/LanguageServer.js +139 -57
  28. package/dist/LanguageServer.js.map +1 -1
  29. package/dist/Logger.d.ts +3 -2
  30. package/dist/Logger.js +10 -2
  31. package/dist/Logger.js.map +1 -1
  32. package/dist/PluginInterface.d.ts +11 -2
  33. package/dist/PluginInterface.js +69 -10
  34. package/dist/PluginInterface.js.map +1 -1
  35. package/dist/Program.d.ts +138 -49
  36. package/dist/Program.js +656 -340
  37. package/dist/Program.js.map +1 -1
  38. package/dist/ProgramBuilder.d.ts +10 -4
  39. package/dist/ProgramBuilder.js +83 -66
  40. package/dist/ProgramBuilder.js.map +1 -1
  41. package/dist/Scope.d.ts +52 -49
  42. package/dist/Scope.js +312 -247
  43. package/dist/Scope.js.map +1 -1
  44. package/dist/SymbolTable.d.ts +35 -14
  45. package/dist/SymbolTable.js +89 -26
  46. package/dist/SymbolTable.js.map +1 -1
  47. package/dist/Throttler.d.ts +12 -0
  48. package/dist/Throttler.js +39 -0
  49. package/dist/Throttler.js.map +1 -1
  50. package/dist/XmlScope.d.ts +7 -4
  51. package/dist/XmlScope.js +52 -12
  52. package/dist/XmlScope.js.map +1 -1
  53. package/dist/astUtils/{AstEditor.d.ts → Editor.d.ts} +6 -1
  54. package/dist/astUtils/{AstEditor.js → Editor.js} +9 -3
  55. package/dist/astUtils/Editor.js.map +1 -0
  56. package/dist/astUtils/{AstEditor.spec.js → Editor.spec.js} +10 -6
  57. package/dist/astUtils/Editor.spec.js.map +1 -0
  58. package/dist/astUtils/creators.d.ts +3 -1
  59. package/dist/astUtils/creators.js +14 -4
  60. package/dist/astUtils/creators.js.map +1 -1
  61. package/dist/astUtils/reflection.d.ts +37 -9
  62. package/dist/astUtils/reflection.js +83 -14
  63. package/dist/astUtils/reflection.js.map +1 -1
  64. package/dist/astUtils/reflection.spec.js +87 -5
  65. package/dist/astUtils/reflection.spec.js.map +1 -1
  66. package/dist/astUtils/visitors.d.ts +14 -3
  67. package/dist/astUtils/visitors.js +22 -2
  68. package/dist/astUtils/visitors.js.map +1 -1
  69. package/dist/astUtils/visitors.spec.js +58 -7
  70. package/dist/astUtils/visitors.spec.js.map +1 -1
  71. package/dist/bscPlugin/BscPlugin.d.ts +11 -4
  72. package/dist/bscPlugin/BscPlugin.js +26 -6
  73. package/dist/bscPlugin/BscPlugin.js.map +1 -1
  74. package/dist/bscPlugin/CallExpressionInfo.d.ts +3 -3
  75. package/dist/bscPlugin/CallExpressionInfo.js.map +1 -1
  76. package/dist/bscPlugin/FileWriter.d.ts +6 -0
  77. package/dist/bscPlugin/FileWriter.js +24 -0
  78. package/dist/bscPlugin/FileWriter.js.map +1 -0
  79. package/dist/bscPlugin/codeActions/CodeActionsProcessor.js +8 -8
  80. package/dist/bscPlugin/codeActions/CodeActionsProcessor.js.map +1 -1
  81. package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js +4 -4
  82. package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js.map +1 -1
  83. package/dist/bscPlugin/completions/CompletionsProcessor.d.ts +50 -1
  84. package/dist/bscPlugin/completions/CompletionsProcessor.js +442 -23
  85. package/dist/bscPlugin/completions/CompletionsProcessor.js.map +1 -1
  86. package/dist/bscPlugin/completions/CompletionsProcessor.spec.js +1737 -0
  87. package/dist/bscPlugin/completions/CompletionsProcessor.spec.js.map +1 -0
  88. package/dist/bscPlugin/fileProviders/FileProvider.d.ts +9 -0
  89. package/dist/bscPlugin/fileProviders/FileProvider.js +51 -0
  90. package/dist/bscPlugin/fileProviders/FileProvider.js.map +1 -0
  91. package/dist/bscPlugin/hover/HoverProcessor.d.ts +7 -3
  92. package/dist/bscPlugin/hover/HoverProcessor.js +133 -103
  93. package/dist/bscPlugin/hover/HoverProcessor.js.map +1 -1
  94. package/dist/bscPlugin/hover/HoverProcessor.spec.js +241 -29
  95. package/dist/bscPlugin/hover/HoverProcessor.spec.js.map +1 -1
  96. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.d.ts +1 -0
  97. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js +43 -0
  98. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js.map +1 -1
  99. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js +22 -0
  100. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js.map +1 -1
  101. package/dist/bscPlugin/serialize/BslibInjector.spec.js +19 -0
  102. package/dist/bscPlugin/serialize/BslibInjector.spec.js.map +1 -0
  103. package/dist/bscPlugin/serialize/BslibManager.d.ts +9 -0
  104. package/dist/bscPlugin/serialize/BslibManager.js +40 -0
  105. package/dist/bscPlugin/serialize/BslibManager.js.map +1 -0
  106. package/dist/bscPlugin/serialize/FileSerializer.d.ts +9 -0
  107. package/dist/bscPlugin/serialize/FileSerializer.js +72 -0
  108. package/dist/bscPlugin/serialize/FileSerializer.js.map +1 -0
  109. package/dist/bscPlugin/transpile/{BrsFilePreTranspileProcessor.d.ts → BrsFileTranspileProcessor.d.ts} +4 -2
  110. package/dist/bscPlugin/transpile/{BrsFilePreTranspileProcessor.js → BrsFileTranspileProcessor.js} +29 -5
  111. package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.js.map +1 -0
  112. package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.spec.d.ts +1 -0
  113. package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.spec.js +41 -0
  114. package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.spec.js.map +1 -0
  115. package/dist/bscPlugin/transpile/XmlFilePreTranspileProcessor.d.ts +2 -2
  116. package/dist/bscPlugin/transpile/XmlFilePreTranspileProcessor.js.map +1 -1
  117. package/dist/bscPlugin/validation/BrsFileValidator.d.ts +0 -4
  118. package/dist/bscPlugin/validation/BrsFileValidator.js +35 -65
  119. package/dist/bscPlugin/validation/BrsFileValidator.js.map +1 -1
  120. package/dist/bscPlugin/validation/BrsFileValidator.spec.js +1 -1
  121. package/dist/bscPlugin/validation/BrsFileValidator.spec.js.map +1 -1
  122. package/dist/bscPlugin/validation/ProgramValidator.d.ts +3 -3
  123. package/dist/bscPlugin/validation/ProgramValidator.js +6 -6
  124. package/dist/bscPlugin/validation/ProgramValidator.js.map +1 -1
  125. package/dist/bscPlugin/validation/ScopeValidator.d.ts +28 -7
  126. package/dist/bscPlugin/validation/ScopeValidator.js +393 -205
  127. package/dist/bscPlugin/validation/ScopeValidator.js.map +1 -1
  128. package/dist/bscPlugin/validation/ScopeValidator.spec.d.ts +1 -0
  129. package/dist/bscPlugin/validation/ScopeValidator.spec.js +2038 -0
  130. package/dist/bscPlugin/validation/ScopeValidator.spec.js.map +1 -0
  131. package/dist/bscPlugin/validation/XmlFileValidator.js +2 -2
  132. package/dist/bscPlugin/validation/XmlFileValidator.js.map +1 -1
  133. package/dist/cli.js +104 -13
  134. package/dist/cli.js.map +1 -1
  135. package/dist/deferred.d.ts +3 -3
  136. package/dist/deferred.js.map +1 -1
  137. package/dist/diagnosticUtils.d.ts +8 -2
  138. package/dist/diagnosticUtils.js +45 -16
  139. package/dist/diagnosticUtils.js.map +1 -1
  140. package/dist/examples/plugins/removePrint.js +1 -1
  141. package/dist/examples/plugins/removePrint.js.map +1 -1
  142. package/dist/files/AssetFile.d.ts +26 -0
  143. package/dist/files/AssetFile.js +26 -0
  144. package/dist/files/AssetFile.js.map +1 -0
  145. package/dist/files/BrsFile.Class.spec.js +383 -56
  146. package/dist/files/BrsFile.Class.spec.js.map +1 -1
  147. package/dist/files/BrsFile.d.ts +73 -46
  148. package/dist/files/BrsFile.js +370 -534
  149. package/dist/files/BrsFile.js.map +1 -1
  150. package/dist/files/BrsFile.spec.js +1139 -682
  151. package/dist/files/BrsFile.spec.js.map +1 -1
  152. package/dist/files/Factory.d.ts +25 -0
  153. package/dist/files/Factory.js +22 -0
  154. package/dist/files/Factory.js.map +1 -0
  155. package/dist/files/File.d.ts +106 -0
  156. package/dist/files/File.js +16 -0
  157. package/dist/files/File.js.map +1 -0
  158. package/dist/files/LazyFileData.d.ts +20 -0
  159. package/dist/files/LazyFileData.js +54 -0
  160. package/dist/files/LazyFileData.js.map +1 -0
  161. package/dist/files/LazyFileData.spec.d.ts +1 -0
  162. package/dist/files/LazyFileData.spec.js +27 -0
  163. package/dist/files/LazyFileData.spec.js.map +1 -0
  164. package/dist/files/XmlFile.d.ts +56 -23
  165. package/dist/files/XmlFile.js +88 -60
  166. package/dist/files/XmlFile.js.map +1 -1
  167. package/dist/files/XmlFile.spec.js +63 -91
  168. package/dist/files/XmlFile.spec.js.map +1 -1
  169. package/dist/files/tests/imports.spec.js +21 -8
  170. package/dist/files/tests/imports.spec.js.map +1 -1
  171. package/dist/files/tests/optionalChaning.spec.js +14 -14
  172. package/dist/files/tests/optionalChaning.spec.js.map +1 -1
  173. package/dist/globalCallables.js +88 -84
  174. package/dist/globalCallables.js.map +1 -1
  175. package/dist/index.d.ts +9 -1
  176. package/dist/index.js +9 -1
  177. package/dist/index.js.map +1 -1
  178. package/dist/interfaces.d.ts +436 -81
  179. package/dist/interfaces.js +13 -2
  180. package/dist/interfaces.js.map +1 -1
  181. package/dist/lexer/Lexer.d.ts +12 -0
  182. package/dist/lexer/Lexer.js +28 -8
  183. package/dist/lexer/Lexer.js.map +1 -1
  184. package/dist/lexer/Lexer.spec.js +40 -0
  185. package/dist/lexer/Lexer.spec.js.map +1 -1
  186. package/dist/lexer/Token.d.ts +4 -0
  187. package/dist/lexer/Token.js.map +1 -1
  188. package/dist/lexer/TokenKind.d.ts +5 -0
  189. package/dist/lexer/TokenKind.js +14 -2
  190. package/dist/lexer/TokenKind.js.map +1 -1
  191. package/dist/parser/AstNode.d.ts +9 -2
  192. package/dist/parser/AstNode.js +16 -0
  193. package/dist/parser/AstNode.js.map +1 -1
  194. package/dist/parser/BrsTranspileState.d.ts +3 -2
  195. package/dist/parser/BrsTranspileState.js +3 -2
  196. package/dist/parser/BrsTranspileState.js.map +1 -1
  197. package/dist/parser/Expression.d.ts +21 -5
  198. package/dist/parser/Expression.js +128 -35
  199. package/dist/parser/Expression.js.map +1 -1
  200. package/dist/parser/Parser.Class.spec.js +103 -1
  201. package/dist/parser/Parser.Class.spec.js.map +1 -1
  202. package/dist/parser/Parser.d.ts +7 -0
  203. package/dist/parser/Parser.js +117 -21
  204. package/dist/parser/Parser.js.map +1 -1
  205. package/dist/parser/Parser.spec.js +557 -5
  206. package/dist/parser/Parser.spec.js.map +1 -1
  207. package/dist/parser/SGParser.d.ts +4 -4
  208. package/dist/parser/SGParser.js +3 -3
  209. package/dist/parser/SGParser.js.map +1 -1
  210. package/dist/parser/SGParser.spec.js +2 -2
  211. package/dist/parser/SGParser.spec.js.map +1 -1
  212. package/dist/parser/SGTypes.d.ts +2 -2
  213. package/dist/parser/Statement.d.ts +37 -12
  214. package/dist/parser/Statement.js +153 -46
  215. package/dist/parser/Statement.js.map +1 -1
  216. package/dist/parser/tests/Parser.spec.js +2 -1
  217. package/dist/parser/tests/Parser.spec.js.map +1 -1
  218. package/dist/parser/tests/controlFlow/For.spec.js +16 -8
  219. package/dist/parser/tests/controlFlow/For.spec.js.map +1 -1
  220. package/dist/parser/tests/controlFlow/ForEach.spec.js +12 -6
  221. package/dist/parser/tests/controlFlow/ForEach.spec.js.map +1 -1
  222. package/dist/parser/tests/controlFlow/While.spec.js +8 -4
  223. package/dist/parser/tests/controlFlow/While.spec.js.map +1 -1
  224. package/dist/parser/tests/expression/Call.spec.js +4 -4
  225. package/dist/parser/tests/expression/Call.spec.js.map +1 -1
  226. package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js +29 -29
  227. package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js.map +1 -1
  228. package/dist/parser/tests/expression/RegexLiteralExpression.spec.js +10 -10
  229. package/dist/parser/tests/expression/RegexLiteralExpression.spec.js.map +1 -1
  230. package/dist/parser/tests/expression/SourceLiteralExpression.spec.js +24 -24
  231. package/dist/parser/tests/expression/SourceLiteralExpression.spec.js.map +1 -1
  232. package/dist/parser/tests/expression/TemplateStringExpression.spec.js +75 -36
  233. package/dist/parser/tests/expression/TemplateStringExpression.spec.js.map +1 -1
  234. package/dist/parser/tests/expression/TernaryExpression.spec.js +36 -36
  235. package/dist/parser/tests/expression/TernaryExpression.spec.js.map +1 -1
  236. package/dist/parser/tests/expression/UnaryExpression.spec.d.ts +1 -0
  237. package/dist/parser/tests/expression/UnaryExpression.spec.js +52 -0
  238. package/dist/parser/tests/expression/UnaryExpression.spec.js.map +1 -0
  239. package/dist/parser/tests/statement/ConstStatement.spec.js +71 -22
  240. package/dist/parser/tests/statement/ConstStatement.spec.js.map +1 -1
  241. package/dist/parser/tests/statement/Continue.spec.js +2 -2
  242. package/dist/parser/tests/statement/Continue.spec.js.map +1 -1
  243. package/dist/parser/tests/statement/Enum.spec.js +38 -285
  244. package/dist/parser/tests/statement/Enum.spec.js.map +1 -1
  245. package/dist/parser/tests/statement/For.spec.js +6 -6
  246. package/dist/parser/tests/statement/For.spec.js.map +1 -1
  247. package/dist/parser/tests/statement/ForEach.spec.js +4 -4
  248. package/dist/parser/tests/statement/ForEach.spec.js.map +1 -1
  249. package/dist/parser/tests/statement/InterfaceStatement.spec.js +26 -10
  250. package/dist/parser/tests/statement/InterfaceStatement.spec.js.map +1 -1
  251. package/dist/parser/tests/statement/PrintStatement.spec.js +16 -13
  252. package/dist/parser/tests/statement/PrintStatement.spec.js.map +1 -1
  253. package/dist/parser/tests/statement/ReturnStatement.spec.js +5 -3
  254. package/dist/parser/tests/statement/ReturnStatement.spec.js.map +1 -1
  255. package/dist/parser/tests/statement/Set.spec.js +26 -13
  256. package/dist/parser/tests/statement/Set.spec.js.map +1 -1
  257. package/dist/preprocessor/Manifest.d.ts +1 -1
  258. package/dist/preprocessor/Manifest.js +2 -2
  259. package/dist/preprocessor/Manifest.js.map +1 -1
  260. package/dist/roku-types/data.json +243 -293
  261. package/dist/roku-types/index.d.ts +17 -38
  262. package/dist/types/ArrayType.d.ts +4 -1
  263. package/dist/types/ArrayType.js +46 -6
  264. package/dist/types/ArrayType.js.map +1 -1
  265. package/dist/types/ArrayType.spec.js +32 -3
  266. package/dist/types/ArrayType.spec.js.map +1 -1
  267. package/dist/types/AssociativeArrayType.d.ts +11 -0
  268. package/dist/types/AssociativeArrayType.js +52 -0
  269. package/dist/types/AssociativeArrayType.js.map +1 -0
  270. package/dist/types/BaseFunctionType.d.ts +9 -0
  271. package/dist/types/BaseFunctionType.js +25 -0
  272. package/dist/types/BaseFunctionType.js.map +1 -0
  273. package/dist/types/BooleanType.d.ts +2 -1
  274. package/dist/types/BooleanType.js +8 -2
  275. package/dist/types/BooleanType.js.map +1 -1
  276. package/dist/types/BscType.d.ts +10 -6
  277. package/dist/types/BscType.js +69 -16
  278. package/dist/types/BscType.js.map +1 -1
  279. package/dist/types/BscTypeKind.d.ts +3 -0
  280. package/dist/types/BscTypeKind.js +3 -0
  281. package/dist/types/BscTypeKind.js.map +1 -1
  282. package/dist/types/BuiltInInterfaceAdder.d.ts +23 -0
  283. package/dist/types/BuiltInInterfaceAdder.js +157 -0
  284. package/dist/types/BuiltInInterfaceAdder.js.map +1 -0
  285. package/dist/types/BuiltInInterfaceAdder.spec.d.ts +1 -0
  286. package/dist/types/BuiltInInterfaceAdder.spec.js +116 -0
  287. package/dist/types/BuiltInInterfaceAdder.spec.js.map +1 -0
  288. package/dist/types/ClassType.d.ts +10 -4
  289. package/dist/types/ClassType.js +32 -5
  290. package/dist/types/ClassType.js.map +1 -1
  291. package/dist/types/ClassType.spec.js +5 -3
  292. package/dist/types/ClassType.spec.js.map +1 -1
  293. package/dist/types/ComponentType.d.ts +26 -0
  294. package/dist/types/ComponentType.js +83 -0
  295. package/dist/types/ComponentType.js.map +1 -0
  296. package/dist/types/DoubleType.d.ts +2 -1
  297. package/dist/types/DoubleType.js +9 -2
  298. package/dist/types/DoubleType.js.map +1 -1
  299. package/dist/types/DynamicType.d.ts +2 -2
  300. package/dist/types/DynamicType.js +3 -1
  301. package/dist/types/DynamicType.js.map +1 -1
  302. package/dist/types/EnumType.d.ts +24 -6
  303. package/dist/types/EnumType.js +29 -7
  304. package/dist/types/EnumType.js.map +1 -1
  305. package/dist/types/FloatType.d.ts +2 -1
  306. package/dist/types/FloatType.js +9 -2
  307. package/dist/types/FloatType.js.map +1 -1
  308. package/dist/types/FunctionType.d.ts +8 -20
  309. package/dist/types/FunctionType.js +17 -45
  310. package/dist/types/FunctionType.js.map +1 -1
  311. package/dist/types/InheritableType.d.ts +7 -4
  312. package/dist/types/InheritableType.js +67 -3
  313. package/dist/types/InheritableType.js.map +1 -1
  314. package/dist/types/IntegerType.d.ts +2 -1
  315. package/dist/types/IntegerType.js +9 -2
  316. package/dist/types/IntegerType.js.map +1 -1
  317. package/dist/types/InterfaceType.d.ts +6 -4
  318. package/dist/types/InterfaceType.js +8 -11
  319. package/dist/types/InterfaceType.js.map +1 -1
  320. package/dist/types/InterfaceType.spec.js +30 -2
  321. package/dist/types/InterfaceType.spec.js.map +1 -1
  322. package/dist/types/InvalidType.d.ts +2 -1
  323. package/dist/types/InvalidType.js +7 -1
  324. package/dist/types/InvalidType.js.map +1 -1
  325. package/dist/types/LongIntegerType.d.ts +2 -1
  326. package/dist/types/LongIntegerType.js +9 -2
  327. package/dist/types/LongIntegerType.js.map +1 -1
  328. package/dist/types/NamespaceType.d.ts +2 -1
  329. package/dist/types/NamespaceType.js +3 -0
  330. package/dist/types/NamespaceType.js.map +1 -1
  331. package/dist/types/ObjectType.d.ts +2 -2
  332. package/dist/types/ObjectType.js +5 -10
  333. package/dist/types/ObjectType.js.map +1 -1
  334. package/dist/types/ReferenceType.d.ts +15 -3
  335. package/dist/types/ReferenceType.js +173 -24
  336. package/dist/types/ReferenceType.js.map +1 -1
  337. package/dist/types/ReferenceType.spec.js +21 -6
  338. package/dist/types/ReferenceType.spec.js.map +1 -1
  339. package/dist/types/StringType.d.ts +2 -1
  340. package/dist/types/StringType.js +9 -2
  341. package/dist/types/StringType.js.map +1 -1
  342. package/dist/types/TypedFunctionType.d.ts +33 -0
  343. package/dist/types/TypedFunctionType.js +106 -0
  344. package/dist/types/TypedFunctionType.js.map +1 -0
  345. package/dist/types/TypedFunctionType.spec.d.ts +1 -0
  346. package/dist/types/TypedFunctionType.spec.js +122 -0
  347. package/dist/types/TypedFunctionType.spec.js.map +1 -0
  348. package/dist/types/UninitializedType.d.ts +2 -1
  349. package/dist/types/UninitializedType.js +1 -1
  350. package/dist/types/UninitializedType.js.map +1 -1
  351. package/dist/types/UnionType.d.ts +4 -2
  352. package/dist/types/UnionType.js +36 -4
  353. package/dist/types/UnionType.js.map +1 -1
  354. package/dist/types/UnionType.spec.js +46 -19
  355. package/dist/types/UnionType.spec.js.map +1 -1
  356. package/dist/types/VoidType.d.ts +2 -1
  357. package/dist/types/VoidType.js +7 -2
  358. package/dist/types/VoidType.js.map +1 -1
  359. package/dist/types/helper.spec.js +15 -0
  360. package/dist/types/helper.spec.js.map +1 -1
  361. package/dist/types/helpers.d.ts +5 -0
  362. package/dist/types/helpers.js +50 -3
  363. package/dist/types/helpers.js.map +1 -1
  364. package/dist/types/index.d.ts +1 -1
  365. package/dist/types/index.js +1 -1
  366. package/dist/types/index.js.map +1 -1
  367. package/dist/util.d.ts +71 -15
  368. package/dist/util.js +578 -150
  369. package/dist/util.js.map +1 -1
  370. package/dist/validators/ClassValidator.d.ts +0 -1
  371. package/dist/validators/ClassValidator.js +0 -22
  372. package/dist/validators/ClassValidator.js.map +1 -1
  373. package/package.json +3 -2
  374. package/dist/astUtils/AstEditor.js.map +0 -1
  375. package/dist/astUtils/AstEditor.spec.js.map +0 -1
  376. package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.js.map +0 -1
  377. package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.js +0 -31
  378. package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.js.map +0 -1
  379. package/dist/types/FunctionType.spec.js +0 -23
  380. package/dist/types/FunctionType.spec.js.map +0 -1
  381. /package/dist/astUtils/{AstEditor.spec.d.ts → Editor.spec.d.ts} +0 -0
  382. /package/dist/bscPlugin/{transpile/BrsFilePreTranspileProcessor.spec.d.ts → completions/CompletionsProcessor.spec.d.ts} +0 -0
  383. /package/dist/{types/FunctionType.spec.d.ts → bscPlugin/serialize/BslibInjector.spec.d.ts} +0 -0
package/dist/util.js CHANGED
@@ -13,9 +13,7 @@ const BooleanType_1 = require("./types/BooleanType");
13
13
  const DoubleType_1 = require("./types/DoubleType");
14
14
  const DynamicType_1 = require("./types/DynamicType");
15
15
  const FloatType_1 = require("./types/FloatType");
16
- const FunctionType_1 = require("./types/FunctionType");
17
16
  const IntegerType_1 = require("./types/IntegerType");
18
- const InvalidType_1 = require("./types/InvalidType");
19
17
  const LongIntegerType_1 = require("./types/LongIntegerType");
20
18
  const ObjectType_1 = require("./types/ObjectType");
21
19
  const StringType_1 = require("./types/StringType");
@@ -27,8 +25,28 @@ const reflection_1 = require("./astUtils/reflection");
27
25
  const visitors_1 = require("./astUtils/visitors");
28
26
  const source_map_1 = require("source-map");
29
27
  const requireRelative = require("require-relative");
28
+ const AstNode_1 = require("./parser/AstNode");
30
29
  const creators_1 = require("./astUtils/creators");
30
+ const FunctionType_1 = require("./types/FunctionType");
31
+ const ArrayType_1 = require("./types/ArrayType");
32
+ const SymbolTable_1 = require("./SymbolTable");
33
+ const AssociativeArrayType_1 = require("./types/AssociativeArrayType");
34
+ const ComponentType_1 = require("./types/ComponentType");
35
+ const diagnosticUtils_1 = require("./diagnosticUtils");
36
+ const ReferenceType_1 = require("./types/ReferenceType");
31
37
  class Util {
38
+ constructor() {
39
+ /**
40
+ * A cache of `Range` objects. The key is a 52bit integer created from the 4 range integers and leveraging bitshifting.
41
+ * The whole point of this cache is to reduce garbage collection churn, so we didn't want to use string concatenation for the key
42
+ */
43
+ this.rangeCache = new Map();
44
+ /**
45
+ * A cache of `Position` objects. The key is a 26bit integer created from line and character and leveraging bitshifting
46
+ * The whole point of this cache is to reduce garbage collection churn, so we didn't want to use string concatenation for the key
47
+ */
48
+ this.positionCache = new Map();
49
+ }
32
50
  clearConsole() {
33
51
  // process.stdout.write('\x1Bc');
34
52
  }
@@ -75,12 +93,10 @@ class Util {
75
93
  * Given a pkg path of any kind, transform it to a roku-specific pkg path (i.e. "pkg:/some/path.brs")
76
94
  */
77
95
  sanitizePkgPath(pkgPath) {
78
- pkgPath = pkgPath.replace(/\\/g, '/');
79
- //if there's no protocol, assume it's supposed to start with `pkg:/`
80
- if (!this.startsWithProtocol(pkgPath)) {
81
- pkgPath = 'pkg:/' + pkgPath;
82
- }
83
- return pkgPath;
96
+ //convert all slashes to forwardslash
97
+ pkgPath = pkgPath.replace(/[\/\\]+/g, '/');
98
+ //ensure every path has the leading pkg:/
99
+ return 'pkg:/' + pkgPath.replace(/^pkg:\//i, '');
84
100
  }
85
101
  /**
86
102
  * Determine if the given path starts with a protocol
@@ -90,10 +106,10 @@ class Util {
90
106
  }
91
107
  /**
92
108
  * Given a pkg path of any kind, transform it to a roku-specific pkg path (i.e. "pkg:/some/path.brs")
109
+ * @deprecated use `sanitizePkgPath instead. Will be removed in v1
93
110
  */
94
111
  getRokuPkgPath(pkgPath) {
95
- pkgPath = pkgPath.replace(/\\/g, '/');
96
- return 'pkg:/' + pkgPath;
112
+ return this.sanitizePkgPath(pkgPath);
97
113
  }
98
114
  /**
99
115
  * Given a path to a file/directory, replace all path separators with the current system's version.
@@ -269,6 +285,9 @@ class Util {
269
285
  */
270
286
  normalizeAndResolveConfig(config) {
271
287
  let result = this.normalizeConfig({});
288
+ if (config === null || config === void 0 ? void 0 : config.noProject) {
289
+ return result;
290
+ }
272
291
  //if no options were provided, try to find a bsconfig.json file
273
292
  if (!config || !config.project) {
274
293
  result.project = this.getConfigFilePath(config === null || config === void 0 ? void 0 : config.cwd);
@@ -290,7 +309,7 @@ class Util {
290
309
  * @param config a bsconfig object to use as the baseline for the resulting config
291
310
  */
292
311
  normalizeConfig(config) {
293
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
312
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
294
313
  config = config || {};
295
314
  config.cwd = (_a = config.cwd) !== null && _a !== void 0 ? _a : process.cwd();
296
315
  config.deploy = config.deploy === true ? true : false;
@@ -315,11 +334,15 @@ class Util {
315
334
  config.allowBrighterScriptInBrightScript = config.allowBrighterScriptInBrightScript === true ? true : false;
316
335
  config.emitDefinitions = config.emitDefinitions === true ? true : false;
317
336
  config.removeParameterTypes = config.removeParameterTypes === true ? true : false;
318
- config.enableTypeValidation = config.enableTypeValidation === true ? true : false;
319
337
  if (typeof config.logLevel === 'string') {
320
338
  config.logLevel = Logger_1.LogLevel[config.logLevel.toLowerCase()];
321
339
  }
322
340
  config.logLevel = (_k = config.logLevel) !== null && _k !== void 0 ? _k : Logger_1.LogLevel.log;
341
+ config.bslibDestinationDir = (_l = config.bslibDestinationDir) !== null && _l !== void 0 ? _l : 'source';
342
+ if (config.bslibDestinationDir !== 'source') {
343
+ // strip leading and trailing slashes
344
+ config.bslibDestinationDir = config.bslibDestinationDir.replace(/^(\/*)(.*?)(\/*)$/, '$2');
345
+ }
323
346
  return config;
324
347
  }
325
348
  /**
@@ -462,6 +485,10 @@ class Util {
462
485
  * ```
463
486
  */
464
487
  rangesIntersect(a, b) {
488
+ //stop if the either range is misisng
489
+ if (!a || !b) {
490
+ return false;
491
+ }
465
492
  // Check if `a` is before `b`
466
493
  if (a.end.line < b.start.line || (a.end.line === b.start.line && a.end.character <= b.start.character)) {
467
494
  return false;
@@ -483,6 +510,10 @@ class Util {
483
510
  * ```
484
511
  */
485
512
  rangesIntersectOrTouch(a, b) {
513
+ //stop if the either range is misisng
514
+ if (!a || !b) {
515
+ return false;
516
+ }
486
517
  // Check if `a` is before `b`
487
518
  if (a.end.line < b.start.line || (a.end.line === b.start.line && a.end.character < b.start.character)) {
488
519
  return false;
@@ -502,6 +533,10 @@ class Util {
502
533
  return this.comparePositionToRange(position, range) === 0;
503
534
  }
504
535
  comparePositionToRange(position, range) {
536
+ //stop if the either range is misisng
537
+ if (!position || !range) {
538
+ return 0;
539
+ }
505
540
  if (position.line < range.start.line || (position.line === range.start.line && position.character < range.start.character)) {
506
541
  return -1;
507
542
  }
@@ -510,6 +545,65 @@ class Util {
510
545
  }
511
546
  return 0;
512
547
  }
548
+ /**
549
+ * Combine all the documentation found before a token (i.e. comment tokens)
550
+ */
551
+ getTokenDocumentation(tokens, token) {
552
+ const comments = [];
553
+ const idx = tokens === null || tokens === void 0 ? void 0 : tokens.indexOf(token);
554
+ if (!idx || idx === -1) {
555
+ return undefined;
556
+ }
557
+ for (let i = idx - 1; i >= 0; i--) {
558
+ const token = tokens[i];
559
+ //skip whitespace and newline chars
560
+ if (token.kind === TokenKind_1.TokenKind.Comment) {
561
+ comments.push(token);
562
+ }
563
+ else if (token.kind === TokenKind_1.TokenKind.Newline || token.kind === TokenKind_1.TokenKind.Whitespace) {
564
+ //skip these tokens
565
+ continue;
566
+ //any other token means there are no more comments
567
+ }
568
+ else {
569
+ break;
570
+ }
571
+ }
572
+ if (comments.length > 0) {
573
+ return comments.reverse().map(x => x.text.replace(/^('|rem)/i, '').trim()).map(line => {
574
+ if (line.startsWith('@')) {
575
+ // Handle jsdoc/brightscriptdoc tags specially
576
+ // make sure they are on their own markdown line, and add italics
577
+ const firstSpaceIndex = line.indexOf(' ');
578
+ if (firstSpaceIndex === -1) {
579
+ return `\n_${line}_`;
580
+ }
581
+ const firstWord = line.substring(0, firstSpaceIndex);
582
+ return `\n_${firstWord}_ ${line.substring(firstSpaceIndex + 1)}`;
583
+ }
584
+ return line;
585
+ }).join('\n');
586
+ }
587
+ }
588
+ /**
589
+ * Combine all the documentation for a node - uses the AstNode's leadingTrivia property
590
+ */
591
+ getNodeDocumentation(node) {
592
+ if (!node) {
593
+ return;
594
+ }
595
+ const leadingTrivia = node.getLeadingTrivia();
596
+ return this.getTokenDocumentation(leadingTrivia, leadingTrivia[leadingTrivia.length - 1]);
597
+ }
598
+ /**
599
+ * Prefixes a component name so it can be used as type in the symbol table, without polluting available symbols
600
+ *
601
+ * @param sgNodeName the Name of the component
602
+ * @returns the node name, prefixed with `roSGNode`
603
+ */
604
+ getSgNodeTypeName(sgNodeName) {
605
+ return 'roSGNode' + sgNodeName;
606
+ }
513
607
  /**
514
608
  * Parse an xml file and get back a javascript object containing its results
515
609
  */
@@ -649,13 +743,14 @@ class Util {
649
743
  const diagnosticCode = typeof diagnostic.code === 'string' ? diagnostic.code.toLowerCase() : diagnostic.code;
650
744
  for (let flag of (_b = (_a = diagnostic.file) === null || _a === void 0 ? void 0 : _a.commentFlags) !== null && _b !== void 0 ? _b : []) {
651
745
  //this diagnostic is affected by this flag
652
- if (this.rangeContains(flag.affectedRange, diagnostic.range.start)) {
746
+ if (diagnostic.range && this.rangeContains(flag.affectedRange, diagnostic.range.start)) {
653
747
  //if the flag acts upon this diagnostic's code
654
748
  if (flag.codes === null || flag.codes.includes(diagnosticCode)) {
655
749
  return true;
656
750
  }
657
751
  }
658
752
  }
753
+ return false;
659
754
  }
660
755
  /**
661
756
  * Walks up the chain to find the closest bsconfig.json file
@@ -836,31 +931,23 @@ class Util {
836
931
  * Helper for creating `Range` objects. Prefer using this function because vscode-languageserver's `Range.create()` is significantly slower
837
932
  */
838
933
  createRange(startLine, startCharacter, endLine, endCharacter) {
839
- return {
840
- start: {
841
- line: startLine,
842
- character: startCharacter
843
- },
844
- end: {
845
- line: endLine,
846
- character: endCharacter
847
- }
848
- };
934
+ // eslint-disable-next-line no-bitwise
935
+ const key = (startLine << 39) + (startCharacter << 26) + (endLine << 13) + endCharacter;
936
+ let range = this.rangeCache.get(key);
937
+ if (!range) {
938
+ range = {
939
+ start: this.createPosition(startLine, startCharacter),
940
+ end: this.createPosition(endLine, endCharacter)
941
+ };
942
+ this.rangeCache.set(key, range);
943
+ }
944
+ return range;
849
945
  }
850
946
  /**
851
947
  * Create a `Range` from two `Position`s
852
948
  */
853
949
  createRangeFromPositions(startPosition, endPosition) {
854
- return {
855
- start: {
856
- line: startPosition.line,
857
- character: startPosition.character
858
- },
859
- end: {
860
- line: endPosition.line,
861
- character: endPosition.character
862
- }
863
- };
950
+ return this.createRange(startPosition.line, startPosition.character, endPosition.line, endPosition.character);
864
951
  }
865
952
  /**
866
953
  * Given a list of ranges, create a range that starts with the first non-null lefthand range, and ends with the first non-null
@@ -900,10 +987,17 @@ class Util {
900
987
  * Create a `Position` object. Prefer this over `Position.create` for performance reasons
901
988
  */
902
989
  createPosition(line, character) {
903
- return {
904
- line: line,
905
- character: character
906
- };
990
+ // eslint-disable-next-line no-bitwise
991
+ const key = (line << 13) + character;
992
+ let position = this.positionCache.get(key);
993
+ if (!position) {
994
+ position = {
995
+ line: line,
996
+ character: character
997
+ };
998
+ this.positionCache.set(key, position);
999
+ }
1000
+ return position;
907
1001
  }
908
1002
  /**
909
1003
  * Convert a list of tokens into a string, including their leading whitespace
@@ -938,14 +1032,13 @@ class Util {
938
1032
  case TokenKind_1.TokenKind.FloatLiteral:
939
1033
  return FloatType_1.FloatType.instance;
940
1034
  case TokenKind_1.TokenKind.Function:
941
- //TODO should there be a more generic function type without a signature that's assignable to all other function types?
942
- return new FunctionType_1.FunctionType(new DynamicType_1.DynamicType(token.text));
1035
+ return new FunctionType_1.FunctionType(token.text);
943
1036
  case TokenKind_1.TokenKind.Integer:
944
1037
  return new IntegerType_1.IntegerType(token.text);
945
1038
  case TokenKind_1.TokenKind.IntegerLiteral:
946
1039
  return IntegerType_1.IntegerType.instance;
947
1040
  case TokenKind_1.TokenKind.Invalid:
948
- return new InvalidType_1.InvalidType(token.text);
1041
+ return DynamicType_1.DynamicType.instance; // TODO: use InvalidType better new InvalidType(token.text);
949
1042
  case TokenKind_1.TokenKind.LongInteger:
950
1043
  return new LongIntegerType_1.LongIntegerType(token.text);
951
1044
  case TokenKind_1.TokenKind.LongIntegerLiteral:
@@ -972,11 +1065,11 @@ class Util {
972
1065
  case 'float':
973
1066
  return new FloatType_1.FloatType(token.text);
974
1067
  case 'function':
975
- return new FunctionType_1.FunctionType(new DynamicType_1.DynamicType(token.text));
1068
+ return new FunctionType_1.FunctionType(token.text);
976
1069
  case 'integer':
977
1070
  return new IntegerType_1.IntegerType(token.text);
978
1071
  case 'invalid':
979
- return new InvalidType_1.InvalidType(token.text);
1072
+ return DynamicType_1.DynamicType.instance; // TODO: use InvalidType better new InvalidType(token.text);
980
1073
  case 'longinteger':
981
1074
  return new LongIntegerType_1.LongIntegerType(token.text);
982
1075
  case 'object':
@@ -988,9 +1081,244 @@ class Util {
988
1081
  }
989
1082
  }
990
1083
  }
1084
+ /**
1085
+ * Deciphers the correct types for fields based on docs
1086
+ * https://developer.roku.com/en-ca/docs/references/scenegraph/xml-elements/interface.md
1087
+ * @param typeDescriptor the type descriptor from the docs
1088
+ * @returns {BscType} the known type, or dynamic
1089
+ */
1090
+ getNodeFieldType(typeDescriptor, lookupTable) {
1091
+ const typeDescriptorLower = typeDescriptor.toLowerCase().trim();
1092
+ const bscType = this.tokenToBscType((0, creators_1.createToken)(TokenKind_1.TokenKind.Identifier, typeDescriptorLower));
1093
+ if (bscType) {
1094
+ return bscType;
1095
+ }
1096
+ if (typeDescriptorLower.startsWith('array of ')) {
1097
+ let arrayOfTypeName = typeDescriptorLower.substring(9); //cut off beginning 'array of'
1098
+ if (arrayOfTypeName.endsWith('s')) {
1099
+ // remove "s" in "floats", etc.
1100
+ arrayOfTypeName = arrayOfTypeName.substring(0, arrayOfTypeName.length - 1);
1101
+ }
1102
+ if (arrayOfTypeName.endsWith('\'')) {
1103
+ // remove "'" in "float's", etc.
1104
+ arrayOfTypeName = arrayOfTypeName.substring(0, arrayOfTypeName.length - 1);
1105
+ }
1106
+ let arrayType = this.getNodeFieldType(arrayOfTypeName, lookupTable);
1107
+ return new ArrayType_1.ArrayType(arrayType);
1108
+ }
1109
+ else if (typeDescriptorLower.startsWith('option ')) {
1110
+ const actualTypeName = typeDescriptorLower.substring('option '.length); //cut off beginning 'option '
1111
+ return this.getNodeFieldType(actualTypeName, lookupTable);
1112
+ }
1113
+ else if (typeDescriptorLower.startsWith('value ')) {
1114
+ const actualTypeName = typeDescriptorLower.substring('value '.length); //cut off beginning 'value '
1115
+ return this.getNodeFieldType(actualTypeName, lookupTable);
1116
+ }
1117
+ else if (typeDescriptorLower === 'uri') {
1118
+ return StringType_1.StringType.instance;
1119
+ }
1120
+ else if (typeDescriptorLower === 'vector2d' || typeDescriptorLower === 'floatarray') {
1121
+ return new ArrayType_1.ArrayType(FloatType_1.FloatType.instance);
1122
+ }
1123
+ else if (typeDescriptorLower === 'intarray') {
1124
+ return new ArrayType_1.ArrayType(IntegerType_1.IntegerType.instance);
1125
+ }
1126
+ else if (typeDescriptorLower === 'boolarray') {
1127
+ return new ArrayType_1.ArrayType(BooleanType_1.BooleanType.instance);
1128
+ }
1129
+ else if (typeDescriptorLower === 'stringarray' || typeDescriptorLower === 'strarray') {
1130
+ return new ArrayType_1.ArrayType(StringType_1.StringType.instance);
1131
+ }
1132
+ else if (typeDescriptorLower === 'int') {
1133
+ return IntegerType_1.IntegerType.instance;
1134
+ }
1135
+ else if (typeDescriptorLower === 'time') {
1136
+ return FloatType_1.FloatType.instance;
1137
+ }
1138
+ else if (typeDescriptorLower === 'str') {
1139
+ return StringType_1.StringType.instance;
1140
+ }
1141
+ else if (typeDescriptorLower === 'bool') {
1142
+ return BooleanType_1.BooleanType.instance;
1143
+ }
1144
+ else if (typeDescriptorLower === 'assocarray' || typeDescriptorLower === 'associative array') {
1145
+ return new AssociativeArrayType_1.AssociativeArrayType();
1146
+ }
1147
+ else if (typeDescriptorLower === 'node') {
1148
+ return ComponentType_1.ComponentType.instance;
1149
+ }
1150
+ else if (typeDescriptorLower === 'nodearray') {
1151
+ return new ArrayType_1.ArrayType(ComponentType_1.ComponentType.instance);
1152
+ }
1153
+ else if (lookupTable) {
1154
+ //try doing a lookup
1155
+ return lookupTable.getSymbolType(typeDescriptorLower, { flags: SymbolTable_1.SymbolTypeFlag.typetime });
1156
+ }
1157
+ // TODO: Handle 'rect2d', 'rect2dArray', 'color', 'colorarray', 'time'
1158
+ return DynamicType_1.DynamicType.instance;
1159
+ }
1160
+ /**
1161
+ * Return the type of the result of a binary operator
1162
+ * Note: compound assignments (eg. +=) internally use a binary expression, so that's why TokenKind.PlusEqual, etc. are here too
1163
+ */
1164
+ binaryOperatorResultType(leftType, operator, rightType) {
1165
+ if (((0, reflection_1.isAnyReferenceType)(leftType) && !leftType.isResolvable()) ||
1166
+ ((0, reflection_1.isAnyReferenceType)(rightType) && !rightType.isResolvable())) {
1167
+ return new ReferenceType_1.BinaryOperatorReferenceType(leftType, operator, rightType, (lhs, op, rhs) => {
1168
+ return this.binaryOperatorResultType(lhs, op, rhs);
1169
+ });
1170
+ }
1171
+ if ((0, reflection_1.isEnumMemberType)(leftType)) {
1172
+ leftType = leftType.underlyingType;
1173
+ }
1174
+ if ((0, reflection_1.isEnumMemberType)(rightType)) {
1175
+ rightType = rightType.underlyingType;
1176
+ }
1177
+ let hasDouble = (0, reflection_1.isDoubleType)(leftType) || (0, reflection_1.isDoubleType)(rightType);
1178
+ let hasFloat = (0, reflection_1.isFloatType)(leftType) || (0, reflection_1.isFloatType)(rightType);
1179
+ let hasLongInteger = (0, reflection_1.isLongIntegerType)(leftType) || (0, reflection_1.isLongIntegerType)(rightType);
1180
+ let hasInvalid = (0, reflection_1.isInvalidType)(leftType) || (0, reflection_1.isInvalidType)(rightType);
1181
+ let hasDynamic = (0, reflection_1.isDynamicType)(leftType) || (0, reflection_1.isDynamicType)(rightType);
1182
+ let bothNumbers = (0, reflection_1.isNumberType)(leftType) && (0, reflection_1.isNumberType)(rightType);
1183
+ let bothStrings = (0, reflection_1.isStringType)(leftType) && (0, reflection_1.isStringType)(rightType);
1184
+ let eitherBooleanOrNum = ((0, reflection_1.isNumberType)(leftType) || (0, reflection_1.isBooleanType)(leftType)) && ((0, reflection_1.isNumberType)(rightType) || (0, reflection_1.isBooleanType)(rightType));
1185
+ // eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
1186
+ switch (operator.kind) {
1187
+ // Math operators
1188
+ case TokenKind_1.TokenKind.Plus:
1189
+ case TokenKind_1.TokenKind.PlusEqual:
1190
+ if (bothStrings) {
1191
+ // "string" + "string" is the only binary expression allowed with strings
1192
+ return StringType_1.StringType.instance;
1193
+ }
1194
+ // eslint-disable-next-line no-fallthrough
1195
+ case TokenKind_1.TokenKind.Minus:
1196
+ case TokenKind_1.TokenKind.MinusEqual:
1197
+ case TokenKind_1.TokenKind.Star:
1198
+ case TokenKind_1.TokenKind.StarEqual:
1199
+ case TokenKind_1.TokenKind.Mod:
1200
+ if (bothNumbers) {
1201
+ if (hasDouble) {
1202
+ return DoubleType_1.DoubleType.instance;
1203
+ }
1204
+ else if (hasFloat) {
1205
+ return FloatType_1.FloatType.instance;
1206
+ }
1207
+ else if (hasLongInteger) {
1208
+ return LongIntegerType_1.LongIntegerType.instance;
1209
+ }
1210
+ return IntegerType_1.IntegerType.instance;
1211
+ }
1212
+ break;
1213
+ case TokenKind_1.TokenKind.Forwardslash:
1214
+ case TokenKind_1.TokenKind.ForwardslashEqual:
1215
+ if (bothNumbers) {
1216
+ if (hasDouble) {
1217
+ return DoubleType_1.DoubleType.instance;
1218
+ }
1219
+ else if (hasFloat) {
1220
+ return FloatType_1.FloatType.instance;
1221
+ }
1222
+ else if (hasLongInteger) {
1223
+ return LongIntegerType_1.LongIntegerType.instance;
1224
+ }
1225
+ return FloatType_1.FloatType.instance;
1226
+ }
1227
+ break;
1228
+ case TokenKind_1.TokenKind.Backslash:
1229
+ case TokenKind_1.TokenKind.BackslashEqual:
1230
+ if (bothNumbers) {
1231
+ if (hasLongInteger) {
1232
+ return LongIntegerType_1.LongIntegerType.instance;
1233
+ }
1234
+ return IntegerType_1.IntegerType.instance;
1235
+ }
1236
+ break;
1237
+ case TokenKind_1.TokenKind.Caret:
1238
+ if (bothNumbers) {
1239
+ if (hasDouble || hasLongInteger) {
1240
+ return DoubleType_1.DoubleType.instance;
1241
+ }
1242
+ else if (hasFloat) {
1243
+ return FloatType_1.FloatType.instance;
1244
+ }
1245
+ return IntegerType_1.IntegerType.instance;
1246
+ }
1247
+ break;
1248
+ // Bitshift operators
1249
+ case TokenKind_1.TokenKind.LeftShift:
1250
+ case TokenKind_1.TokenKind.LeftShiftEqual:
1251
+ case TokenKind_1.TokenKind.RightShift:
1252
+ case TokenKind_1.TokenKind.RightShiftEqual:
1253
+ if (bothNumbers) {
1254
+ if (hasLongInteger) {
1255
+ return LongIntegerType_1.LongIntegerType.instance;
1256
+ }
1257
+ // Bitshifts are allowed with non-integer numerics
1258
+ // but will always truncate to ints
1259
+ return IntegerType_1.IntegerType.instance;
1260
+ }
1261
+ break;
1262
+ // Comparison operators
1263
+ // All comparison operators result in boolean
1264
+ case TokenKind_1.TokenKind.Equal:
1265
+ case TokenKind_1.TokenKind.LessGreater:
1266
+ // = and <> can accept invalid / dynamic
1267
+ if (hasDynamic || hasInvalid || bothStrings || eitherBooleanOrNum) {
1268
+ return BooleanType_1.BooleanType.instance;
1269
+ }
1270
+ break;
1271
+ case TokenKind_1.TokenKind.Greater:
1272
+ case TokenKind_1.TokenKind.Less:
1273
+ case TokenKind_1.TokenKind.GreaterEqual:
1274
+ case TokenKind_1.TokenKind.LessEqual:
1275
+ if (bothStrings || bothNumbers) {
1276
+ return BooleanType_1.BooleanType.instance;
1277
+ }
1278
+ break;
1279
+ // Logical operators
1280
+ case TokenKind_1.TokenKind.Or:
1281
+ case TokenKind_1.TokenKind.And:
1282
+ if (eitherBooleanOrNum) {
1283
+ return BooleanType_1.BooleanType.instance;
1284
+ }
1285
+ break;
1286
+ }
1287
+ return DynamicType_1.DynamicType.instance;
1288
+ }
1289
+ /**
1290
+ * Return the type of the result of a binary operator
1291
+ */
1292
+ unaryOperatorResultType(operator, exprType) {
1293
+ // eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
1294
+ switch (operator.kind) {
1295
+ // Math operators
1296
+ case TokenKind_1.TokenKind.Minus:
1297
+ if ((0, reflection_1.isNumberType)(exprType)) {
1298
+ // a negative number will be the same type, eg, double->double, int->int, etc.
1299
+ return exprType;
1300
+ }
1301
+ break;
1302
+ case TokenKind_1.TokenKind.Not:
1303
+ if ((0, reflection_1.isBooleanType)(exprType)) {
1304
+ return BooleanType_1.BooleanType.instance;
1305
+ }
1306
+ else if ((0, reflection_1.isNumberType)(exprType)) {
1307
+ //numbers can be "notted"
1308
+ // by default they go to ints, except longints, which stay that way
1309
+ if ((0, reflection_1.isLongIntegerType)(exprType)) {
1310
+ return LongIntegerType_1.LongIntegerType.instance;
1311
+ }
1312
+ return IntegerType_1.IntegerType.instance;
1313
+ }
1314
+ break;
1315
+ }
1316
+ return DynamicType_1.DynamicType.instance;
1317
+ }
991
1318
  /**
992
1319
  * Get the extension for the given file path. Basically the part after the final dot, except for
993
1320
  * `d.bs` which is treated as single extension
1321
+ * @returns the file extension (i.e. ".d.bs", ".bs", ".brs", ".xml", ".jpg", etc...)
994
1322
  */
995
1323
  getExtension(filePath) {
996
1324
  filePath = filePath.toLowerCase();
@@ -998,10 +1326,7 @@ class Util {
998
1326
  return '.d.bs';
999
1327
  }
1000
1328
  else {
1001
- const idx = filePath.lastIndexOf('.');
1002
- if (idx > -1) {
1003
- return filePath.substring(idx);
1004
- }
1329
+ return path.extname(filePath).toLowerCase();
1005
1330
  }
1006
1331
  }
1007
1332
  /**
@@ -1067,6 +1392,10 @@ class Util {
1067
1392
  expressionWalker(expression);
1068
1393
  return { expressions: expressions, varExpressions: variableExpressions, uniqueVarNames: [...uniqueVarNames] };
1069
1394
  }
1395
+ concatAnnotationLeadingTrivia(stmt, otherTrivia) {
1396
+ var _a, _b;
1397
+ return [...((_b = (_a = stmt.annotations) === null || _a === void 0 ? void 0 : _a.map(anno => anno.getLeadingTrivia()).flat()) !== null && _b !== void 0 ? _b : []), ...otherTrivia];
1398
+ }
1070
1399
  /**
1071
1400
  * Create a SourceNode that maps every line to itself. Useful for creating maps for files
1072
1401
  * that haven't changed at all, but we still need the map
@@ -1087,29 +1416,6 @@ class Util {
1087
1416
  standardizePath(thePath) {
1088
1417
  return exports.util.driveLetterToLower((0, roku_deploy_1.standardizePath)(thePath));
1089
1418
  }
1090
- /**
1091
- * Copy the version of bslib from local node_modules to the staging folder
1092
- */
1093
- async copyBslibToStaging(stagingDir) {
1094
- //copy bslib to the output directory
1095
- await fsExtra.ensureDir(standardizePath(`${stagingDir}/source`));
1096
- // eslint-disable-next-line
1097
- const bslib = require('@rokucommunity/bslib');
1098
- let source = bslib.source;
1099
- //apply the `bslib_` prefix to the functions
1100
- let match;
1101
- const positions = [];
1102
- const regexp = /^(\s*(?:function|sub)\s+)([a-z0-9_]+)/mg;
1103
- // eslint-disable-next-line no-cond-assign
1104
- while (match = regexp.exec(source)) {
1105
- positions.push(match.index + match[1].length);
1106
- }
1107
- for (let i = positions.length - 1; i >= 0; i--) {
1108
- const position = positions[i];
1109
- source = source.slice(0, position) + 'bslib_' + source.slice(position);
1110
- }
1111
- await fsExtra.writeFile(`${stagingDir}/source/bslib.brs`, source);
1112
- }
1113
1419
  /**
1114
1420
  * Given a Diagnostic or BsDiagnostic, return a deep clone of the diagnostic.
1115
1421
  * @param diagnostic the diagnostic to clone
@@ -1117,11 +1423,20 @@ class Util {
1117
1423
  */
1118
1424
  toDiagnostic(diagnostic, relatedInformationFallbackLocation) {
1119
1425
  var _a;
1426
+ let relatedInformation = (_a = diagnostic.relatedInformation) !== null && _a !== void 0 ? _a : [];
1427
+ if (relatedInformation.length > diagnosticUtils_1.MAX_RELATED_INFOS_COUNT) {
1428
+ const relatedInfoLength = relatedInformation.length;
1429
+ relatedInformation = relatedInformation.slice(0, diagnosticUtils_1.MAX_RELATED_INFOS_COUNT);
1430
+ relatedInformation.push({
1431
+ message: `...and ${relatedInfoLength - diagnosticUtils_1.MAX_RELATED_INFOS_COUNT} more`,
1432
+ location: exports.util.createLocation(' ', exports.util.createRange(0, 0, 0, 0))
1433
+ });
1434
+ }
1120
1435
  return {
1121
1436
  severity: diagnostic.severity,
1122
1437
  range: diagnostic.range,
1123
1438
  message: diagnostic.message,
1124
- relatedInformation: (_a = diagnostic.relatedInformation) === null || _a === void 0 ? void 0 : _a.map(x => {
1439
+ relatedInformation: relatedInformation.map(x => {
1125
1440
  //clone related information just in case a plugin added circular ref info here
1126
1441
  const clone = Object.assign({}, x);
1127
1442
  if (!clone.location) {
@@ -1222,55 +1537,70 @@ class Util {
1222
1537
  * @returns an array of the parts of the dotted get. If not fully a dotted get, then returns undefined
1223
1538
  */
1224
1539
  getAllDottedGetParts(node) {
1540
+ //this is a hot function and has been optimized. Don't rewrite unless necessary
1225
1541
  const parts = [];
1226
1542
  let nextPart = node;
1227
- while (nextPart) {
1228
- if ((0, reflection_1.isAssignmentStatement)(node)) {
1229
- return [node.name];
1230
- }
1231
- else if ((0, reflection_1.isDottedGetExpression)(nextPart)) {
1232
- parts.push(nextPart === null || nextPart === void 0 ? void 0 : nextPart.name);
1233
- nextPart = nextPart.obj;
1234
- }
1235
- else if ((0, reflection_1.isCallExpression)(nextPart)) {
1236
- nextPart = nextPart.callee;
1237
- }
1238
- else if ((0, reflection_1.isTypeExpression)(nextPart)) {
1239
- nextPart = nextPart.expression;
1240
- }
1241
- else if ((0, reflection_1.isVariableExpression)(nextPart)) {
1242
- parts.push(nextPart === null || nextPart === void 0 ? void 0 : nextPart.name);
1243
- break;
1244
- }
1245
- else if ((0, reflection_1.isLiteralExpression)(nextPart)) {
1246
- parts.push(nextPart === null || nextPart === void 0 ? void 0 : nextPart.token);
1247
- break;
1248
- }
1249
- else if ((0, reflection_1.isIndexedGetExpression)(nextPart)) {
1250
- nextPart = nextPart.obj;
1251
- }
1252
- else if ((0, reflection_1.isFunctionParameterExpression)(nextPart)) {
1253
- return [nextPart.name];
1254
- }
1255
- else if ((0, reflection_1.isGroupingExpression)(nextPart)) {
1256
- parts.push((0, creators_1.createIdentifier)('()', nextPart.range));
1257
- break;
1258
- }
1259
- else {
1260
- //we found a non-DottedGet expression, so return because this whole operation is invalid.
1261
- return undefined;
1543
+ loop: while (nextPart) {
1544
+ switch (nextPart === null || nextPart === void 0 ? void 0 : nextPart.kind) {
1545
+ case AstNode_1.AstNodeKind.AssignmentStatement:
1546
+ return [node.name];
1547
+ case AstNode_1.AstNodeKind.DottedGetExpression:
1548
+ parts.push(nextPart === null || nextPart === void 0 ? void 0 : nextPart.name);
1549
+ nextPart = nextPart.obj;
1550
+ continue;
1551
+ case AstNode_1.AstNodeKind.CallExpression:
1552
+ nextPart = nextPart.callee;
1553
+ continue;
1554
+ case AstNode_1.AstNodeKind.TypeExpression:
1555
+ nextPart = nextPart.expression;
1556
+ continue;
1557
+ case AstNode_1.AstNodeKind.VariableExpression:
1558
+ parts.push(nextPart === null || nextPart === void 0 ? void 0 : nextPart.name);
1559
+ break loop;
1560
+ case AstNode_1.AstNodeKind.LiteralExpression:
1561
+ parts.push(nextPart === null || nextPart === void 0 ? void 0 : nextPart.token);
1562
+ break loop;
1563
+ case AstNode_1.AstNodeKind.IndexedGetExpression:
1564
+ nextPart = nextPart.obj;
1565
+ continue;
1566
+ case AstNode_1.AstNodeKind.FunctionParameterExpression:
1567
+ return [nextPart.name];
1568
+ case AstNode_1.AstNodeKind.GroupingExpression:
1569
+ parts.push((0, creators_1.createIdentifier)('()', nextPart.range));
1570
+ break loop;
1571
+ default:
1572
+ //we found a non-DottedGet expression, so return because this whole operation is invalid.
1573
+ return undefined;
1262
1574
  }
1263
1575
  }
1264
1576
  return parts.reverse();
1265
1577
  }
1578
+ /**
1579
+ * Given an expression, return all the DottedGet name parts as a string.
1580
+ * Mostly used to convert namespaced item full names to a strings
1581
+ */
1266
1582
  getAllDottedGetPartsAsString(node, parseMode = Parser_1.ParseMode.BrighterScript) {
1583
+ var _a, _b;
1584
+ //this is a hot function and has been optimized. Don't rewrite unless necessary
1585
+ /* eslint-disable no-var */
1586
+ var sep = parseMode === Parser_1.ParseMode.BrighterScript ? '.' : '_';
1587
+ const parts = (_a = this.getAllDottedGetParts(node)) !== null && _a !== void 0 ? _a : [];
1588
+ var result = (_b = parts[0]) === null || _b === void 0 ? void 0 : _b.text;
1589
+ for (var i = 1; i < parts.length; i++) {
1590
+ result += sep + parts[i].text;
1591
+ }
1592
+ return result;
1593
+ /* eslint-enable no-var */
1594
+ }
1595
+ stringJoin(strings, separator) {
1267
1596
  var _a;
1268
- const sep = parseMode === Parser_1.ParseMode.BrighterScript ? '.' : '_';
1269
- const hello = (_a = this.getAllDottedGetParts(node)) === null || _a === void 0 ? void 0 : _a.map(part => part.text).join(sep);
1270
- if (!hello) {
1271
- console.log(node);
1597
+ // eslint-disable-next-line no-var
1598
+ var result = (_a = strings[0]) !== null && _a !== void 0 ? _a : '';
1599
+ // eslint-disable-next-line no-var
1600
+ for (var i = 1; i < strings.length; i++) {
1601
+ result += separator + strings[i];
1272
1602
  }
1273
- return hello;
1603
+ return result;
1274
1604
  }
1275
1605
  /**
1276
1606
  * Break an expression into each part.
@@ -1301,36 +1631,37 @@ class Util {
1301
1631
  getDottedGetPath(expression) {
1302
1632
  let parts = [];
1303
1633
  let nextPart = expression;
1304
- while (nextPart) {
1305
- if ((0, reflection_1.isDottedGetExpression)(nextPart)) {
1306
- parts.unshift(nextPart);
1307
- nextPart = nextPart.obj;
1308
- }
1309
- else if ((0, reflection_1.isIndexedGetExpression)(nextPart) || (0, reflection_1.isXmlAttributeGetExpression)(nextPart)) {
1310
- nextPart = nextPart.obj;
1311
- parts = [];
1312
- }
1313
- else if ((0, reflection_1.isCallExpression)(nextPart) || (0, reflection_1.isCallfuncExpression)(nextPart)) {
1314
- nextPart = nextPart.callee;
1315
- parts = [];
1316
- }
1317
- else if ((0, reflection_1.isNewExpression)(nextPart)) {
1318
- nextPart = nextPart.call.callee;
1319
- parts = [];
1320
- }
1321
- else if ((0, reflection_1.isTypeExpression)(nextPart)) {
1322
- nextPart = nextPart.expression;
1323
- }
1324
- else if ((0, reflection_1.isVariableExpression)(nextPart)) {
1325
- parts.unshift(nextPart);
1326
- break;
1327
- }
1328
- else {
1329
- parts = [];
1330
- break;
1634
+ loop: while (nextPart) {
1635
+ switch (nextPart === null || nextPart === void 0 ? void 0 : nextPart.kind) {
1636
+ case AstNode_1.AstNodeKind.DottedGetExpression:
1637
+ parts.push(nextPart);
1638
+ nextPart = nextPart.obj;
1639
+ continue;
1640
+ case AstNode_1.AstNodeKind.IndexedGetExpression:
1641
+ case AstNode_1.AstNodeKind.XmlAttributeGetExpression:
1642
+ nextPart = nextPart.obj;
1643
+ parts = [];
1644
+ continue;
1645
+ case AstNode_1.AstNodeKind.CallExpression:
1646
+ case AstNode_1.AstNodeKind.CallfuncExpression:
1647
+ nextPart = nextPart.callee;
1648
+ parts = [];
1649
+ continue;
1650
+ case AstNode_1.AstNodeKind.NewExpression:
1651
+ nextPart = nextPart.call.callee;
1652
+ parts = [];
1653
+ continue;
1654
+ case AstNode_1.AstNodeKind.TypeExpression:
1655
+ nextPart = nextPart.expression;
1656
+ continue;
1657
+ case AstNode_1.AstNodeKind.VariableExpression:
1658
+ parts.push(nextPart);
1659
+ break loop;
1660
+ default:
1661
+ return [];
1331
1662
  }
1332
1663
  }
1333
- return parts;
1664
+ return parts.reverse();
1334
1665
  }
1335
1666
  /**
1336
1667
  * Returns an integer if valid, or undefined. Eliminates checking for NaN
@@ -1354,15 +1685,15 @@ class Util {
1354
1685
  validateTooDeepFile(file) {
1355
1686
  var _a;
1356
1687
  //find any files nested too deep
1357
- let pkgPath = (_a = file.pkgPath) !== null && _a !== void 0 ? _a : file.pkgPath.toString();
1358
- let rootFolder = pkgPath.replace(/^pkg:/, '').split(/[\\\/]/)[0].toLowerCase();
1688
+ let destPath = (_a = file === null || file === void 0 ? void 0 : file.destPath) === null || _a === void 0 ? void 0 : _a.toString();
1689
+ let rootFolder = destPath === null || destPath === void 0 ? void 0 : destPath.replace(/^pkg:/, '').split(/[\\\/]/)[0].toLowerCase();
1359
1690
  if ((0, reflection_1.isBrsFile)(file) && rootFolder !== 'source') {
1360
1691
  return;
1361
1692
  }
1362
1693
  if ((0, reflection_1.isXmlFile)(file) && rootFolder !== 'components') {
1363
1694
  return;
1364
1695
  }
1365
- let fileDepth = this.getParentDirectoryCount(pkgPath);
1696
+ let fileDepth = this.getParentDirectoryCount(destPath);
1366
1697
  if (fileDepth >= 8) {
1367
1698
  file.addDiagnostics([Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.detectedTooDeepFileSource(fileDepth)), { file: file, range: this.createRange(0, 0, 0, Number.MAX_VALUE) })]);
1368
1699
  }
@@ -1378,35 +1709,132 @@ class Util {
1378
1709
  }
1379
1710
  }
1380
1711
  processTypeChain(typeChain) {
1712
+ var _a, _b, _c, _d;
1381
1713
  let fullChainName = '';
1382
1714
  let fullErrorName = '';
1383
- let missingItemName = '';
1715
+ let itemName = '';
1384
1716
  let previousTypeName = '';
1385
1717
  let parentTypeName = '';
1386
1718
  let errorRange;
1719
+ let containsDynamic = false;
1387
1720
  for (let i = 0; i < typeChain.length; i++) {
1388
1721
  const chainItem = typeChain[i];
1722
+ const dotSep = (_b = (_a = chainItem.separatorToken) === null || _a === void 0 ? void 0 : _a.text) !== null && _b !== void 0 ? _b : '.';
1389
1723
  if (i > 0) {
1390
- fullChainName += '.';
1724
+ fullChainName += dotSep;
1391
1725
  }
1392
1726
  fullChainName += chainItem.name;
1393
1727
  parentTypeName = previousTypeName;
1394
- fullErrorName = previousTypeName ? `${previousTypeName}.${chainItem.name}` : chainItem.name;
1395
- previousTypeName = chainItem.type.toString();
1396
- missingItemName = chainItem.name;
1728
+ fullErrorName = previousTypeName ? `${previousTypeName}${dotSep}${chainItem.name}` : chainItem.name;
1729
+ previousTypeName = (_d = (_c = chainItem.type) === null || _c === void 0 ? void 0 : _c.toString()) !== null && _d !== void 0 ? _d : '';
1730
+ itemName = chainItem.name;
1731
+ containsDynamic = containsDynamic || ((0, reflection_1.isDynamicType)(chainItem.type) && !(0, reflection_1.isAnyReferenceType)(chainItem.type));
1397
1732
  if (!chainItem.isResolved) {
1398
1733
  errorRange = chainItem.range;
1399
1734
  break;
1400
1735
  }
1401
1736
  }
1402
1737
  return {
1403
- missingItemName: missingItemName,
1404
- missingItemParentTypeName: parentTypeName,
1405
- fullNameOfMissingItem: fullErrorName,
1738
+ itemName: itemName,
1739
+ itemParentTypeName: parentTypeName,
1740
+ fullNameOfItem: fullErrorName,
1406
1741
  fullChainName: fullChainName,
1407
- range: errorRange
1742
+ range: errorRange,
1743
+ containsDynamic: containsDynamic
1408
1744
  };
1409
1745
  }
1746
+ isInTypeExpression(expression) {
1747
+ //TODO: this is much faster than node.findAncestor(), but may need to be updated for "complicated" type expressions
1748
+ if ((0, reflection_1.isTypeExpression)(expression) ||
1749
+ (0, reflection_1.isTypeExpression)(expression.parent) ||
1750
+ (0, reflection_1.isTypedArrayExpression)(expression) ||
1751
+ (0, reflection_1.isTypedArrayExpression)(expression.parent)) {
1752
+ return true;
1753
+ }
1754
+ if ((0, reflection_1.isBinaryExpression)(expression.parent)) {
1755
+ let currentExpr = expression.parent;
1756
+ while ((0, reflection_1.isBinaryExpression)(currentExpr) && currentExpr.operator.kind === TokenKind_1.TokenKind.Or) {
1757
+ currentExpr = currentExpr.parent;
1758
+ }
1759
+ return (0, reflection_1.isTypeExpression)(currentExpr) || (0, reflection_1.isTypedArrayExpression)(currentExpr);
1760
+ }
1761
+ return false;
1762
+ }
1763
+ setContainsUnresolvedSymbol(symbolLowerNameSet, symbol) {
1764
+ var _a, _b;
1765
+ const possibleOriginalSymbolNamesLower = [];
1766
+ let nameSoFar = '';
1767
+ for (const tce of symbol.typeChain) {
1768
+ if (nameSoFar.length > 0) {
1769
+ nameSoFar += '.';
1770
+ }
1771
+ nameSoFar += tce.name.toLowerCase();
1772
+ possibleOriginalSymbolNamesLower.push(nameSoFar);
1773
+ }
1774
+ const possibleNamespace = (_b = (_a = symbol.containingNamespaces) === null || _a === void 0 ? void 0 : _a.join('.')) !== null && _b !== void 0 ? _b : '';
1775
+ for (const possibleNameLower of possibleOriginalSymbolNamesLower) {
1776
+ if (symbolLowerNameSet.has(possibleNameLower)) {
1777
+ return true;
1778
+ }
1779
+ if (possibleNamespace) {
1780
+ const fullName = possibleNamespace + '.' + possibleNameLower;
1781
+ if (symbolLowerNameSet.has(fullName.toLowerCase())) {
1782
+ return true;
1783
+ }
1784
+ }
1785
+ }
1786
+ return false;
1787
+ }
1788
+ truncate(options) {
1789
+ var _a, _b, _c, _d, _e, _f, _g;
1790
+ let leadingText = options.leadingText;
1791
+ let items = (_a = options === null || options === void 0 ? void 0 : options.items) !== null && _a !== void 0 ? _a : [];
1792
+ let trailingText = (_b = options === null || options === void 0 ? void 0 : options.trailingText) !== null && _b !== void 0 ? _b : '';
1793
+ let maxLength = (_c = options === null || options === void 0 ? void 0 : options.maxLength) !== null && _c !== void 0 ? _c : 160;
1794
+ let itemSeparator = (_d = options === null || options === void 0 ? void 0 : options.itemSeparator) !== null && _d !== void 0 ? _d : ', ';
1795
+ let partBuilder = (_e = options === null || options === void 0 ? void 0 : options.partBuilder) !== null && _e !== void 0 ? _e : ((x) => x.toString());
1796
+ let parts = [];
1797
+ let length = leadingText.length + ((_f = trailingText === null || trailingText === void 0 ? void 0 : trailingText.length) !== null && _f !== void 0 ? _f : 0);
1798
+ //calculate the max number of items we could fit in the given space
1799
+ for (let i = 0; i < items.length; i++) {
1800
+ let part = partBuilder(items[i]);
1801
+ if (i > 0) {
1802
+ part = itemSeparator + part;
1803
+ }
1804
+ parts.push(part);
1805
+ length += part.length;
1806
+ //exit the loop if we've maxed out our length
1807
+ if (length >= maxLength) {
1808
+ break;
1809
+ }
1810
+ }
1811
+ let message;
1812
+ //we have enough space to include all the parts
1813
+ if (parts.length >= items.length) {
1814
+ message = leadingText + parts.join('') + trailingText;
1815
+ //we require truncation
1816
+ }
1817
+ else {
1818
+ //account for truncation message length including max possible "more" items digits, trailing text length, and the separator between last item and trailing text
1819
+ length = leadingText.length + `...and ${items.length} more`.length + itemSeparator.length + ((_g = trailingText === null || trailingText === void 0 ? void 0 : trailingText.length) !== null && _g !== void 0 ? _g : 0);
1820
+ message = leadingText;
1821
+ for (let i = 0; i < parts.length; i++) {
1822
+ //always include at least 2 items. if this part would overflow the max, then skip it and finalize the message
1823
+ if (i > 1 && length + parts[i].length > maxLength) {
1824
+ message += itemSeparator + `...and ${items.length - i} more` + trailingText;
1825
+ return message;
1826
+ }
1827
+ else {
1828
+ message += parts[i];
1829
+ length += parts[i].length;
1830
+ }
1831
+ }
1832
+ }
1833
+ return message;
1834
+ }
1835
+ getAstNodeFriendlyName(node) {
1836
+ return node === null || node === void 0 ? void 0 : node.kind.replace(/Statement|Expression/g, '');
1837
+ }
1410
1838
  }
1411
1839
  exports.Util = Util;
1412
1840
  /**