brighterscript 0.66.0-alpha.6 → 0.66.0-alpha.8

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 (288) hide show
  1. package/CHANGELOG.md +88 -10
  2. package/README.md +16 -0
  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 +15 -1
  11. package/dist/CommentFlagProcessor.d.ts +4 -3
  12. package/dist/CommentFlagProcessor.js.map +1 -1
  13. package/dist/DiagnosticMessages.d.ts +8 -1
  14. package/dist/DiagnosticMessages.js +30 -13
  15. package/dist/DiagnosticMessages.js.map +1 -1
  16. package/dist/LanguageServer.js +7 -1
  17. package/dist/LanguageServer.js.map +1 -1
  18. package/dist/PluginInterface.d.ts +11 -2
  19. package/dist/PluginInterface.js +69 -10
  20. package/dist/PluginInterface.js.map +1 -1
  21. package/dist/Program.d.ts +107 -38
  22. package/dist/Program.js +502 -270
  23. package/dist/Program.js.map +1 -1
  24. package/dist/ProgramBuilder.d.ts +10 -4
  25. package/dist/ProgramBuilder.js +44 -54
  26. package/dist/ProgramBuilder.js.map +1 -1
  27. package/dist/Scope.d.ts +26 -38
  28. package/dist/Scope.js +153 -174
  29. package/dist/Scope.js.map +1 -1
  30. package/dist/SymbolTable.d.ts +4 -1
  31. package/dist/SymbolTable.js +19 -7
  32. package/dist/SymbolTable.js.map +1 -1
  33. package/dist/XmlScope.d.ts +5 -4
  34. package/dist/XmlScope.js +16 -14
  35. package/dist/XmlScope.js.map +1 -1
  36. package/dist/astUtils/{AstEditor.d.ts → Editor.d.ts} +6 -1
  37. package/dist/astUtils/{AstEditor.js → Editor.js} +9 -3
  38. package/dist/astUtils/Editor.js.map +1 -0
  39. package/dist/astUtils/{AstEditor.spec.js → Editor.spec.js} +10 -6
  40. package/dist/astUtils/Editor.spec.js.map +1 -0
  41. package/dist/astUtils/reflection.d.ts +9 -4
  42. package/dist/astUtils/reflection.js +23 -7
  43. package/dist/astUtils/reflection.js.map +1 -1
  44. package/dist/astUtils/reflection.spec.js +2 -2
  45. package/dist/astUtils/reflection.spec.js.map +1 -1
  46. package/dist/astUtils/visitors.d.ts +14 -3
  47. package/dist/astUtils/visitors.js +22 -2
  48. package/dist/astUtils/visitors.js.map +1 -1
  49. package/dist/astUtils/visitors.spec.js +58 -7
  50. package/dist/astUtils/visitors.spec.js.map +1 -1
  51. package/dist/bscPlugin/BscPlugin.d.ts +10 -2
  52. package/dist/bscPlugin/BscPlugin.js +24 -4
  53. package/dist/bscPlugin/BscPlugin.js.map +1 -1
  54. package/dist/bscPlugin/FileWriter.d.ts +6 -0
  55. package/dist/bscPlugin/FileWriter.js +24 -0
  56. package/dist/bscPlugin/FileWriter.js.map +1 -0
  57. package/dist/bscPlugin/codeActions/CodeActionsProcessor.js +8 -8
  58. package/dist/bscPlugin/codeActions/CodeActionsProcessor.js.map +1 -1
  59. package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js.map +1 -1
  60. package/dist/bscPlugin/completions/CompletionsProcessor.d.ts +7 -2
  61. package/dist/bscPlugin/completions/CompletionsProcessor.js +112 -44
  62. package/dist/bscPlugin/completions/CompletionsProcessor.js.map +1 -1
  63. package/dist/bscPlugin/completions/CompletionsProcessor.spec.js +212 -6
  64. package/dist/bscPlugin/completions/CompletionsProcessor.spec.js.map +1 -1
  65. package/dist/bscPlugin/fileProviders/FileProvider.d.ts +9 -0
  66. package/dist/bscPlugin/fileProviders/FileProvider.js +51 -0
  67. package/dist/bscPlugin/fileProviders/FileProvider.js.map +1 -0
  68. package/dist/bscPlugin/hover/HoverProcessor.d.ts +1 -7
  69. package/dist/bscPlugin/hover/HoverProcessor.js +10 -8
  70. package/dist/bscPlugin/hover/HoverProcessor.js.map +1 -1
  71. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.d.ts +1 -0
  72. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js +43 -0
  73. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js.map +1 -1
  74. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js +22 -0
  75. package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js.map +1 -1
  76. package/dist/bscPlugin/serialize/BslibInjector.spec.js +19 -0
  77. package/dist/bscPlugin/serialize/BslibInjector.spec.js.map +1 -0
  78. package/dist/bscPlugin/serialize/BslibManager.d.ts +9 -0
  79. package/dist/bscPlugin/serialize/BslibManager.js +40 -0
  80. package/dist/bscPlugin/serialize/BslibManager.js.map +1 -0
  81. package/dist/bscPlugin/serialize/FileSerializer.d.ts +9 -0
  82. package/dist/bscPlugin/serialize/FileSerializer.js +72 -0
  83. package/dist/bscPlugin/serialize/FileSerializer.js.map +1 -0
  84. package/dist/bscPlugin/transpile/{BrsFilePreTranspileProcessor.d.ts → BrsFileTranspileProcessor.d.ts} +4 -2
  85. package/dist/bscPlugin/transpile/{BrsFilePreTranspileProcessor.js → BrsFileTranspileProcessor.js} +29 -5
  86. package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.js.map +1 -0
  87. package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.spec.d.ts +1 -0
  88. package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.spec.js +41 -0
  89. package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.spec.js.map +1 -0
  90. package/dist/bscPlugin/transpile/XmlFilePreTranspileProcessor.d.ts +2 -2
  91. package/dist/bscPlugin/transpile/XmlFilePreTranspileProcessor.js.map +1 -1
  92. package/dist/bscPlugin/validation/BrsFileValidator.js +8 -3
  93. package/dist/bscPlugin/validation/BrsFileValidator.js.map +1 -1
  94. package/dist/bscPlugin/validation/BrsFileValidator.spec.js +1 -1
  95. package/dist/bscPlugin/validation/BrsFileValidator.spec.js.map +1 -1
  96. package/dist/bscPlugin/validation/ScopeValidator.d.ts +5 -9
  97. package/dist/bscPlugin/validation/ScopeValidator.js +214 -222
  98. package/dist/bscPlugin/validation/ScopeValidator.js.map +1 -1
  99. package/dist/bscPlugin/validation/ScopeValidator.spec.js +669 -0
  100. package/dist/bscPlugin/validation/ScopeValidator.spec.js.map +1 -1
  101. package/dist/bscPlugin/validation/XmlFileValidator.js +2 -2
  102. package/dist/bscPlugin/validation/XmlFileValidator.js.map +1 -1
  103. package/dist/cli.js +1 -0
  104. package/dist/cli.js.map +1 -1
  105. package/dist/deferred.d.ts +2 -2
  106. package/dist/deferred.js.map +1 -1
  107. package/dist/diagnosticUtils.d.ts +1 -0
  108. package/dist/diagnosticUtils.js +4 -3
  109. package/dist/diagnosticUtils.js.map +1 -1
  110. package/dist/examples/plugins/removePrint.js +1 -1
  111. package/dist/examples/plugins/removePrint.js.map +1 -1
  112. package/dist/files/AssetFile.d.ts +26 -0
  113. package/dist/files/AssetFile.js +26 -0
  114. package/dist/files/AssetFile.js.map +1 -0
  115. package/dist/files/BrsFile.Class.spec.js +241 -40
  116. package/dist/files/BrsFile.Class.spec.js.map +1 -1
  117. package/dist/files/BrsFile.d.ts +66 -16
  118. package/dist/files/BrsFile.js +330 -80
  119. package/dist/files/BrsFile.js.map +1 -1
  120. package/dist/files/BrsFile.spec.js +1134 -167
  121. package/dist/files/BrsFile.spec.js.map +1 -1
  122. package/dist/files/Factory.d.ts +25 -0
  123. package/dist/files/Factory.js +22 -0
  124. package/dist/files/Factory.js.map +1 -0
  125. package/dist/files/File.d.ts +106 -0
  126. package/dist/files/File.js +16 -0
  127. package/dist/files/File.js.map +1 -0
  128. package/dist/files/LazyFileData.d.ts +20 -0
  129. package/dist/files/LazyFileData.js +54 -0
  130. package/dist/files/LazyFileData.js.map +1 -0
  131. package/dist/files/LazyFileData.spec.d.ts +1 -0
  132. package/dist/files/LazyFileData.spec.js +27 -0
  133. package/dist/files/LazyFileData.spec.js.map +1 -0
  134. package/dist/files/XmlFile.d.ts +55 -17
  135. package/dist/files/XmlFile.js +88 -47
  136. package/dist/files/XmlFile.js.map +1 -1
  137. package/dist/files/XmlFile.spec.js +64 -57
  138. package/dist/files/XmlFile.spec.js.map +1 -1
  139. package/dist/files/tests/imports.spec.js +21 -8
  140. package/dist/files/tests/imports.spec.js.map +1 -1
  141. package/dist/files/tests/optionalChaning.spec.js +14 -14
  142. package/dist/files/tests/optionalChaning.spec.js.map +1 -1
  143. package/dist/globalCallables.js +1 -1
  144. package/dist/globalCallables.js.map +1 -1
  145. package/dist/index.d.ts +6 -1
  146. package/dist/index.js +6 -1
  147. package/dist/index.js.map +1 -1
  148. package/dist/interfaces.d.ts +357 -89
  149. package/dist/interfaces.js +10 -2
  150. package/dist/interfaces.js.map +1 -1
  151. package/dist/lexer/Lexer.js +1 -1
  152. package/dist/lexer/TokenKind.d.ts +1 -0
  153. package/dist/lexer/TokenKind.js +4 -1
  154. package/dist/lexer/TokenKind.js.map +1 -1
  155. package/dist/parser/AstNode.d.ts +2 -2
  156. package/dist/parser/AstNode.js +1 -1
  157. package/dist/parser/AstNode.js.map +1 -1
  158. package/dist/parser/BrsTranspileState.d.ts +3 -2
  159. package/dist/parser/BrsTranspileState.js +3 -2
  160. package/dist/parser/BrsTranspileState.js.map +1 -1
  161. package/dist/parser/Expression.d.ts +2 -2
  162. package/dist/parser/Expression.js +23 -19
  163. package/dist/parser/Expression.js.map +1 -1
  164. package/dist/parser/Parser.Class.spec.js +103 -0
  165. package/dist/parser/Parser.Class.spec.js.map +1 -1
  166. package/dist/parser/Parser.js +61 -13
  167. package/dist/parser/Parser.js.map +1 -1
  168. package/dist/parser/Parser.spec.js +227 -1
  169. package/dist/parser/Parser.spec.js.map +1 -1
  170. package/dist/parser/SGParser.d.ts +2 -2
  171. package/dist/parser/SGParser.js +3 -3
  172. package/dist/parser/SGParser.js.map +1 -1
  173. package/dist/parser/SGParser.spec.js +2 -2
  174. package/dist/parser/SGParser.spec.js.map +1 -1
  175. package/dist/parser/SGTypes.d.ts +1 -1
  176. package/dist/parser/Statement.d.ts +12 -5
  177. package/dist/parser/Statement.js +56 -26
  178. package/dist/parser/Statement.js.map +1 -1
  179. package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js +16 -16
  180. package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js.map +1 -1
  181. package/dist/parser/tests/expression/RegexLiteralExpression.spec.js +10 -10
  182. package/dist/parser/tests/expression/RegexLiteralExpression.spec.js.map +1 -1
  183. package/dist/parser/tests/expression/SourceLiteralExpression.spec.js +24 -24
  184. package/dist/parser/tests/expression/SourceLiteralExpression.spec.js.map +1 -1
  185. package/dist/parser/tests/expression/TemplateStringExpression.spec.js +64 -36
  186. package/dist/parser/tests/expression/TemplateStringExpression.spec.js.map +1 -1
  187. package/dist/parser/tests/expression/TernaryExpression.spec.js +34 -34
  188. package/dist/parser/tests/expression/TernaryExpression.spec.js.map +1 -1
  189. package/dist/parser/tests/expression/UnaryExpression.spec.d.ts +1 -0
  190. package/dist/parser/tests/expression/UnaryExpression.spec.js +52 -0
  191. package/dist/parser/tests/expression/UnaryExpression.spec.js.map +1 -0
  192. package/dist/parser/tests/statement/ConstStatement.spec.js +90 -16
  193. package/dist/parser/tests/statement/ConstStatement.spec.js.map +1 -1
  194. package/dist/parser/tests/statement/Continue.spec.js +2 -2
  195. package/dist/parser/tests/statement/Continue.spec.js.map +1 -1
  196. package/dist/parser/tests/statement/Enum.spec.js +35 -26
  197. package/dist/parser/tests/statement/Enum.spec.js.map +1 -1
  198. package/dist/parser/tests/statement/For.spec.js +6 -6
  199. package/dist/parser/tests/statement/For.spec.js.map +1 -1
  200. package/dist/parser/tests/statement/ForEach.spec.js +4 -4
  201. package/dist/parser/tests/statement/ForEach.spec.js.map +1 -1
  202. package/dist/parser/tests/statement/InterfaceStatement.spec.js +20 -12
  203. package/dist/parser/tests/statement/InterfaceStatement.spec.js.map +1 -1
  204. package/dist/parser/tests/statement/PrintStatement.spec.js +10 -10
  205. package/dist/parser/tests/statement/PrintStatement.spec.js.map +1 -1
  206. package/dist/preprocessor/Manifest.d.ts +1 -1
  207. package/dist/preprocessor/Manifest.js +2 -2
  208. package/dist/preprocessor/Manifest.js.map +1 -1
  209. package/dist/roku-types/data.json +98 -193
  210. package/dist/roku-types/index.d.ts +15 -11
  211. package/dist/types/ArrayType.d.ts +1 -1
  212. package/dist/types/ArrayType.js +4 -0
  213. package/dist/types/ArrayType.js.map +1 -1
  214. package/dist/types/ArrayType.spec.js +1 -1
  215. package/dist/types/ArrayType.spec.js.map +1 -1
  216. package/dist/types/AssociativeArrayType.d.ts +1 -1
  217. package/dist/types/AssociativeArrayType.js +1 -1
  218. package/dist/types/AssociativeArrayType.js.map +1 -1
  219. package/dist/types/BooleanType.d.ts +1 -1
  220. package/dist/types/BooleanType.js +2 -1
  221. package/dist/types/BooleanType.js.map +1 -1
  222. package/dist/types/BscType.d.ts +2 -2
  223. package/dist/types/BscType.js +30 -9
  224. package/dist/types/BscType.js.map +1 -1
  225. package/dist/types/BuiltInInterfaceAdder.d.ts +3 -0
  226. package/dist/types/BuiltInInterfaceAdder.js +37 -16
  227. package/dist/types/BuiltInInterfaceAdder.js.map +1 -1
  228. package/dist/types/BuiltInInterfaceAdder.spec.js +7 -0
  229. package/dist/types/BuiltInInterfaceAdder.spec.js.map +1 -1
  230. package/dist/types/ClassType.d.ts +4 -3
  231. package/dist/types/ClassType.js +6 -3
  232. package/dist/types/ClassType.js.map +1 -1
  233. package/dist/types/ClassType.spec.js +5 -3
  234. package/dist/types/ClassType.spec.js.map +1 -1
  235. package/dist/types/ComponentType.d.ts +1 -1
  236. package/dist/types/ComponentType.js +3 -0
  237. package/dist/types/ComponentType.js.map +1 -1
  238. package/dist/types/DoubleType.js +3 -1
  239. package/dist/types/DoubleType.js.map +1 -1
  240. package/dist/types/EnumType.d.ts +1 -1
  241. package/dist/types/EnumType.js +7 -2
  242. package/dist/types/EnumType.js.map +1 -1
  243. package/dist/types/FloatType.js +3 -1
  244. package/dist/types/FloatType.js.map +1 -1
  245. package/dist/types/InheritableType.d.ts +7 -4
  246. package/dist/types/InheritableType.js +67 -3
  247. package/dist/types/InheritableType.js.map +1 -1
  248. package/dist/types/IntegerType.js +3 -1
  249. package/dist/types/IntegerType.js.map +1 -1
  250. package/dist/types/InterfaceType.d.ts +5 -4
  251. package/dist/types/InterfaceType.js +5 -12
  252. package/dist/types/InterfaceType.js.map +1 -1
  253. package/dist/types/InterfaceType.spec.js +23 -0
  254. package/dist/types/InterfaceType.spec.js.map +1 -1
  255. package/dist/types/LongIntegerType.js +3 -1
  256. package/dist/types/LongIntegerType.js.map +1 -1
  257. package/dist/types/NamespaceType.d.ts +2 -1
  258. package/dist/types/NamespaceType.js +3 -0
  259. package/dist/types/NamespaceType.js.map +1 -1
  260. package/dist/types/ObjectType.d.ts +1 -1
  261. package/dist/types/ReferenceType.js +40 -6
  262. package/dist/types/ReferenceType.js.map +1 -1
  263. package/dist/types/StringType.js +2 -2
  264. package/dist/types/StringType.js.map +1 -1
  265. package/dist/types/TypedFunctionType.d.ts +6 -1
  266. package/dist/types/TypedFunctionType.js +46 -16
  267. package/dist/types/TypedFunctionType.js.map +1 -1
  268. package/dist/types/TypedFunctionType.spec.js +99 -0
  269. package/dist/types/TypedFunctionType.spec.js.map +1 -1
  270. package/dist/types/UnionType.js +8 -0
  271. package/dist/types/UnionType.js.map +1 -1
  272. package/dist/types/helper.spec.js +15 -0
  273. package/dist/types/helper.spec.js.map +1 -1
  274. package/dist/types/helpers.d.ts +3 -0
  275. package/dist/types/helpers.js +33 -1
  276. package/dist/types/helpers.js.map +1 -1
  277. package/dist/util.d.ts +25 -9
  278. package/dist/util.js +165 -72
  279. package/dist/util.js.map +1 -1
  280. package/dist/validators/ClassValidator.js.map +1 -1
  281. package/package.json +2 -2
  282. package/dist/astUtils/AstEditor.js.map +0 -1
  283. package/dist/astUtils/AstEditor.spec.js.map +0 -1
  284. package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.js.map +0 -1
  285. package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.js +0 -31
  286. package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.js.map +0 -1
  287. /package/dist/astUtils/{AstEditor.spec.d.ts → Editor.spec.d.ts} +0 -0
  288. /package/dist/bscPlugin/{transpile/BrsFilePreTranspileProcessor.spec.d.ts → serialize/BslibInjector.spec.d.ts} +0 -0
