brighterscript 1.0.0-alpha.24 → 1.0.0-alpha.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +521 -233
- package/README.md +45 -139
- package/bsconfig.schema.json +46 -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 +152 -0
- package/dist/AstValidationSegmenter.js.map +1 -0
- package/dist/BsConfig.d.ts +40 -4
- package/dist/BusyStatusTracker.d.ts +31 -0
- package/dist/BusyStatusTracker.js +83 -0
- package/dist/BusyStatusTracker.js.map +1 -0
- package/dist/Cache.js +3 -3
- package/dist/Cache.js.map +1 -1
- package/dist/CacheVerifier.d.ts +7 -0
- package/dist/CacheVerifier.js +20 -0
- package/dist/CacheVerifier.js.map +1 -0
- package/dist/CodeActionUtil.d.ts +3 -3
- package/dist/CodeActionUtil.js.map +1 -1
- package/dist/CommentFlagProcessor.d.ts +3 -2
- package/dist/CommentFlagProcessor.js +5 -4
- package/dist/CommentFlagProcessor.js.map +1 -1
- package/dist/DependencyGraph.d.ts +3 -2
- package/dist/DependencyGraph.js +11 -10
- package/dist/DependencyGraph.js.map +1 -1
- package/dist/DiagnosticCollection.js +9 -5
- package/dist/DiagnosticCollection.js.map +1 -1
- package/dist/DiagnosticFilterer.d.ts +1 -0
- package/dist/DiagnosticFilterer.js +5 -3
- package/dist/DiagnosticFilterer.js.map +1 -1
- package/dist/DiagnosticMessages.d.ts +61 -13
- package/dist/DiagnosticMessages.js +116 -19
- package/dist/DiagnosticMessages.js.map +1 -1
- package/dist/DiagnosticSeverityAdjuster.d.ts +7 -0
- package/dist/DiagnosticSeverityAdjuster.js +41 -0
- package/dist/DiagnosticSeverityAdjuster.js.map +1 -0
- package/dist/FunctionScope.d.ts +28 -0
- package/dist/FunctionScope.js +52 -0
- package/dist/FunctionScope.js.map +1 -0
- package/dist/KeyedThrottler.d.ts +3 -3
- package/dist/KeyedThrottler.js +3 -3
- package/dist/KeyedThrottler.js.map +1 -1
- package/dist/LanguageServer.d.ts +23 -11
- package/dist/LanguageServer.js +150 -69
- package/dist/LanguageServer.js.map +1 -1
- package/dist/Logger.d.ts +3 -2
- package/dist/Logger.js +11 -3
- package/dist/Logger.js.map +1 -1
- package/dist/PluginInterface.d.ts +21 -3
- package/dist/PluginInterface.js +74 -6
- package/dist/PluginInterface.js.map +1 -1
- package/dist/Program.d.ts +158 -79
- package/dist/Program.js +841 -706
- package/dist/Program.js.map +1 -1
- package/dist/ProgramBuilder.d.ts +22 -12
- package/dist/ProgramBuilder.js +130 -103
- package/dist/ProgramBuilder.js.map +1 -1
- package/dist/Scope.d.ts +86 -137
- package/dist/Scope.js +453 -519
- package/dist/Scope.js.map +1 -1
- package/dist/Stopwatch.js +1 -1
- package/dist/Stopwatch.js.map +1 -1
- package/dist/SymbolTable.d.ts +89 -34
- package/dist/SymbolTable.js +239 -114
- package/dist/SymbolTable.js.map +1 -1
- package/dist/Throttler.d.ts +12 -0
- package/dist/Throttler.js +39 -0
- package/dist/Throttler.js.map +1 -1
- package/dist/Watcher.d.ts +0 -3
- package/dist/Watcher.js +0 -3
- package/dist/Watcher.js.map +1 -1
- package/dist/XmlScope.d.ts +4 -11
- package/dist/XmlScope.js +75 -88
- package/dist/XmlScope.js.map +1 -1
- package/dist/astUtils/CachedLookups.d.ts +48 -0
- package/dist/astUtils/CachedLookups.js +323 -0
- package/dist/astUtils/CachedLookups.js.map +1 -0
- package/dist/astUtils/{AstEditor.d.ts → Editor.d.ts} +9 -5
- package/dist/astUtils/{AstEditor.js → Editor.js} +10 -4
- package/dist/astUtils/Editor.js.map +1 -0
- package/dist/astUtils/{AstEditor.spec.js → Editor.spec.js} +69 -65
- package/dist/astUtils/Editor.spec.js.map +1 -0
- package/dist/astUtils/creators.d.ts +10 -10
- package/dist/astUtils/creators.js +54 -24
- package/dist/astUtils/creators.js.map +1 -1
- package/dist/astUtils/creators.spec.js +5 -5
- package/dist/astUtils/creators.spec.js.map +1 -1
- package/dist/astUtils/reflection.d.ts +132 -104
- package/dist/astUtils/reflection.js +220 -174
- package/dist/astUtils/reflection.js.map +1 -1
- package/dist/astUtils/reflection.spec.js +256 -157
- package/dist/astUtils/reflection.spec.js.map +1 -1
- package/dist/astUtils/stackedVisitor.spec.js +12 -12
- package/dist/astUtils/stackedVisitor.spec.js.map +1 -1
- package/dist/astUtils/visitors.d.ts +53 -35
- package/dist/astUtils/visitors.js +29 -3
- package/dist/astUtils/visitors.js.map +1 -1
- package/dist/astUtils/visitors.spec.js +208 -52
- package/dist/astUtils/visitors.spec.js.map +1 -1
- package/dist/astUtils/xml.d.ts +9 -9
- package/dist/astUtils/xml.js +9 -9
- package/dist/astUtils/xml.js.map +1 -1
- package/dist/bscPlugin/BscPlugin.d.ts +11 -2
- package/dist/bscPlugin/BscPlugin.js +37 -3
- package/dist/bscPlugin/BscPlugin.js.map +1 -1
- package/dist/bscPlugin/CallExpressionInfo.d.ts +36 -0
- package/dist/bscPlugin/CallExpressionInfo.js +131 -0
- package/dist/bscPlugin/CallExpressionInfo.js.map +1 -0
- 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/SignatureHelpUtil.d.ts +10 -0
- package/dist/bscPlugin/SignatureHelpUtil.js +136 -0
- package/dist/bscPlugin/SignatureHelpUtil.js.map +1 -0
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.js +16 -13
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.js.map +1 -1
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js +16 -16
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js.map +1 -1
- package/dist/bscPlugin/completions/CompletionsProcessor.d.ts +52 -1
- package/dist/bscPlugin/completions/CompletionsProcessor.js +517 -26
- package/dist/bscPlugin/completions/CompletionsProcessor.js.map +1 -1
- package/dist/bscPlugin/completions/CompletionsProcessor.spec.js +1909 -0
- package/dist/bscPlugin/completions/CompletionsProcessor.spec.js.map +1 -0
- package/dist/bscPlugin/definition/DefinitionProvider.d.ts +13 -0
- package/dist/bscPlugin/definition/DefinitionProvider.js +210 -0
- package/dist/bscPlugin/definition/DefinitionProvider.js.map +1 -0
- package/dist/bscPlugin/definition/DefinitionProvider.spec.js +88 -0
- package/dist/bscPlugin/definition/DefinitionProvider.spec.js.map +1 -0
- 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 +7 -7
- package/dist/bscPlugin/hover/HoverProcessor.js +123 -125
- package/dist/bscPlugin/hover/HoverProcessor.js.map +1 -1
- package/dist/bscPlugin/hover/HoverProcessor.spec.js +371 -53
- package/dist/bscPlugin/hover/HoverProcessor.spec.js.map +1 -1
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.d.ts +2 -1
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js +83 -23
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js.map +1 -1
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js +83 -6
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js.map +1 -1
- package/dist/bscPlugin/serialize/BslibInjector.spec.d.ts +1 -0
- 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} +38 -12
- 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 +12 -0
- package/dist/bscPlugin/transpile/XmlFilePreTranspileProcessor.js +99 -0
- package/dist/bscPlugin/transpile/XmlFilePreTranspileProcessor.js.map +1 -0
- package/dist/bscPlugin/validation/BrsFileValidator.d.ts +13 -5
- package/dist/bscPlugin/validation/BrsFileValidator.js +262 -52
- package/dist/bscPlugin/validation/BrsFileValidator.js.map +1 -1
- package/dist/bscPlugin/validation/BrsFileValidator.spec.js +230 -14
- package/dist/bscPlugin/validation/BrsFileValidator.spec.js.map +1 -1
- package/dist/bscPlugin/validation/ProgramValidator.d.ts +10 -0
- package/dist/bscPlugin/validation/ProgramValidator.js +32 -0
- package/dist/bscPlugin/validation/ProgramValidator.js.map +1 -0
- package/dist/bscPlugin/validation/ScopeValidator.d.ts +58 -27
- package/dist/bscPlugin/validation/ScopeValidator.js +514 -286
- package/dist/bscPlugin/validation/ScopeValidator.js.map +1 -1
- package/dist/bscPlugin/validation/ScopeValidator.spec.d.ts +1 -0
- package/dist/bscPlugin/validation/ScopeValidator.spec.js +2527 -0
- package/dist/bscPlugin/validation/ScopeValidator.spec.js.map +1 -0
- package/dist/bscPlugin/validation/XmlFileValidator.d.ts +8 -0
- package/dist/bscPlugin/validation/XmlFileValidator.js +44 -0
- package/dist/bscPlugin/validation/XmlFileValidator.js.map +1 -0
- package/dist/cli.js +104 -13
- package/dist/cli.js.map +1 -1
- package/dist/deferred.d.ts +3 -3
- package/dist/deferred.js.map +1 -1
- package/dist/diagnosticUtils.d.ts +8 -2
- package/dist/diagnosticUtils.js +47 -17
- package/dist/diagnosticUtils.js.map +1 -1
- package/dist/examples/plugins/removePrint.js +8 -10
- 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 +523 -493
- package/dist/files/BrsFile.Class.spec.js.map +1 -1
- package/dist/files/BrsFile.d.ts +111 -117
- package/dist/files/BrsFile.js +684 -1142
- package/dist/files/BrsFile.js.map +1 -1
- package/dist/files/BrsFile.spec.js +1783 -1233
- package/dist/files/BrsFile.spec.js.map +1 -1
- package/dist/files/BscFile.d.ts +104 -0
- package/dist/files/BscFile.js +16 -0
- package/dist/files/BscFile.js.map +1 -0
- 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/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 +70 -32
- package/dist/files/XmlFile.js +106 -118
- package/dist/files/XmlFile.js.map +1 -1
- package/dist/files/XmlFile.spec.js +325 -262
- package/dist/files/XmlFile.spec.js.map +1 -1
- package/dist/files/tests/imports.spec.js +48 -40
- package/dist/files/tests/imports.spec.js.map +1 -1
- package/dist/files/tests/optionalChaning.spec.js +84 -24
- package/dist/files/tests/optionalChaning.spec.js.map +1 -1
- package/dist/globalCallables.js +16 -21
- package/dist/globalCallables.js.map +1 -1
- package/dist/index.d.ts +12 -1
- package/dist/index.js +12 -1
- package/dist/index.js.map +1 -1
- package/dist/interfaces.d.ts +421 -162
- package/dist/interfaces.js +27 -0
- package/dist/interfaces.js.map +1 -1
- package/dist/lexer/Character.spec.js +5 -5
- package/dist/lexer/Character.spec.js.map +1 -1
- package/dist/lexer/Lexer.d.ts +12 -5
- package/dist/lexer/Lexer.js +28 -13
- package/dist/lexer/Lexer.js.map +1 -1
- package/dist/lexer/Lexer.spec.js +181 -135
- package/dist/lexer/Lexer.spec.js.map +1 -1
- package/dist/lexer/Token.d.ts +9 -1
- package/dist/lexer/Token.js +9 -1
- package/dist/lexer/Token.js.map +1 -1
- package/dist/lexer/TokenKind.d.ts +8 -0
- package/dist/lexer/TokenKind.js +24 -4
- package/dist/lexer/TokenKind.js.map +1 -1
- package/dist/parser/AstNode.d.ts +162 -0
- package/dist/parser/AstNode.js +225 -0
- package/dist/parser/AstNode.js.map +1 -0
- package/dist/parser/AstNode.spec.d.ts +1 -0
- package/dist/parser/AstNode.spec.js +165 -0
- package/dist/parser/AstNode.spec.js.map +1 -0
- package/dist/parser/BrsTranspileState.d.ts +4 -7
- package/dist/parser/BrsTranspileState.js +4 -12
- package/dist/parser/BrsTranspileState.js.map +1 -1
- package/dist/parser/Expression.d.ts +376 -283
- package/dist/parser/Expression.js +742 -585
- package/dist/parser/Expression.js.map +1 -1
- package/dist/parser/Parser.Class.spec.js +151 -145
- package/dist/parser/Parser.Class.spec.js.map +1 -1
- package/dist/parser/Parser.d.ts +48 -201
- package/dist/parser/Parser.js +705 -1026
- package/dist/parser/Parser.js.map +1 -1
- package/dist/parser/Parser.spec.d.ts +3 -1
- package/dist/parser/Parser.spec.js +861 -848
- package/dist/parser/Parser.spec.js.map +1 -1
- package/dist/parser/SGParser.d.ts +9 -8
- package/dist/parser/SGParser.js +10 -8
- package/dist/parser/SGParser.js.map +1 -1
- package/dist/parser/SGParser.spec.js +27 -38
- package/dist/parser/SGParser.spec.js.map +1 -1
- package/dist/parser/SGTypes.d.ts +98 -35
- package/dist/parser/SGTypes.js +169 -99
- package/dist/parser/SGTypes.js.map +1 -1
- package/dist/parser/Statement.d.ts +468 -272
- package/dist/parser/Statement.js +904 -631
- package/dist/parser/Statement.js.map +1 -1
- package/dist/parser/Statement.spec.js +47 -23
- package/dist/parser/Statement.spec.js.map +1 -1
- package/dist/parser/TranspileState.d.ts +1 -1
- package/dist/parser/TranspileState.js +7 -12
- package/dist/parser/TranspileState.js.map +1 -1
- package/dist/parser/tests/Parser.spec.js +3 -2
- package/dist/parser/tests/Parser.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/For.spec.js +33 -23
- package/dist/parser/tests/controlFlow/For.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/ForEach.spec.js +25 -20
- package/dist/parser/tests/controlFlow/ForEach.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/If.spec.js +96 -94
- package/dist/parser/tests/controlFlow/If.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/While.spec.js +22 -16
- package/dist/parser/tests/controlFlow/While.spec.js.map +1 -1
- package/dist/parser/tests/expression/Additive.spec.js +8 -8
- package/dist/parser/tests/expression/Additive.spec.js.map +1 -1
- package/dist/parser/tests/expression/ArrayLiterals.spec.js +58 -21
- package/dist/parser/tests/expression/ArrayLiterals.spec.js.map +1 -1
- package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js +62 -21
- package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js.map +1 -1
- package/dist/parser/tests/expression/Boolean.spec.js +8 -8
- package/dist/parser/tests/expression/Boolean.spec.js.map +1 -1
- package/dist/parser/tests/expression/Call.spec.js +129 -21
- package/dist/parser/tests/expression/Call.spec.js.map +1 -1
- package/dist/parser/tests/expression/Exponential.spec.js +5 -5
- package/dist/parser/tests/expression/Exponential.spec.js.map +1 -1
- package/dist/parser/tests/expression/Function.spec.js +36 -36
- package/dist/parser/tests/expression/Function.spec.js.map +1 -1
- package/dist/parser/tests/expression/Indexing.spec.js +92 -22
- package/dist/parser/tests/expression/Indexing.spec.js.map +1 -1
- package/dist/parser/tests/expression/Multiplicative.spec.js +9 -9
- package/dist/parser/tests/expression/Multiplicative.spec.js.map +1 -1
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js +59 -59
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/PrefixUnary.spec.js +12 -12
- package/dist/parser/tests/expression/PrefixUnary.spec.js.map +1 -1
- package/dist/parser/tests/expression/Primary.spec.js +12 -12
- package/dist/parser/tests/expression/Primary.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/Relational.spec.js +13 -13
- package/dist/parser/tests/expression/Relational.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 +96 -57
- package/dist/parser/tests/expression/TemplateStringExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/TernaryExpression.spec.js +89 -89
- package/dist/parser/tests/expression/TernaryExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/TypeExpression.spec.d.ts +1 -0
- package/dist/parser/tests/expression/TypeExpression.spec.js +127 -0
- package/dist/parser/tests/expression/TypeExpression.spec.js.map +1 -0
- 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/AssignmentOperators.spec.js +15 -15
- package/dist/parser/tests/statement/AssignmentOperators.spec.js.map +1 -1
- package/dist/parser/tests/statement/ConstStatement.spec.js +82 -33
- package/dist/parser/tests/statement/ConstStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/Continue.spec.d.ts +1 -0
- package/dist/parser/tests/statement/Continue.spec.js +119 -0
- package/dist/parser/tests/statement/Continue.spec.js.map +1 -0
- package/dist/parser/tests/statement/Declaration.spec.js +19 -19
- package/dist/parser/tests/statement/Declaration.spec.js.map +1 -1
- package/dist/parser/tests/statement/Dim.spec.js +22 -22
- package/dist/parser/tests/statement/Dim.spec.js.map +1 -1
- package/dist/parser/tests/statement/Enum.spec.js +98 -302
- package/dist/parser/tests/statement/Enum.spec.js.map +1 -1
- package/dist/parser/tests/statement/For.spec.js +9 -10
- package/dist/parser/tests/statement/For.spec.js.map +1 -1
- package/dist/parser/tests/statement/ForEach.spec.js +8 -9
- package/dist/parser/tests/statement/ForEach.spec.js.map +1 -1
- package/dist/parser/tests/statement/Function.spec.js +44 -35
- package/dist/parser/tests/statement/Function.spec.js.map +1 -1
- package/dist/parser/tests/statement/Goto.spec.js +5 -5
- package/dist/parser/tests/statement/Goto.spec.js.map +1 -1
- package/dist/parser/tests/statement/Increment.spec.js +20 -20
- package/dist/parser/tests/statement/Increment.spec.js.map +1 -1
- package/dist/parser/tests/statement/InterfaceStatement.spec.js +30 -196
- package/dist/parser/tests/statement/InterfaceStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/LibraryStatement.spec.js +11 -11
- package/dist/parser/tests/statement/LibraryStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/Misc.spec.js +16 -78
- package/dist/parser/tests/statement/Misc.spec.js.map +1 -1
- package/dist/parser/tests/statement/PrintStatement.spec.js +36 -34
- package/dist/parser/tests/statement/PrintStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/ReturnStatement.spec.js +14 -12
- package/dist/parser/tests/statement/ReturnStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/Set.spec.js +48 -35
- package/dist/parser/tests/statement/Set.spec.js.map +1 -1
- package/dist/parser/tests/statement/Stop.spec.js +6 -6
- package/dist/parser/tests/statement/Stop.spec.js.map +1 -1
- package/dist/parser/tests/statement/Throw.spec.js +6 -6
- package/dist/parser/tests/statement/Throw.spec.js.map +1 -1
- package/dist/parser/tests/statement/TryCatch.spec.js +18 -16
- package/dist/parser/tests/statement/TryCatch.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/preprocessor/Manifest.spec.js +8 -8
- package/dist/preprocessor/Manifest.spec.js.map +1 -1
- package/dist/preprocessor/Preprocessor.d.ts +5 -6
- package/dist/preprocessor/Preprocessor.js +5 -5
- package/dist/preprocessor/Preprocessor.js.map +1 -1
- package/dist/preprocessor/Preprocessor.spec.js +25 -25
- package/dist/preprocessor/Preprocessor.spec.js.map +1 -1
- package/dist/preprocessor/PreprocessorParser.d.ts +1 -1
- package/dist/preprocessor/PreprocessorParser.js +7 -1
- package/dist/preprocessor/PreprocessorParser.js.map +1 -1
- package/dist/preprocessor/PreprocessorParser.spec.js +13 -13
- package/dist/preprocessor/PreprocessorParser.spec.js.map +1 -1
- package/dist/roku-types/data.json +5892 -10081
- package/dist/roku-types/index.d.ts +622 -1719
- package/dist/types/ArrayType.d.ts +10 -9
- package/dist/types/ArrayType.js +65 -60
- package/dist/types/ArrayType.js.map +1 -1
- package/dist/types/ArrayType.spec.js +36 -68
- package/dist/types/ArrayType.spec.js.map +1 -1
- package/dist/types/AssociativeArrayType.d.ts +11 -0
- package/dist/types/AssociativeArrayType.js +52 -0
- package/dist/types/AssociativeArrayType.js.map +1 -0
- package/dist/types/BaseFunctionType.d.ts +9 -0
- package/dist/types/BaseFunctionType.js +25 -0
- package/dist/types/BaseFunctionType.js.map +1 -0
- package/dist/types/BooleanType.d.ts +8 -5
- package/dist/types/BooleanType.js +14 -7
- package/dist/types/BooleanType.js.map +1 -1
- package/dist/types/BooleanType.spec.js +10 -6
- package/dist/types/BooleanType.spec.js.map +1 -1
- package/dist/types/BscType.d.ts +32 -21
- package/dist/types/BscType.js +118 -21
- package/dist/types/BscType.js.map +1 -1
- package/dist/types/BscTypeKind.d.ts +25 -0
- package/dist/types/BscTypeKind.js +30 -0
- package/dist/types/BscTypeKind.js.map +1 -0
- package/dist/types/BuiltInInterfaceAdder.d.ts +23 -0
- package/dist/types/BuiltInInterfaceAdder.js +171 -0
- package/dist/types/BuiltInInterfaceAdder.js.map +1 -0
- package/dist/types/BuiltInInterfaceAdder.spec.d.ts +1 -0
- package/dist/types/BuiltInInterfaceAdder.spec.js +116 -0
- package/dist/types/BuiltInInterfaceAdder.spec.js.map +1 -0
- package/dist/types/ClassType.d.ts +17 -0
- package/dist/types/ClassType.js +58 -0
- package/dist/types/ClassType.js.map +1 -0
- package/dist/types/ClassType.spec.d.ts +1 -0
- package/dist/types/ClassType.spec.js +77 -0
- package/dist/types/ClassType.spec.js.map +1 -0
- package/dist/types/ComponentType.d.ts +26 -0
- package/dist/types/ComponentType.js +83 -0
- package/dist/types/ComponentType.js.map +1 -0
- package/dist/types/DoubleType.d.ts +8 -5
- package/dist/types/DoubleType.js +18 -16
- package/dist/types/DoubleType.js.map +1 -1
- package/dist/types/DoubleType.spec.js +12 -6
- package/dist/types/DoubleType.spec.js.map +1 -1
- package/dist/types/DynamicType.d.ts +9 -5
- package/dist/types/DynamicType.js +15 -4
- package/dist/types/DynamicType.js.map +1 -1
- package/dist/types/DynamicType.spec.js +16 -5
- package/dist/types/DynamicType.spec.js.map +1 -1
- package/dist/types/EnumType.d.ts +30 -12
- package/dist/types/EnumType.js +43 -17
- package/dist/types/EnumType.js.map +1 -1
- package/dist/types/EnumType.spec.d.ts +1 -0
- package/dist/types/EnumType.spec.js +33 -0
- package/dist/types/EnumType.spec.js.map +1 -0
- package/dist/types/FloatType.d.ts +8 -5
- package/dist/types/FloatType.js +18 -16
- package/dist/types/FloatType.js.map +1 -1
- package/dist/types/FloatType.spec.js +4 -6
- package/dist/types/FloatType.spec.js.map +1 -1
- package/dist/types/FunctionType.d.ts +13 -8
- package/dist/types/FunctionType.js +30 -14
- package/dist/types/FunctionType.js.map +1 -1
- package/dist/types/InheritableType.d.ts +28 -0
- package/dist/types/InheritableType.js +152 -0
- package/dist/types/InheritableType.js.map +1 -0
- package/dist/types/IntegerType.d.ts +8 -5
- package/dist/types/IntegerType.js +18 -16
- package/dist/types/IntegerType.js.map +1 -1
- package/dist/types/IntegerType.spec.js +8 -6
- package/dist/types/IntegerType.spec.js.map +1 -1
- package/dist/types/InterfaceType.d.ts +12 -13
- package/dist/types/InterfaceType.js +20 -48
- package/dist/types/InterfaceType.js.map +1 -1
- package/dist/types/InterfaceType.spec.js +90 -56
- package/dist/types/InterfaceType.spec.js.map +1 -1
- package/dist/types/InvalidType.d.ts +7 -5
- package/dist/types/InvalidType.js +13 -7
- package/dist/types/InvalidType.js.map +1 -1
- package/dist/types/InvalidType.spec.js +8 -6
- package/dist/types/InvalidType.spec.js.map +1 -1
- package/dist/types/LongIntegerType.d.ts +8 -5
- package/dist/types/LongIntegerType.js +17 -15
- package/dist/types/LongIntegerType.js.map +1 -1
- package/dist/types/LongIntegerType.spec.js +10 -6
- package/dist/types/LongIntegerType.spec.js.map +1 -1
- package/dist/types/NamespaceType.d.ts +12 -0
- package/dist/types/NamespaceType.js +28 -0
- package/dist/types/NamespaceType.js.map +1 -0
- package/dist/types/ObjectType.d.ts +9 -8
- package/dist/types/ObjectType.js +21 -11
- package/dist/types/ObjectType.js.map +1 -1
- package/dist/types/ObjectType.spec.js +3 -3
- package/dist/types/ObjectType.spec.js.map +1 -1
- package/dist/types/ReferenceType.d.ts +63 -0
- package/dist/types/ReferenceType.js +423 -0
- package/dist/types/ReferenceType.js.map +1 -0
- package/dist/types/ReferenceType.spec.d.ts +1 -0
- package/dist/types/ReferenceType.spec.js +137 -0
- package/dist/types/ReferenceType.spec.js.map +1 -0
- package/dist/types/StringType.d.ts +11 -5
- package/dist/types/StringType.js +18 -7
- package/dist/types/StringType.js.map +1 -1
- package/dist/types/StringType.spec.js +3 -5
- package/dist/types/StringType.spec.js.map +1 -1
- package/dist/types/TypedFunctionType.d.ts +22 -17
- package/dist/types/TypedFunctionType.js +78 -60
- package/dist/types/TypedFunctionType.js.map +1 -1
- package/dist/types/TypedFunctionType.spec.js +105 -20
- package/dist/types/TypedFunctionType.spec.js.map +1 -1
- package/dist/types/UninitializedType.d.ts +8 -6
- package/dist/types/UninitializedType.js +13 -7
- package/dist/types/UninitializedType.js.map +1 -1
- package/dist/types/UnionType.d.ts +20 -0
- package/dist/types/UnionType.js +123 -0
- package/dist/types/UnionType.js.map +1 -0
- package/dist/types/UnionType.spec.d.ts +1 -0
- package/dist/types/UnionType.spec.js +130 -0
- package/dist/types/UnionType.spec.js.map +1 -0
- package/dist/types/VoidType.d.ts +8 -5
- package/dist/types/VoidType.js +14 -7
- package/dist/types/VoidType.js.map +1 -1
- package/dist/types/VoidType.spec.js +3 -3
- package/dist/types/VoidType.spec.js.map +1 -1
- package/dist/types/helper.spec.d.ts +1 -0
- package/dist/types/helper.spec.js +145 -0
- package/dist/types/helper.spec.js.map +1 -0
- package/dist/types/helpers.d.ts +19 -37
- package/dist/types/helpers.js +159 -99
- package/dist/types/helpers.js.map +1 -1
- package/dist/types/index.d.ts +22 -0
- package/dist/types/index.js +39 -0
- package/dist/types/index.js.map +1 -0
- package/dist/util.d.ts +143 -139
- package/dist/util.js +864 -385
- package/dist/util.js.map +1 -1
- package/dist/validators/ClassValidator.d.ts +8 -25
- package/dist/validators/ClassValidator.js +99 -179
- package/dist/validators/ClassValidator.js.map +1 -1
- package/package.json +165 -152
- 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 -32
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.js.map +0 -1
- package/dist/parser/SGTypes.spec.js +0 -351
- package/dist/parser/SGTypes.spec.js.map +0 -1
- package/dist/types/CustomType.d.ts +0 -12
- package/dist/types/CustomType.js +0 -44
- package/dist/types/CustomType.js.map +0 -1
- package/dist/types/LazyType.d.ts +0 -16
- package/dist/types/LazyType.js +0 -44
- package/dist/types/LazyType.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 → completions/CompletionsProcessor.spec.d.ts} +0 -0
- /package/dist/{parser/SGTypes.spec.d.ts → bscPlugin/definition/DefinitionProvider.spec.d.ts} +0 -0
package/dist/util.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.util = exports.standardizePath = exports.Util = void 0;
|
|
4
4
|
const fs = require("fs");
|
|
5
5
|
const fsExtra = require("fs-extra");
|
|
6
6
|
const jsonc_parser_1 = require("jsonc-parser");
|
|
7
7
|
const path = require("path");
|
|
8
8
|
const roku_deploy_1 = require("roku-deploy");
|
|
9
|
+
const vscode_languageserver_1 = require("vscode-languageserver");
|
|
9
10
|
const vscode_uri_1 = require("vscode-uri");
|
|
10
11
|
const xml2js = require("xml2js");
|
|
11
12
|
const DiagnosticMessages_1 = require("./DiagnosticMessages");
|
|
@@ -13,9 +14,7 @@ const BooleanType_1 = require("./types/BooleanType");
|
|
|
13
14
|
const DoubleType_1 = require("./types/DoubleType");
|
|
14
15
|
const DynamicType_1 = require("./types/DynamicType");
|
|
15
16
|
const FloatType_1 = require("./types/FloatType");
|
|
16
|
-
const TypedFunctionType_1 = require("./types/TypedFunctionType");
|
|
17
17
|
const IntegerType_1 = require("./types/IntegerType");
|
|
18
|
-
const InvalidType_1 = require("./types/InvalidType");
|
|
19
18
|
const LongIntegerType_1 = require("./types/LongIntegerType");
|
|
20
19
|
const ObjectType_1 = require("./types/ObjectType");
|
|
21
20
|
const StringType_1 = require("./types/StringType");
|
|
@@ -26,29 +25,44 @@ const TokenKind_1 = require("./lexer/TokenKind");
|
|
|
26
25
|
const reflection_1 = require("./astUtils/reflection");
|
|
27
26
|
const visitors_1 = require("./astUtils/visitors");
|
|
28
27
|
const source_map_1 = require("source-map");
|
|
29
|
-
const SGTypes_1 = require("./parser/SGTypes");
|
|
30
28
|
const requireRelative = require("require-relative");
|
|
29
|
+
const AstNode_1 = require("./parser/AstNode");
|
|
30
|
+
const SymbolTable_1 = require("./SymbolTable");
|
|
31
|
+
const creators_1 = require("./astUtils/creators");
|
|
32
|
+
const diagnosticUtils_1 = require("./diagnosticUtils");
|
|
33
|
+
const types_1 = require("./types");
|
|
34
|
+
const AssociativeArrayType_1 = require("./types/AssociativeArrayType");
|
|
35
|
+
const ComponentType_1 = require("./types/ComponentType");
|
|
31
36
|
const FunctionType_1 = require("./types/FunctionType");
|
|
32
|
-
const LazyType_1 = require("./types/LazyType");
|
|
33
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
|
+
}
|
|
34
50
|
clearConsole() {
|
|
35
51
|
// process.stdout.write('\x1Bc');
|
|
36
52
|
}
|
|
37
53
|
/**
|
|
38
54
|
* Returns the number of parent directories in the filPath
|
|
39
|
-
* @param filePath
|
|
40
55
|
*/
|
|
41
56
|
getParentDirectoryCount(filePath) {
|
|
42
57
|
if (!filePath) {
|
|
43
58
|
return -1;
|
|
44
59
|
}
|
|
45
60
|
else {
|
|
46
|
-
return filePath.replace(/^pkg
|
|
61
|
+
return filePath.replace(/^pkg:/, '').split(/[\\\/]/).length - 1;
|
|
47
62
|
}
|
|
48
63
|
}
|
|
49
64
|
/**
|
|
50
65
|
* Determine if the file exists
|
|
51
|
-
* @param filePath
|
|
52
66
|
*/
|
|
53
67
|
async pathExists(filePath) {
|
|
54
68
|
if (!filePath) {
|
|
@@ -60,7 +74,6 @@ class Util {
|
|
|
60
74
|
}
|
|
61
75
|
/**
|
|
62
76
|
* Determine if the file exists
|
|
63
|
-
* @param filePath
|
|
64
77
|
*/
|
|
65
78
|
pathExistsSync(filePath) {
|
|
66
79
|
if (!filePath) {
|
|
@@ -74,18 +87,16 @@ class Util {
|
|
|
74
87
|
* Determine if this path is a directory
|
|
75
88
|
*/
|
|
76
89
|
isDirectorySync(dirPath) {
|
|
77
|
-
return fs.existsSync(dirPath) && fs.lstatSync(dirPath).isDirectory();
|
|
90
|
+
return dirPath !== undefined && fs.existsSync(dirPath) && fs.lstatSync(dirPath).isDirectory();
|
|
78
91
|
}
|
|
79
92
|
/**
|
|
80
93
|
* Given a pkg path of any kind, transform it to a roku-specific pkg path (i.e. "pkg:/some/path.brs")
|
|
81
94
|
*/
|
|
82
95
|
sanitizePkgPath(pkgPath) {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}
|
|
88
|
-
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, '');
|
|
89
100
|
}
|
|
90
101
|
/**
|
|
91
102
|
* Determine if the given path starts with a protocol
|
|
@@ -93,9 +104,15 @@ class Util {
|
|
|
93
104
|
startsWithProtocol(path) {
|
|
94
105
|
return !!/^[-a-z]+:\//i.exec(path);
|
|
95
106
|
}
|
|
107
|
+
/**
|
|
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
|
|
110
|
+
*/
|
|
111
|
+
getRokuPkgPath(pkgPath) {
|
|
112
|
+
return this.sanitizePkgPath(pkgPath);
|
|
113
|
+
}
|
|
96
114
|
/**
|
|
97
115
|
* Given a path to a file/directory, replace all path separators with the current system's version.
|
|
98
|
-
* @param filePath
|
|
99
116
|
*/
|
|
100
117
|
pathSepNormalize(filePath, separator) {
|
|
101
118
|
if (!filePath) {
|
|
@@ -107,7 +124,7 @@ class Util {
|
|
|
107
124
|
/**
|
|
108
125
|
* Find the path to the config file.
|
|
109
126
|
* If the config file path doesn't exist
|
|
110
|
-
* @param
|
|
127
|
+
* @param cwd the current working directory where the search for configs should begin
|
|
111
128
|
*/
|
|
112
129
|
getConfigFilePath(cwd) {
|
|
113
130
|
cwd = cwd !== null && cwd !== void 0 ? cwd : process.cwd();
|
|
@@ -141,13 +158,13 @@ class Util {
|
|
|
141
158
|
colIndex++;
|
|
142
159
|
}
|
|
143
160
|
}
|
|
144
|
-
return
|
|
161
|
+
return exports.util.createRange(lineIndex, colIndex, lineIndex, colIndex + length);
|
|
145
162
|
}
|
|
146
163
|
/**
|
|
147
164
|
* Load the contents of a config file.
|
|
148
165
|
* If the file extends another config, this will load the base config as well.
|
|
149
|
-
* @param configFilePath
|
|
150
|
-
* @param parentProjectPaths
|
|
166
|
+
* @param configFilePath the relative or absolute path to a brighterscript config json file
|
|
167
|
+
* @param parentProjectPaths a list of parent config files. This is used by this method to recursively build the config list
|
|
151
168
|
*/
|
|
152
169
|
loadConfigFile(configFilePath, parentProjectPaths, cwd = process.cwd()) {
|
|
153
170
|
var _a;
|
|
@@ -216,7 +233,8 @@ class Util {
|
|
|
216
233
|
}
|
|
217
234
|
/**
|
|
218
235
|
* Convert relative paths to absolute paths, relative to the given directory. Also de-dupes the paths. Modifies the array in-place
|
|
219
|
-
* @param
|
|
236
|
+
* @param collection usually a bsconfig.
|
|
237
|
+
* @param key a key of the config to read paths from (usually this is `'plugins'` or `'require'`)
|
|
220
238
|
* @param relativeDir the path to the folder where the paths should be resolved relative to. This should be an absolute path
|
|
221
239
|
*/
|
|
222
240
|
resolvePathsRelativeTo(collection, key, relativeDir) {
|
|
@@ -234,8 +252,8 @@ class Util {
|
|
|
234
252
|
}
|
|
235
253
|
/**
|
|
236
254
|
* Do work within the scope of a changed current working directory
|
|
237
|
-
* @param targetCwd
|
|
238
|
-
* @param callback
|
|
255
|
+
* @param targetCwd the cwd where the work should be performed
|
|
256
|
+
* @param callback a function to call when the cwd has been changed to `targetCwd`
|
|
239
257
|
*/
|
|
240
258
|
cwdWork(targetCwd, callback) {
|
|
241
259
|
let originalCwd = process.cwd();
|
|
@@ -257,16 +275,20 @@ class Util {
|
|
|
257
275
|
throw err;
|
|
258
276
|
}
|
|
259
277
|
else {
|
|
278
|
+
//justification: `result` is set as long as `err` is not set and vice versa
|
|
260
279
|
return result;
|
|
261
280
|
}
|
|
262
281
|
}
|
|
263
282
|
/**
|
|
264
283
|
* Given a BsConfig object, start with defaults,
|
|
265
284
|
* merge with bsconfig.json and the provided options.
|
|
266
|
-
* @param config
|
|
285
|
+
* @param config a bsconfig object to use as the baseline for the resulting config
|
|
267
286
|
*/
|
|
268
287
|
normalizeAndResolveConfig(config) {
|
|
269
288
|
let result = this.normalizeConfig({});
|
|
289
|
+
if (config === null || config === void 0 ? void 0 : config.noProject) {
|
|
290
|
+
return result;
|
|
291
|
+
}
|
|
270
292
|
//if no options were provided, try to find a bsconfig.json file
|
|
271
293
|
if (!config || !config.project) {
|
|
272
294
|
result.project = this.getConfigFilePath(config === null || config === void 0 ? void 0 : config.cwd);
|
|
@@ -276,7 +298,7 @@ class Util {
|
|
|
276
298
|
result.project = config.project;
|
|
277
299
|
}
|
|
278
300
|
if (result.project) {
|
|
279
|
-
let configFile = this.loadConfigFile(result.project,
|
|
301
|
+
let configFile = this.loadConfigFile(result.project, undefined, config === null || config === void 0 ? void 0 : config.cwd);
|
|
280
302
|
result = Object.assign(result, configFile);
|
|
281
303
|
}
|
|
282
304
|
//override the defaults with the specified options
|
|
@@ -285,43 +307,60 @@ class Util {
|
|
|
285
307
|
}
|
|
286
308
|
/**
|
|
287
309
|
* Set defaults for any missing items
|
|
288
|
-
* @param config
|
|
310
|
+
* @param config a bsconfig object to use as the baseline for the resulting config
|
|
289
311
|
*/
|
|
290
312
|
normalizeConfig(config) {
|
|
291
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
292
|
-
config = config
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
config.createPackage = config.createPackage === false ? false : true;
|
|
298
|
-
let rootFolderName = path.basename(config.cwd);
|
|
299
|
-
config.outFile = (_c = config.outFile) !== null && _c !== void 0 ? _c : `./out/${rootFolderName}.zip`;
|
|
300
|
-
config.sourceMap = config.sourceMap === true;
|
|
301
|
-
config.username = (_d = config.username) !== null && _d !== void 0 ? _d : 'rokudev';
|
|
302
|
-
config.watch = config.watch === true ? true : false;
|
|
303
|
-
config.emitFullPaths = config.emitFullPaths === true ? true : false;
|
|
304
|
-
config.retainStagingFolder = config.retainStagingFolder === true ? true : false;
|
|
305
|
-
config.copyToStaging = config.copyToStaging === false ? false : true;
|
|
306
|
-
config.ignoreErrorCodes = (_e = config.ignoreErrorCodes) !== null && _e !== void 0 ? _e : [];
|
|
307
|
-
config.diagnosticFilters = (_f = config.diagnosticFilters) !== null && _f !== void 0 ? _f : [];
|
|
308
|
-
config.plugins = (_g = config.plugins) !== null && _g !== void 0 ? _g : [];
|
|
309
|
-
config.autoImportComponentScript = config.autoImportComponentScript === true ? true : false;
|
|
310
|
-
config.showDiagnosticsInConsole = config.showDiagnosticsInConsole === false ? false : true;
|
|
311
|
-
config.sourceRoot = config.sourceRoot ? standardizePath(config.sourceRoot) : undefined;
|
|
312
|
-
config.allowBrighterScriptInBrightScript = config.allowBrighterScriptInBrightScript === true ? true : false;
|
|
313
|
-
config.emitDefinitions = config.emitDefinitions === true ? true : false;
|
|
313
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
314
|
+
config = config !== null && config !== void 0 ? config : {};
|
|
315
|
+
const cwd = (_a = config.cwd) !== null && _a !== void 0 ? _a : process.cwd();
|
|
316
|
+
const rootFolderName = path.basename(cwd);
|
|
317
|
+
const retainStagingDir = ((_b = config.retainStagingDir) !== null && _b !== void 0 ? _b : config.retainStagingDir) === true ? true : false;
|
|
318
|
+
let logLevel = Logger_1.LogLevel.log;
|
|
314
319
|
if (typeof config.logLevel === 'string') {
|
|
315
|
-
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
|
|
320
|
+
logLevel = (_c = Logger_1.LogLevel[config.logLevel.toLowerCase()]) !== null && _c !== void 0 ? _c : Logger_1.LogLevel.log;
|
|
321
|
+
}
|
|
322
|
+
let bslibDestinationDir = (_d = config.bslibDestinationDir) !== null && _d !== void 0 ? _d : 'source';
|
|
323
|
+
if (bslibDestinationDir !== 'source') {
|
|
324
|
+
// strip leading and trailing slashes
|
|
325
|
+
bslibDestinationDir = bslibDestinationDir.replace(/^(\/*)(.*?)(\/*)$/, '$2');
|
|
326
|
+
}
|
|
327
|
+
const configWithDefaults = {
|
|
328
|
+
cwd: cwd,
|
|
329
|
+
deploy: config.deploy === true ? true : false,
|
|
330
|
+
//use default files array from rokuDeploy
|
|
331
|
+
files: (_e = config.files) !== null && _e !== void 0 ? _e : [...roku_deploy_1.DefaultFiles],
|
|
332
|
+
createPackage: config.createPackage === false ? false : true,
|
|
333
|
+
outFile: (_f = config.outFile) !== null && _f !== void 0 ? _f : `./out/${rootFolderName}.zip`,
|
|
334
|
+
sourceMap: config.sourceMap === true,
|
|
335
|
+
username: (_g = config.username) !== null && _g !== void 0 ? _g : 'rokudev',
|
|
336
|
+
watch: config.watch === true ? true : false,
|
|
337
|
+
emitFullPaths: config.emitFullPaths === true ? true : false,
|
|
338
|
+
retainStagingDir: retainStagingDir,
|
|
339
|
+
copyToStaging: config.copyToStaging === false ? false : true,
|
|
340
|
+
ignoreErrorCodes: (_h = config.ignoreErrorCodes) !== null && _h !== void 0 ? _h : [],
|
|
341
|
+
diagnosticSeverityOverrides: (_j = config.diagnosticSeverityOverrides) !== null && _j !== void 0 ? _j : {},
|
|
342
|
+
diagnosticFilters: (_k = config.diagnosticFilters) !== null && _k !== void 0 ? _k : [],
|
|
343
|
+
plugins: (_l = config.plugins) !== null && _l !== void 0 ? _l : [],
|
|
344
|
+
pruneEmptyCodeFiles: config.pruneEmptyCodeFiles === true ? true : false,
|
|
345
|
+
autoImportComponentScript: config.autoImportComponentScript === true ? true : false,
|
|
346
|
+
showDiagnosticsInConsole: config.showDiagnosticsInConsole === false ? false : true,
|
|
347
|
+
sourceRoot: config.sourceRoot ? standardizePath(config.sourceRoot) : undefined,
|
|
348
|
+
allowBrighterScriptInBrightScript: config.allowBrighterScriptInBrightScript === true ? true : false,
|
|
349
|
+
emitDefinitions: config.emitDefinitions === true ? true : false,
|
|
350
|
+
removeParameterTypes: config.removeParameterTypes === true ? true : false,
|
|
351
|
+
logLevel: logLevel,
|
|
352
|
+
bslibDestinationDir: bslibDestinationDir,
|
|
353
|
+
legacyCallfuncHandling: config.legacyCallfuncHandling === true ? true : false
|
|
354
|
+
};
|
|
355
|
+
//mutate `config` in case anyone is holding a reference to the incomplete one
|
|
356
|
+
const merged = Object.assign(config, configWithDefaults);
|
|
357
|
+
return merged;
|
|
319
358
|
}
|
|
320
359
|
/**
|
|
321
360
|
* Get the root directory from options.
|
|
322
361
|
* Falls back to options.cwd.
|
|
323
362
|
* Falls back to process.cwd
|
|
324
|
-
* @param options
|
|
363
|
+
* @param options a bsconfig object
|
|
325
364
|
*/
|
|
326
365
|
getRootDir(options) {
|
|
327
366
|
if (!options) {
|
|
@@ -333,19 +372,8 @@ class Util {
|
|
|
333
372
|
rootDir = path.resolve(cwd, rootDir);
|
|
334
373
|
return rootDir;
|
|
335
374
|
}
|
|
336
|
-
/**
|
|
337
|
-
* Format a string with placeholders replaced by argument indexes
|
|
338
|
-
* @param subject
|
|
339
|
-
* @param params
|
|
340
|
-
*/
|
|
341
|
-
stringFormat(subject, ...args) {
|
|
342
|
-
return subject.replace(/{(\d+)}/g, (match, num) => {
|
|
343
|
-
return typeof args[num] !== 'undefined' ? args[num] : match;
|
|
344
|
-
});
|
|
345
|
-
}
|
|
346
375
|
/**
|
|
347
376
|
* Given a list of callables as a dictionary indexed by their full name (namespace included, transpiled to underscore-separated.
|
|
348
|
-
* @param callables
|
|
349
377
|
*/
|
|
350
378
|
getCallableContainersByLowerName(callables) {
|
|
351
379
|
//find duplicate functions
|
|
@@ -365,32 +393,39 @@ class Util {
|
|
|
365
393
|
}
|
|
366
394
|
/**
|
|
367
395
|
* Split a file by newline characters (LF or CRLF)
|
|
368
|
-
* @param text
|
|
369
396
|
*/
|
|
370
397
|
getLines(text) {
|
|
371
398
|
return text.split(/\r?\n/);
|
|
372
399
|
}
|
|
373
400
|
/**
|
|
374
|
-
*
|
|
375
|
-
*
|
|
376
|
-
* @param targetPath a full pkgPath, or a path relative to the containing file
|
|
401
|
+
* Given an absolute path to a source file, and a target path,
|
|
402
|
+
* compute the pkg path for the target relative to the source file's location
|
|
377
403
|
*/
|
|
378
|
-
getPkgPathFromTarget(
|
|
404
|
+
getPkgPathFromTarget(containingFilePathAbsolute, targetPath) {
|
|
379
405
|
var _a;
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
406
|
+
// https://regex101.com/r/w7CG2N/1
|
|
407
|
+
const regexp = /^(?:pkg|libpkg):(\/)?/i;
|
|
408
|
+
const [fullScheme, slash] = (_a = regexp.exec(targetPath)) !== null && _a !== void 0 ? _a : [];
|
|
409
|
+
//if the target starts with 'pkg:' or 'libpkg:' then it's an absolute path. Return as is
|
|
410
|
+
if (slash) {
|
|
411
|
+
targetPath = targetPath.substring(fullScheme.length);
|
|
412
|
+
if (targetPath === '') {
|
|
413
|
+
return null;
|
|
414
|
+
}
|
|
415
|
+
else {
|
|
416
|
+
return path.normalize(targetPath);
|
|
417
|
+
}
|
|
384
418
|
}
|
|
385
|
-
//if the
|
|
386
|
-
if (
|
|
387
|
-
return
|
|
419
|
+
//if the path is exactly `pkg:` or `libpkg:`
|
|
420
|
+
if (targetPath === fullScheme && !slash) {
|
|
421
|
+
return null;
|
|
388
422
|
}
|
|
423
|
+
//remove the filename
|
|
424
|
+
let containingFolder = path.normalize(path.dirname(containingFilePathAbsolute));
|
|
389
425
|
//start with the containing folder, split by slash
|
|
390
|
-
|
|
391
|
-
let result = containingFolder.split(/[\\/]/);
|
|
426
|
+
let result = containingFolder.split(path.sep);
|
|
392
427
|
//split on slash
|
|
393
|
-
let targetParts = path.
|
|
428
|
+
let targetParts = path.normalize(targetPath).split(path.sep);
|
|
394
429
|
for (let part of targetParts) {
|
|
395
430
|
if (part === '' || part === '.') {
|
|
396
431
|
//do nothing, it means current directory
|
|
@@ -404,7 +439,7 @@ class Util {
|
|
|
404
439
|
result.push(part);
|
|
405
440
|
}
|
|
406
441
|
}
|
|
407
|
-
return result.join(
|
|
442
|
+
return result.join(path.sep);
|
|
408
443
|
}
|
|
409
444
|
/**
|
|
410
445
|
* Compute the relative path from the source file to the target file
|
|
@@ -466,6 +501,10 @@ class Util {
|
|
|
466
501
|
* ```
|
|
467
502
|
*/
|
|
468
503
|
rangesIntersect(a, b) {
|
|
504
|
+
//stop if the either range is misisng
|
|
505
|
+
if (!a || !b) {
|
|
506
|
+
return false;
|
|
507
|
+
}
|
|
469
508
|
// Check if `a` is before `b`
|
|
470
509
|
if (a.end.line < b.start.line || (a.end.line === b.start.line && a.end.character <= b.start.character)) {
|
|
471
510
|
return false;
|
|
@@ -487,6 +526,10 @@ class Util {
|
|
|
487
526
|
* ```
|
|
488
527
|
*/
|
|
489
528
|
rangesIntersectOrTouch(a, b) {
|
|
529
|
+
//stop if the either range is misisng
|
|
530
|
+
if (!a || !b) {
|
|
531
|
+
return false;
|
|
532
|
+
}
|
|
490
533
|
// Check if `a` is before `b`
|
|
491
534
|
if (a.end.line < b.start.line || (a.end.line === b.start.line && a.end.character < b.start.character)) {
|
|
492
535
|
return false;
|
|
@@ -501,34 +544,97 @@ class Util {
|
|
|
501
544
|
/**
|
|
502
545
|
* Test if `position` is in `range`. If the position is at the edges, will return true.
|
|
503
546
|
* Adapted from core vscode
|
|
504
|
-
* @param range
|
|
505
|
-
* @param position
|
|
506
547
|
*/
|
|
507
548
|
rangeContains(range, position) {
|
|
508
549
|
return this.comparePositionToRange(position, range) === 0;
|
|
509
550
|
}
|
|
510
551
|
comparePositionToRange(position, range) {
|
|
511
|
-
if
|
|
552
|
+
//stop if the either range is missng
|
|
553
|
+
if (!position || !range) {
|
|
554
|
+
return 0;
|
|
555
|
+
}
|
|
556
|
+
if (this.comparePosition(position, range.start) < 0) {
|
|
557
|
+
return -1;
|
|
558
|
+
}
|
|
559
|
+
if (this.comparePosition(position, range.end) > 0) {
|
|
560
|
+
return 1;
|
|
561
|
+
}
|
|
562
|
+
return 0;
|
|
563
|
+
}
|
|
564
|
+
comparePosition(a, b) {
|
|
565
|
+
//stop if the either position is missing
|
|
566
|
+
if (!a || !b) {
|
|
567
|
+
return 0;
|
|
568
|
+
}
|
|
569
|
+
if (a.line < b.line || (a.line === b.line && a.character < b.character)) {
|
|
512
570
|
return -1;
|
|
513
571
|
}
|
|
514
|
-
if (
|
|
572
|
+
if (a.line > b.line || (a.line === b.line && a.character > b.character)) {
|
|
515
573
|
return 1;
|
|
516
574
|
}
|
|
517
575
|
return 0;
|
|
518
576
|
}
|
|
519
577
|
/**
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
578
|
+
* Combine all the documentation found before a token (i.e. comment tokens)
|
|
579
|
+
*/
|
|
580
|
+
getTokenDocumentation(tokens, token) {
|
|
581
|
+
const comments = [];
|
|
582
|
+
const idx = tokens === null || tokens === void 0 ? void 0 : tokens.indexOf(token);
|
|
583
|
+
if (!idx || idx === -1) {
|
|
584
|
+
return undefined;
|
|
585
|
+
}
|
|
586
|
+
for (let i = idx - 1; i >= 0; i--) {
|
|
587
|
+
const token = tokens[i];
|
|
588
|
+
//skip whitespace and newline chars
|
|
589
|
+
if (token.kind === TokenKind_1.TokenKind.Comment) {
|
|
590
|
+
comments.push(token);
|
|
591
|
+
}
|
|
592
|
+
else if (token.kind === TokenKind_1.TokenKind.Newline || token.kind === TokenKind_1.TokenKind.Whitespace) {
|
|
593
|
+
//skip these tokens
|
|
594
|
+
continue;
|
|
595
|
+
//any other token means there are no more comments
|
|
596
|
+
}
|
|
597
|
+
else {
|
|
598
|
+
break;
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
if (comments.length > 0) {
|
|
602
|
+
return comments.reverse().map(x => x.text.replace(/^('|rem)/i, '').trim()).map(line => {
|
|
603
|
+
if (line.startsWith('@')) {
|
|
604
|
+
// Handle jsdoc/brightscriptdoc tags specially
|
|
605
|
+
// make sure they are on their own markdown line, and add italics
|
|
606
|
+
const firstSpaceIndex = line.indexOf(' ');
|
|
607
|
+
if (firstSpaceIndex === -1) {
|
|
608
|
+
return `\n_${line}_`;
|
|
609
|
+
}
|
|
610
|
+
const firstWord = line.substring(0, firstSpaceIndex);
|
|
611
|
+
return `\n_${firstWord}_ ${line.substring(firstSpaceIndex + 1)}`;
|
|
612
|
+
}
|
|
613
|
+
return line;
|
|
614
|
+
}).join('\n');
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
/**
|
|
618
|
+
* Combine all the documentation for a node - uses the AstNode's leadingTrivia property
|
|
619
|
+
*/
|
|
620
|
+
getNodeDocumentation(node) {
|
|
621
|
+
if (!node) {
|
|
622
|
+
return;
|
|
623
|
+
}
|
|
624
|
+
const leadingTrivia = node.getLeadingTrivia();
|
|
625
|
+
return this.getTokenDocumentation(leadingTrivia, leadingTrivia[leadingTrivia.length - 1]);
|
|
626
|
+
}
|
|
627
|
+
/**
|
|
628
|
+
* Prefixes a component name so it can be used as type in the symbol table, without polluting available symbols
|
|
629
|
+
*
|
|
630
|
+
* @param sgNodeName the Name of the component
|
|
631
|
+
* @returns the node name, prefixed with `roSGNode`
|
|
632
|
+
*/
|
|
633
|
+
getSgNodeTypeName(sgNodeName) {
|
|
634
|
+
return 'roSGNode' + sgNodeName;
|
|
528
635
|
}
|
|
529
636
|
/**
|
|
530
637
|
* Parse an xml file and get back a javascript object containing its results
|
|
531
|
-
* @param text
|
|
532
638
|
*/
|
|
533
639
|
parseXml(text) {
|
|
534
640
|
return new Promise((resolve, reject) => {
|
|
@@ -560,7 +666,6 @@ class Util {
|
|
|
560
666
|
}
|
|
561
667
|
/**
|
|
562
668
|
* Given a URI, convert that to a regular fs path
|
|
563
|
-
* @param uri
|
|
564
669
|
*/
|
|
565
670
|
uriToPath(uri) {
|
|
566
671
|
let parsedPath = vscode_uri_1.URI.parse(uri).fsPath;
|
|
@@ -575,7 +680,6 @@ class Util {
|
|
|
575
680
|
}
|
|
576
681
|
/**
|
|
577
682
|
* Force the drive letter to lower case
|
|
578
|
-
* @param fullPath
|
|
579
683
|
*/
|
|
580
684
|
driveLetterToLower(fullPath) {
|
|
581
685
|
if (fullPath) {
|
|
@@ -590,6 +694,19 @@ class Util {
|
|
|
590
694
|
}
|
|
591
695
|
return fullPath;
|
|
592
696
|
}
|
|
697
|
+
/**
|
|
698
|
+
* Replace the first instance of `search` in `subject` with `replacement`
|
|
699
|
+
*/
|
|
700
|
+
replaceCaseInsensitive(subject, search, replacement) {
|
|
701
|
+
let idx = subject.toLowerCase().indexOf(search.toLowerCase());
|
|
702
|
+
if (idx > -1) {
|
|
703
|
+
let result = subject.substring(0, idx) + replacement + subject.substring(idx + search.length);
|
|
704
|
+
return result;
|
|
705
|
+
}
|
|
706
|
+
else {
|
|
707
|
+
return subject;
|
|
708
|
+
}
|
|
709
|
+
}
|
|
593
710
|
/**
|
|
594
711
|
* Determine if two arrays containing primitive values are equal.
|
|
595
712
|
* This considers order and compares by equality.
|
|
@@ -607,14 +724,12 @@ class Util {
|
|
|
607
724
|
}
|
|
608
725
|
/**
|
|
609
726
|
* Given a file path, convert it to a URI string
|
|
610
|
-
* @param srcPath The absolute path to the source file on disk
|
|
611
727
|
*/
|
|
612
|
-
pathToUri(
|
|
613
|
-
return vscode_uri_1.URI.file(
|
|
728
|
+
pathToUri(filePath) {
|
|
729
|
+
return vscode_uri_1.URI.file(filePath).toString();
|
|
614
730
|
}
|
|
615
731
|
/**
|
|
616
732
|
* Get the outDir from options, taking into account cwd and absolute outFile paths
|
|
617
|
-
* @param options
|
|
618
733
|
*/
|
|
619
734
|
getOutDir(options) {
|
|
620
735
|
options = this.normalizeConfig(options);
|
|
@@ -636,8 +751,7 @@ class Util {
|
|
|
636
751
|
}
|
|
637
752
|
/**
|
|
638
753
|
* Given a path to a brs file, compute the path to a theoretical d.bs file.
|
|
639
|
-
* Only `.brs` files can have
|
|
640
|
-
* @param brsSrcPath The absolute path to the .brs source file on disk
|
|
754
|
+
* Only `.brs` files can have typedef path, so return undefined for everything else
|
|
641
755
|
*/
|
|
642
756
|
getTypedefPath(brsSrcPath) {
|
|
643
757
|
const typedefPath = brsSrcPath
|
|
@@ -652,24 +766,23 @@ class Util {
|
|
|
652
766
|
}
|
|
653
767
|
/**
|
|
654
768
|
* Determine whether this diagnostic should be supressed or not, based on brs comment-flags
|
|
655
|
-
* @param diagnostic
|
|
656
769
|
*/
|
|
657
770
|
diagnosticIsSuppressed(diagnostic) {
|
|
658
771
|
var _a, _b;
|
|
659
772
|
const diagnosticCode = typeof diagnostic.code === 'string' ? diagnostic.code.toLowerCase() : diagnostic.code;
|
|
660
773
|
for (let flag of (_b = (_a = diagnostic.file) === null || _a === void 0 ? void 0 : _a.commentFlags) !== null && _b !== void 0 ? _b : []) {
|
|
661
774
|
//this diagnostic is affected by this flag
|
|
662
|
-
if (this.rangeContains(flag.affectedRange, diagnostic.range.start)) {
|
|
775
|
+
if (diagnostic.range && this.rangeContains(flag.affectedRange, diagnostic.range.start)) {
|
|
663
776
|
//if the flag acts upon this diagnostic's code
|
|
664
|
-
if (flag.codes === null || flag.codes.includes(diagnosticCode)) {
|
|
777
|
+
if (flag.codes === null || (diagnosticCode !== undefined && flag.codes.includes(diagnosticCode))) {
|
|
665
778
|
return true;
|
|
666
779
|
}
|
|
667
780
|
}
|
|
668
781
|
}
|
|
782
|
+
return false;
|
|
669
783
|
}
|
|
670
784
|
/**
|
|
671
|
-
* Walks up the chain
|
|
672
|
-
* @param currentPath
|
|
785
|
+
* Walks up the chain to find the closest bsconfig.json file
|
|
673
786
|
*/
|
|
674
787
|
async findClosestConfigFile(currentPath) {
|
|
675
788
|
//make the path absolute
|
|
@@ -695,7 +808,7 @@ class Util {
|
|
|
695
808
|
}
|
|
696
809
|
/**
|
|
697
810
|
* Set a timeout for the specified milliseconds, and resolve the promise once the timeout is finished.
|
|
698
|
-
* @param milliseconds
|
|
811
|
+
* @param milliseconds the minimum number of milliseconds to sleep for
|
|
699
812
|
*/
|
|
700
813
|
sleep(milliseconds) {
|
|
701
814
|
return new Promise((resolve) => {
|
|
@@ -710,11 +823,11 @@ class Util {
|
|
|
710
823
|
}
|
|
711
824
|
/**
|
|
712
825
|
* Given an array, map and then flatten
|
|
713
|
-
* @param
|
|
714
|
-
* @param
|
|
826
|
+
* @param array the array to flatMap over
|
|
827
|
+
* @param callback a function that is called for every array item
|
|
715
828
|
*/
|
|
716
|
-
flatMap(array,
|
|
717
|
-
return Array.prototype.concat.apply([], array.map(
|
|
829
|
+
flatMap(array, callback) {
|
|
830
|
+
return Array.prototype.concat.apply([], array.map(callback));
|
|
718
831
|
}
|
|
719
832
|
/**
|
|
720
833
|
* Determines if the position is greater than the range. This means
|
|
@@ -758,8 +871,6 @@ class Util {
|
|
|
758
871
|
}
|
|
759
872
|
/**
|
|
760
873
|
* If the two items have lines that touch
|
|
761
|
-
* @param first
|
|
762
|
-
* @param second
|
|
763
874
|
*/
|
|
764
875
|
linesTouch(first, second) {
|
|
765
876
|
if (first && second && (first.range.start.line === second.range.start.line ||
|
|
@@ -789,7 +900,8 @@ class Util {
|
|
|
789
900
|
*/
|
|
790
901
|
getScriptImportAtPosition(scriptImports, position) {
|
|
791
902
|
let scriptImport = scriptImports.find((x) => {
|
|
792
|
-
return x.filePathRange
|
|
903
|
+
return x.filePathRange &&
|
|
904
|
+
x.filePathRange.start.line === position.line &&
|
|
793
905
|
//column between start and end
|
|
794
906
|
position.character >= x.filePathRange.start.character &&
|
|
795
907
|
position.character <= x.filePathRange.end.character;
|
|
@@ -833,7 +945,9 @@ class Util {
|
|
|
833
945
|
rangeLines.push(lines[i]);
|
|
834
946
|
}
|
|
835
947
|
const lastLine = rangeLines.pop();
|
|
836
|
-
|
|
948
|
+
if (lastLine !== undefined) {
|
|
949
|
+
rangeLines.push(lastLine.substring(0, endCharacter));
|
|
950
|
+
}
|
|
837
951
|
return rangeLines.join('\n');
|
|
838
952
|
}
|
|
839
953
|
/**
|
|
@@ -849,61 +963,86 @@ class Util {
|
|
|
849
963
|
* Helper for creating `Range` objects. Prefer using this function because vscode-languageserver's `Range.create()` is significantly slower
|
|
850
964
|
*/
|
|
851
965
|
createRange(startLine, startCharacter, endLine, endCharacter) {
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
}
|
|
966
|
+
// eslint-disable-next-line no-bitwise
|
|
967
|
+
const key = (startLine << 39) + (startCharacter << 26) + (endLine << 13) + endCharacter;
|
|
968
|
+
let range = this.rangeCache.get(key);
|
|
969
|
+
if (!range) {
|
|
970
|
+
range = {
|
|
971
|
+
start: this.createPosition(startLine, startCharacter),
|
|
972
|
+
end: this.createPosition(endLine, endCharacter)
|
|
973
|
+
};
|
|
974
|
+
this.rangeCache.set(key, range);
|
|
975
|
+
}
|
|
976
|
+
return range;
|
|
862
977
|
}
|
|
863
978
|
/**
|
|
864
979
|
* Create a `Range` from two `Position`s
|
|
865
980
|
*/
|
|
866
981
|
createRangeFromPositions(startPosition, endPosition) {
|
|
867
|
-
return
|
|
868
|
-
start: {
|
|
869
|
-
line: startPosition.line,
|
|
870
|
-
character: startPosition.character
|
|
871
|
-
},
|
|
872
|
-
end: {
|
|
873
|
-
line: endPosition.line,
|
|
874
|
-
character: endPosition.character
|
|
875
|
-
}
|
|
876
|
-
};
|
|
982
|
+
return this.createRange(startPosition.line, startPosition.character, endPosition.line, endPosition.character);
|
|
877
983
|
}
|
|
878
984
|
/**
|
|
879
|
-
*
|
|
880
|
-
*
|
|
985
|
+
* Gets the bounding range of a bunch of ranges or objects that have ranges
|
|
986
|
+
* TODO: this does a full iteration of the args. If the args were guaranteed to be in range order, we could optimize this
|
|
881
987
|
*/
|
|
882
988
|
createBoundingRange(...locatables) {
|
|
883
|
-
let
|
|
884
|
-
let
|
|
885
|
-
for (let
|
|
886
|
-
//set the leftmost non-null-range item
|
|
887
|
-
const left = locatables[i];
|
|
989
|
+
let startPosition;
|
|
990
|
+
let endPosition;
|
|
991
|
+
for (let locatable of locatables) {
|
|
888
992
|
//the range might be a getter, so access it exactly once
|
|
889
|
-
const
|
|
890
|
-
if (!
|
|
891
|
-
|
|
993
|
+
const locatableRange = vscode_languageserver_1.Range.is(locatable) ? locatable : locatable === null || locatable === void 0 ? void 0 : locatable.range;
|
|
994
|
+
if (!locatableRange) {
|
|
995
|
+
continue;
|
|
892
996
|
}
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
//the range might be a getter, so access it exactly once
|
|
896
|
-
const rightRange = right === null || right === void 0 ? void 0 : right.range;
|
|
897
|
-
if (!rightmostRange && rightRange) {
|
|
898
|
-
rightmostRange = rightRange;
|
|
997
|
+
if (!startPosition) {
|
|
998
|
+
startPosition = locatableRange.start;
|
|
899
999
|
}
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
1000
|
+
else if (this.comparePosition(locatableRange.start, startPosition) < 0) {
|
|
1001
|
+
startPosition = locatableRange.start;
|
|
1002
|
+
}
|
|
1003
|
+
if (!endPosition) {
|
|
1004
|
+
endPosition = locatableRange.end;
|
|
1005
|
+
}
|
|
1006
|
+
else if (this.comparePosition(locatableRange.end, endPosition) > 0) {
|
|
1007
|
+
endPosition = locatableRange.end;
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
if (startPosition && endPosition) {
|
|
1011
|
+
return this.createRangeFromPositions(startPosition, endPosition);
|
|
1012
|
+
}
|
|
1013
|
+
else {
|
|
1014
|
+
return undefined;
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
/**
|
|
1018
|
+
* Gets the bounding range of an object that contains a bunch of tokens
|
|
1019
|
+
* @param tokens Object with tokens in it
|
|
1020
|
+
* @returns Range containing all the tokens
|
|
1021
|
+
*/
|
|
1022
|
+
createBoundingRangeFromTokens(tokens) {
|
|
1023
|
+
var _a;
|
|
1024
|
+
let startPosition;
|
|
1025
|
+
let endPosition;
|
|
1026
|
+
for (let key in tokens) {
|
|
1027
|
+
let locatableRange = (_a = tokens === null || tokens === void 0 ? void 0 : tokens[key]) === null || _a === void 0 ? void 0 : _a.range;
|
|
1028
|
+
if (!locatableRange) {
|
|
1029
|
+
continue;
|
|
1030
|
+
}
|
|
1031
|
+
if (!startPosition) {
|
|
1032
|
+
startPosition = locatableRange.start;
|
|
1033
|
+
}
|
|
1034
|
+
else if (this.comparePosition(locatableRange.start, startPosition) < 0) {
|
|
1035
|
+
startPosition = locatableRange.start;
|
|
1036
|
+
}
|
|
1037
|
+
if (!endPosition) {
|
|
1038
|
+
endPosition = locatableRange.end;
|
|
1039
|
+
}
|
|
1040
|
+
else if (this.comparePosition(locatableRange.end, endPosition) > 0) {
|
|
1041
|
+
endPosition = locatableRange.end;
|
|
903
1042
|
}
|
|
904
1043
|
}
|
|
905
|
-
if (
|
|
906
|
-
return this.createRangeFromPositions(
|
|
1044
|
+
if (startPosition && endPosition) {
|
|
1045
|
+
return this.createRangeFromPositions(startPosition, endPosition);
|
|
907
1046
|
}
|
|
908
1047
|
else {
|
|
909
1048
|
return undefined;
|
|
@@ -913,10 +1052,17 @@ class Util {
|
|
|
913
1052
|
* Create a `Position` object. Prefer this over `Position.create` for performance reasons
|
|
914
1053
|
*/
|
|
915
1054
|
createPosition(line, character) {
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
1055
|
+
// eslint-disable-next-line no-bitwise
|
|
1056
|
+
const key = (line << 13) + character;
|
|
1057
|
+
let position = this.positionCache.get(key);
|
|
1058
|
+
if (!position) {
|
|
1059
|
+
position = {
|
|
1060
|
+
line: line,
|
|
1061
|
+
character: character
|
|
1062
|
+
};
|
|
1063
|
+
this.positionCache.set(key, position);
|
|
1064
|
+
}
|
|
1065
|
+
return position;
|
|
920
1066
|
}
|
|
921
1067
|
/**
|
|
922
1068
|
* Convert a list of tokens into a string, including their leading whitespace
|
|
@@ -924,8 +1070,7 @@ class Util {
|
|
|
924
1070
|
tokensToString(tokens) {
|
|
925
1071
|
let result = '';
|
|
926
1072
|
//skip iterating the final token
|
|
927
|
-
for (let
|
|
928
|
-
let token = tokens[i];
|
|
1073
|
+
for (let token of tokens) {
|
|
929
1074
|
result += token.leadingWhitespace + token.text;
|
|
930
1075
|
}
|
|
931
1076
|
return result;
|
|
@@ -933,39 +1078,36 @@ class Util {
|
|
|
933
1078
|
/**
|
|
934
1079
|
* Convert a token into a BscType
|
|
935
1080
|
*/
|
|
936
|
-
tokenToBscType(token
|
|
937
|
-
if (!token) {
|
|
938
|
-
return new DynamicType_1.DynamicType();
|
|
939
|
-
}
|
|
1081
|
+
tokenToBscType(token) {
|
|
940
1082
|
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
|
|
941
1083
|
switch (token.kind) {
|
|
942
1084
|
case TokenKind_1.TokenKind.Boolean:
|
|
943
1085
|
return new BooleanType_1.BooleanType(token.text);
|
|
944
1086
|
case TokenKind_1.TokenKind.True:
|
|
945
1087
|
case TokenKind_1.TokenKind.False:
|
|
946
|
-
return
|
|
1088
|
+
return BooleanType_1.BooleanType.instance;
|
|
947
1089
|
case TokenKind_1.TokenKind.Double:
|
|
948
1090
|
return new DoubleType_1.DoubleType(token.text);
|
|
949
1091
|
case TokenKind_1.TokenKind.DoubleLiteral:
|
|
950
|
-
return
|
|
1092
|
+
return DoubleType_1.DoubleType.instance;
|
|
951
1093
|
case TokenKind_1.TokenKind.Dynamic:
|
|
952
1094
|
return new DynamicType_1.DynamicType(token.text);
|
|
953
1095
|
case TokenKind_1.TokenKind.Float:
|
|
954
1096
|
return new FloatType_1.FloatType(token.text);
|
|
955
1097
|
case TokenKind_1.TokenKind.FloatLiteral:
|
|
956
|
-
return
|
|
1098
|
+
return FloatType_1.FloatType.instance;
|
|
957
1099
|
case TokenKind_1.TokenKind.Function:
|
|
958
|
-
return new FunctionType_1.FunctionType();
|
|
1100
|
+
return new FunctionType_1.FunctionType(token.text);
|
|
959
1101
|
case TokenKind_1.TokenKind.Integer:
|
|
960
1102
|
return new IntegerType_1.IntegerType(token.text);
|
|
961
1103
|
case TokenKind_1.TokenKind.IntegerLiteral:
|
|
962
|
-
return
|
|
1104
|
+
return IntegerType_1.IntegerType.instance;
|
|
963
1105
|
case TokenKind_1.TokenKind.Invalid:
|
|
964
|
-
return new
|
|
1106
|
+
return DynamicType_1.DynamicType.instance; // TODO: use InvalidType better new InvalidType(token.text);
|
|
965
1107
|
case TokenKind_1.TokenKind.LongInteger:
|
|
966
1108
|
return new LongIntegerType_1.LongIntegerType(token.text);
|
|
967
1109
|
case TokenKind_1.TokenKind.LongIntegerLiteral:
|
|
968
|
-
return
|
|
1110
|
+
return LongIntegerType_1.LongIntegerType.instance;
|
|
969
1111
|
case TokenKind_1.TokenKind.Object:
|
|
970
1112
|
return new ObjectType_1.ObjectType(token.text);
|
|
971
1113
|
case TokenKind_1.TokenKind.String:
|
|
@@ -974,59 +1116,303 @@ class Util {
|
|
|
974
1116
|
case TokenKind_1.TokenKind.TemplateStringExpressionBegin:
|
|
975
1117
|
case TokenKind_1.TokenKind.TemplateStringExpressionEnd:
|
|
976
1118
|
case TokenKind_1.TokenKind.TemplateStringQuasi:
|
|
977
|
-
return
|
|
1119
|
+
return StringType_1.StringType.instance;
|
|
978
1120
|
case TokenKind_1.TokenKind.Void:
|
|
979
1121
|
return new VoidType_1.VoidType(token.text);
|
|
980
1122
|
case TokenKind_1.TokenKind.Identifier:
|
|
981
|
-
|
|
982
|
-
let typeClass;
|
|
983
|
-
switch (typeText) {
|
|
1123
|
+
switch (token.text.toLowerCase()) {
|
|
984
1124
|
case 'boolean':
|
|
985
|
-
|
|
986
|
-
break;
|
|
1125
|
+
return new BooleanType_1.BooleanType(token.text);
|
|
987
1126
|
case 'double':
|
|
988
|
-
|
|
989
|
-
|
|
1127
|
+
return new DoubleType_1.DoubleType(token.text);
|
|
1128
|
+
case 'dynamic':
|
|
1129
|
+
return new DynamicType_1.DynamicType(token.text);
|
|
990
1130
|
case 'float':
|
|
991
|
-
|
|
992
|
-
break;
|
|
1131
|
+
return new FloatType_1.FloatType(token.text);
|
|
993
1132
|
case 'function':
|
|
994
|
-
|
|
995
|
-
break;
|
|
1133
|
+
return new FunctionType_1.FunctionType(token.text);
|
|
996
1134
|
case 'integer':
|
|
997
|
-
|
|
998
|
-
break;
|
|
1135
|
+
return new IntegerType_1.IntegerType(token.text);
|
|
999
1136
|
case 'invalid':
|
|
1000
|
-
|
|
1001
|
-
break;
|
|
1137
|
+
return DynamicType_1.DynamicType.instance; // TODO: use InvalidType better new InvalidType(token.text);
|
|
1002
1138
|
case 'longinteger':
|
|
1003
|
-
|
|
1004
|
-
break;
|
|
1139
|
+
return new LongIntegerType_1.LongIntegerType(token.text);
|
|
1005
1140
|
case 'object':
|
|
1006
|
-
|
|
1007
|
-
break;
|
|
1141
|
+
return new ObjectType_1.ObjectType(token.text);
|
|
1008
1142
|
case 'string':
|
|
1009
|
-
|
|
1010
|
-
break;
|
|
1143
|
+
return new StringType_1.StringType(token.text);
|
|
1011
1144
|
case 'void':
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1145
|
+
return new VoidType_1.VoidType(token.text);
|
|
1146
|
+
}
|
|
1147
|
+
}
|
|
1148
|
+
}
|
|
1149
|
+
/**
|
|
1150
|
+
* Deciphers the correct types for fields based on docs
|
|
1151
|
+
* https://developer.roku.com/en-ca/docs/references/scenegraph/xml-elements/interface.md
|
|
1152
|
+
* @param typeDescriptor the type descriptor from the docs
|
|
1153
|
+
* @returns {BscType} the known type, or dynamic
|
|
1154
|
+
*/
|
|
1155
|
+
getNodeFieldType(typeDescriptor, lookupTable) {
|
|
1156
|
+
const typeDescriptorLower = typeDescriptor.toLowerCase().trim();
|
|
1157
|
+
const bscType = this.tokenToBscType((0, creators_1.createToken)(TokenKind_1.TokenKind.Identifier, typeDescriptorLower));
|
|
1158
|
+
if (bscType) {
|
|
1159
|
+
return bscType;
|
|
1160
|
+
}
|
|
1161
|
+
function getRect2dType() {
|
|
1162
|
+
const rect2dType = new AssociativeArrayType_1.AssociativeArrayType();
|
|
1163
|
+
rect2dType.addMember('height', {}, FloatType_1.FloatType.instance, SymbolTable_1.SymbolTypeFlag.runtime);
|
|
1164
|
+
rect2dType.addMember('width', {}, FloatType_1.FloatType.instance, SymbolTable_1.SymbolTypeFlag.runtime);
|
|
1165
|
+
rect2dType.addMember('x', {}, FloatType_1.FloatType.instance, SymbolTable_1.SymbolTypeFlag.runtime);
|
|
1166
|
+
rect2dType.addMember('y', {}, FloatType_1.FloatType.instance, SymbolTable_1.SymbolTypeFlag.runtime);
|
|
1167
|
+
return rect2dType;
|
|
1168
|
+
}
|
|
1169
|
+
function getColorType() {
|
|
1170
|
+
return (0, types_1.unionTypeFactory)([IntegerType_1.IntegerType.instance, StringType_1.StringType.instance]);
|
|
1171
|
+
}
|
|
1172
|
+
if (typeDescriptorLower.startsWith('array of ')) {
|
|
1173
|
+
let arrayOfTypeName = typeDescriptorLower.substring(9); //cut off beginning 'array of'
|
|
1174
|
+
if (arrayOfTypeName.endsWith('s')) {
|
|
1175
|
+
// remove "s" in "floats", etc.
|
|
1176
|
+
arrayOfTypeName = arrayOfTypeName.substring(0, arrayOfTypeName.length - 1);
|
|
1177
|
+
}
|
|
1178
|
+
if (arrayOfTypeName.endsWith('\'')) {
|
|
1179
|
+
// remove "'" in "float's", etc.
|
|
1180
|
+
arrayOfTypeName = arrayOfTypeName.substring(0, arrayOfTypeName.length - 1);
|
|
1181
|
+
}
|
|
1182
|
+
let arrayType = this.getNodeFieldType(arrayOfTypeName, lookupTable);
|
|
1183
|
+
return new types_1.ArrayType(arrayType);
|
|
1184
|
+
}
|
|
1185
|
+
else if (typeDescriptorLower.startsWith('option ')) {
|
|
1186
|
+
const actualTypeName = typeDescriptorLower.substring('option '.length); //cut off beginning 'option '
|
|
1187
|
+
return this.getNodeFieldType(actualTypeName, lookupTable);
|
|
1188
|
+
}
|
|
1189
|
+
else if (typeDescriptorLower.startsWith('value ')) {
|
|
1190
|
+
const actualTypeName = typeDescriptorLower.substring('value '.length); //cut off beginning 'value '
|
|
1191
|
+
return this.getNodeFieldType(actualTypeName, lookupTable);
|
|
1192
|
+
}
|
|
1193
|
+
else if (typeDescriptorLower === 'uri') {
|
|
1194
|
+
return StringType_1.StringType.instance;
|
|
1195
|
+
}
|
|
1196
|
+
else if (typeDescriptorLower === 'color') {
|
|
1197
|
+
return getColorType();
|
|
1198
|
+
}
|
|
1199
|
+
else if (typeDescriptorLower === 'vector2d' || typeDescriptorLower === 'floatarray') {
|
|
1200
|
+
return new types_1.ArrayType(FloatType_1.FloatType.instance);
|
|
1201
|
+
}
|
|
1202
|
+
else if (typeDescriptorLower === 'vector2darray') {
|
|
1203
|
+
return new types_1.ArrayType(new types_1.ArrayType(FloatType_1.FloatType.instance));
|
|
1204
|
+
}
|
|
1205
|
+
else if (typeDescriptorLower === 'intarray') {
|
|
1206
|
+
return new types_1.ArrayType(IntegerType_1.IntegerType.instance);
|
|
1207
|
+
}
|
|
1208
|
+
else if (typeDescriptorLower === 'colorarray') {
|
|
1209
|
+
return new types_1.ArrayType(getColorType());
|
|
1210
|
+
}
|
|
1211
|
+
else if (typeDescriptorLower === 'boolarray') {
|
|
1212
|
+
return new types_1.ArrayType(BooleanType_1.BooleanType.instance);
|
|
1213
|
+
}
|
|
1214
|
+
else if (typeDescriptorLower === 'stringarray' || typeDescriptorLower === 'strarray') {
|
|
1215
|
+
return new types_1.ArrayType(StringType_1.StringType.instance);
|
|
1216
|
+
}
|
|
1217
|
+
else if (typeDescriptorLower === 'int') {
|
|
1218
|
+
return IntegerType_1.IntegerType.instance;
|
|
1219
|
+
}
|
|
1220
|
+
else if (typeDescriptorLower === 'time') {
|
|
1221
|
+
return DoubleType_1.DoubleType.instance;
|
|
1222
|
+
}
|
|
1223
|
+
else if (typeDescriptorLower === 'str') {
|
|
1224
|
+
return StringType_1.StringType.instance;
|
|
1225
|
+
}
|
|
1226
|
+
else if (typeDescriptorLower === 'bool') {
|
|
1227
|
+
return BooleanType_1.BooleanType.instance;
|
|
1228
|
+
}
|
|
1229
|
+
else if (typeDescriptorLower === 'array') {
|
|
1230
|
+
return new types_1.ArrayType();
|
|
1231
|
+
}
|
|
1232
|
+
else if (typeDescriptorLower === 'assocarray' || typeDescriptorLower === 'associative array' || typeDescriptorLower === 'associativearray') {
|
|
1233
|
+
return new AssociativeArrayType_1.AssociativeArrayType();
|
|
1234
|
+
}
|
|
1235
|
+
else if (typeDescriptorLower === 'node') {
|
|
1236
|
+
return ComponentType_1.ComponentType.instance;
|
|
1237
|
+
}
|
|
1238
|
+
else if (typeDescriptorLower === 'nodearray') {
|
|
1239
|
+
return new types_1.ArrayType(ComponentType_1.ComponentType.instance);
|
|
1240
|
+
}
|
|
1241
|
+
else if (typeDescriptorLower === 'rect2d') {
|
|
1242
|
+
return getRect2dType();
|
|
1243
|
+
}
|
|
1244
|
+
else if (typeDescriptorLower === 'rect2darray') {
|
|
1245
|
+
return new types_1.ArrayType(getRect2dType());
|
|
1246
|
+
}
|
|
1247
|
+
else if (lookupTable) {
|
|
1248
|
+
//try doing a lookup
|
|
1249
|
+
return lookupTable.getSymbolType(typeDescriptorLower, { flags: SymbolTable_1.SymbolTypeFlag.typetime });
|
|
1250
|
+
}
|
|
1251
|
+
// TODO: Handle 'rect2d', 'rect2dArray',
|
|
1252
|
+
return DynamicType_1.DynamicType.instance;
|
|
1253
|
+
}
|
|
1254
|
+
/**
|
|
1255
|
+
* Return the type of the result of a binary operator
|
|
1256
|
+
* Note: compound assignments (eg. +=) internally use a binary expression, so that's why TokenKind.PlusEqual, etc. are here too
|
|
1257
|
+
*/
|
|
1258
|
+
binaryOperatorResultType(leftType, operator, rightType) {
|
|
1259
|
+
if (((0, reflection_1.isAnyReferenceType)(leftType) && !leftType.isResolvable()) ||
|
|
1260
|
+
((0, reflection_1.isAnyReferenceType)(rightType) && !rightType.isResolvable())) {
|
|
1261
|
+
return new types_1.BinaryOperatorReferenceType(leftType, operator, rightType, (lhs, op, rhs) => {
|
|
1262
|
+
return this.binaryOperatorResultType(lhs, op, rhs);
|
|
1263
|
+
});
|
|
1264
|
+
}
|
|
1265
|
+
if ((0, reflection_1.isEnumMemberType)(leftType)) {
|
|
1266
|
+
leftType = leftType.underlyingType;
|
|
1267
|
+
}
|
|
1268
|
+
if ((0, reflection_1.isEnumMemberType)(rightType)) {
|
|
1269
|
+
rightType = rightType.underlyingType;
|
|
1270
|
+
}
|
|
1271
|
+
let hasDouble = (0, reflection_1.isDoubleType)(leftType) || (0, reflection_1.isDoubleType)(rightType);
|
|
1272
|
+
let hasFloat = (0, reflection_1.isFloatType)(leftType) || (0, reflection_1.isFloatType)(rightType);
|
|
1273
|
+
let hasLongInteger = (0, reflection_1.isLongIntegerType)(leftType) || (0, reflection_1.isLongIntegerType)(rightType);
|
|
1274
|
+
let hasInvalid = (0, reflection_1.isInvalidType)(leftType) || (0, reflection_1.isInvalidType)(rightType);
|
|
1275
|
+
let hasDynamic = (0, reflection_1.isDynamicType)(leftType) || (0, reflection_1.isDynamicType)(rightType);
|
|
1276
|
+
let bothNumbers = (0, reflection_1.isNumberType)(leftType) && (0, reflection_1.isNumberType)(rightType);
|
|
1277
|
+
let bothStrings = (0, reflection_1.isStringType)(leftType) && (0, reflection_1.isStringType)(rightType);
|
|
1278
|
+
let eitherBooleanOrNum = ((0, reflection_1.isNumberType)(leftType) || (0, reflection_1.isBooleanType)(leftType)) && ((0, reflection_1.isNumberType)(rightType) || (0, reflection_1.isBooleanType)(rightType));
|
|
1279
|
+
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
|
|
1280
|
+
switch (operator.kind) {
|
|
1281
|
+
// Math operators
|
|
1282
|
+
case TokenKind_1.TokenKind.Plus:
|
|
1283
|
+
case TokenKind_1.TokenKind.PlusEqual:
|
|
1284
|
+
if (bothStrings) {
|
|
1285
|
+
// "string" + "string" is the only binary expression allowed with strings
|
|
1286
|
+
return StringType_1.StringType.instance;
|
|
1287
|
+
}
|
|
1288
|
+
// eslint-disable-next-line no-fallthrough
|
|
1289
|
+
case TokenKind_1.TokenKind.Minus:
|
|
1290
|
+
case TokenKind_1.TokenKind.MinusEqual:
|
|
1291
|
+
case TokenKind_1.TokenKind.Star:
|
|
1292
|
+
case TokenKind_1.TokenKind.StarEqual:
|
|
1293
|
+
case TokenKind_1.TokenKind.Mod:
|
|
1294
|
+
if (bothNumbers) {
|
|
1295
|
+
if (hasDouble) {
|
|
1296
|
+
return DoubleType_1.DoubleType.instance;
|
|
1297
|
+
}
|
|
1298
|
+
else if (hasFloat) {
|
|
1299
|
+
return FloatType_1.FloatType.instance;
|
|
1300
|
+
}
|
|
1301
|
+
else if (hasLongInteger) {
|
|
1302
|
+
return LongIntegerType_1.LongIntegerType.instance;
|
|
1303
|
+
}
|
|
1304
|
+
return IntegerType_1.IntegerType.instance;
|
|
1305
|
+
}
|
|
1306
|
+
break;
|
|
1307
|
+
case TokenKind_1.TokenKind.Forwardslash:
|
|
1308
|
+
case TokenKind_1.TokenKind.ForwardslashEqual:
|
|
1309
|
+
if (bothNumbers) {
|
|
1310
|
+
if (hasDouble) {
|
|
1311
|
+
return DoubleType_1.DoubleType.instance;
|
|
1312
|
+
}
|
|
1313
|
+
else if (hasFloat) {
|
|
1314
|
+
return FloatType_1.FloatType.instance;
|
|
1315
|
+
}
|
|
1316
|
+
else if (hasLongInteger) {
|
|
1317
|
+
return LongIntegerType_1.LongIntegerType.instance;
|
|
1318
|
+
}
|
|
1319
|
+
return FloatType_1.FloatType.instance;
|
|
1320
|
+
}
|
|
1321
|
+
break;
|
|
1322
|
+
case TokenKind_1.TokenKind.Backslash:
|
|
1323
|
+
case TokenKind_1.TokenKind.BackslashEqual:
|
|
1324
|
+
if (bothNumbers) {
|
|
1325
|
+
if (hasLongInteger) {
|
|
1326
|
+
return LongIntegerType_1.LongIntegerType.instance;
|
|
1327
|
+
}
|
|
1328
|
+
return IntegerType_1.IntegerType.instance;
|
|
1329
|
+
}
|
|
1330
|
+
break;
|
|
1331
|
+
case TokenKind_1.TokenKind.Caret:
|
|
1332
|
+
if (bothNumbers) {
|
|
1333
|
+
if (hasDouble || hasLongInteger) {
|
|
1334
|
+
return DoubleType_1.DoubleType.instance;
|
|
1335
|
+
}
|
|
1336
|
+
else if (hasFloat) {
|
|
1337
|
+
return FloatType_1.FloatType.instance;
|
|
1338
|
+
}
|
|
1339
|
+
return IntegerType_1.IntegerType.instance;
|
|
1340
|
+
}
|
|
1341
|
+
break;
|
|
1342
|
+
// Bitshift operators
|
|
1343
|
+
case TokenKind_1.TokenKind.LeftShift:
|
|
1344
|
+
case TokenKind_1.TokenKind.LeftShiftEqual:
|
|
1345
|
+
case TokenKind_1.TokenKind.RightShift:
|
|
1346
|
+
case TokenKind_1.TokenKind.RightShiftEqual:
|
|
1347
|
+
if (bothNumbers) {
|
|
1348
|
+
if (hasLongInteger) {
|
|
1349
|
+
return LongIntegerType_1.LongIntegerType.instance;
|
|
1350
|
+
}
|
|
1351
|
+
// Bitshifts are allowed with non-integer numerics
|
|
1352
|
+
// but will always truncate to ints
|
|
1353
|
+
return IntegerType_1.IntegerType.instance;
|
|
1354
|
+
}
|
|
1355
|
+
break;
|
|
1356
|
+
// Comparison operators
|
|
1357
|
+
// All comparison operators result in boolean
|
|
1358
|
+
case TokenKind_1.TokenKind.Equal:
|
|
1359
|
+
case TokenKind_1.TokenKind.LessGreater:
|
|
1360
|
+
// = and <> can accept invalid / dynamic
|
|
1361
|
+
if (hasDynamic || hasInvalid || bothStrings || eitherBooleanOrNum) {
|
|
1362
|
+
return BooleanType_1.BooleanType.instance;
|
|
1363
|
+
}
|
|
1364
|
+
break;
|
|
1365
|
+
case TokenKind_1.TokenKind.Greater:
|
|
1366
|
+
case TokenKind_1.TokenKind.Less:
|
|
1367
|
+
case TokenKind_1.TokenKind.GreaterEqual:
|
|
1368
|
+
case TokenKind_1.TokenKind.LessEqual:
|
|
1369
|
+
if (bothStrings || bothNumbers) {
|
|
1370
|
+
return BooleanType_1.BooleanType.instance;
|
|
1371
|
+
}
|
|
1372
|
+
break;
|
|
1373
|
+
// Logical operators
|
|
1374
|
+
case TokenKind_1.TokenKind.Or:
|
|
1375
|
+
case TokenKind_1.TokenKind.And:
|
|
1376
|
+
if (eitherBooleanOrNum) {
|
|
1377
|
+
return BooleanType_1.BooleanType.instance;
|
|
1017
1378
|
}
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1379
|
+
break;
|
|
1380
|
+
}
|
|
1381
|
+
return DynamicType_1.DynamicType.instance;
|
|
1382
|
+
}
|
|
1383
|
+
/**
|
|
1384
|
+
* Return the type of the result of a binary operator
|
|
1385
|
+
*/
|
|
1386
|
+
unaryOperatorResultType(operator, exprType) {
|
|
1387
|
+
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
|
|
1388
|
+
switch (operator.kind) {
|
|
1389
|
+
// Math operators
|
|
1390
|
+
case TokenKind_1.TokenKind.Minus:
|
|
1391
|
+
if ((0, reflection_1.isNumberType)(exprType)) {
|
|
1392
|
+
// a negative number will be the same type, eg, double->double, int->int, etc.
|
|
1393
|
+
return exprType;
|
|
1394
|
+
}
|
|
1395
|
+
break;
|
|
1396
|
+
case TokenKind_1.TokenKind.Not:
|
|
1397
|
+
if ((0, reflection_1.isBooleanType)(exprType)) {
|
|
1398
|
+
return BooleanType_1.BooleanType.instance;
|
|
1399
|
+
}
|
|
1400
|
+
else if ((0, reflection_1.isNumberType)(exprType)) {
|
|
1401
|
+
//numbers can be "notted"
|
|
1402
|
+
// by default they go to ints, except longints, which stay that way
|
|
1403
|
+
if ((0, reflection_1.isLongIntegerType)(exprType)) {
|
|
1404
|
+
return LongIntegerType_1.LongIntegerType.instance;
|
|
1405
|
+
}
|
|
1406
|
+
return IntegerType_1.IntegerType.instance;
|
|
1023
1407
|
}
|
|
1024
|
-
|
|
1408
|
+
break;
|
|
1025
1409
|
}
|
|
1410
|
+
return DynamicType_1.DynamicType.instance;
|
|
1026
1411
|
}
|
|
1027
1412
|
/**
|
|
1028
1413
|
* Get the extension for the given file path. Basically the part after the final dot, except for
|
|
1029
1414
|
* `d.bs` which is treated as single extension
|
|
1415
|
+
* @returns the file extension (i.e. ".d.bs", ".bs", ".brs", ".xml", ".jpg", etc...)
|
|
1030
1416
|
*/
|
|
1031
1417
|
getExtension(filePath) {
|
|
1032
1418
|
filePath = filePath.toLowerCase();
|
|
@@ -1034,10 +1420,7 @@ class Util {
|
|
|
1034
1420
|
return '.d.bs';
|
|
1035
1421
|
}
|
|
1036
1422
|
else {
|
|
1037
|
-
|
|
1038
|
-
if (idx > -1) {
|
|
1039
|
-
return filePath.substring(idx);
|
|
1040
|
-
}
|
|
1423
|
+
return path.extname(filePath).toLowerCase();
|
|
1041
1424
|
}
|
|
1042
1425
|
}
|
|
1043
1426
|
/**
|
|
@@ -1060,6 +1443,10 @@ class Util {
|
|
|
1060
1443
|
else if (typeof theExport === 'function') {
|
|
1061
1444
|
plugin = theExport();
|
|
1062
1445
|
}
|
|
1446
|
+
else {
|
|
1447
|
+
//this should never happen; somehow an invalid plugin has made it into here
|
|
1448
|
+
throw new Error(`TILT: Encountered an invalid plugin: ${String(plugin)}`);
|
|
1449
|
+
}
|
|
1063
1450
|
if (!plugin.name) {
|
|
1064
1451
|
plugin.name = pathOrModule;
|
|
1065
1452
|
}
|
|
@@ -1091,7 +1478,7 @@ class Util {
|
|
|
1091
1478
|
}
|
|
1092
1479
|
if ((0, reflection_1.isVariableExpression)(expression)) {
|
|
1093
1480
|
variableExpressions.push(expression);
|
|
1094
|
-
uniqueVarNames.add(expression.name.text);
|
|
1481
|
+
uniqueVarNames.add(expression.tokens.name.text);
|
|
1095
1482
|
}
|
|
1096
1483
|
}
|
|
1097
1484
|
// Collect all expressions. Most of these expressions are fairly small so this should be quick!
|
|
@@ -1103,6 +1490,10 @@ class Util {
|
|
|
1103
1490
|
expressionWalker(expression);
|
|
1104
1491
|
return { expressions: expressions, varExpressions: variableExpressions, uniqueVarNames: [...uniqueVarNames] };
|
|
1105
1492
|
}
|
|
1493
|
+
concatAnnotationLeadingTrivia(stmt, otherTrivia) {
|
|
1494
|
+
var _a, _b;
|
|
1495
|
+
return [...((_b = (_a = stmt.annotations) === null || _a === void 0 ? void 0 : _a.map(anno => anno.getLeadingTrivia()).flat()) !== null && _b !== void 0 ? _b : []), ...otherTrivia];
|
|
1496
|
+
}
|
|
1106
1497
|
/**
|
|
1107
1498
|
* Create a SourceNode that maps every line to itself. Useful for creating maps for files
|
|
1108
1499
|
* that haven't changed at all, but we still need the map
|
|
@@ -1117,86 +1508,39 @@ class Util {
|
|
|
1117
1508
|
}
|
|
1118
1509
|
return new source_map_1.SourceNode(null, null, source, chunks);
|
|
1119
1510
|
}
|
|
1120
|
-
/**
|
|
1121
|
-
* Creates a new SGAttribute object, but keeps the existing Range references (since those should be immutable)
|
|
1122
|
-
*/
|
|
1123
|
-
cloneSGAttribute(attr, value) {
|
|
1124
|
-
return new SGTypes_1.SGAttribute({ text: attr.tokens.key.text, range: attr.range }, { text: '=' }, { text: '"' }, { text: value, range: attr.tokens.value.range }, { text: '"' });
|
|
1125
|
-
}
|
|
1126
|
-
/**
|
|
1127
|
-
* Shorthand for creating a new source node
|
|
1128
|
-
*/
|
|
1129
|
-
sourceNode(source, locatable, code) {
|
|
1130
|
-
if (code !== undefined) {
|
|
1131
|
-
const node = new source_map_1.SourceNode(null, null, source, code);
|
|
1132
|
-
if (locatable.range) {
|
|
1133
|
-
//convert 0-based Range line to 1-based SourceNode line
|
|
1134
|
-
node.line = locatable.range.start.line + 1;
|
|
1135
|
-
//SourceNode columns are 0-based so no conversion necessary
|
|
1136
|
-
node.column = locatable.range.start.character;
|
|
1137
|
-
}
|
|
1138
|
-
return node;
|
|
1139
|
-
}
|
|
1140
|
-
}
|
|
1141
|
-
/**
|
|
1142
|
-
* Remove leading simple protocols from a path (if present)
|
|
1143
|
-
*/
|
|
1144
|
-
removeProtocol(pkgPath) {
|
|
1145
|
-
let match = /^[-a-z_]+:\//.exec(pkgPath);
|
|
1146
|
-
if (match) {
|
|
1147
|
-
return pkgPath.substring(match[0].length);
|
|
1148
|
-
}
|
|
1149
|
-
else {
|
|
1150
|
-
return pkgPath;
|
|
1151
|
-
}
|
|
1152
|
-
}
|
|
1153
1511
|
/**
|
|
1154
1512
|
* Converts a path into a standardized format (drive letter to lower, remove extra slashes, use single slash type, resolve relative parts, etc...)
|
|
1155
1513
|
*/
|
|
1156
1514
|
standardizePath(thePath) {
|
|
1157
1515
|
return exports.util.driveLetterToLower((0, roku_deploy_1.standardizePath)(thePath));
|
|
1158
1516
|
}
|
|
1159
|
-
/**
|
|
1160
|
-
* Copy the version of bslib from local node_modules to the staging folder
|
|
1161
|
-
*/
|
|
1162
|
-
async copyBslibToStaging(stagingDir) {
|
|
1163
|
-
//copy bslib to the output directory
|
|
1164
|
-
await fsExtra.ensureDir(standardizePath(`${stagingDir}/source`));
|
|
1165
|
-
// eslint-disable-next-line
|
|
1166
|
-
const bslib = require('@rokucommunity/bslib');
|
|
1167
|
-
let source = bslib.source;
|
|
1168
|
-
//apply the `bslib_` prefix to the functions
|
|
1169
|
-
let match;
|
|
1170
|
-
const positions = [];
|
|
1171
|
-
const regexp = /^(\s*(?:function|sub)\s+)([a-z0-9_]+)/mg;
|
|
1172
|
-
// eslint-disable-next-line no-cond-assign
|
|
1173
|
-
while (match = regexp.exec(source)) {
|
|
1174
|
-
positions.push(match.index + match[1].length);
|
|
1175
|
-
}
|
|
1176
|
-
for (let i = positions.length - 1; i >= 0; i--) {
|
|
1177
|
-
const position = positions[i];
|
|
1178
|
-
source = source.slice(0, position) + 'bslib_' + source.slice(position);
|
|
1179
|
-
}
|
|
1180
|
-
await fsExtra.writeFile(`${stagingDir}/source/bslib.brs`, source);
|
|
1181
|
-
}
|
|
1182
1517
|
/**
|
|
1183
1518
|
* Given a Diagnostic or BsDiagnostic, return a deep clone of the diagnostic.
|
|
1184
1519
|
* @param diagnostic the diagnostic to clone
|
|
1185
1520
|
* @param relatedInformationFallbackLocation a default location to use for all `relatedInformation` entries that are missing a location
|
|
1186
1521
|
*/
|
|
1187
|
-
toDiagnostic(diagnostic,
|
|
1522
|
+
toDiagnostic(diagnostic, relatedInformationFallbackLocation) {
|
|
1188
1523
|
var _a;
|
|
1524
|
+
let relatedInformation = (_a = diagnostic.relatedInformation) !== null && _a !== void 0 ? _a : [];
|
|
1525
|
+
if (relatedInformation.length > diagnosticUtils_1.MAX_RELATED_INFOS_COUNT) {
|
|
1526
|
+
const relatedInfoLength = relatedInformation.length;
|
|
1527
|
+
relatedInformation = relatedInformation.slice(0, diagnosticUtils_1.MAX_RELATED_INFOS_COUNT);
|
|
1528
|
+
relatedInformation.push({
|
|
1529
|
+
message: `...and ${relatedInfoLength - diagnosticUtils_1.MAX_RELATED_INFOS_COUNT} more`,
|
|
1530
|
+
location: exports.util.createLocation(' ', exports.util.createRange(0, 0, 0, 0))
|
|
1531
|
+
});
|
|
1532
|
+
}
|
|
1189
1533
|
return {
|
|
1190
1534
|
severity: diagnostic.severity,
|
|
1191
1535
|
range: diagnostic.range,
|
|
1192
1536
|
message: diagnostic.message,
|
|
1193
|
-
relatedInformation:
|
|
1537
|
+
relatedInformation: relatedInformation.map(x => {
|
|
1194
1538
|
//clone related information just in case a plugin added circular ref info here
|
|
1195
1539
|
const clone = Object.assign({}, x);
|
|
1196
1540
|
if (!clone.location) {
|
|
1197
1541
|
// use the fallback location if available
|
|
1198
|
-
if (
|
|
1199
|
-
clone.location = exports.util.createLocation(
|
|
1542
|
+
if (relatedInformationFallbackLocation) {
|
|
1543
|
+
clone.location = exports.util.createLocation(relatedInformationFallbackLocation, diagnostic.range);
|
|
1200
1544
|
}
|
|
1201
1545
|
else {
|
|
1202
1546
|
//remove this related information so it doesn't bring crash the language server
|
|
@@ -1205,81 +1549,16 @@ class Util {
|
|
|
1205
1549
|
}
|
|
1206
1550
|
return clone;
|
|
1207
1551
|
//filter out null relatedInformation items
|
|
1208
|
-
}).filter(x => x),
|
|
1552
|
+
}).filter((x) => Boolean(x)),
|
|
1209
1553
|
code: diagnostic.code,
|
|
1210
1554
|
source: 'brs'
|
|
1211
1555
|
};
|
|
1212
1556
|
}
|
|
1213
1557
|
/**
|
|
1214
|
-
*
|
|
1215
|
-
* @param
|
|
1216
|
-
* @
|
|
1217
|
-
*/
|
|
1218
|
-
getMinMaxParamCount(params) {
|
|
1219
|
-
//get min/max parameter count for callable
|
|
1220
|
-
let minParams = 0;
|
|
1221
|
-
let maxParams = 0;
|
|
1222
|
-
let continueCheckingForRequired = true;
|
|
1223
|
-
for (let param of params) {
|
|
1224
|
-
maxParams++;
|
|
1225
|
-
//optional parameters must come last, so we can assume that minParams won't increase once we hit
|
|
1226
|
-
//the first isOptional
|
|
1227
|
-
if (continueCheckingForRequired && !param.isOptional) {
|
|
1228
|
-
minParams++;
|
|
1229
|
-
}
|
|
1230
|
-
else {
|
|
1231
|
-
continueCheckingForRequired = false;
|
|
1232
|
-
}
|
|
1233
|
-
}
|
|
1234
|
-
return { min: minParams, max: maxParams };
|
|
1235
|
-
}
|
|
1236
|
-
/**
|
|
1237
|
-
* Gets the minimum and maximum number of allowed params for ALL functions with the name of the function call
|
|
1238
|
-
* @param callablesByLowerName The map of callable containers
|
|
1239
|
-
* @param expCall function call expression to use for the name
|
|
1240
|
-
* @returns the minimum and maximum number of allowed params
|
|
1558
|
+
* Get the first locatable item found at the specified position
|
|
1559
|
+
* @param locatables an array of items that have a `range` property
|
|
1560
|
+
* @param position the position that the locatable must contain
|
|
1241
1561
|
*/
|
|
1242
|
-
getMinMaxParamCountByFunctionCall(callablesByLowerName, expCall) {
|
|
1243
|
-
const callablesWithThisName = this.getCallableContainersByName(callablesByLowerName, expCall);
|
|
1244
|
-
if ((callablesWithThisName === null || callablesWithThisName === void 0 ? void 0 : callablesWithThisName.length) > 0) {
|
|
1245
|
-
const paramCount = { min: exports.MAX_PARAM_COUNT, max: 0 };
|
|
1246
|
-
for (const callableContainer of callablesWithThisName) {
|
|
1247
|
-
let specificParamCount = exports.util.getMinMaxParamCount(callableContainer.callable.params);
|
|
1248
|
-
if (specificParamCount.max > paramCount.max) {
|
|
1249
|
-
paramCount.max = specificParamCount.max;
|
|
1250
|
-
}
|
|
1251
|
-
if (specificParamCount.min < paramCount.min) {
|
|
1252
|
-
paramCount.min = specificParamCount.min;
|
|
1253
|
-
}
|
|
1254
|
-
}
|
|
1255
|
-
return paramCount;
|
|
1256
|
-
}
|
|
1257
|
-
}
|
|
1258
|
-
/**
|
|
1259
|
-
* Finds the array of callables from a container map, based on the name of the function call
|
|
1260
|
-
* If the callable was called in a function in a namespace, functions in that namespace are preferred
|
|
1261
|
-
* @param callablesByLowerName The map of callable containers
|
|
1262
|
-
* @param expCall function call expression to use for the name
|
|
1263
|
-
* @return an array with callable containers - could be empty if nothing was found
|
|
1264
|
-
*/
|
|
1265
|
-
getCallableContainersByName(callablesByLowerName, expCall) {
|
|
1266
|
-
let callablesWithThisName = [];
|
|
1267
|
-
const lowerName = expCall.name.text.toLowerCase();
|
|
1268
|
-
if (expCall.functionExpression.namespaceName) {
|
|
1269
|
-
// prefer namespaced function
|
|
1270
|
-
const potentialNamespacedCallable = expCall.functionExpression.namespaceName.getName(Parser_1.ParseMode.BrightScript).toLowerCase() + '_' + lowerName;
|
|
1271
|
-
callablesWithThisName = callablesByLowerName.get(potentialNamespacedCallable.toLowerCase());
|
|
1272
|
-
}
|
|
1273
|
-
if (!callablesWithThisName || callablesWithThisName.length === 0) {
|
|
1274
|
-
// just try it as is
|
|
1275
|
-
callablesWithThisName = callablesByLowerName.get(lowerName);
|
|
1276
|
-
}
|
|
1277
|
-
return callablesWithThisName;
|
|
1278
|
-
}
|
|
1279
|
-
/**
|
|
1280
|
-
* Get the first locatable item found at the specified position
|
|
1281
|
-
* @param position
|
|
1282
|
-
*/
|
|
1283
1562
|
getFirstLocatableAt(locatables, position) {
|
|
1284
1563
|
for (let token of locatables) {
|
|
1285
1564
|
if (exports.util.rangeContains(token.range, position)) {
|
|
@@ -1332,8 +1611,7 @@ class Util {
|
|
|
1332
1611
|
const chunks = text.split(separator);
|
|
1333
1612
|
const result = [];
|
|
1334
1613
|
let offset = 0;
|
|
1335
|
-
for (let
|
|
1336
|
-
const chunk = chunks[i];
|
|
1614
|
+
for (let chunk of chunks) {
|
|
1337
1615
|
//only keep nonzero chunks
|
|
1338
1616
|
if (chunk.length > 0) {
|
|
1339
1617
|
result.push({
|
|
@@ -1345,56 +1623,83 @@ class Util {
|
|
|
1345
1623
|
}
|
|
1346
1624
|
return result;
|
|
1347
1625
|
}
|
|
1348
|
-
|
|
1626
|
+
/**
|
|
1349
1627
|
* Wrap the given code in a markdown code fence (with the language)
|
|
1350
1628
|
*/
|
|
1351
1629
|
mdFence(code, language = '') {
|
|
1352
1630
|
return '```' + language + '\n' + code + '\n```';
|
|
1353
1631
|
}
|
|
1354
|
-
/**
|
|
1355
|
-
* Finds a callable from a container map based on the name AND number of arguments
|
|
1356
|
-
* If the callable was called in a function in a namespace, functions in that namespace are preferred
|
|
1357
|
-
* The first callable that matches the name AND will accept the number of arguments given is returned
|
|
1358
|
-
* @return a callable containers that matches the call
|
|
1359
|
-
*/
|
|
1360
|
-
getCallableContainerByFunctionCall(callablesByLowerName, expCall) {
|
|
1361
|
-
const callablesWithThisName = this.getCallableContainersByName(callablesByLowerName, expCall);
|
|
1362
|
-
if ((callablesWithThisName === null || callablesWithThisName === void 0 ? void 0 : callablesWithThisName.length) > 0) {
|
|
1363
|
-
for (const callableContainer of callablesWithThisName) {
|
|
1364
|
-
const paramCount = exports.util.getMinMaxParamCount(callableContainer.callable.params);
|
|
1365
|
-
if (paramCount.min <= expCall.args.length && paramCount.max >= expCall.args.length) {
|
|
1366
|
-
return callableContainer;
|
|
1367
|
-
}
|
|
1368
|
-
}
|
|
1369
|
-
}
|
|
1370
|
-
}
|
|
1371
1632
|
/**
|
|
1372
1633
|
* Gets each part of the dotted get.
|
|
1373
|
-
* @param expression
|
|
1634
|
+
* @param node any ast expression
|
|
1374
1635
|
* @returns an array of the parts of the dotted get. If not fully a dotted get, then returns undefined
|
|
1375
1636
|
*/
|
|
1376
|
-
getAllDottedGetParts(
|
|
1637
|
+
getAllDottedGetParts(node) {
|
|
1638
|
+
//this is a hot function and has been optimized. Don't rewrite unless necessary
|
|
1377
1639
|
const parts = [];
|
|
1378
|
-
let nextPart =
|
|
1379
|
-
while (nextPart) {
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1640
|
+
let nextPart = node;
|
|
1641
|
+
loop: while (nextPart) {
|
|
1642
|
+
switch (nextPart === null || nextPart === void 0 ? void 0 : nextPart.kind) {
|
|
1643
|
+
case AstNode_1.AstNodeKind.AssignmentStatement:
|
|
1644
|
+
return [node.tokens.name];
|
|
1645
|
+
case AstNode_1.AstNodeKind.DottedGetExpression:
|
|
1646
|
+
parts.push(nextPart === null || nextPart === void 0 ? void 0 : nextPart.tokens.name);
|
|
1647
|
+
nextPart = nextPart.obj;
|
|
1648
|
+
continue;
|
|
1649
|
+
case AstNode_1.AstNodeKind.CallExpression:
|
|
1650
|
+
nextPart = nextPart.callee;
|
|
1651
|
+
continue;
|
|
1652
|
+
case AstNode_1.AstNodeKind.TypeExpression:
|
|
1653
|
+
nextPart = nextPart.expression;
|
|
1654
|
+
continue;
|
|
1655
|
+
case AstNode_1.AstNodeKind.VariableExpression:
|
|
1656
|
+
parts.push(nextPart === null || nextPart === void 0 ? void 0 : nextPart.tokens.name);
|
|
1657
|
+
break loop;
|
|
1658
|
+
case AstNode_1.AstNodeKind.LiteralExpression:
|
|
1659
|
+
parts.push(nextPart === null || nextPart === void 0 ? void 0 : nextPart.tokens.value);
|
|
1660
|
+
break loop;
|
|
1661
|
+
case AstNode_1.AstNodeKind.IndexedGetExpression:
|
|
1662
|
+
nextPart = nextPart.obj;
|
|
1663
|
+
continue;
|
|
1664
|
+
case AstNode_1.AstNodeKind.FunctionParameterExpression:
|
|
1665
|
+
return [nextPart.tokens.name];
|
|
1666
|
+
case AstNode_1.AstNodeKind.GroupingExpression:
|
|
1667
|
+
parts.push((0, creators_1.createIdentifier)('()', nextPart.range));
|
|
1668
|
+
break loop;
|
|
1669
|
+
default:
|
|
1670
|
+
//we found a non-DottedGet expression, so return because this whole operation is invalid.
|
|
1671
|
+
return undefined;
|
|
1394
1672
|
}
|
|
1395
1673
|
}
|
|
1396
1674
|
return parts.reverse();
|
|
1397
1675
|
}
|
|
1676
|
+
/**
|
|
1677
|
+
* Given an expression, return all the DottedGet name parts as a string.
|
|
1678
|
+
* Mostly used to convert namespaced item full names to a strings
|
|
1679
|
+
*/
|
|
1680
|
+
getAllDottedGetPartsAsString(node, parseMode = Parser_1.ParseMode.BrighterScript) {
|
|
1681
|
+
var _a, _b;
|
|
1682
|
+
//this is a hot function and has been optimized. Don't rewrite unless necessary
|
|
1683
|
+
/* eslint-disable no-var */
|
|
1684
|
+
var sep = parseMode === Parser_1.ParseMode.BrighterScript ? '.' : '_';
|
|
1685
|
+
const parts = (_a = this.getAllDottedGetParts(node)) !== null && _a !== void 0 ? _a : [];
|
|
1686
|
+
var result = (_b = parts[0]) === null || _b === void 0 ? void 0 : _b.text;
|
|
1687
|
+
for (var i = 1; i < parts.length; i++) {
|
|
1688
|
+
result += sep + parts[i].text;
|
|
1689
|
+
}
|
|
1690
|
+
return result;
|
|
1691
|
+
/* eslint-enable no-var */
|
|
1692
|
+
}
|
|
1693
|
+
stringJoin(strings, separator) {
|
|
1694
|
+
var _a;
|
|
1695
|
+
// eslint-disable-next-line no-var
|
|
1696
|
+
var result = (_a = strings[0]) !== null && _a !== void 0 ? _a : '';
|
|
1697
|
+
// eslint-disable-next-line no-var
|
|
1698
|
+
for (var i = 1; i < strings.length; i++) {
|
|
1699
|
+
result += separator + strings[i];
|
|
1700
|
+
}
|
|
1701
|
+
return result;
|
|
1702
|
+
}
|
|
1398
1703
|
/**
|
|
1399
1704
|
* Break an expression into each part.
|
|
1400
1705
|
*/
|
|
@@ -1408,7 +1713,7 @@ class Util {
|
|
|
1408
1713
|
else if ((0, reflection_1.isCallExpression)(nextPart) || (0, reflection_1.isCallfuncExpression)(nextPart)) {
|
|
1409
1714
|
nextPart = nextPart.callee;
|
|
1410
1715
|
}
|
|
1411
|
-
else if ((0, reflection_1.
|
|
1716
|
+
else if ((0, reflection_1.isTypeExpression)(nextPart)) {
|
|
1412
1717
|
nextPart = nextPart.expression;
|
|
1413
1718
|
}
|
|
1414
1719
|
else {
|
|
@@ -1418,6 +1723,44 @@ class Util {
|
|
|
1418
1723
|
}
|
|
1419
1724
|
return parts;
|
|
1420
1725
|
}
|
|
1726
|
+
/**
|
|
1727
|
+
* Break an expression into each part, and return any VariableExpression or DottedGet expresisons from left-to-right.
|
|
1728
|
+
*/
|
|
1729
|
+
getDottedGetPath(expression) {
|
|
1730
|
+
let parts = [];
|
|
1731
|
+
let nextPart = expression;
|
|
1732
|
+
loop: while (nextPart) {
|
|
1733
|
+
switch (nextPart === null || nextPart === void 0 ? void 0 : nextPart.kind) {
|
|
1734
|
+
case AstNode_1.AstNodeKind.DottedGetExpression:
|
|
1735
|
+
parts.push(nextPart);
|
|
1736
|
+
nextPart = nextPart.obj;
|
|
1737
|
+
continue;
|
|
1738
|
+
case AstNode_1.AstNodeKind.IndexedGetExpression:
|
|
1739
|
+
case AstNode_1.AstNodeKind.XmlAttributeGetExpression:
|
|
1740
|
+
nextPart = nextPart.obj;
|
|
1741
|
+
parts = [];
|
|
1742
|
+
continue;
|
|
1743
|
+
case AstNode_1.AstNodeKind.CallExpression:
|
|
1744
|
+
case AstNode_1.AstNodeKind.CallfuncExpression:
|
|
1745
|
+
nextPart = nextPart.callee;
|
|
1746
|
+
parts = [];
|
|
1747
|
+
continue;
|
|
1748
|
+
case AstNode_1.AstNodeKind.NewExpression:
|
|
1749
|
+
nextPart = nextPart.call.callee;
|
|
1750
|
+
parts = [];
|
|
1751
|
+
continue;
|
|
1752
|
+
case AstNode_1.AstNodeKind.TypeExpression:
|
|
1753
|
+
nextPart = nextPart.expression;
|
|
1754
|
+
continue;
|
|
1755
|
+
case AstNode_1.AstNodeKind.VariableExpression:
|
|
1756
|
+
parts.push(nextPart);
|
|
1757
|
+
break loop;
|
|
1758
|
+
default:
|
|
1759
|
+
return [];
|
|
1760
|
+
}
|
|
1761
|
+
}
|
|
1762
|
+
return parts.reverse();
|
|
1763
|
+
}
|
|
1421
1764
|
/**
|
|
1422
1765
|
* Returns an integer if valid, or undefined. Eliminates checking for NaN
|
|
1423
1766
|
*/
|
|
@@ -1440,19 +1783,156 @@ class Util {
|
|
|
1440
1783
|
validateTooDeepFile(file) {
|
|
1441
1784
|
var _a;
|
|
1442
1785
|
//find any files nested too deep
|
|
1443
|
-
let
|
|
1444
|
-
let rootFolder =
|
|
1786
|
+
let destPath = (_a = file === null || file === void 0 ? void 0 : file.destPath) === null || _a === void 0 ? void 0 : _a.toString();
|
|
1787
|
+
let rootFolder = destPath === null || destPath === void 0 ? void 0 : destPath.replace(/^pkg:/, '').split(/[\\\/]/)[0].toLowerCase();
|
|
1445
1788
|
if ((0, reflection_1.isBrsFile)(file) && rootFolder !== 'source') {
|
|
1446
1789
|
return;
|
|
1447
1790
|
}
|
|
1448
1791
|
if ((0, reflection_1.isXmlFile)(file) && rootFolder !== 'components') {
|
|
1449
1792
|
return;
|
|
1450
1793
|
}
|
|
1451
|
-
let fileDepth = this.getParentDirectoryCount(
|
|
1794
|
+
let fileDepth = this.getParentDirectoryCount(destPath);
|
|
1452
1795
|
if (fileDepth >= 8) {
|
|
1453
1796
|
file.addDiagnostics([Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.detectedTooDeepFileSource(fileDepth)), { file: file, range: this.createRange(0, 0, 0, Number.MAX_VALUE) })]);
|
|
1454
1797
|
}
|
|
1455
1798
|
}
|
|
1799
|
+
/**
|
|
1800
|
+
* Find the index of the last item in the array that matches.
|
|
1801
|
+
*/
|
|
1802
|
+
findLastIndex(array, matcher) {
|
|
1803
|
+
for (let i = array.length - 1; i >= 0; i--) {
|
|
1804
|
+
if (matcher(array[i])) {
|
|
1805
|
+
return i;
|
|
1806
|
+
}
|
|
1807
|
+
}
|
|
1808
|
+
}
|
|
1809
|
+
processTypeChain(typeChain) {
|
|
1810
|
+
var _a, _b, _c, _d;
|
|
1811
|
+
let fullChainName = '';
|
|
1812
|
+
let fullErrorName = '';
|
|
1813
|
+
let itemName = '';
|
|
1814
|
+
let previousTypeName = '';
|
|
1815
|
+
let parentTypeName = '';
|
|
1816
|
+
let errorRange;
|
|
1817
|
+
let containsDynamic = false;
|
|
1818
|
+
for (let i = 0; i < typeChain.length; i++) {
|
|
1819
|
+
const chainItem = typeChain[i];
|
|
1820
|
+
const dotSep = (_b = (_a = chainItem.separatorToken) === null || _a === void 0 ? void 0 : _a.text) !== null && _b !== void 0 ? _b : '.';
|
|
1821
|
+
if (i > 0) {
|
|
1822
|
+
fullChainName += dotSep;
|
|
1823
|
+
}
|
|
1824
|
+
fullChainName += chainItem.name;
|
|
1825
|
+
parentTypeName = previousTypeName;
|
|
1826
|
+
fullErrorName = previousTypeName ? `${previousTypeName}${dotSep}${chainItem.name}` : chainItem.name;
|
|
1827
|
+
previousTypeName = (_d = (_c = chainItem.type) === null || _c === void 0 ? void 0 : _c.toString()) !== null && _d !== void 0 ? _d : '';
|
|
1828
|
+
itemName = chainItem.name;
|
|
1829
|
+
containsDynamic = containsDynamic || ((0, reflection_1.isDynamicType)(chainItem.type) && !(0, reflection_1.isAnyReferenceType)(chainItem.type));
|
|
1830
|
+
if (!chainItem.isResolved) {
|
|
1831
|
+
errorRange = chainItem.range;
|
|
1832
|
+
break;
|
|
1833
|
+
}
|
|
1834
|
+
}
|
|
1835
|
+
return {
|
|
1836
|
+
itemName: itemName,
|
|
1837
|
+
itemParentTypeName: parentTypeName,
|
|
1838
|
+
fullNameOfItem: fullErrorName,
|
|
1839
|
+
fullChainName: fullChainName,
|
|
1840
|
+
range: errorRange,
|
|
1841
|
+
containsDynamic: containsDynamic
|
|
1842
|
+
};
|
|
1843
|
+
}
|
|
1844
|
+
isInTypeExpression(expression) {
|
|
1845
|
+
//TODO: this is much faster than node.findAncestor(), but may need to be updated for "complicated" type expressions
|
|
1846
|
+
if ((0, reflection_1.isTypeExpression)(expression) ||
|
|
1847
|
+
(0, reflection_1.isTypeExpression)(expression.parent) ||
|
|
1848
|
+
(0, reflection_1.isTypedArrayExpression)(expression) ||
|
|
1849
|
+
(0, reflection_1.isTypedArrayExpression)(expression.parent)) {
|
|
1850
|
+
return true;
|
|
1851
|
+
}
|
|
1852
|
+
if ((0, reflection_1.isBinaryExpression)(expression.parent)) {
|
|
1853
|
+
let currentExpr = expression.parent;
|
|
1854
|
+
while ((0, reflection_1.isBinaryExpression)(currentExpr) && currentExpr.tokens.operator.kind === TokenKind_1.TokenKind.Or) {
|
|
1855
|
+
currentExpr = currentExpr.parent;
|
|
1856
|
+
}
|
|
1857
|
+
return (0, reflection_1.isTypeExpression)(currentExpr) || (0, reflection_1.isTypedArrayExpression)(currentExpr);
|
|
1858
|
+
}
|
|
1859
|
+
return false;
|
|
1860
|
+
}
|
|
1861
|
+
setContainsUnresolvedSymbol(symbolLowerNameSet, symbol) {
|
|
1862
|
+
var _a, _b;
|
|
1863
|
+
const possibleOriginalSymbolNamesLower = [];
|
|
1864
|
+
let nameSoFar = '';
|
|
1865
|
+
for (const tce of symbol.typeChain) {
|
|
1866
|
+
if (nameSoFar.length > 0) {
|
|
1867
|
+
nameSoFar += '.';
|
|
1868
|
+
}
|
|
1869
|
+
nameSoFar += tce.name.toLowerCase();
|
|
1870
|
+
possibleOriginalSymbolNamesLower.push(nameSoFar);
|
|
1871
|
+
}
|
|
1872
|
+
const possibleNamespace = (_b = (_a = symbol.containingNamespaces) === null || _a === void 0 ? void 0 : _a.join('.')) !== null && _b !== void 0 ? _b : '';
|
|
1873
|
+
for (const possibleNameLower of possibleOriginalSymbolNamesLower) {
|
|
1874
|
+
if (symbolLowerNameSet.has(possibleNameLower)) {
|
|
1875
|
+
return true;
|
|
1876
|
+
}
|
|
1877
|
+
if (possibleNamespace) {
|
|
1878
|
+
const fullName = possibleNamespace + '.' + possibleNameLower;
|
|
1879
|
+
if (symbolLowerNameSet.has(fullName.toLowerCase())) {
|
|
1880
|
+
return true;
|
|
1881
|
+
}
|
|
1882
|
+
}
|
|
1883
|
+
}
|
|
1884
|
+
return false;
|
|
1885
|
+
}
|
|
1886
|
+
truncate(options) {
|
|
1887
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
1888
|
+
let leadingText = options.leadingText;
|
|
1889
|
+
let items = (_a = options === null || options === void 0 ? void 0 : options.items) !== null && _a !== void 0 ? _a : [];
|
|
1890
|
+
let trailingText = (_b = options === null || options === void 0 ? void 0 : options.trailingText) !== null && _b !== void 0 ? _b : '';
|
|
1891
|
+
let maxLength = (_c = options === null || options === void 0 ? void 0 : options.maxLength) !== null && _c !== void 0 ? _c : 160;
|
|
1892
|
+
let itemSeparator = (_d = options === null || options === void 0 ? void 0 : options.itemSeparator) !== null && _d !== void 0 ? _d : ', ';
|
|
1893
|
+
let partBuilder = (_e = options === null || options === void 0 ? void 0 : options.partBuilder) !== null && _e !== void 0 ? _e : ((x) => x.toString());
|
|
1894
|
+
let parts = [];
|
|
1895
|
+
let length = leadingText.length + ((_f = trailingText === null || trailingText === void 0 ? void 0 : trailingText.length) !== null && _f !== void 0 ? _f : 0);
|
|
1896
|
+
//calculate the max number of items we could fit in the given space
|
|
1897
|
+
for (let i = 0; i < items.length; i++) {
|
|
1898
|
+
let part = partBuilder(items[i]);
|
|
1899
|
+
if (i > 0) {
|
|
1900
|
+
part = itemSeparator + part;
|
|
1901
|
+
}
|
|
1902
|
+
parts.push(part);
|
|
1903
|
+
length += part.length;
|
|
1904
|
+
//exit the loop if we've maxed out our length
|
|
1905
|
+
if (length >= maxLength) {
|
|
1906
|
+
break;
|
|
1907
|
+
}
|
|
1908
|
+
}
|
|
1909
|
+
let message;
|
|
1910
|
+
//we have enough space to include all the parts
|
|
1911
|
+
if (parts.length >= items.length) {
|
|
1912
|
+
message = leadingText + parts.join('') + trailingText;
|
|
1913
|
+
//we require truncation
|
|
1914
|
+
}
|
|
1915
|
+
else {
|
|
1916
|
+
//account for truncation message length including max possible "more" items digits, trailing text length, and the separator between last item and trailing text
|
|
1917
|
+
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);
|
|
1918
|
+
message = leadingText;
|
|
1919
|
+
for (let i = 0; i < parts.length; i++) {
|
|
1920
|
+
//always include at least 2 items. if this part would overflow the max, then skip it and finalize the message
|
|
1921
|
+
if (i > 1 && length + parts[i].length > maxLength) {
|
|
1922
|
+
message += itemSeparator + `...and ${items.length - i} more` + trailingText;
|
|
1923
|
+
return message;
|
|
1924
|
+
}
|
|
1925
|
+
else {
|
|
1926
|
+
message += parts[i];
|
|
1927
|
+
length += parts[i].length;
|
|
1928
|
+
}
|
|
1929
|
+
}
|
|
1930
|
+
}
|
|
1931
|
+
return message;
|
|
1932
|
+
}
|
|
1933
|
+
getAstNodeFriendlyName(node) {
|
|
1934
|
+
return node === null || node === void 0 ? void 0 : node.kind.replace(/Statement|Expression/g, '');
|
|
1935
|
+
}
|
|
1456
1936
|
}
|
|
1457
1937
|
exports.Util = Util;
|
|
1458
1938
|
/**
|
|
@@ -1469,5 +1949,4 @@ function standardizePath(stringParts, ...expressions) {
|
|
|
1469
1949
|
exports.standardizePath = standardizePath;
|
|
1470
1950
|
exports.util = new Util();
|
|
1471
1951
|
exports.default = exports.util;
|
|
1472
|
-
exports.MAX_PARAM_COUNT = 32;
|
|
1473
1952
|
//# sourceMappingURL=util.js.map
|