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.
- package/CHANGELOG.md +88 -10
- package/README.md +16 -0
- package/bsconfig.schema.json +15 -0
- package/dist/ActionPipeline.d.ts +10 -0
- package/dist/ActionPipeline.js +40 -0
- package/dist/ActionPipeline.js.map +1 -0
- package/dist/AstValidationSegmenter.d.ts +25 -0
- package/dist/AstValidationSegmenter.js +150 -0
- package/dist/AstValidationSegmenter.js.map +1 -0
- package/dist/BsConfig.d.ts +15 -1
- package/dist/CommentFlagProcessor.d.ts +4 -3
- package/dist/CommentFlagProcessor.js.map +1 -1
- package/dist/DiagnosticMessages.d.ts +8 -1
- package/dist/DiagnosticMessages.js +30 -13
- package/dist/DiagnosticMessages.js.map +1 -1
- package/dist/LanguageServer.js +7 -1
- package/dist/LanguageServer.js.map +1 -1
- package/dist/PluginInterface.d.ts +11 -2
- package/dist/PluginInterface.js +69 -10
- package/dist/PluginInterface.js.map +1 -1
- package/dist/Program.d.ts +107 -38
- package/dist/Program.js +502 -270
- package/dist/Program.js.map +1 -1
- package/dist/ProgramBuilder.d.ts +10 -4
- package/dist/ProgramBuilder.js +44 -54
- package/dist/ProgramBuilder.js.map +1 -1
- package/dist/Scope.d.ts +26 -38
- package/dist/Scope.js +153 -174
- package/dist/Scope.js.map +1 -1
- package/dist/SymbolTable.d.ts +4 -1
- package/dist/SymbolTable.js +19 -7
- package/dist/SymbolTable.js.map +1 -1
- package/dist/XmlScope.d.ts +5 -4
- package/dist/XmlScope.js +16 -14
- package/dist/XmlScope.js.map +1 -1
- package/dist/astUtils/{AstEditor.d.ts → Editor.d.ts} +6 -1
- package/dist/astUtils/{AstEditor.js → Editor.js} +9 -3
- package/dist/astUtils/Editor.js.map +1 -0
- package/dist/astUtils/{AstEditor.spec.js → Editor.spec.js} +10 -6
- package/dist/astUtils/Editor.spec.js.map +1 -0
- package/dist/astUtils/reflection.d.ts +9 -4
- package/dist/astUtils/reflection.js +23 -7
- package/dist/astUtils/reflection.js.map +1 -1
- package/dist/astUtils/reflection.spec.js +2 -2
- package/dist/astUtils/reflection.spec.js.map +1 -1
- package/dist/astUtils/visitors.d.ts +14 -3
- package/dist/astUtils/visitors.js +22 -2
- package/dist/astUtils/visitors.js.map +1 -1
- package/dist/astUtils/visitors.spec.js +58 -7
- package/dist/astUtils/visitors.spec.js.map +1 -1
- package/dist/bscPlugin/BscPlugin.d.ts +10 -2
- package/dist/bscPlugin/BscPlugin.js +24 -4
- package/dist/bscPlugin/BscPlugin.js.map +1 -1
- package/dist/bscPlugin/FileWriter.d.ts +6 -0
- package/dist/bscPlugin/FileWriter.js +24 -0
- package/dist/bscPlugin/FileWriter.js.map +1 -0
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.js +8 -8
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.js.map +1 -1
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js.map +1 -1
- package/dist/bscPlugin/completions/CompletionsProcessor.d.ts +7 -2
- package/dist/bscPlugin/completions/CompletionsProcessor.js +112 -44
- package/dist/bscPlugin/completions/CompletionsProcessor.js.map +1 -1
- package/dist/bscPlugin/completions/CompletionsProcessor.spec.js +212 -6
- package/dist/bscPlugin/completions/CompletionsProcessor.spec.js.map +1 -1
- package/dist/bscPlugin/fileProviders/FileProvider.d.ts +9 -0
- package/dist/bscPlugin/fileProviders/FileProvider.js +51 -0
- package/dist/bscPlugin/fileProviders/FileProvider.js.map +1 -0
- package/dist/bscPlugin/hover/HoverProcessor.d.ts +1 -7
- package/dist/bscPlugin/hover/HoverProcessor.js +10 -8
- package/dist/bscPlugin/hover/HoverProcessor.js.map +1 -1
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.d.ts +1 -0
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js +43 -0
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js.map +1 -1
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js +22 -0
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js.map +1 -1
- package/dist/bscPlugin/serialize/BslibInjector.spec.js +19 -0
- package/dist/bscPlugin/serialize/BslibInjector.spec.js.map +1 -0
- package/dist/bscPlugin/serialize/BslibManager.d.ts +9 -0
- package/dist/bscPlugin/serialize/BslibManager.js +40 -0
- package/dist/bscPlugin/serialize/BslibManager.js.map +1 -0
- package/dist/bscPlugin/serialize/FileSerializer.d.ts +9 -0
- package/dist/bscPlugin/serialize/FileSerializer.js +72 -0
- package/dist/bscPlugin/serialize/FileSerializer.js.map +1 -0
- package/dist/bscPlugin/transpile/{BrsFilePreTranspileProcessor.d.ts → BrsFileTranspileProcessor.d.ts} +4 -2
- package/dist/bscPlugin/transpile/{BrsFilePreTranspileProcessor.js → BrsFileTranspileProcessor.js} +29 -5
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.js.map +1 -0
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.spec.d.ts +1 -0
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.spec.js +41 -0
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.spec.js.map +1 -0
- package/dist/bscPlugin/transpile/XmlFilePreTranspileProcessor.d.ts +2 -2
- package/dist/bscPlugin/transpile/XmlFilePreTranspileProcessor.js.map +1 -1
- package/dist/bscPlugin/validation/BrsFileValidator.js +8 -3
- package/dist/bscPlugin/validation/BrsFileValidator.js.map +1 -1
- package/dist/bscPlugin/validation/BrsFileValidator.spec.js +1 -1
- package/dist/bscPlugin/validation/BrsFileValidator.spec.js.map +1 -1
- package/dist/bscPlugin/validation/ScopeValidator.d.ts +5 -9
- package/dist/bscPlugin/validation/ScopeValidator.js +214 -222
- package/dist/bscPlugin/validation/ScopeValidator.js.map +1 -1
- package/dist/bscPlugin/validation/ScopeValidator.spec.js +669 -0
- package/dist/bscPlugin/validation/ScopeValidator.spec.js.map +1 -1
- package/dist/bscPlugin/validation/XmlFileValidator.js +2 -2
- package/dist/bscPlugin/validation/XmlFileValidator.js.map +1 -1
- package/dist/cli.js +1 -0
- package/dist/cli.js.map +1 -1
- package/dist/deferred.d.ts +2 -2
- package/dist/deferred.js.map +1 -1
- package/dist/diagnosticUtils.d.ts +1 -0
- package/dist/diagnosticUtils.js +4 -3
- package/dist/diagnosticUtils.js.map +1 -1
- package/dist/examples/plugins/removePrint.js +1 -1
- package/dist/examples/plugins/removePrint.js.map +1 -1
- package/dist/files/AssetFile.d.ts +26 -0
- package/dist/files/AssetFile.js +26 -0
- package/dist/files/AssetFile.js.map +1 -0
- package/dist/files/BrsFile.Class.spec.js +241 -40
- package/dist/files/BrsFile.Class.spec.js.map +1 -1
- package/dist/files/BrsFile.d.ts +66 -16
- package/dist/files/BrsFile.js +330 -80
- package/dist/files/BrsFile.js.map +1 -1
- package/dist/files/BrsFile.spec.js +1134 -167
- package/dist/files/BrsFile.spec.js.map +1 -1
- package/dist/files/Factory.d.ts +25 -0
- package/dist/files/Factory.js +22 -0
- package/dist/files/Factory.js.map +1 -0
- package/dist/files/File.d.ts +106 -0
- package/dist/files/File.js +16 -0
- package/dist/files/File.js.map +1 -0
- package/dist/files/LazyFileData.d.ts +20 -0
- package/dist/files/LazyFileData.js +54 -0
- package/dist/files/LazyFileData.js.map +1 -0
- package/dist/files/LazyFileData.spec.d.ts +1 -0
- package/dist/files/LazyFileData.spec.js +27 -0
- package/dist/files/LazyFileData.spec.js.map +1 -0
- package/dist/files/XmlFile.d.ts +55 -17
- package/dist/files/XmlFile.js +88 -47
- package/dist/files/XmlFile.js.map +1 -1
- package/dist/files/XmlFile.spec.js +64 -57
- package/dist/files/XmlFile.spec.js.map +1 -1
- package/dist/files/tests/imports.spec.js +21 -8
- package/dist/files/tests/imports.spec.js.map +1 -1
- package/dist/files/tests/optionalChaning.spec.js +14 -14
- package/dist/files/tests/optionalChaning.spec.js.map +1 -1
- package/dist/globalCallables.js +1 -1
- package/dist/globalCallables.js.map +1 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.js +6 -1
- package/dist/index.js.map +1 -1
- package/dist/interfaces.d.ts +357 -89
- package/dist/interfaces.js +10 -2
- package/dist/interfaces.js.map +1 -1
- package/dist/lexer/Lexer.js +1 -1
- package/dist/lexer/TokenKind.d.ts +1 -0
- package/dist/lexer/TokenKind.js +4 -1
- package/dist/lexer/TokenKind.js.map +1 -1
- package/dist/parser/AstNode.d.ts +2 -2
- package/dist/parser/AstNode.js +1 -1
- package/dist/parser/AstNode.js.map +1 -1
- package/dist/parser/BrsTranspileState.d.ts +3 -2
- package/dist/parser/BrsTranspileState.js +3 -2
- package/dist/parser/BrsTranspileState.js.map +1 -1
- package/dist/parser/Expression.d.ts +2 -2
- package/dist/parser/Expression.js +23 -19
- package/dist/parser/Expression.js.map +1 -1
- package/dist/parser/Parser.Class.spec.js +103 -0
- package/dist/parser/Parser.Class.spec.js.map +1 -1
- package/dist/parser/Parser.js +61 -13
- package/dist/parser/Parser.js.map +1 -1
- package/dist/parser/Parser.spec.js +227 -1
- package/dist/parser/Parser.spec.js.map +1 -1
- package/dist/parser/SGParser.d.ts +2 -2
- package/dist/parser/SGParser.js +3 -3
- package/dist/parser/SGParser.js.map +1 -1
- package/dist/parser/SGParser.spec.js +2 -2
- package/dist/parser/SGParser.spec.js.map +1 -1
- package/dist/parser/SGTypes.d.ts +1 -1
- package/dist/parser/Statement.d.ts +12 -5
- package/dist/parser/Statement.js +56 -26
- package/dist/parser/Statement.js.map +1 -1
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js +16 -16
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/RegexLiteralExpression.spec.js +10 -10
- package/dist/parser/tests/expression/RegexLiteralExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/SourceLiteralExpression.spec.js +24 -24
- package/dist/parser/tests/expression/SourceLiteralExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/TemplateStringExpression.spec.js +64 -36
- package/dist/parser/tests/expression/TemplateStringExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/TernaryExpression.spec.js +34 -34
- package/dist/parser/tests/expression/TernaryExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/UnaryExpression.spec.d.ts +1 -0
- package/dist/parser/tests/expression/UnaryExpression.spec.js +52 -0
- package/dist/parser/tests/expression/UnaryExpression.spec.js.map +1 -0
- package/dist/parser/tests/statement/ConstStatement.spec.js +90 -16
- package/dist/parser/tests/statement/ConstStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/Continue.spec.js +2 -2
- package/dist/parser/tests/statement/Continue.spec.js.map +1 -1
- package/dist/parser/tests/statement/Enum.spec.js +35 -26
- package/dist/parser/tests/statement/Enum.spec.js.map +1 -1
- package/dist/parser/tests/statement/For.spec.js +6 -6
- package/dist/parser/tests/statement/For.spec.js.map +1 -1
- package/dist/parser/tests/statement/ForEach.spec.js +4 -4
- package/dist/parser/tests/statement/ForEach.spec.js.map +1 -1
- package/dist/parser/tests/statement/InterfaceStatement.spec.js +20 -12
- package/dist/parser/tests/statement/InterfaceStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/PrintStatement.spec.js +10 -10
- package/dist/parser/tests/statement/PrintStatement.spec.js.map +1 -1
- package/dist/preprocessor/Manifest.d.ts +1 -1
- package/dist/preprocessor/Manifest.js +2 -2
- package/dist/preprocessor/Manifest.js.map +1 -1
- package/dist/roku-types/data.json +98 -193
- package/dist/roku-types/index.d.ts +15 -11
- package/dist/types/ArrayType.d.ts +1 -1
- package/dist/types/ArrayType.js +4 -0
- package/dist/types/ArrayType.js.map +1 -1
- package/dist/types/ArrayType.spec.js +1 -1
- package/dist/types/ArrayType.spec.js.map +1 -1
- package/dist/types/AssociativeArrayType.d.ts +1 -1
- package/dist/types/AssociativeArrayType.js +1 -1
- package/dist/types/AssociativeArrayType.js.map +1 -1
- package/dist/types/BooleanType.d.ts +1 -1
- package/dist/types/BooleanType.js +2 -1
- package/dist/types/BooleanType.js.map +1 -1
- package/dist/types/BscType.d.ts +2 -2
- package/dist/types/BscType.js +30 -9
- package/dist/types/BscType.js.map +1 -1
- package/dist/types/BuiltInInterfaceAdder.d.ts +3 -0
- package/dist/types/BuiltInInterfaceAdder.js +37 -16
- package/dist/types/BuiltInInterfaceAdder.js.map +1 -1
- package/dist/types/BuiltInInterfaceAdder.spec.js +7 -0
- package/dist/types/BuiltInInterfaceAdder.spec.js.map +1 -1
- package/dist/types/ClassType.d.ts +4 -3
- package/dist/types/ClassType.js +6 -3
- package/dist/types/ClassType.js.map +1 -1
- package/dist/types/ClassType.spec.js +5 -3
- package/dist/types/ClassType.spec.js.map +1 -1
- package/dist/types/ComponentType.d.ts +1 -1
- package/dist/types/ComponentType.js +3 -0
- package/dist/types/ComponentType.js.map +1 -1
- package/dist/types/DoubleType.js +3 -1
- package/dist/types/DoubleType.js.map +1 -1
- package/dist/types/EnumType.d.ts +1 -1
- package/dist/types/EnumType.js +7 -2
- package/dist/types/EnumType.js.map +1 -1
- package/dist/types/FloatType.js +3 -1
- package/dist/types/FloatType.js.map +1 -1
- package/dist/types/InheritableType.d.ts +7 -4
- package/dist/types/InheritableType.js +67 -3
- package/dist/types/InheritableType.js.map +1 -1
- package/dist/types/IntegerType.js +3 -1
- package/dist/types/IntegerType.js.map +1 -1
- package/dist/types/InterfaceType.d.ts +5 -4
- package/dist/types/InterfaceType.js +5 -12
- package/dist/types/InterfaceType.js.map +1 -1
- package/dist/types/InterfaceType.spec.js +23 -0
- package/dist/types/InterfaceType.spec.js.map +1 -1
- package/dist/types/LongIntegerType.js +3 -1
- package/dist/types/LongIntegerType.js.map +1 -1
- package/dist/types/NamespaceType.d.ts +2 -1
- package/dist/types/NamespaceType.js +3 -0
- package/dist/types/NamespaceType.js.map +1 -1
- package/dist/types/ObjectType.d.ts +1 -1
- package/dist/types/ReferenceType.js +40 -6
- package/dist/types/ReferenceType.js.map +1 -1
- package/dist/types/StringType.js +2 -2
- package/dist/types/StringType.js.map +1 -1
- package/dist/types/TypedFunctionType.d.ts +6 -1
- package/dist/types/TypedFunctionType.js +46 -16
- package/dist/types/TypedFunctionType.js.map +1 -1
- package/dist/types/TypedFunctionType.spec.js +99 -0
- package/dist/types/TypedFunctionType.spec.js.map +1 -1
- package/dist/types/UnionType.js +8 -0
- package/dist/types/UnionType.js.map +1 -1
- package/dist/types/helper.spec.js +15 -0
- package/dist/types/helper.spec.js.map +1 -1
- package/dist/types/helpers.d.ts +3 -0
- package/dist/types/helpers.js +33 -1
- package/dist/types/helpers.js.map +1 -1
- package/dist/util.d.ts +25 -9
- package/dist/util.js +165 -72
- package/dist/util.js.map +1 -1
- package/dist/validators/ClassValidator.js.map +1 -1
- package/package.json +2 -2
- package/dist/astUtils/AstEditor.js.map +0 -1
- package/dist/astUtils/AstEditor.spec.js.map +0 -1
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.js.map +0 -1
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.js +0 -31
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.js.map +0 -1
- /package/dist/astUtils/{AstEditor.spec.d.ts → Editor.spec.d.ts} +0 -0
- /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
|
|
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
|
|
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
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
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
|
-
|
|
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
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
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
|
-
|
|
978
|
-
|
|
979
|
-
|
|
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
|
|
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
|
|
1121
|
+
return new ArrayType_1.ArrayType(FloatType_1.FloatType.instance);
|
|
1102
1122
|
}
|
|
1103
1123
|
else if (typeDescriptorLower === 'intarray') {
|
|
1104
|
-
return new
|
|
1124
|
+
return new ArrayType_1.ArrayType(IntegerType_1.IntegerType.instance);
|
|
1105
1125
|
}
|
|
1106
1126
|
else if (typeDescriptorLower === 'boolarray') {
|
|
1107
|
-
return new
|
|
1127
|
+
return new ArrayType_1.ArrayType(BooleanType_1.BooleanType.instance);
|
|
1108
1128
|
}
|
|
1109
1129
|
else if (typeDescriptorLower === 'stringarray' || typeDescriptorLower === 'strarray') {
|
|
1110
|
-
return new
|
|
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
|
|
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
|
|
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
|
-
|
|
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:
|
|
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
|
|
1685
|
-
let rootFolder =
|
|
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(
|
|
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
|
/**
|