package/dist/util.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { Diagnostic, Position, Range, Location } from 'vscode-languageserver';
1
+ import { type Diagnostic, type Position, type Range, type Location } from 'vscode-languageserver';
2
2
  import type { BsConfig } from './BsConfig';
3
3
  import type { CallableContainer, BsDiagnostic, FileReference, CallableContainerMap, CompilerPlugin, ExpressionInfo, TypeChainEntry, TypeChainProcessResult } from './interfaces';
4
4
  import { BooleanType } from './types/BooleanType';
@@ -21,6 +21,7 @@ import { type Expression, type Statement } from './parser/AstNode';
21
21
  import type { BscType } from './types/BscType';
22
22
  import { FunctionType } from './types/FunctionType';
23
23
  import type { SymbolTable } from './SymbolTable';
24
+ import type { UnresolvedSymbol } from './AstValidationSegmenter';
24
25
  export declare class Util {
25
26
  clearConsole(): void;
26
27
  /**
@@ -49,6 +50,7 @@ export declare class Util {
49
50
  startsWithProtocol(path: string): boolean;
50
51
  /**
51
52
  * Given a pkg path of any kind, transform it to a roku-specific pkg path (i.e. "pkg:/some/path.brs")
53
+ * @deprecated use `sanitizePkgPath instead. Will be removed in v1
52
54
  */
53
55
  getRokuPkgPath(pkgPath: string): string;
54
56
  /**
@@ -276,6 +278,11 @@ export declare class Util {
276
278
  * Helper for creating `Location` objects. Prefer using this function because vscode-languageserver's `Location.create()` is significantly slower at scale
277
279
  */
278
280
  createLocation(uri: string, range: Range): Location;
281
+ /**
282
+ * A cache of `Range` objects. The key is a 52bit integer created from the 4 range integers and leveraging bitshifting.
283
+ * The whole point of this cache is to reduce garbage collection churn, so we didn't want to use string concatenation for the key
284
+ */
285
+ private rangeCache;
279
286
  /**
280
287
  * Helper for creating `Range` objects. Prefer using this function because vscode-languageserver's `Range.create()` is significantly slower
281
288
  */
@@ -291,13 +298,15 @@ export declare class Util {
291
298
  createBoundingRange(...locatables: Array<{
292
299
  range?: Range;
293
300
  }>): Range;
301
+ /**
302
+ * A cache of `Position` objects. The key is a 26bit integer created from line and character and leveraging bitshifting
303
+ * The whole point of this cache is to reduce garbage collection churn, so we didn't want to use string concatenation for the key
304
+ */
305
+ private positionCache;
294
306
  /**
295
307
  * Create a `Position` object. Prefer this over `Position.create` for performance reasons
296
308
  */
297
- createPosition(line: number, character: number): {
298
- line: number;
299
- character: number;
300
- };
309
+ createPosition(line: number, character: number): Position;
301
310
  /**
302
311
  * Convert a list of tokens into a string, including their leading whitespace
303
312
  */
@@ -325,6 +334,7 @@ export declare class Util {
325
334
  /**
326
335
  * Get the extension for the given file path. Basically the part after the final dot, except for
327
336
  * `d.bs` which is treated as single extension
337
+ * @returns the file extension (i.e. ".d.bs", ".bs", ".brs", ".xml", ".jpg", etc...)
328
338
  */
329
339
  getExtension(filePath: string): string;
330
340
  /**
@@ -346,10 +356,6 @@ export declare class Util {
346
356
  * Converts a path into a standardized format (drive letter to lower, remove extra slashes, use single slash type, resolve relative parts, etc...)
347
357
  */
348
358
  standardizePath(thePath: string): string;
349
- /**
350
- * Copy the version of bslib from local node_modules to the staging folder
351
- */
352
- copyBslibToStaging(stagingDir: string): Promise<void>;
353
359
  /**
354
360
  * Given a Diagnostic or BsDiagnostic, return a deep clone of the diagnostic.
355
361
  * @param diagnostic the diagnostic to clone
@@ -422,6 +428,16 @@ export declare class Util {
422
428
  */
423
429
  findLastIndex<T>(array: T[], matcher: (T: any) => boolean): number;
424
430
  processTypeChain(typeChain: TypeChainEntry[]): TypeChainProcessResult;
431
+ isInTypeExpression(expression: AstNode): boolean;
432
+ setContainsUnresolvedSymbol(symbolLowerNameSet: Set<string>, symbol: UnresolvedSymbol): boolean;
433
+ truncate<T>(options: {
434
+ leadingText: string;
435
+ items: T[];
436
+ trailingText?: string;
437
+ maxLength: number;
438
+ itemSeparator?: string;
439
+ partBuilder?: (item: T) => string;
440
+ }): string;
425
441
  }
426
442
  /**
427
443
  * A tagged template literal function for standardizing the path. This has to be defined as standalone function since it's a tagged template literal function,
package/dist/util.js CHANGED
@@ -28,11 +28,25 @@ const requireRelative = require("require-relative");
28
28
  const AstNode_1 = require("./parser/AstNode");
29
29
  const creators_1 = require("./astUtils/creators");
30
30
  const FunctionType_1 = require("./types/FunctionType");
31
- const types_1 = require("./types");
31
+ const ArrayType_1 = require("./types/ArrayType");
32
32
  const SymbolTable_1 = require("./SymbolTable");
33
33
  const AssociativeArrayType_1 = require("./types/AssociativeArrayType");
34
34
  const ComponentType_1 = require("./types/ComponentType");
35
+ const diagnosticUtils_1 = require("./diagnosticUtils");
36
+ const ReferenceType_1 = require("./types/ReferenceType");
35
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
+ }
36
50
  clearConsole() {
37
51
  // process.stdout.write('\x1Bc');
38
52
  }
@@ -79,12 +93,10 @@ class Util {
79
93
  * Given a pkg path of any kind, transform it to a roku-specific pkg path (i.e. "pkg:/some/path.brs")
80
94
  */
81
95
  sanitizePkgPath(pkgPath) {
82
- pkgPath = pkgPath.replace(/\\/g, '/');
83
- //if there's no protocol, assume it's supposed to start with `pkg:/`
84
- if (!this.startsWithProtocol(pkgPath)) {
85
- pkgPath = 'pkg:/' + pkgPath;
86
- }
87
- 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, '');
88
100
  }
89
101
  /**
90
102
  * Determine if the given path starts with a protocol
@@ -94,10 +106,10 @@ class Util {
94
106
  }
95
107
  /**
96
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
97
110
  */
98
111
  getRokuPkgPath(pkgPath) {
99
- pkgPath = pkgPath.replace(/\\/g, '/');
100
- return 'pkg:/' + pkgPath;
112
+ return this.sanitizePkgPath(pkgPath);
101
113
  }
102
114
  /**
103
115
  * Given a path to a file/directory, replace all path separators with the current system's version.
@@ -273,6 +285,9 @@ class Util {
273
285
  */
274
286
  normalizeAndResolveConfig(config) {
275
287
  let result = this.normalizeConfig({});
288
+ if (config === null || config === void 0 ? void 0 : config.noProject) {
289
+ return result;
290
+ }
276
291
  //if no options were provided, try to find a bsconfig.json file
277
292
  if (!config || !config.project) {
278
293
  result.project = this.getConfigFilePath(config === null || config === void 0 ? void 0 : config.cwd);
@@ -294,7 +309,7 @@ class Util {
294
309
  * @param config a bsconfig object to use as the baseline for the resulting config
295
310
  */
296
311
  normalizeConfig(config) {
297
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
312
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
298
313
  config = config || {};
299
314
  config.cwd = (_a = config.cwd) !== null && _a !== void 0 ? _a : process.cwd();
300
315
  config.deploy = config.deploy === true ? true : false;
@@ -323,6 +338,11 @@ class Util {
323
338
  config.logLevel = Logger_1.LogLevel[config.logLevel.toLowerCase()];
324
339
  }
325
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
+ }
326
346
  return config;
327
347
  }
328
348
  /**
@@ -730,6 +750,7 @@ class Util {
730
750
  }
731
751
  }
732
752
  }
753
+ return false;
733
754
  }
734
755
  /**
735
756
  * Walks up the chain to find the closest bsconfig.json file
@@ -910,31 +931,23 @@ class Util {
910
931
  * Helper for creating `Range` objects. Prefer using this function because vscode-languageserver's `Range.create()` is significantly slower
911
932
  */
912
933
  createRange(startLine, startCharacter, endLine, endCharacter) {
913
- return {
914
- start: {
915
- line: startLine,
916
- character: startCharacter
917
- },
918
- end: {
919
- line: endLine,
920
- character: endCharacter
921
- }
922
- };
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;
923
945
  }
924
946
  /**
925
947
  * Create a `Range` from two `Position`s
926
948
  */
927
949
  createRangeFromPositions(startPosition, endPosition) {
928
- return {
929
- start: {
930
- line: startPosition.line,
931
- character: startPosition.character
932
- },
933
- end: {
934
- line: endPosition.line,
935
- character: endPosition.character
936
- }
937
- };
950
+ return this.createRange(startPosition.line, startPosition.character, endPosition.line, endPosition.character);
938
951
  }
939
952
  /**
940
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
@@ -974,10 +987,17 @@ class Util {
974
987
  * Create a `Position` object. Prefer this over `Position.create` for performance reasons
975
988
  */
976
989
  createPosition(line, character) {
977
- return {
978
- line: line,
979
- character: character
980
- };
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;
981
1001
  }
982
1002
  /**
983
1003
  * Convert a list of tokens into a string, including their leading whitespace
@@ -1084,7 +1104,7 @@ class Util {
1084
1104
  arrayOfTypeName = arrayOfTypeName.substring(0, arrayOfTypeName.length - 1);
1085
1105
  }
1086
1106
  let arrayType = this.getNodeFieldType(arrayOfTypeName, lookupTable);
1087
- return new types_1.ArrayType(arrayType);
1107
+ return new ArrayType_1.ArrayType(arrayType);
1088
1108
  }
1089
1109
  else if (typeDescriptorLower.startsWith('option ')) {
1090
1110
  const actualTypeName = typeDescriptorLower.substring('option '.length); //cut off beginning 'option '
@@ -1098,16 +1118,16 @@ class Util {
1098
1118
  return StringType_1.StringType.instance;
1099
1119
  }
1100
1120
  else if (typeDescriptorLower === 'vector2d' || typeDescriptorLower === 'floatarray') {
1101
- return new types_1.ArrayType(FloatType_1.FloatType.instance);
1121
+ return new ArrayType_1.ArrayType(FloatType_1.FloatType.instance);
1102
1122
  }
1103
1123
  else if (typeDescriptorLower === 'intarray') {
1104
- return new types_1.ArrayType(IntegerType_1.IntegerType.instance);
1124
+ return new ArrayType_1.ArrayType(IntegerType_1.IntegerType.instance);
1105
1125
  }
1106
1126
  else if (typeDescriptorLower === 'boolarray') {
1107
- return new types_1.ArrayType(BooleanType_1.BooleanType.instance);
1127
+ return new ArrayType_1.ArrayType(BooleanType_1.BooleanType.instance);
1108
1128
  }
1109
1129
  else if (typeDescriptorLower === 'stringarray' || typeDescriptorLower === 'strarray') {
1110
- return new types_1.ArrayType(StringType_1.StringType.instance);
1130
+ return new ArrayType_1.ArrayType(StringType_1.StringType.instance);
1111
1131
  }
1112
1132
  else if (typeDescriptorLower === 'int') {
1113
1133
  return IntegerType_1.IntegerType.instance;
@@ -1128,7 +1148,7 @@ class Util {
1128
1148
  return ComponentType_1.ComponentType.instance;
1129
1149
  }
1130
1150
  else if (typeDescriptorLower === 'nodearray') {
1131
- return new types_1.ArrayType(ComponentType_1.ComponentType.instance);
1151
+ return new ArrayType_1.ArrayType(ComponentType_1.ComponentType.instance);
1132
1152
  }
1133
1153
  else if (lookupTable) {
1134
1154
  //try doing a lookup
@@ -1144,7 +1164,7 @@ class Util {
1144
1164
  binaryOperatorResultType(leftType, operator, rightType) {
1145
1165
  if (((0, reflection_1.isAnyReferenceType)(leftType) && !leftType.isResolvable()) ||
1146
1166
  ((0, reflection_1.isAnyReferenceType)(rightType) && !rightType.isResolvable())) {
1147
- return new types_1.BinaryOperatorReferenceType(leftType, operator, rightType, (lhs, op, rhs) => {
1167
+ return new ReferenceType_1.BinaryOperatorReferenceType(leftType, operator, rightType, (lhs, op, rhs) => {
1148
1168
  return this.binaryOperatorResultType(lhs, op, rhs);
1149
1169
  });
1150
1170
  }
@@ -1298,6 +1318,7 @@ class Util {
1298
1318
  /**
1299
1319
  * Get the extension for the given file path. Basically the part after the final dot, except for
1300
1320
  * `d.bs` which is treated as single extension
1321
+ * @returns the file extension (i.e. ".d.bs", ".bs", ".brs", ".xml", ".jpg", etc...)
1301
1322
  */
1302
1323
  getExtension(filePath) {
1303
1324
  filePath = filePath.toLowerCase();
@@ -1305,10 +1326,7 @@ class Util {
1305
1326
  return '.d.bs';
1306
1327
  }
1307
1328
  else {
1308
- const idx = filePath.lastIndexOf('.');
1309
- if (idx > -1) {
1310
- return filePath.substring(idx);
1311
- }
1329
+ return path.extname(filePath).toLowerCase();
1312
1330
  }
1313
1331
  }
1314
1332
  /**
@@ -1398,29 +1416,6 @@ class Util {
1398
1416
  standardizePath(thePath) {
1399
1417
  return exports.util.driveLetterToLower((0, roku_deploy_1.standardizePath)(thePath));
1400
1418
  }
1401
- /**
1402
- * Copy the version of bslib from local node_modules to the staging folder
1403
- */
1404
- async copyBslibToStaging(stagingDir) {
1405
- //copy bslib to the output directory
1406
- await fsExtra.ensureDir(standardizePath(`${stagingDir}/source`));
1407
- // eslint-disable-next-line
1408
- const bslib = require('@rokucommunity/bslib');
1409
- let source = bslib.source;
1410
- //apply the `bslib_` prefix to the functions
1411
- let match;
1412
- const positions = [];
1413
- const regexp = /^(\s*(?:function|sub)\s+)([a-z0-9_]+)/mg;
1414
- // eslint-disable-next-line no-cond-assign
1415
- while (match = regexp.exec(source)) {
1416
- positions.push(match.index + match[1].length);
1417
- }
1418
- for (let i = positions.length - 1; i >= 0; i--) {
1419
- const position = positions[i];
1420
- source = source.slice(0, position) + 'bslib_' + source.slice(position);
1421
- }
1422
- await fsExtra.writeFile(`${stagingDir}/source/bslib.brs`, source);
1423
- }
1424
1419
  /**
1425
1420
  * Given a Diagnostic or BsDiagnostic, return a deep clone of the diagnostic.
1426
1421
  * @param diagnostic the diagnostic to clone
@@ -1428,11 +1423,20 @@ class Util {
1428
1423
  */
1429
1424
  toDiagnostic(diagnostic, relatedInformationFallbackLocation) {
1430
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
+ }
1431
1435
  return {
1432
1436
  severity: diagnostic.severity,
1433
1437
  range: diagnostic.range,
1434
1438
  message: diagnostic.message,
1435
- relatedInformation: (_a = diagnostic.relatedInformation) === null || _a === void 0 ? void 0 : _a.map(x => {
1439
+ relatedInformation: relatedInformation.map(x => {
1436
1440
  //clone related information just in case a plugin added circular ref info here
1437
1441
  const clone = Object.assign({}, x);
1438
1442
  if (!clone.location) {
@@ -1681,15 +1685,15 @@ class Util {
1681
1685
  validateTooDeepFile(file) {
1682
1686
  var _a;
1683
1687
  //find any files nested too deep
1684
- let pkgPath = (_a = file.pkgPath) !== null && _a !== void 0 ? _a : file.pkgPath.toString();
1685
- 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();
1686
1690
  if ((0, reflection_1.isBrsFile)(file) && rootFolder !== 'source') {
1687
1691
  return;
1688
1692
  }
1689
1693
  if ((0, reflection_1.isXmlFile)(file) && rootFolder !== 'components') {
1690
1694
  return;
1691
1695
  }
1692
- let fileDepth = this.getParentDirectoryCount(pkgPath);
1696
+ let fileDepth = this.getParentDirectoryCount(destPath);
1693
1697
  if (fileDepth >= 8) {
1694
1698
  file.addDiagnostics([Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.detectedTooDeepFileSource(fileDepth)), { file: file, range: this.createRange(0, 0, 0, Number.MAX_VALUE) })]);
1695
1699
  }
@@ -1739,6 +1743,95 @@ class Util {
1739
1743
  containsDynamic: containsDynamic
1740
1744
  };
1741
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
+ }
1742
1835
  }
1743
1836
  exports.Util = Util;
1744
1837
  /**