brighterscript 1.0.0-alpha.3 → 1.0.0-alpha.30
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 +1230 -285
- package/README.md +61 -131
- package/bsconfig.schema.json +68 -2
- 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 +35 -0
- package/dist/AstValidationSegmenter.js +209 -0
- package/dist/AstValidationSegmenter.js.map +1 -0
- package/dist/BsConfig.d.ts +51 -6
- package/dist/BusyStatusTracker.d.ts +31 -0
- package/dist/BusyStatusTracker.js +83 -0
- package/dist/BusyStatusTracker.js.map +1 -0
- package/dist/Cache.d.ts +5 -6
- package/dist/Cache.js +12 -11
- 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 +11 -2
- package/dist/CodeActionUtil.js +17 -3
- package/dist/CodeActionUtil.js.map +1 -1
- package/dist/CommentFlagProcessor.d.ts +7 -6
- package/dist/CommentFlagProcessor.js +10 -7
- package/dist/CommentFlagProcessor.js.map +1 -1
- package/dist/DependencyGraph.d.ts +8 -3
- package/dist/DependencyGraph.js +49 -16
- package/dist/DependencyGraph.js.map +1 -1
- package/dist/DiagnosticCollection.d.ts +5 -3
- package/dist/DiagnosticCollection.js +18 -16
- package/dist/DiagnosticCollection.js.map +1 -1
- package/dist/DiagnosticFilterer.d.ts +8 -4
- package/dist/DiagnosticFilterer.js +77 -44
- package/dist/DiagnosticFilterer.js.map +1 -1
- package/dist/DiagnosticManager.d.ts +55 -0
- package/dist/DiagnosticManager.js +214 -0
- package/dist/DiagnosticManager.js.map +1 -0
- package/dist/DiagnosticMessages.d.ts +184 -17
- package/dist/DiagnosticMessages.js +242 -24
- 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 +72 -47
- package/dist/LanguageServer.js +544 -312
- package/dist/LanguageServer.js.map +1 -1
- package/dist/Logger.d.ts +9 -10
- package/dist/Logger.js +36 -30
- package/dist/Logger.js.map +1 -1
- package/dist/PluginInterface.d.ts +29 -7
- package/dist/PluginInterface.js +90 -7
- package/dist/PluginInterface.js.map +1 -1
- package/dist/Program.d.ts +204 -99
- package/dist/Program.js +1060 -699
- package/dist/Program.js.map +1 -1
- package/dist/ProgramBuilder.d.ts +29 -18
- package/dist/ProgramBuilder.js +170 -132
- package/dist/ProgramBuilder.js.map +1 -1
- package/dist/Scope.d.ts +144 -109
- package/dist/Scope.js +538 -551
- package/dist/Scope.js.map +1 -1
- package/dist/SemanticTokenUtils.d.ts +14 -0
- package/dist/SemanticTokenUtils.js +81 -0
- package/dist/SemanticTokenUtils.js.map +1 -0
- package/dist/Stopwatch.d.ts +4 -0
- package/dist/Stopwatch.js +8 -1
- package/dist/Stopwatch.js.map +1 -1
- package/dist/SymbolTable.d.ts +91 -24
- package/dist/SymbolTable.js +286 -63
- package/dist/SymbolTable.js.map +1 -1
- package/dist/SymbolTypeFlag.d.ts +8 -0
- package/dist/SymbolTypeFlag.js +13 -0
- package/dist/SymbolTypeFlag.js.map +1 -0
- 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 +5 -15
- package/dist/XmlScope.js +35 -87
- package/dist/XmlScope.js.map +1 -1
- package/dist/astUtils/CachedLookups.d.ts +49 -0
- package/dist/astUtils/CachedLookups.js +324 -0
- package/dist/astUtils/CachedLookups.js.map +1 -0
- package/dist/astUtils/Editor.d.ts +69 -0
- package/dist/astUtils/Editor.js +245 -0
- package/dist/astUtils/Editor.js.map +1 -0
- package/dist/astUtils/Editor.spec.js +258 -0
- package/dist/astUtils/Editor.spec.js.map +1 -0
- package/dist/astUtils/creators.d.ts +33 -10
- package/dist/astUtils/creators.js +224 -30
- 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 +145 -82
- package/dist/astUtils/reflection.js +304 -132
- package/dist/astUtils/reflection.js.map +1 -1
- package/dist/astUtils/reflection.spec.js +267 -162
- package/dist/astUtils/reflection.spec.js.map +1 -1
- package/dist/astUtils/stackedVisitor.js.map +1 -1
- package/dist/astUtils/stackedVisitor.spec.js +14 -14
- package/dist/astUtils/stackedVisitor.spec.js.map +1 -1
- package/dist/astUtils/visitors.d.ts +114 -53
- package/dist/astUtils/visitors.js +70 -13
- package/dist/astUtils/visitors.js.map +1 -1
- package/dist/astUtils/visitors.spec.js +465 -51
- package/dist/astUtils/visitors.spec.js.map +1 -1
- package/dist/astUtils/xml.d.ts +9 -8
- package/dist/astUtils/xml.js +10 -5
- package/dist/astUtils/xml.js.map +1 -1
- package/dist/bscPlugin/BscPlugin.d.ts +22 -1
- package/dist/bscPlugin/BscPlugin.js +88 -0
- 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 +137 -0
- package/dist/bscPlugin/SignatureHelpUtil.js.map +1 -0
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.d.ts +1 -1
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.js +26 -17
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.js.map +1 -1
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js +94 -20
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js.map +1 -1
- package/dist/bscPlugin/completions/CompletionsProcessor.d.ts +60 -0
- package/dist/bscPlugin/completions/CompletionsProcessor.js +601 -0
- package/dist/bscPlugin/completions/CompletionsProcessor.js.map +1 -0
- package/dist/bscPlugin/completions/CompletionsProcessor.spec.js +2139 -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 +18 -0
- package/dist/bscPlugin/hover/HoverProcessor.js +218 -0
- package/dist/bscPlugin/hover/HoverProcessor.js.map +1 -0
- package/dist/bscPlugin/hover/HoverProcessor.spec.d.ts +1 -0
- package/dist/bscPlugin/hover/HoverProcessor.spec.js +737 -0
- package/dist/bscPlugin/hover/HoverProcessor.spec.js.map +1 -0
- package/dist/bscPlugin/references/ReferencesProvider.d.ts +12 -0
- package/dist/bscPlugin/references/ReferencesProvider.js +56 -0
- package/dist/bscPlugin/references/ReferencesProvider.js.map +1 -0
- package/dist/bscPlugin/references/ReferencesProvider.spec.d.ts +1 -0
- package/dist/bscPlugin/references/ReferencesProvider.spec.js +51 -0
- package/dist/bscPlugin/references/ReferencesProvider.spec.js.map +1 -0
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.d.ts +14 -0
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js +138 -0
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js.map +1 -0
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.d.ts +1 -0
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js +491 -0
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js.map +1 -0
- 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/symbols/DocumentSymbolProcessor.d.ts +7 -0
- package/dist/bscPlugin/symbols/DocumentSymbolProcessor.js +22 -0
- package/dist/bscPlugin/symbols/DocumentSymbolProcessor.js.map +1 -0
- package/dist/bscPlugin/symbols/DocumentSymbolProcessor.spec.d.ts +1 -0
- package/dist/bscPlugin/symbols/DocumentSymbolProcessor.spec.js +291 -0
- package/dist/bscPlugin/symbols/DocumentSymbolProcessor.spec.js.map +1 -0
- package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.d.ts +7 -0
- package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.js +26 -0
- package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.js.map +1 -0
- package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.spec.d.ts +1 -0
- package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.spec.js +245 -0
- package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.spec.js.map +1 -0
- package/dist/bscPlugin/symbols/symbolUtils.d.ts +5 -0
- package/dist/bscPlugin/symbols/symbolUtils.js +140 -0
- package/dist/bscPlugin/symbols/symbolUtils.js.map +1 -0
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.d.ts +21 -0
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.js +202 -0
- 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/BrsFileAfterValidatior.d.ts +7 -0
- package/dist/bscPlugin/validation/BrsFileAfterValidatior.js +18 -0
- package/dist/bscPlugin/validation/BrsFileAfterValidatior.js.map +1 -0
- package/dist/bscPlugin/validation/BrsFileValidator.d.ts +34 -0
- package/dist/bscPlugin/validation/BrsFileValidator.js +462 -0
- package/dist/bscPlugin/validation/BrsFileValidator.js.map +1 -0
- package/dist/bscPlugin/validation/BrsFileValidator.spec.d.ts +1 -0
- package/dist/bscPlugin/validation/BrsFileValidator.spec.js +758 -0
- package/dist/bscPlugin/validation/BrsFileValidator.spec.js.map +1 -0
- package/dist/bscPlugin/validation/ProgramValidator.d.ts +11 -0
- package/dist/bscPlugin/validation/ProgramValidator.js +33 -0
- package/dist/bscPlugin/validation/ProgramValidator.js.map +1 -0
- package/dist/bscPlugin/validation/ScopeValidator.d.ts +131 -0
- package/dist/bscPlugin/validation/ScopeValidator.js +1097 -0
- package/dist/bscPlugin/validation/ScopeValidator.js.map +1 -0
- package/dist/bscPlugin/validation/ScopeValidator.spec.d.ts +1 -0
- package/dist/bscPlugin/validation/ScopeValidator.spec.js +2796 -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 +117 -11
- 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 +10 -3
- package/dist/diagnosticUtils.js +58 -21
- package/dist/diagnosticUtils.js.map +1 -1
- package/dist/examples/plugins/removePrint.js +8 -12
- package/dist/examples/plugins/removePrint.js.map +1 -1
- package/dist/files/AssetFile.d.ts +24 -0
- package/dist/files/AssetFile.js +25 -0
- package/dist/files/AssetFile.js.map +1 -0
- package/dist/files/BrsFile.Class.spec.js +858 -153
- package/dist/files/BrsFile.Class.spec.js.map +1 -1
- package/dist/files/BrsFile.d.ts +144 -82
- package/dist/files/BrsFile.js +847 -911
- package/dist/files/BrsFile.js.map +1 -1
- package/dist/files/BrsFile.spec.js +2928 -834
- package/dist/files/BrsFile.spec.js.map +1 -1
- package/dist/files/BscFile.d.ts +101 -0
- package/dist/files/BscFile.js +15 -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 +73 -41
- package/dist/files/XmlFile.js +126 -138
- package/dist/files/XmlFile.js.map +1 -1
- package/dist/files/XmlFile.spec.js +450 -318
- package/dist/files/XmlFile.spec.js.map +1 -1
- package/dist/files/tests/imports.spec.js +62 -52
- package/dist/files/tests/imports.spec.js.map +1 -1
- package/dist/files/tests/optionalChaning.spec.d.ts +1 -0
- package/dist/files/tests/optionalChaning.spec.js +152 -0
- package/dist/files/tests/optionalChaning.spec.js.map +1 -0
- package/dist/globalCallables.d.ts +3 -1
- package/dist/globalCallables.js +416 -162
- package/dist/globalCallables.js.map +1 -1
- package/dist/index.d.ts +25 -3
- package/dist/index.js +42 -5
- package/dist/index.js.map +1 -1
- package/dist/interfaces.d.ts +722 -119
- package/dist/interfaces.js +31 -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 +40 -9
- package/dist/lexer/Lexer.js +191 -49
- package/dist/lexer/Lexer.js.map +1 -1
- package/dist/lexer/Lexer.spec.js +775 -563
- package/dist/lexer/Lexer.spec.js.map +1 -1
- package/dist/lexer/Token.d.ts +11 -3
- package/dist/lexer/Token.js +10 -2
- package/dist/lexer/Token.js.map +1 -1
- package/dist/lexer/TokenKind.d.ts +27 -1
- package/dist/lexer/TokenKind.js +112 -5
- package/dist/lexer/TokenKind.js.map +1 -1
- package/dist/logging.d.ts +9 -0
- package/dist/logging.js +16 -0
- package/dist/logging.js.map +1 -0
- package/dist/parser/AstNode.d.ts +180 -0
- package/dist/parser/AstNode.js +245 -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 +12 -2
- package/dist/parser/BrsTranspileState.js +6 -0
- package/dist/parser/BrsTranspileState.js.map +1 -1
- package/dist/parser/Expression.d.ts +454 -210
- package/dist/parser/Expression.js +953 -498
- package/dist/parser/Expression.js.map +1 -1
- package/dist/parser/Parser.Class.spec.js +200 -95
- package/dist/parser/Parser.Class.spec.js.map +1 -1
- package/dist/parser/Parser.d.ts +105 -120
- package/dist/parser/Parser.js +1406 -912
- package/dist/parser/Parser.js.map +1 -1
- package/dist/parser/Parser.spec.d.ts +3 -1
- package/dist/parser/Parser.spec.js +1383 -456
- package/dist/parser/Parser.spec.js.map +1 -1
- package/dist/parser/SGParser.d.ts +44 -6
- package/dist/parser/SGParser.js +212 -185
- package/dist/parser/SGParser.js.map +1 -1
- package/dist/parser/SGParser.spec.js +30 -28
- package/dist/parser/SGParser.spec.js.map +1 -1
- package/dist/parser/SGTypes.d.ts +293 -50
- package/dist/parser/SGTypes.js +540 -187
- package/dist/parser/SGTypes.js.map +1 -1
- package/dist/parser/Statement.d.ts +734 -244
- package/dist/parser/Statement.js +1758 -611
- package/dist/parser/Statement.js.map +1 -1
- package/dist/parser/Statement.spec.js +45 -34
- package/dist/parser/Statement.spec.js.map +1 -1
- package/dist/parser/TranspileState.d.ts +17 -8
- package/dist/parser/TranspileState.js +73 -11
- package/dist/parser/TranspileState.js.map +1 -1
- package/dist/parser/tests/Parser.spec.d.ts +10 -9
- package/dist/parser/tests/Parser.spec.js +18 -14
- package/dist/parser/tests/Parser.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/For.spec.js +79 -69
- package/dist/parser/tests/controlFlow/For.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/ForEach.spec.js +53 -47
- package/dist/parser/tests/controlFlow/ForEach.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/If.spec.js +217 -196
- package/dist/parser/tests/controlFlow/If.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/While.spec.js +48 -42
- package/dist/parser/tests/controlFlow/While.spec.js.map +1 -1
- package/dist/parser/tests/expression/Additive.spec.js +31 -31
- package/dist/parser/tests/expression/Additive.spec.js.map +1 -1
- package/dist/parser/tests/expression/ArrayLiterals.spec.js +157 -120
- package/dist/parser/tests/expression/ArrayLiterals.spec.js.map +1 -1
- package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js +202 -139
- package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js.map +1 -1
- package/dist/parser/tests/expression/Boolean.spec.js +25 -25
- package/dist/parser/tests/expression/Boolean.spec.js.map +1 -1
- package/dist/parser/tests/expression/Call.spec.js +150 -41
- package/dist/parser/tests/expression/Call.spec.js.map +1 -1
- package/dist/parser/tests/expression/Exponential.spec.js +18 -18
- package/dist/parser/tests/expression/Exponential.spec.js.map +1 -1
- package/dist/parser/tests/expression/Function.spec.js +257 -257
- package/dist/parser/tests/expression/Function.spec.js.map +1 -1
- package/dist/parser/tests/expression/Indexing.spec.js +160 -90
- package/dist/parser/tests/expression/Indexing.spec.js.map +1 -1
- package/dist/parser/tests/expression/Multiplicative.spec.js +38 -38
- package/dist/parser/tests/expression/Multiplicative.spec.js.map +1 -1
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js +196 -98
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/PrefixUnary.spec.js +42 -42
- package/dist/parser/tests/expression/PrefixUnary.spec.js.map +1 -1
- package/dist/parser/tests/expression/Primary.spec.js +42 -42
- package/dist/parser/tests/expression/Primary.spec.js.map +1 -1
- package/dist/parser/tests/expression/RegexLiteralExpression.spec.d.ts +1 -0
- package/dist/parser/tests/expression/RegexLiteralExpression.spec.js +171 -0
- package/dist/parser/tests/expression/RegexLiteralExpression.spec.js.map +1 -0
- package/dist/parser/tests/expression/Relational.spec.js +44 -44
- package/dist/parser/tests/expression/Relational.spec.js.map +1 -1
- package/dist/parser/tests/expression/SourceLiteralExpression.spec.js +31 -31
- package/dist/parser/tests/expression/SourceLiteralExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/TemplateStringExpression.spec.js +230 -90
- package/dist/parser/tests/expression/TemplateStringExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/TernaryExpression.spec.js +377 -148
- 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 +126 -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 +37 -37
- package/dist/parser/tests/statement/AssignmentOperators.spec.js.map +1 -1
- package/dist/parser/tests/statement/ConstStatement.spec.d.ts +1 -0
- package/dist/parser/tests/statement/ConstStatement.spec.js +262 -0
- package/dist/parser/tests/statement/ConstStatement.spec.js.map +1 -0
- 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 +45 -45
- 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.d.ts +1 -0
- package/dist/parser/tests/statement/Enum.spec.js +684 -0
- package/dist/parser/tests/statement/Enum.spec.js.map +1 -0
- package/dist/parser/tests/statement/For.spec.d.ts +1 -0
- package/dist/parser/tests/statement/For.spec.js +45 -0
- package/dist/parser/tests/statement/For.spec.js.map +1 -0
- package/dist/parser/tests/statement/ForEach.spec.d.ts +1 -0
- package/dist/parser/tests/statement/ForEach.spec.js +36 -0
- package/dist/parser/tests/statement/ForEach.spec.js.map +1 -0
- package/dist/parser/tests/statement/Function.spec.js +208 -198
- package/dist/parser/tests/statement/Function.spec.js.map +1 -1
- package/dist/parser/tests/statement/Goto.spec.js +16 -15
- package/dist/parser/tests/statement/Goto.spec.js.map +1 -1
- package/dist/parser/tests/statement/Increment.spec.js +51 -51
- package/dist/parser/tests/statement/Increment.spec.js.map +1 -1
- package/dist/parser/tests/statement/InterfaceStatement.spec.d.ts +1 -0
- package/dist/parser/tests/statement/InterfaceStatement.spec.js +109 -0
- package/dist/parser/tests/statement/InterfaceStatement.spec.js.map +1 -0
- package/dist/parser/tests/statement/LibraryStatement.spec.js +18 -18
- package/dist/parser/tests/statement/LibraryStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/Misc.spec.js +123 -163
- package/dist/parser/tests/statement/Misc.spec.js.map +1 -1
- package/dist/parser/tests/statement/PrintStatement.spec.js +125 -108
- package/dist/parser/tests/statement/PrintStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/ReturnStatement.spec.js +51 -49
- package/dist/parser/tests/statement/ReturnStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/Set.spec.js +110 -97
- package/dist/parser/tests/statement/Set.spec.js.map +1 -1
- package/dist/parser/tests/statement/Stop.spec.js +13 -12
- 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 +26 -15
- package/dist/parser/tests/statement/TryCatch.spec.js.map +1 -1
- package/dist/preprocessor/Manifest.d.ts +6 -6
- package/dist/preprocessor/Manifest.js +17 -38
- package/dist/preprocessor/Manifest.js.map +1 -1
- package/dist/preprocessor/Manifest.spec.d.ts +1 -0
- package/dist/preprocessor/Manifest.spec.js +78 -103
- package/dist/preprocessor/Manifest.spec.js.map +1 -1
- package/dist/roku-types/data.json +19351 -0
- package/dist/roku-types/index.d.ts +5483 -0
- package/dist/roku-types/index.js +11 -0
- package/dist/roku-types/index.js.map +1 -0
- package/dist/types/ArrayType.d.ts +9 -5
- package/dist/types/ArrayType.js +68 -24
- package/dist/types/ArrayType.js.map +1 -1
- package/dist/types/ArrayType.spec.js +39 -11
- package/dist/types/ArrayType.spec.js.map +1 -1
- package/dist/types/AssociativeArrayType.d.ts +14 -0
- package/dist/types/AssociativeArrayType.js +60 -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 +10 -5
- package/dist/types/BooleanType.js +21 -9
- package/dist/types/BooleanType.js.map +1 -1
- package/dist/types/BooleanType.spec.js +10 -4
- package/dist/types/BooleanType.spec.js.map +1 -1
- package/dist/types/BscType.d.ts +29 -3
- package/dist/types/BscType.js +121 -0
- 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 +174 -0
- package/dist/types/BuiltInInterfaceAdder.js.map +1 -0
- package/dist/types/BuiltInInterfaceAdder.spec.d.ts +1 -0
- package/dist/types/BuiltInInterfaceAdder.spec.js +115 -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 +76 -0
- package/dist/types/ClassType.spec.js.map +1 -0
- package/dist/types/ComponentType.d.ts +27 -0
- package/dist/types/ComponentType.js +83 -0
- package/dist/types/ComponentType.js.map +1 -0
- package/dist/types/DoubleType.d.ts +10 -5
- package/dist/types/DoubleType.js +25 -18
- package/dist/types/DoubleType.js.map +1 -1
- package/dist/types/DoubleType.spec.js +12 -4
- package/dist/types/DoubleType.spec.js.map +1 -1
- package/dist/types/DynamicType.d.ts +12 -5
- package/dist/types/DynamicType.js +22 -6
- 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 +40 -0
- package/dist/types/EnumType.js +80 -0
- package/dist/types/EnumType.js.map +1 -0
- 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 +10 -5
- package/dist/types/FloatType.js +25 -18
- package/dist/types/FloatType.js.map +1 -1
- package/dist/types/FloatType.spec.js +4 -4
- package/dist/types/FloatType.spec.js.map +1 -1
- package/dist/types/FunctionType.d.ts +10 -22
- package/dist/types/FunctionType.js +26 -63
- package/dist/types/FunctionType.js.map +1 -1
- package/dist/types/InheritableType.d.ts +28 -0
- package/dist/types/InheritableType.js +157 -0
- package/dist/types/InheritableType.js.map +1 -0
- package/dist/types/IntegerType.d.ts +10 -5
- package/dist/types/IntegerType.js +25 -18
- package/dist/types/IntegerType.js.map +1 -1
- package/dist/types/IntegerType.spec.js +8 -4
- package/dist/types/IntegerType.spec.js.map +1 -1
- package/dist/types/InterfaceType.d.ts +14 -6
- package/dist/types/InterfaceType.js +26 -15
- package/dist/types/InterfaceType.js.map +1 -1
- package/dist/types/InterfaceType.spec.d.ts +1 -0
- package/dist/types/InterfaceType.spec.js +227 -0
- package/dist/types/InterfaceType.spec.js.map +1 -0
- package/dist/types/InvalidType.d.ts +9 -5
- package/dist/types/InvalidType.js +20 -9
- package/dist/types/InvalidType.js.map +1 -1
- package/dist/types/InvalidType.spec.js +8 -4
- package/dist/types/InvalidType.spec.js.map +1 -1
- package/dist/types/LongIntegerType.d.ts +10 -5
- package/dist/types/LongIntegerType.js +25 -18
- package/dist/types/LongIntegerType.js.map +1 -1
- package/dist/types/LongIntegerType.spec.js +10 -4
- 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 +10 -5
- package/dist/types/ObjectType.js +23 -9
- 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 +71 -0
- package/dist/types/ReferenceType.js +467 -0
- package/dist/types/ReferenceType.js.map +1 -0
- package/dist/types/ReferenceType.spec.d.ts +1 -0
- package/dist/types/ReferenceType.spec.js +151 -0
- package/dist/types/ReferenceType.spec.js.map +1 -0
- package/dist/types/StringType.d.ts +13 -5
- package/dist/types/StringType.js +25 -9
- package/dist/types/StringType.js.map +1 -1
- package/dist/types/StringType.spec.js +3 -3
- package/dist/types/StringType.spec.js.map +1 -1
- package/dist/types/TypedFunctionType.d.ts +33 -0
- package/dist/types/TypedFunctionType.js +106 -0
- package/dist/types/TypedFunctionType.js.map +1 -0
- package/dist/types/TypedFunctionType.spec.d.ts +1 -0
- package/dist/types/TypedFunctionType.spec.js +122 -0
- package/dist/types/TypedFunctionType.spec.js.map +1 -0
- package/dist/types/UninitializedType.d.ts +8 -6
- package/dist/types/UninitializedType.js +15 -9
- package/dist/types/UninitializedType.js.map +1 -1
- package/dist/types/UnionType.d.ts +20 -0
- package/dist/types/UnionType.js +127 -0
- package/dist/types/UnionType.js.map +1 -0
- package/dist/types/UnionType.spec.d.ts +1 -0
- package/dist/types/UnionType.spec.js +129 -0
- package/dist/types/UnionType.spec.js.map +1 -0
- package/dist/types/VoidType.d.ts +10 -5
- package/dist/types/VoidType.js +20 -9
- 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 +144 -0
- package/dist/types/helper.spec.js.map +1 -0
- package/dist/types/helpers.d.ts +24 -0
- package/dist/types/helpers.js +178 -0
- package/dist/types/helpers.js.map +1 -0
- 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 +216 -106
- package/dist/util.js +1289 -319
- package/dist/util.js.map +1 -1
- package/dist/validators/ClassValidator.d.ts +9 -15
- package/dist/validators/ClassValidator.js +81 -134
- package/dist/validators/ClassValidator.js.map +1 -1
- package/package.json +169 -138
- package/dist/astUtils/index.d.ts +0 -7
- package/dist/astUtils/index.js +0 -26
- package/dist/astUtils/index.js.map +0 -1
- package/dist/lexer/index.d.ts +0 -3
- package/dist/lexer/index.js +0 -17
- package/dist/lexer/index.js.map +0 -1
- package/dist/parser/index.d.ts +0 -3
- package/dist/parser/index.js +0 -16
- package/dist/parser/index.js.map +0 -1
- package/dist/preprocessor/Chunk.d.ts +0 -82
- package/dist/preprocessor/Chunk.js +0 -77
- package/dist/preprocessor/Chunk.js.map +0 -1
- package/dist/preprocessor/Preprocessor.d.ts +0 -60
- package/dist/preprocessor/Preprocessor.js +0 -156
- package/dist/preprocessor/Preprocessor.js.map +0 -1
- package/dist/preprocessor/Preprocessor.spec.js +0 -152
- package/dist/preprocessor/Preprocessor.spec.js.map +0 -1
- package/dist/preprocessor/PreprocessorParser.d.ts +0 -61
- package/dist/preprocessor/PreprocessorParser.js +0 -194
- package/dist/preprocessor/PreprocessorParser.js.map +0 -1
- package/dist/preprocessor/PreprocessorParser.spec.js +0 -116
- package/dist/preprocessor/PreprocessorParser.spec.js.map +0 -1
- package/dist/preprocessor/index.d.ts +0 -3
- package/dist/preprocessor/index.js +0 -16
- package/dist/preprocessor/index.js.map +0 -1
- package/dist/types/CustomType.d.ts +0 -10
- package/dist/types/CustomType.js +0 -35
- package/dist/types/CustomType.js.map +0 -1
- package/dist/types/FunctionType.spec.js +0 -29
- package/dist/types/FunctionType.spec.js.map +0 -1
- package/dist/types/LazyType.d.ts +0 -15
- package/dist/types/LazyType.js +0 -32
- package/dist/types/LazyType.js.map +0 -1
- /package/dist/{preprocessor/Preprocessor.spec.d.ts → astUtils/Editor.spec.d.ts} +0 -0
- /package/dist/{preprocessor/PreprocessorParser.spec.d.ts → bscPlugin/completions/CompletionsProcessor.spec.d.ts} +0 -0
- /package/dist/{types/FunctionType.spec.d.ts → bscPlugin/definition/DefinitionProvider.spec.d.ts} +0 -0
package/dist/LanguageServer.js
CHANGED
|
@@ -6,39 +6,40 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
6
6
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
7
|
};
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.CustomCommands = exports.LanguageServer = void 0;
|
|
9
|
+
exports.NotificationName = exports.CustomCommands = exports.LanguageServer = void 0;
|
|
10
10
|
require("array-flat-polyfill");
|
|
11
|
-
const
|
|
11
|
+
const fastGlob = require("fast-glob");
|
|
12
12
|
const path = require("path");
|
|
13
|
-
const
|
|
14
|
-
const
|
|
13
|
+
const roku_deploy_1 = require("roku-deploy");
|
|
14
|
+
const node_1 = require("vscode-languageserver/node");
|
|
15
15
|
const vscode_uri_1 = require("vscode-uri");
|
|
16
16
|
const vscode_languageserver_textdocument_1 = require("vscode-languageserver-textdocument");
|
|
17
17
|
const deferred_1 = require("./deferred");
|
|
18
18
|
const DiagnosticMessages_1 = require("./DiagnosticMessages");
|
|
19
19
|
const ProgramBuilder_1 = require("./ProgramBuilder");
|
|
20
20
|
const util_1 = require("./util");
|
|
21
|
-
const Logger_1 = require("./Logger");
|
|
22
21
|
const Throttler_1 = require("./Throttler");
|
|
23
22
|
const KeyedThrottler_1 = require("./KeyedThrottler");
|
|
24
23
|
const DiagnosticCollection_1 = require("./DiagnosticCollection");
|
|
25
24
|
const reflection_1 = require("./astUtils/reflection");
|
|
25
|
+
const SemanticTokenUtils_1 = require("./SemanticTokenUtils");
|
|
26
|
+
const BusyStatusTracker_1 = require("./BusyStatusTracker");
|
|
27
|
+
const logging_1 = require("./logging");
|
|
26
28
|
class LanguageServer {
|
|
27
29
|
constructor() {
|
|
28
|
-
//cast undefined as any to get around strictNullChecks...it's ok in this case
|
|
29
30
|
this.connection = undefined;
|
|
30
|
-
this.
|
|
31
|
+
this.projects = [];
|
|
31
32
|
/**
|
|
32
33
|
* The number of milliseconds that should be used for language server typing debouncing
|
|
33
34
|
*/
|
|
34
35
|
this.debounceTimeout = 150;
|
|
35
36
|
/**
|
|
36
|
-
* These
|
|
37
|
-
* in any of the workspace projects.
|
|
38
|
-
* Basically these are single-file
|
|
37
|
+
* These projects are created on the fly whenever a file is opened that is not included
|
|
38
|
+
* in any of the workspace-based projects.
|
|
39
|
+
* Basically these are single-file projects to at least get parsing for standalone files.
|
|
39
40
|
* Also, they should only be created when the file is opened, and destroyed when the file is closed.
|
|
40
41
|
*/
|
|
41
|
-
this.
|
|
42
|
+
this.standaloneFileProjects = {};
|
|
42
43
|
this.hasConfigurationCapability = false;
|
|
43
44
|
/**
|
|
44
45
|
* Indicates whether the client supports workspace folders
|
|
@@ -48,14 +49,21 @@ class LanguageServer {
|
|
|
48
49
|
* Create a simple text document manager.
|
|
49
50
|
* The text document manager supports full document sync only
|
|
50
51
|
*/
|
|
51
|
-
this.documents = new
|
|
52
|
+
this.documents = new node_1.TextDocuments(vscode_languageserver_textdocument_1.TextDocument);
|
|
52
53
|
this.keyedThrottler = new KeyedThrottler_1.KeyedThrottler(this.debounceTimeout);
|
|
53
54
|
this.validateThrottler = new Throttler_1.Throttler(0);
|
|
55
|
+
this.sendDiagnosticsThrottler = new Throttler_1.Throttler(0);
|
|
54
56
|
this.boundValidateAll = this.validateAll.bind(this);
|
|
57
|
+
this.busyStatusTracker = new BusyStatusTracker_1.BusyStatusTracker();
|
|
58
|
+
this.busyStatusIndex = -1;
|
|
59
|
+
/**
|
|
60
|
+
* A unique project counter to help distinguish log entries in lsp mode
|
|
61
|
+
*/
|
|
62
|
+
this.projectCounter = 0;
|
|
55
63
|
this.diagnosticCollection = new DiagnosticCollection_1.DiagnosticCollection();
|
|
56
64
|
}
|
|
57
65
|
createConnection() {
|
|
58
|
-
return
|
|
66
|
+
return (0, node_1.createConnection)(node_1.ProposedFeatures.all);
|
|
59
67
|
}
|
|
60
68
|
validateAllThrottled() {
|
|
61
69
|
return this.validateThrottler.run(this.boundValidateAll);
|
|
@@ -65,9 +73,15 @@ class LanguageServer {
|
|
|
65
73
|
// Create a connection for the server. The connection uses Node's IPC as a transport.
|
|
66
74
|
// Also include all preview / proposed LSP features.
|
|
67
75
|
this.connection = this.createConnection();
|
|
76
|
+
// Send the current status of the busyStatusTracker anytime it changes
|
|
77
|
+
this.busyStatusTracker.on('change', (status) => {
|
|
78
|
+
void this.sendBusyStatus(status);
|
|
79
|
+
});
|
|
80
|
+
//disable logger colors when running in LSP mode
|
|
81
|
+
logging_1.logger.enableColor = false;
|
|
68
82
|
//listen to all of the output log events and pipe them into the debug channel in the extension
|
|
69
|
-
this.loggerSubscription =
|
|
70
|
-
this.connection.tracer.log(
|
|
83
|
+
this.loggerSubscription = logging_1.logger.subscribe((message) => {
|
|
84
|
+
this.connection.tracer.log(message.argsText);
|
|
71
85
|
});
|
|
72
86
|
this.connection.onInitialize(this.onInitialize.bind(this));
|
|
73
87
|
this.connection.onInitialized(this.onInitialized.bind(this)); //eslint-disable-line
|
|
@@ -77,17 +91,11 @@ class LanguageServer {
|
|
|
77
91
|
// when the text document is first opened, when its content has changed,
|
|
78
92
|
// or when document is closed without saving (original contents are sent as a change)
|
|
79
93
|
//
|
|
80
|
-
this.documents.onDidChangeContent(
|
|
81
|
-
await this.validateTextDocument(change.document);
|
|
82
|
-
});
|
|
94
|
+
this.documents.onDidChangeContent(this.validateTextDocument.bind(this));
|
|
83
95
|
//whenever a document gets closed
|
|
84
|
-
this.documents.onDidClose(
|
|
85
|
-
await this.onDocumentClose(change.document);
|
|
86
|
-
});
|
|
96
|
+
this.documents.onDidClose(this.onDocumentClose.bind(this));
|
|
87
97
|
// This handler provides the initial list of the completion items.
|
|
88
|
-
this.connection.onCompletion(
|
|
89
|
-
return this.onCompletion(params.textDocument.uri, params.position);
|
|
90
|
-
});
|
|
98
|
+
this.connection.onCompletion(this.onCompletion.bind(this));
|
|
91
99
|
// This handler resolves additional information for the item selected in
|
|
92
100
|
// the completion list.
|
|
93
101
|
this.connection.onCompletionResolve(this.onCompletionResolve.bind(this));
|
|
@@ -99,6 +107,8 @@ class LanguageServer {
|
|
|
99
107
|
this.connection.onSignatureHelp(this.onSignatureHelp.bind(this));
|
|
100
108
|
this.connection.onReferences(this.onReferences.bind(this));
|
|
101
109
|
this.connection.onCodeAction(this.onCodeAction.bind(this));
|
|
110
|
+
//TODO switch to a more specific connection function call once they actually add it
|
|
111
|
+
this.connection.onRequest(node_1.SemanticTokensRequest.method, this.onFullSemanticTokens.bind(this));
|
|
102
112
|
/*
|
|
103
113
|
this.connection.onDidOpenTextDocument((params) => {
|
|
104
114
|
// A text document got opened in VSCode.
|
|
@@ -123,9 +133,17 @@ class LanguageServer {
|
|
|
123
133
|
// Listen on the connection
|
|
124
134
|
this.connection.listen();
|
|
125
135
|
}
|
|
136
|
+
async sendBusyStatus(status) {
|
|
137
|
+
this.busyStatusIndex = ++this.busyStatusIndex <= 0 ? 0 : this.busyStatusIndex;
|
|
138
|
+
await this.connection.sendNotification(NotificationName.busyStatus, {
|
|
139
|
+
status: status,
|
|
140
|
+
timestamp: Date.now(),
|
|
141
|
+
index: this.busyStatusIndex,
|
|
142
|
+
activeRuns: [...this.busyStatusTracker.activeRuns]
|
|
143
|
+
});
|
|
144
|
+
}
|
|
126
145
|
/**
|
|
127
146
|
* Called when the client starts initialization
|
|
128
|
-
* @param params
|
|
129
147
|
*/
|
|
130
148
|
onInitialize(params) {
|
|
131
149
|
let clientCapabilities = params.capabilities;
|
|
@@ -136,7 +154,7 @@ class LanguageServer {
|
|
|
136
154
|
//return the capabilities of the server
|
|
137
155
|
return {
|
|
138
156
|
capabilities: {
|
|
139
|
-
textDocumentSync:
|
|
157
|
+
textDocumentSync: node_1.TextDocumentSyncKind.Full,
|
|
140
158
|
// Tell the client that the server supports code completion
|
|
141
159
|
completionProvider: {
|
|
142
160
|
resolveProvider: true,
|
|
@@ -146,9 +164,13 @@ class LanguageServer {
|
|
|
146
164
|
},
|
|
147
165
|
documentSymbolProvider: true,
|
|
148
166
|
workspaceSymbolProvider: true,
|
|
167
|
+
semanticTokensProvider: {
|
|
168
|
+
legend: SemanticTokenUtils_1.semanticTokensLegend,
|
|
169
|
+
full: true
|
|
170
|
+
},
|
|
149
171
|
referencesProvider: true,
|
|
150
172
|
codeActionProvider: {
|
|
151
|
-
codeActionKinds: [
|
|
173
|
+
codeActionKinds: [node_1.CodeActionKind.Refactor]
|
|
152
174
|
},
|
|
153
175
|
signatureHelpProvider: {
|
|
154
176
|
triggerCharacters: ['(', ',']
|
|
@@ -163,46 +185,146 @@ class LanguageServer {
|
|
|
163
185
|
}
|
|
164
186
|
};
|
|
165
187
|
}
|
|
188
|
+
/**
|
|
189
|
+
* Ask the client for the list of `files.exclude` patterns. Useful when determining if we should process a file
|
|
190
|
+
*/
|
|
191
|
+
async getWorkspaceExcludeGlobs(workspaceFolder) {
|
|
192
|
+
var _a;
|
|
193
|
+
let config = {
|
|
194
|
+
exclude: {}
|
|
195
|
+
};
|
|
196
|
+
//if supported, ask vscode for the `files.exclude` configuration
|
|
197
|
+
if (this.hasConfigurationCapability) {
|
|
198
|
+
//get any `files.exclude` globs to use to filter
|
|
199
|
+
config = await this.connection.workspace.getConfiguration({
|
|
200
|
+
scopeUri: workspaceFolder,
|
|
201
|
+
section: 'files'
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
return Object
|
|
205
|
+
.keys((_a = config === null || config === void 0 ? void 0 : config.exclude) !== null && _a !== void 0 ? _a : {})
|
|
206
|
+
.filter(x => { var _a; return (_a = config === null || config === void 0 ? void 0 : config.exclude) === null || _a === void 0 ? void 0 : _a[x]; })
|
|
207
|
+
//vscode files.exclude patterns support ignoring folders without needing to add `**/*`. So for our purposes, we need to
|
|
208
|
+
//append **/* to everything without a file extension or magic at the end
|
|
209
|
+
.map(pattern => [
|
|
210
|
+
//send the pattern as-is (this handles weird cases and exact file matches)
|
|
211
|
+
pattern,
|
|
212
|
+
//treat the pattern as a directory (no harm in doing this because if it's a file, the pattern will just never match anything)
|
|
213
|
+
`${pattern}/**/*`
|
|
214
|
+
])
|
|
215
|
+
.flat(1)
|
|
216
|
+
.concat([
|
|
217
|
+
//always ignore projects from node_modules
|
|
218
|
+
'**/node_modules/**/*'
|
|
219
|
+
]);
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Scan the workspace for all `bsconfig.json` files. If at least one is found, then only folders who have bsconfig.json are returned.
|
|
223
|
+
* If none are found, then the workspaceFolder itself is treated as a project
|
|
224
|
+
*/
|
|
225
|
+
async getProjectPaths(workspaceFolder) {
|
|
226
|
+
const excludes = (await this.getWorkspaceExcludeGlobs(workspaceFolder)).map(x => (0, util_1.standardizePath) `!${x}`);
|
|
227
|
+
const files = await roku_deploy_1.rokuDeploy.getFilePaths([
|
|
228
|
+
'**/bsconfig.json',
|
|
229
|
+
//exclude all files found in `files.exclude`
|
|
230
|
+
...excludes
|
|
231
|
+
], workspaceFolder);
|
|
232
|
+
//if we found at least one bsconfig.json, then ALL projects must have a bsconfig.json.
|
|
233
|
+
if (files.length > 0) {
|
|
234
|
+
return files.map(file => (0, util_1.standardizePath) `${path.dirname(file.src)}`);
|
|
235
|
+
}
|
|
236
|
+
//look for roku project folders
|
|
237
|
+
const rokuLikeDirs = (await Promise.all(
|
|
238
|
+
//find all folders containing a `manifest` file
|
|
239
|
+
(await roku_deploy_1.rokuDeploy.getFilePaths([
|
|
240
|
+
'**/manifest',
|
|
241
|
+
...excludes
|
|
242
|
+
//is there at least one .bs|.brs file under the `/source` folder?
|
|
243
|
+
], workspaceFolder)).map(async (manifestEntry) => {
|
|
244
|
+
const manifestDir = path.dirname(manifestEntry.src);
|
|
245
|
+
const files = await roku_deploy_1.rokuDeploy.getFilePaths([
|
|
246
|
+
'source/**/*.{brs,bs}',
|
|
247
|
+
...excludes
|
|
248
|
+
], manifestDir);
|
|
249
|
+
if (files.length > 0) {
|
|
250
|
+
return manifestDir;
|
|
251
|
+
}
|
|
252
|
+
})
|
|
253
|
+
//throw out nulls
|
|
254
|
+
)).filter(x => !!x);
|
|
255
|
+
if (rokuLikeDirs.length > 0) {
|
|
256
|
+
return rokuLikeDirs;
|
|
257
|
+
}
|
|
258
|
+
//treat the workspace folder as a brightscript project itself
|
|
259
|
+
return [workspaceFolder];
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Find all folders with bsconfig.json files in them, and treat each as a project.
|
|
263
|
+
* Treat workspaces that don't have a bsconfig.json as a project.
|
|
264
|
+
* Handle situations where bsconfig.json files were added or removed (to elevate/lower workspaceFolder projects accordingly)
|
|
265
|
+
* Leave existing projects alone if they are not affected by these changes
|
|
266
|
+
*/
|
|
267
|
+
async syncProjects() {
|
|
268
|
+
const workspacePaths = await this.getWorkspacePaths();
|
|
269
|
+
let projectPaths = (await Promise.all(workspacePaths.map(async (workspacePath) => {
|
|
270
|
+
const projectPaths = await this.getProjectPaths(workspacePath);
|
|
271
|
+
return projectPaths.map(projectPath => ({
|
|
272
|
+
projectPath: projectPath,
|
|
273
|
+
workspacePath: workspacePath
|
|
274
|
+
}));
|
|
275
|
+
}))).flat(1);
|
|
276
|
+
//delete projects not represented in the list
|
|
277
|
+
for (const project of this.getProjects()) {
|
|
278
|
+
if (!projectPaths.find(x => x.projectPath === project.projectPath)) {
|
|
279
|
+
this.removeProject(project);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
//exclude paths to projects we already have
|
|
283
|
+
projectPaths = projectPaths.filter(x => {
|
|
284
|
+
//only keep this project path if there's not a project with that path
|
|
285
|
+
return !this.projects.find(project => project.projectPath === x.projectPath);
|
|
286
|
+
});
|
|
287
|
+
//dedupe by project path
|
|
288
|
+
projectPaths = [
|
|
289
|
+
...projectPaths.reduce((acc, x) => acc.set(x.projectPath, x), new Map()).values()
|
|
290
|
+
];
|
|
291
|
+
//create missing projects
|
|
292
|
+
await Promise.all(projectPaths.map(x => this.createProject(x.projectPath, x.workspacePath)));
|
|
293
|
+
//flush diagnostics
|
|
294
|
+
await this.sendDiagnostics();
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Get all workspace paths from the client
|
|
298
|
+
*/
|
|
299
|
+
async getWorkspacePaths() {
|
|
300
|
+
var _a;
|
|
301
|
+
let workspaceFolders = (_a = await this.connection.workspace.getWorkspaceFolders()) !== null && _a !== void 0 ? _a : [];
|
|
302
|
+
return workspaceFolders.map((x) => {
|
|
303
|
+
return util_1.util.uriToPath(x.uri);
|
|
304
|
+
});
|
|
305
|
+
}
|
|
166
306
|
/**
|
|
167
307
|
* Called when the client has finished initializing
|
|
168
|
-
* @param params
|
|
169
308
|
*/
|
|
170
309
|
async onInitialized() {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
this.initialWorkspacesCreated = workspaceCreatedDeferred.promise;
|
|
310
|
+
let projectCreatedDeferred = new deferred_1.Deferred();
|
|
311
|
+
this.initialProjectsCreated = projectCreatedDeferred.promise;
|
|
174
312
|
try {
|
|
175
313
|
if (this.hasConfigurationCapability) {
|
|
176
314
|
// Register for all configuration changes.
|
|
177
|
-
await this.connection.client.register(
|
|
315
|
+
await this.connection.client.register(node_1.DidChangeConfigurationNotification.type, undefined);
|
|
178
316
|
}
|
|
179
|
-
|
|
180
|
-
let workspaceFolders = (_a = await this.connection.workspace.getWorkspaceFolders()) !== null && _a !== void 0 ? _a : [];
|
|
181
|
-
let workspacePaths = workspaceFolders.map((x) => {
|
|
182
|
-
return util_1.util.uriToPath(x.uri);
|
|
183
|
-
});
|
|
184
|
-
await this.createWorkspaces(workspacePaths);
|
|
317
|
+
await this.syncProjects();
|
|
185
318
|
if (this.clientHasWorkspaceFolderCapability) {
|
|
186
319
|
this.connection.workspace.onDidChangeWorkspaceFolders(async (evt) => {
|
|
187
|
-
|
|
188
|
-
for (let removed of evt.removed) {
|
|
189
|
-
let workspacePath = util_1.util.uriToPath(removed.uri);
|
|
190
|
-
let workspace = this.workspaces.find((x) => x.workspacePath === workspacePath);
|
|
191
|
-
if (workspace) {
|
|
192
|
-
workspace.builder.dispose();
|
|
193
|
-
this.workspaces.splice(this.workspaces.indexOf(workspace), 1);
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
//create programs for new workspace folders
|
|
197
|
-
await this.createWorkspaces(evt.added.map((x) => util_1.util.uriToPath(x.uri)));
|
|
320
|
+
await this.syncProjects();
|
|
198
321
|
});
|
|
199
322
|
}
|
|
200
|
-
await this.
|
|
201
|
-
|
|
202
|
-
await this.sendDiagnostics();
|
|
323
|
+
await this.waitAllProjectFirstRuns(false);
|
|
324
|
+
projectCreatedDeferred.resolve();
|
|
203
325
|
}
|
|
204
326
|
catch (e) {
|
|
205
|
-
this.sendCriticalFailure(`Critical failure during BrighterScript language server startup.
|
|
327
|
+
await this.sendCriticalFailure(`Critical failure during BrighterScript language server startup.
|
|
206
328
|
Please file a github issue and include the contents of the 'BrighterScript Language Server' output channel.
|
|
207
329
|
|
|
208
330
|
Error message: ${e.message}`);
|
|
@@ -212,39 +334,28 @@ class LanguageServer {
|
|
|
212
334
|
/**
|
|
213
335
|
* Send a critical failure notification to the client, which should show a notification of some kind
|
|
214
336
|
*/
|
|
215
|
-
sendCriticalFailure(message) {
|
|
216
|
-
this.connection.sendNotification('critical-failure', message);
|
|
337
|
+
async sendCriticalFailure(message) {
|
|
338
|
+
await this.connection.sendNotification('critical-failure', message);
|
|
217
339
|
}
|
|
218
340
|
/**
|
|
219
341
|
* Wait for all programs' first run to complete
|
|
220
342
|
*/
|
|
221
|
-
async
|
|
222
|
-
if (
|
|
223
|
-
await this.
|
|
343
|
+
async waitAllProjectFirstRuns(waitForFirstProject = true) {
|
|
344
|
+
if (waitForFirstProject) {
|
|
345
|
+
await this.initialProjectsCreated;
|
|
224
346
|
}
|
|
225
|
-
let
|
|
226
|
-
let workspaces = this.getWorkspaces();
|
|
227
|
-
for (let workspace of workspaces) {
|
|
347
|
+
for (let project of this.getProjects()) {
|
|
228
348
|
try {
|
|
229
|
-
await
|
|
349
|
+
await project.firstRunPromise;
|
|
230
350
|
}
|
|
231
351
|
catch (e) {
|
|
232
352
|
status = 'critical-error';
|
|
233
353
|
//the first run failed...that won't change unless we reload the workspace, so replace with resolved promise
|
|
234
354
|
//so we don't show this error again
|
|
235
|
-
|
|
236
|
-
this.sendCriticalFailure(`BrighterScript language server failed to start: \n${e.message}`);
|
|
355
|
+
project.firstRunPromise = Promise.resolve();
|
|
356
|
+
await this.sendCriticalFailure(`BrighterScript language server failed to start: \n${e.message}`);
|
|
237
357
|
}
|
|
238
358
|
}
|
|
239
|
-
this.connection.sendNotification('build-status', status ? status : 'success');
|
|
240
|
-
}
|
|
241
|
-
/**
|
|
242
|
-
* Create project for each new workspace. If the workspace is already known,
|
|
243
|
-
* it is skipped.
|
|
244
|
-
* @param workspaceFolders
|
|
245
|
-
*/
|
|
246
|
-
async createWorkspaces(workspacePaths) {
|
|
247
|
-
return Promise.all(workspacePaths.map(async (workspacePath) => this.createWorkspace(workspacePath)));
|
|
248
359
|
}
|
|
249
360
|
/**
|
|
250
361
|
* Event handler for when the program wants to load file contents.
|
|
@@ -265,11 +376,16 @@ class LanguageServer {
|
|
|
265
376
|
else {
|
|
266
377
|
scopeUri = vscode_uri_1.URI.file(workspacePath).toString();
|
|
267
378
|
}
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
379
|
+
let config = {
|
|
380
|
+
configFile: undefined
|
|
381
|
+
};
|
|
382
|
+
//if the client supports configuration, look for config group called "brightscript"
|
|
383
|
+
if (this.hasConfigurationCapability) {
|
|
384
|
+
config = await this.connection.workspace.getConfiguration({
|
|
385
|
+
scopeUri: scopeUri,
|
|
386
|
+
section: 'brightscript'
|
|
387
|
+
});
|
|
388
|
+
}
|
|
273
389
|
let configFilePath;
|
|
274
390
|
//if there's a setting, we need to find the file or show error if it can't be found
|
|
275
391
|
if (config === null || config === void 0 ? void 0 : config.configFile) {
|
|
@@ -278,7 +394,7 @@ class LanguageServer {
|
|
|
278
394
|
return configFilePath;
|
|
279
395
|
}
|
|
280
396
|
else {
|
|
281
|
-
this.sendCriticalFailure(`Cannot find config file specified in user/workspace settings at '${configFilePath}'`);
|
|
397
|
+
await this.sendCriticalFailure(`Cannot find config file specified in user / workspace settings at '${configFilePath}'`);
|
|
282
398
|
}
|
|
283
399
|
}
|
|
284
400
|
//default to config file path found in the root of the workspace
|
|
@@ -294,19 +410,35 @@ class LanguageServer {
|
|
|
294
410
|
//no config file could be found
|
|
295
411
|
return undefined;
|
|
296
412
|
}
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
413
|
+
/**
|
|
414
|
+
* @param projectPath path to the project
|
|
415
|
+
* @param workspacePath path to the workspace in which all project should reside or are referenced by
|
|
416
|
+
* @param projectNumber an optional project number to assign to the project. Used when reloading projects that should keep the same number
|
|
417
|
+
*/
|
|
418
|
+
async createProject(projectPath, workspacePath = projectPath, projectNumber) {
|
|
419
|
+
workspacePath !== null && workspacePath !== void 0 ? workspacePath : (workspacePath = projectPath);
|
|
420
|
+
let project = this.projects.find((x) => x.projectPath === projectPath);
|
|
421
|
+
//skip this project if we already have it
|
|
422
|
+
if (project) {
|
|
301
423
|
return;
|
|
302
424
|
}
|
|
303
425
|
let builder = new ProgramBuilder_1.ProgramBuilder();
|
|
426
|
+
projectNumber !== null && projectNumber !== void 0 ? projectNumber : (projectNumber = this.projectCounter++);
|
|
427
|
+
builder.logger.prefix = `[prj${projectNumber}]`;
|
|
428
|
+
builder.logger.log(`Created project #${projectNumber} for: "${projectPath}"`);
|
|
429
|
+
//flush diagnostics every time the program finishes validating
|
|
430
|
+
builder.plugins.add({
|
|
431
|
+
name: 'bsc-language-server',
|
|
432
|
+
afterProgramValidate: () => {
|
|
433
|
+
void this.sendDiagnostics();
|
|
434
|
+
}
|
|
435
|
+
});
|
|
304
436
|
//prevent clearing the console on run...this isn't the CLI so we want to keep a full log of everything
|
|
305
437
|
builder.allowConsoleClearing = false;
|
|
306
438
|
//look for files in our in-memory cache before going to the file system
|
|
307
439
|
builder.addFileResolver(this.documentFileResolver.bind(this));
|
|
308
|
-
let configFilePath = await this.getConfigFilePath(
|
|
309
|
-
let cwd =
|
|
440
|
+
let configFilePath = await this.getConfigFilePath(projectPath);
|
|
441
|
+
let cwd = projectPath;
|
|
310
442
|
//if the config file exists, use it and its folder as cwd
|
|
311
443
|
if (configFilePath && await util_1.util.pathExists(configFilePath)) {
|
|
312
444
|
cwd = path.dirname(configFilePath);
|
|
@@ -315,49 +447,49 @@ class LanguageServer {
|
|
|
315
447
|
//config file doesn't exist...let `brighterscript` resolve the default way
|
|
316
448
|
configFilePath = undefined;
|
|
317
449
|
}
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
watch: false,
|
|
322
|
-
createPackage: false,
|
|
323
|
-
deploy: false,
|
|
324
|
-
copyToStaging: false,
|
|
325
|
-
showDiagnosticsInConsole: false
|
|
326
|
-
});
|
|
327
|
-
firstRunPromise.catch((err) => {
|
|
328
|
-
console.error(err);
|
|
329
|
-
});
|
|
330
|
-
let newWorkspace = {
|
|
450
|
+
const firstRunDeferred = new deferred_1.Deferred();
|
|
451
|
+
let newProject = {
|
|
452
|
+
projectNumber: projectNumber,
|
|
331
453
|
builder: builder,
|
|
332
|
-
firstRunPromise:
|
|
454
|
+
firstRunPromise: firstRunDeferred.promise,
|
|
455
|
+
projectPath: projectPath,
|
|
333
456
|
workspacePath: workspacePath,
|
|
334
457
|
isFirstRunComplete: false,
|
|
335
458
|
isFirstRunSuccessful: false,
|
|
336
459
|
configFilePath: configFilePath,
|
|
337
|
-
|
|
460
|
+
isStandaloneFileProject: false
|
|
338
461
|
};
|
|
339
|
-
this.
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
462
|
+
this.projects.push(newProject);
|
|
463
|
+
try {
|
|
464
|
+
await builder.run({
|
|
465
|
+
cwd: cwd,
|
|
466
|
+
project: configFilePath,
|
|
467
|
+
watch: false,
|
|
468
|
+
createPackage: false,
|
|
469
|
+
deploy: false,
|
|
470
|
+
copyToStaging: false,
|
|
471
|
+
showDiagnosticsInConsole: false
|
|
472
|
+
});
|
|
473
|
+
newProject.isFirstRunComplete = true;
|
|
474
|
+
newProject.isFirstRunSuccessful = true;
|
|
475
|
+
firstRunDeferred.resolve();
|
|
476
|
+
}
|
|
477
|
+
catch (e) {
|
|
478
|
+
builder.logger.error(e);
|
|
479
|
+
firstRunDeferred.reject(e);
|
|
480
|
+
newProject.isFirstRunComplete = true;
|
|
481
|
+
newProject.isFirstRunSuccessful = false;
|
|
482
|
+
}
|
|
483
|
+
//if we found a deprecated brsconfig.json, add a diagnostic warning the user
|
|
484
|
+
if (configFilePath && path.basename(configFilePath) === 'brsconfig.json') {
|
|
485
|
+
builder.addDiagnostic(configFilePath, Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.brsConfigJsonIsDeprecated()), { range: util_1.util.createRange(0, 0, 0, 0) }));
|
|
486
|
+
return this.sendDiagnostics();
|
|
487
|
+
}
|
|
353
488
|
}
|
|
354
|
-
|
|
355
|
-
* @param srcPath The absolute path to the source file on disk
|
|
356
|
-
*/
|
|
357
|
-
async createStandaloneFileWorkspace(srcPath) {
|
|
489
|
+
async createStandaloneFileProject(srcPath) {
|
|
358
490
|
//skip this workspace if we already have it
|
|
359
|
-
if (this.
|
|
360
|
-
return this.
|
|
491
|
+
if (this.standaloneFileProjects[srcPath]) {
|
|
492
|
+
return this.standaloneFileProjects[srcPath];
|
|
361
493
|
}
|
|
362
494
|
let builder = new ProgramBuilder_1.ProgramBuilder();
|
|
363
495
|
//prevent clearing the console on run...this isn't the CLI so we want to keep a full log of everything
|
|
@@ -384,53 +516,61 @@ class LanguageServer {
|
|
|
384
516
|
] })).catch((err) => {
|
|
385
517
|
console.error(err);
|
|
386
518
|
});
|
|
387
|
-
let
|
|
519
|
+
let newProject = {
|
|
520
|
+
projectNumber: this.projectCounter++,
|
|
388
521
|
builder: builder,
|
|
389
522
|
firstRunPromise: firstRunPromise,
|
|
523
|
+
projectPath: srcPath,
|
|
390
524
|
workspacePath: srcPath,
|
|
391
525
|
isFirstRunComplete: false,
|
|
392
526
|
isFirstRunSuccessful: false,
|
|
393
527
|
configFilePath: configFilePath,
|
|
394
|
-
|
|
528
|
+
isStandaloneFileProject: true
|
|
395
529
|
};
|
|
396
|
-
this.
|
|
530
|
+
this.standaloneFileProjects[srcPath] = newProject;
|
|
397
531
|
await firstRunPromise.then(() => {
|
|
398
|
-
|
|
399
|
-
|
|
532
|
+
newProject.isFirstRunComplete = true;
|
|
533
|
+
newProject.isFirstRunSuccessful = true;
|
|
400
534
|
}).catch(() => {
|
|
401
|
-
|
|
402
|
-
|
|
535
|
+
newProject.isFirstRunComplete = true;
|
|
536
|
+
newProject.isFirstRunSuccessful = false;
|
|
403
537
|
});
|
|
404
|
-
return
|
|
538
|
+
return newProject;
|
|
405
539
|
}
|
|
406
|
-
|
|
407
|
-
let
|
|
408
|
-
for (let key in this.
|
|
409
|
-
|
|
540
|
+
getProjects() {
|
|
541
|
+
let projects = this.projects.slice();
|
|
542
|
+
for (let key in this.standaloneFileProjects) {
|
|
543
|
+
projects.push(this.standaloneFileProjects[key]);
|
|
410
544
|
}
|
|
411
|
-
return
|
|
545
|
+
return projects;
|
|
412
546
|
}
|
|
413
547
|
/**
|
|
414
548
|
* Provide a list of completion items based on the current cursor position
|
|
415
|
-
* @param textDocumentPosition
|
|
416
549
|
*/
|
|
417
|
-
async onCompletion(
|
|
550
|
+
async onCompletion(params) {
|
|
418
551
|
//ensure programs are initialized
|
|
419
|
-
await this.
|
|
420
|
-
let filePath = util_1.util.uriToPath(uri);
|
|
552
|
+
await this.waitAllProjectFirstRuns();
|
|
553
|
+
let filePath = util_1.util.uriToPath(params.textDocument.uri);
|
|
421
554
|
//wait until the file has settled
|
|
422
555
|
await this.keyedThrottler.onIdleOnce(filePath, true);
|
|
556
|
+
// make sure validation is complete
|
|
557
|
+
await this.validateAllThrottled();
|
|
558
|
+
//wait for the validation cycle to settle
|
|
559
|
+
await this.onValidateSettled();
|
|
423
560
|
let completions = this
|
|
424
|
-
.
|
|
425
|
-
.flatMap(workspace => workspace.builder.program.getCompletions(filePath, position));
|
|
561
|
+
.getProjects()
|
|
562
|
+
.flatMap(workspace => workspace.builder.program.getCompletions(filePath, params.position));
|
|
563
|
+
//only send one completion if name and type are the same
|
|
564
|
+
let completionsMap = new Map();
|
|
426
565
|
for (let completion of completions) {
|
|
427
566
|
completion.commitCharacters = ['.'];
|
|
567
|
+
let key = `${completion.sortText}-${completion.label}-${completion.kind}`;
|
|
568
|
+
completionsMap.set(key, completion);
|
|
428
569
|
}
|
|
429
|
-
return
|
|
570
|
+
return [...completionsMap.values()];
|
|
430
571
|
}
|
|
431
572
|
/**
|
|
432
573
|
* Provide a full completion item from the selection
|
|
433
|
-
* @param item
|
|
434
574
|
*/
|
|
435
575
|
onCompletionResolve(item) {
|
|
436
576
|
if (item.data === 1) {
|
|
@@ -444,57 +584,62 @@ class LanguageServer {
|
|
|
444
584
|
return item;
|
|
445
585
|
}
|
|
446
586
|
async onCodeAction(params) {
|
|
587
|
+
var _a;
|
|
447
588
|
//ensure programs are initialized
|
|
448
|
-
await this.
|
|
589
|
+
await this.waitAllProjectFirstRuns();
|
|
449
590
|
let srcPath = util_1.util.uriToPath(params.textDocument.uri);
|
|
450
591
|
//wait until the file has settled
|
|
451
592
|
await this.keyedThrottler.onIdleOnce(srcPath, true);
|
|
452
593
|
const codeActions = this
|
|
453
|
-
.
|
|
594
|
+
.getProjects()
|
|
454
595
|
//skip programs that don't have this file
|
|
455
596
|
.filter(x => { var _a, _b; return (_b = (_a = x.builder) === null || _a === void 0 ? void 0 : _a.program) === null || _b === void 0 ? void 0 : _b.hasFile(srcPath); })
|
|
456
597
|
.flatMap(workspace => workspace.builder.program.getCodeActions(srcPath, params.range));
|
|
457
598
|
//clone the diagnostics for each code action, since certain diagnostics can have circular reference properties that kill the language server if serialized
|
|
458
599
|
for (const codeAction of codeActions) {
|
|
459
600
|
if (codeAction.diagnostics) {
|
|
460
|
-
codeAction.diagnostics = codeAction.diagnostics.map(x => util_1.util.toDiagnostic(x));
|
|
601
|
+
codeAction.diagnostics = (_a = codeAction.diagnostics) === null || _a === void 0 ? void 0 : _a.map(x => util_1.util.toDiagnostic(x, params.textDocument.uri));
|
|
461
602
|
}
|
|
462
603
|
}
|
|
463
604
|
return codeActions;
|
|
464
605
|
}
|
|
465
606
|
/**
|
|
466
|
-
*
|
|
607
|
+
* Remove a project from the language server
|
|
608
|
+
*/
|
|
609
|
+
removeProject(project) {
|
|
610
|
+
var _a;
|
|
611
|
+
const idx = this.projects.indexOf(project);
|
|
612
|
+
if (idx > -1) {
|
|
613
|
+
this.projects.splice(idx, 1);
|
|
614
|
+
}
|
|
615
|
+
(_a = project === null || project === void 0 ? void 0 : project.builder) === null || _a === void 0 ? void 0 : _a.dispose();
|
|
616
|
+
}
|
|
617
|
+
/**
|
|
618
|
+
* Reload each of the specified workspaces
|
|
467
619
|
*/
|
|
468
|
-
async
|
|
469
|
-
|
|
470
|
-
await Promise.all(workspaces.map(async (workspace) => {
|
|
620
|
+
async reloadProjects(projects) {
|
|
621
|
+
await Promise.all(projects.map(async (project) => {
|
|
471
622
|
//ensure the workspace has finished starting up
|
|
472
623
|
try {
|
|
473
|
-
await
|
|
624
|
+
await project.firstRunPromise;
|
|
474
625
|
}
|
|
475
626
|
catch (e) { }
|
|
476
627
|
//handle standard workspace
|
|
477
|
-
if (
|
|
478
|
-
|
|
479
|
-
if (idx > -1) {
|
|
480
|
-
//remove this workspace
|
|
481
|
-
this.workspaces.splice(idx, 1);
|
|
482
|
-
//dispose this workspace's resources
|
|
483
|
-
workspace.builder.dispose();
|
|
484
|
-
}
|
|
628
|
+
if (project.isStandaloneFileProject === false) {
|
|
629
|
+
this.removeProject(project);
|
|
485
630
|
//create a new workspace/brs program
|
|
486
|
-
await this.
|
|
631
|
+
await this.createProject(project.projectPath, project.workspacePath, project.projectNumber);
|
|
487
632
|
//handle temp workspace
|
|
488
633
|
}
|
|
489
634
|
else {
|
|
490
|
-
|
|
491
|
-
delete this.
|
|
492
|
-
await this.
|
|
635
|
+
project.builder.dispose();
|
|
636
|
+
delete this.standaloneFileProjects[project.projectPath];
|
|
637
|
+
await this.createStandaloneFileProject(project.projectPath);
|
|
493
638
|
}
|
|
494
639
|
}));
|
|
495
|
-
if (
|
|
640
|
+
if (projects.length > 0) {
|
|
496
641
|
//wait for all of the programs to finish starting up
|
|
497
|
-
await this.
|
|
642
|
+
await this.waitAllProjectFirstRuns();
|
|
498
643
|
// valdiate all workspaces
|
|
499
644
|
this.validateAllThrottled(); //eslint-disable-line
|
|
500
645
|
}
|
|
@@ -511,42 +656,42 @@ class LanguageServer {
|
|
|
511
656
|
*
|
|
512
657
|
* Sometimes files that used to be included are now excluded, so those open files need to be re-processed as standalone
|
|
513
658
|
*/
|
|
514
|
-
async
|
|
659
|
+
async synchronizeStandaloneProjects() {
|
|
515
660
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
516
661
|
//remove standalone workspaces that are now included in projects
|
|
517
|
-
for (let standaloneFilePath in this.
|
|
518
|
-
let
|
|
519
|
-
for (let
|
|
520
|
-
await
|
|
521
|
-
let dest = rokuDeploy.getDestPath(standaloneFilePath, (_d = (_c = (_b = (_a =
|
|
662
|
+
for (let standaloneFilePath in this.standaloneFileProjects) {
|
|
663
|
+
let standaloneProject = this.standaloneFileProjects[standaloneFilePath];
|
|
664
|
+
for (let project of this.projects) {
|
|
665
|
+
await standaloneProject.firstRunPromise;
|
|
666
|
+
let dest = roku_deploy_1.rokuDeploy.getDestPath(standaloneFilePath, (_d = (_c = (_b = (_a = project === null || project === void 0 ? void 0 : project.builder) === null || _a === void 0 ? void 0 : _a.program) === null || _b === void 0 ? void 0 : _b.options) === null || _c === void 0 ? void 0 : _c.files) !== null && _d !== void 0 ? _d : [], this.getRootDir(project));
|
|
522
667
|
//destroy this standalone workspace because the file has now been included in an actual workspace,
|
|
523
668
|
//or if the workspace wants the file
|
|
524
|
-
if (((_f = (_e =
|
|
525
|
-
|
|
526
|
-
delete this.
|
|
669
|
+
if (((_f = (_e = project === null || project === void 0 ? void 0 : project.builder) === null || _e === void 0 ? void 0 : _e.program) === null || _f === void 0 ? void 0 : _f.hasFile(standaloneFilePath)) || dest) {
|
|
670
|
+
standaloneProject.builder.dispose();
|
|
671
|
+
delete this.standaloneFileProjects[standaloneFilePath];
|
|
527
672
|
}
|
|
528
673
|
}
|
|
529
674
|
}
|
|
530
|
-
//create standalone
|
|
675
|
+
//create standalone projects for open files that no longer have a project
|
|
531
676
|
let textDocuments = this.documents.all();
|
|
532
677
|
outer: for (let textDocument of textDocuments) {
|
|
533
678
|
let filePath = vscode_uri_1.URI.parse(textDocument.uri).fsPath;
|
|
534
|
-
let
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
if (((_m = (_l = workspace === null || workspace === void 0 ? void 0 : workspace.builder) === null || _l === void 0 ? void 0 : _l.program) === null || _m === void 0 ? void 0 : _m.hasFile(filePath)) || dest) {
|
|
679
|
+
for (let project of this.getProjects()) {
|
|
680
|
+
let dest = roku_deploy_1.rokuDeploy.getDestPath(filePath, (_k = (_j = (_h = (_g = project === null || project === void 0 ? void 0 : project.builder) === null || _g === void 0 ? void 0 : _g.program) === null || _h === void 0 ? void 0 : _h.options) === null || _j === void 0 ? void 0 : _j.files) !== null && _k !== void 0 ? _k : [], this.getRootDir(project));
|
|
681
|
+
//if this project has the file, or it wants the file, do NOT make a standaloneProject for this file
|
|
682
|
+
if (((_m = (_l = project === null || project === void 0 ? void 0 : project.builder) === null || _l === void 0 ? void 0 : _l.program) === null || _m === void 0 ? void 0 : _m.hasFile(filePath)) || dest) {
|
|
539
683
|
continue outer;
|
|
540
684
|
}
|
|
541
685
|
}
|
|
542
686
|
//if we got here, no workspace has this file, so make a standalone file workspace
|
|
543
|
-
let
|
|
544
|
-
await
|
|
687
|
+
let project = await this.createStandaloneFileProject(filePath);
|
|
688
|
+
await project.firstRunPromise;
|
|
545
689
|
}
|
|
546
690
|
}
|
|
547
691
|
async onDidChangeConfiguration() {
|
|
548
692
|
if (this.hasConfigurationCapability) {
|
|
549
|
-
|
|
693
|
+
//if the user changes any config value, just mass-reload all projects
|
|
694
|
+
await this.reloadProjects(this.getProjects());
|
|
550
695
|
// Reset all cached document settings
|
|
551
696
|
}
|
|
552
697
|
else {
|
|
@@ -560,18 +705,16 @@ class LanguageServer {
|
|
|
560
705
|
* The CLIENT is in charge of what files to watch, so all client
|
|
561
706
|
* implementations should ensure that all valid project
|
|
562
707
|
* file types are watched (.brs,.bs,.xml,manifest, and any json/text/image files)
|
|
563
|
-
* @param params
|
|
564
708
|
*/
|
|
565
709
|
async onDidChangeWatchedFiles(params) {
|
|
566
710
|
//ensure programs are initialized
|
|
567
|
-
await this.
|
|
568
|
-
this.
|
|
569
|
-
let workspaces = this.getWorkspaces();
|
|
711
|
+
await this.waitAllProjectFirstRuns();
|
|
712
|
+
let projects = this.getProjects();
|
|
570
713
|
//convert all file paths to absolute paths
|
|
571
714
|
let changes = params.changes.map(x => {
|
|
572
715
|
return {
|
|
573
716
|
type: x.type,
|
|
574
|
-
srcPath: util_1.standardizePath `${vscode_uri_1.URI.parse(x.uri).fsPath}`
|
|
717
|
+
srcPath: (0, util_1.standardizePath) `${vscode_uri_1.URI.parse(x.uri).fsPath}`
|
|
575
718
|
};
|
|
576
719
|
});
|
|
577
720
|
let keys = changes.map(x => x.srcPath);
|
|
@@ -579,28 +722,32 @@ class LanguageServer {
|
|
|
579
722
|
changes = changes.filter(x => keys.includes(x.srcPath));
|
|
580
723
|
//if we have changes to work with
|
|
581
724
|
if (changes.length > 0) {
|
|
725
|
+
//if any bsconfig files were added or deleted, re-sync all projects instead of the more specific approach below
|
|
726
|
+
if (changes.find(x => (x.type === node_1.FileChangeType.Created || x.type === node_1.FileChangeType.Deleted) && path.basename(x.srcPath).toLowerCase() === 'bsconfig.json')) {
|
|
727
|
+
return this.syncProjects();
|
|
728
|
+
}
|
|
582
729
|
//reload any workspace whose bsconfig.json file has changed
|
|
583
730
|
{
|
|
584
|
-
let
|
|
731
|
+
let projectsToReload = [];
|
|
585
732
|
//get the file paths as a string array
|
|
586
733
|
let filePaths = changes.map((x) => x.srcPath);
|
|
587
|
-
for (let
|
|
588
|
-
if (
|
|
589
|
-
|
|
734
|
+
for (let project of projects) {
|
|
735
|
+
if (project.configFilePath && filePaths.includes(project.configFilePath)) {
|
|
736
|
+
projectsToReload.push(project);
|
|
590
737
|
}
|
|
591
738
|
}
|
|
592
|
-
if (
|
|
593
|
-
//vsc can generate a ton of these changes, for vsc system files, so we need to bail if there's no work to do on any of our actual
|
|
594
|
-
//reload any
|
|
595
|
-
await this.
|
|
739
|
+
if (projectsToReload.length > 0) {
|
|
740
|
+
//vsc can generate a ton of these changes, for vsc system files, so we need to bail if there's no work to do on any of our actual project files
|
|
741
|
+
//reload any projects that need to be reloaded
|
|
742
|
+
await this.reloadProjects(projectsToReload);
|
|
596
743
|
}
|
|
597
|
-
//
|
|
598
|
-
|
|
744
|
+
//reassign `projects` to the non-reloaded projects
|
|
745
|
+
projects = projects.filter(x => !projectsToReload.includes(x));
|
|
599
746
|
}
|
|
600
747
|
//convert created folders into a list of files of their contents
|
|
601
748
|
const directoryChanges = changes
|
|
602
749
|
//get only creation items
|
|
603
|
-
.filter(change => change.type ===
|
|
750
|
+
.filter(change => change.type === node_1.FileChangeType.Created)
|
|
604
751
|
//keep only the directories
|
|
605
752
|
.filter(change => util_1.util.isDirectorySync(change.srcPath));
|
|
606
753
|
//remove the created directories from the changes array (we will add back each of their files next)
|
|
@@ -613,56 +760,50 @@ class LanguageServer {
|
|
|
613
760
|
.filter(dirPath => !dirPath.includes('.roku-deploy-staging'))
|
|
614
761
|
//get the files for each folder recursively
|
|
615
762
|
.flatMap(dirPath => {
|
|
616
|
-
//
|
|
617
|
-
let
|
|
618
|
-
|
|
619
|
-
|
|
763
|
+
//look up all files
|
|
764
|
+
let files = fastGlob.sync('**/*', {
|
|
765
|
+
absolute: true,
|
|
766
|
+
cwd: roku_deploy_1.util.toForwardSlashes(dirPath)
|
|
620
767
|
});
|
|
621
768
|
return files.map(x => {
|
|
622
769
|
return {
|
|
623
|
-
type:
|
|
624
|
-
srcPath: util_1.standardizePath `${x}`
|
|
770
|
+
type: node_1.FileChangeType.Created,
|
|
771
|
+
srcPath: (0, util_1.standardizePath) `${x}`
|
|
625
772
|
};
|
|
626
773
|
});
|
|
627
774
|
});
|
|
628
775
|
//add the new file changes to the changes array.
|
|
629
776
|
changes.push(...newFileChanges);
|
|
630
777
|
//give every workspace the chance to handle file changes
|
|
631
|
-
await Promise.all(
|
|
778
|
+
await Promise.all(projects.map((project) => this.handleFileChanges(project, changes)));
|
|
632
779
|
}
|
|
633
|
-
this.connection.sendNotification('build-status', 'success');
|
|
634
780
|
}
|
|
635
781
|
/**
|
|
636
782
|
* This only operates on files that match the specified files globs, so it is safe to throw
|
|
637
783
|
* any file changes you receive with no unexpected side-effects
|
|
638
|
-
* @param changes
|
|
639
784
|
*/
|
|
640
|
-
async handleFileChanges(
|
|
785
|
+
async handleFileChanges(project, changes) {
|
|
641
786
|
//this loop assumes paths are both file paths and folder paths, which eliminates the need to detect.
|
|
642
787
|
//All functions below can handle being given a file path AND a folder path, and will only operate on the one they are looking for
|
|
643
|
-
let consumeCount = 0;
|
|
644
788
|
await Promise.all(changes.map(async (change) => {
|
|
645
789
|
await this.keyedThrottler.run(change.srcPath, async () => {
|
|
646
|
-
|
|
790
|
+
if (await this.handleFileChange(project, change)) {
|
|
791
|
+
await this.validateAllThrottled();
|
|
792
|
+
}
|
|
647
793
|
});
|
|
648
794
|
}));
|
|
649
|
-
if (consumeCount > 0) {
|
|
650
|
-
await this.validateAllThrottled();
|
|
651
|
-
}
|
|
652
795
|
}
|
|
653
796
|
/**
|
|
654
797
|
* This only operates on files that match the specified files globs, so it is safe to throw
|
|
655
798
|
* any file changes you receive with no unexpected side-effects
|
|
656
|
-
* @
|
|
799
|
+
* @returns true if the file was handled by this project, false if it was not
|
|
657
800
|
*/
|
|
658
|
-
async handleFileChange(
|
|
659
|
-
const program =
|
|
660
|
-
const options = workspace.builder.options;
|
|
661
|
-
const rootDir = workspace.builder.rootDir;
|
|
801
|
+
async handleFileChange(project, change) {
|
|
802
|
+
const { program, options, rootDir } = project.builder;
|
|
662
803
|
//deleted
|
|
663
|
-
if (change.type ===
|
|
804
|
+
if (change.type === node_1.FileChangeType.Deleted) {
|
|
664
805
|
//try to act on this path as a directory
|
|
665
|
-
|
|
806
|
+
project.builder.removeFilesInFolder(change.srcPath);
|
|
666
807
|
//if this is a file loaded in the program, remove it
|
|
667
808
|
if (program.hasFile(change.srcPath)) {
|
|
668
809
|
program.removeFile(change.srcPath);
|
|
@@ -673,16 +814,16 @@ class LanguageServer {
|
|
|
673
814
|
}
|
|
674
815
|
//created
|
|
675
816
|
}
|
|
676
|
-
else if (change.type ===
|
|
817
|
+
else if (change.type === node_1.FileChangeType.Created) {
|
|
677
818
|
// thanks to `onDidChangeWatchedFiles`, we can safely assume that all "Created" changes are file paths, (not directories)
|
|
678
819
|
//get the dest path for this file.
|
|
679
|
-
let destPath = rokuDeploy.getDestPath(change.srcPath, options.files, rootDir);
|
|
820
|
+
let destPath = roku_deploy_1.rokuDeploy.getDestPath(change.srcPath, options.files, rootDir);
|
|
680
821
|
//if we got a dest path, then the program wants this file
|
|
681
822
|
if (destPath) {
|
|
682
823
|
program.setFile({
|
|
683
824
|
src: change.srcPath,
|
|
684
|
-
dest: rokuDeploy.getDestPath(change.srcPath, options.files, rootDir)
|
|
685
|
-
}, await
|
|
825
|
+
dest: roku_deploy_1.rokuDeploy.getDestPath(change.srcPath, options.files, rootDir)
|
|
826
|
+
}, await project.builder.getFileContents(change.srcPath));
|
|
686
827
|
return true;
|
|
687
828
|
}
|
|
688
829
|
else {
|
|
@@ -697,8 +838,8 @@ class LanguageServer {
|
|
|
697
838
|
if (await util_1.util.pathExists(change.srcPath)) {
|
|
698
839
|
program.setFile({
|
|
699
840
|
src: change.srcPath,
|
|
700
|
-
dest: rokuDeploy.getDestPath(change.srcPath, options.files, rootDir)
|
|
701
|
-
}, await
|
|
841
|
+
dest: roku_deploy_1.rokuDeploy.getDestPath(change.srcPath, options.files, rootDir)
|
|
842
|
+
}, await project.builder.getFileContents(change.srcPath));
|
|
702
843
|
}
|
|
703
844
|
else {
|
|
704
845
|
program.removeFile(change.srcPath);
|
|
@@ -707,85 +848,100 @@ class LanguageServer {
|
|
|
707
848
|
}
|
|
708
849
|
}
|
|
709
850
|
async onHover(params) {
|
|
851
|
+
var _a;
|
|
710
852
|
//ensure programs are initialized
|
|
711
|
-
await this.
|
|
712
|
-
|
|
713
|
-
let
|
|
714
|
-
let hovers =
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
//
|
|
722
|
-
|
|
723
|
-
|
|
853
|
+
await this.waitAllProjectFirstRuns();
|
|
854
|
+
const srcPath = util_1.util.uriToPath(params.textDocument.uri);
|
|
855
|
+
let projects = this.getProjects();
|
|
856
|
+
let hovers = projects
|
|
857
|
+
//get hovers from all projects
|
|
858
|
+
.map((x) => x.builder.program.getHover(srcPath, params.position))
|
|
859
|
+
//flatten to a single list
|
|
860
|
+
.flat();
|
|
861
|
+
const contents = [
|
|
862
|
+
...(hovers !== null && hovers !== void 0 ? hovers : [])
|
|
863
|
+
//pull all hover contents out into a flag array of strings
|
|
864
|
+
.map(x => {
|
|
865
|
+
return Array.isArray(x === null || x === void 0 ? void 0 : x.contents) ? x === null || x === void 0 ? void 0 : x.contents : [x === null || x === void 0 ? void 0 : x.contents];
|
|
866
|
+
}).flat()
|
|
867
|
+
//remove nulls
|
|
868
|
+
.filter(x => !!x)
|
|
869
|
+
//dedupe hovers across all projects
|
|
870
|
+
.reduce((set, content) => set.add(content), new Set()).values()
|
|
871
|
+
];
|
|
872
|
+
if (contents.length > 0) {
|
|
873
|
+
let hover = {
|
|
874
|
+
//use the range from the first hover
|
|
875
|
+
range: (_a = hovers[0]) === null || _a === void 0 ? void 0 : _a.range,
|
|
876
|
+
//the contents of all hovers
|
|
877
|
+
contents: contents
|
|
724
878
|
};
|
|
879
|
+
return hover;
|
|
725
880
|
}
|
|
726
|
-
return hover;
|
|
727
881
|
}
|
|
728
|
-
async onDocumentClose(
|
|
729
|
-
|
|
730
|
-
let
|
|
882
|
+
async onDocumentClose(event) {
|
|
883
|
+
const { document } = event;
|
|
884
|
+
let filePath = vscode_uri_1.URI.parse(document.uri).fsPath;
|
|
885
|
+
let standaloneFileProject = this.standaloneFileProjects[filePath];
|
|
731
886
|
//if this was a temp file, close it
|
|
732
|
-
if (
|
|
733
|
-
await
|
|
734
|
-
|
|
735
|
-
delete this.
|
|
887
|
+
if (standaloneFileProject) {
|
|
888
|
+
await standaloneFileProject.firstRunPromise;
|
|
889
|
+
standaloneFileProject.builder.dispose();
|
|
890
|
+
delete this.standaloneFileProjects[filePath];
|
|
736
891
|
await this.sendDiagnostics();
|
|
737
892
|
}
|
|
738
893
|
}
|
|
739
|
-
async validateTextDocument(
|
|
894
|
+
async validateTextDocument(event) {
|
|
895
|
+
const { document } = event;
|
|
740
896
|
//ensure programs are initialized
|
|
741
|
-
await this.
|
|
742
|
-
let filePath = vscode_uri_1.URI.parse(
|
|
897
|
+
await this.waitAllProjectFirstRuns();
|
|
898
|
+
let filePath = vscode_uri_1.URI.parse(document.uri).fsPath;
|
|
743
899
|
try {
|
|
744
900
|
//throttle file processing. first call is run immediately, and then the last call is processed.
|
|
745
901
|
await this.keyedThrottler.run(filePath, () => {
|
|
746
902
|
var _a;
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
for (const workspace of this.getWorkspaces()) {
|
|
903
|
+
let documentText = document.getText();
|
|
904
|
+
for (const project of this.getProjects()) {
|
|
750
905
|
//only add or replace existing files. All of the files in the project should
|
|
751
906
|
//have already been loaded by other means
|
|
752
|
-
if (
|
|
753
|
-
let rootDir = (_a =
|
|
754
|
-
let dest = rokuDeploy.getDestPath(filePath,
|
|
755
|
-
|
|
907
|
+
if (project.builder.program.hasFile(filePath)) {
|
|
908
|
+
let rootDir = (_a = project.builder.program.options.rootDir) !== null && _a !== void 0 ? _a : project.builder.program.options.cwd;
|
|
909
|
+
let dest = roku_deploy_1.rokuDeploy.getDestPath(filePath, project.builder.program.options.files, rootDir);
|
|
910
|
+
project.builder.program.setFile({
|
|
756
911
|
src: filePath,
|
|
757
912
|
dest: dest
|
|
758
913
|
}, documentText);
|
|
759
914
|
}
|
|
760
915
|
}
|
|
761
916
|
});
|
|
762
|
-
// validate all
|
|
917
|
+
// validate all projects
|
|
763
918
|
await this.validateAllThrottled();
|
|
764
919
|
}
|
|
765
920
|
catch (e) {
|
|
766
|
-
this.sendCriticalFailure(`Critical error parsing/
|
|
921
|
+
await this.sendCriticalFailure(`Critical error parsing/validating ${filePath}: ${e.message}`);
|
|
767
922
|
}
|
|
768
923
|
}
|
|
769
924
|
async validateAll() {
|
|
770
925
|
var _a;
|
|
771
926
|
try {
|
|
772
927
|
//synchronize parsing for open files that were included/excluded from projects
|
|
773
|
-
await this.
|
|
774
|
-
let
|
|
928
|
+
await this.synchronizeStandaloneProjects();
|
|
929
|
+
let projects = this.getProjects();
|
|
775
930
|
//validate all programs
|
|
776
|
-
await Promise.all(
|
|
777
|
-
|
|
931
|
+
await Promise.all(projects.map((project) => {
|
|
932
|
+
project.builder.program.validate();
|
|
933
|
+
return project;
|
|
934
|
+
}));
|
|
778
935
|
}
|
|
779
936
|
catch (e) {
|
|
780
937
|
this.connection.console.error(e);
|
|
781
|
-
this.sendCriticalFailure(`Critical error validating
|
|
938
|
+
await this.sendCriticalFailure(`Critical error validating project: ${e.message}${(_a = e.stack) !== null && _a !== void 0 ? _a : ''}`);
|
|
782
939
|
}
|
|
783
|
-
this.connection.sendNotification('build-status', 'success');
|
|
784
940
|
}
|
|
785
941
|
async onWorkspaceSymbol(params) {
|
|
786
|
-
await this.
|
|
787
|
-
const results = util_1.util.flatMap(await Promise.all(this.
|
|
788
|
-
return
|
|
942
|
+
await this.waitAllProjectFirstRuns();
|
|
943
|
+
const results = util_1.util.flatMap(await Promise.all(this.getProjects().map(project => {
|
|
944
|
+
return project.builder.program.getWorkspaceSymbols();
|
|
789
945
|
})), c => c);
|
|
790
946
|
// Remove duplicates
|
|
791
947
|
const allSymbols = Object.values(results.reduce((map, symbol) => {
|
|
@@ -796,33 +952,33 @@ class LanguageServer {
|
|
|
796
952
|
return allSymbols;
|
|
797
953
|
}
|
|
798
954
|
async onDocumentSymbol(params) {
|
|
799
|
-
await this.
|
|
955
|
+
await this.waitAllProjectFirstRuns();
|
|
800
956
|
await this.keyedThrottler.onIdleOnce(util_1.util.uriToPath(params.textDocument.uri), true);
|
|
801
957
|
const srcPath = util_1.util.uriToPath(params.textDocument.uri);
|
|
802
|
-
for (const
|
|
803
|
-
const file =
|
|
804
|
-
if (reflection_1.isBrsFile(file)) {
|
|
958
|
+
for (const project of this.getProjects()) {
|
|
959
|
+
const file = project.builder.program.getFile(srcPath);
|
|
960
|
+
if ((0, reflection_1.isBrsFile)(file)) {
|
|
805
961
|
return file.getDocumentSymbols();
|
|
806
962
|
}
|
|
807
963
|
}
|
|
808
964
|
}
|
|
809
965
|
async onDefinition(params) {
|
|
810
|
-
await this.
|
|
966
|
+
await this.waitAllProjectFirstRuns();
|
|
811
967
|
const srcPath = util_1.util.uriToPath(params.textDocument.uri);
|
|
812
|
-
const results = util_1.util.flatMap(await Promise.all(this.
|
|
813
|
-
return
|
|
968
|
+
const results = util_1.util.flatMap(await Promise.all(this.getProjects().map(project => {
|
|
969
|
+
return project.builder.program.getDefinition(srcPath, params.position);
|
|
814
970
|
})), c => c);
|
|
815
971
|
return results;
|
|
816
972
|
}
|
|
817
973
|
async onSignatureHelp(params) {
|
|
818
974
|
var _a, _b, _c;
|
|
819
|
-
await this.
|
|
975
|
+
await this.waitAllProjectFirstRuns();
|
|
820
976
|
const filepath = util_1.util.uriToPath(params.textDocument.uri);
|
|
821
977
|
await this.keyedThrottler.onIdleOnce(filepath, true);
|
|
822
978
|
try {
|
|
823
|
-
const signatures = util_1.util.flatMap(await Promise.all(this.
|
|
979
|
+
const signatures = util_1.util.flatMap(await Promise.all(this.getProjects().map(project => project.builder.program.getSignatureHelp(filepath, params.position))), c => c);
|
|
824
980
|
const activeSignature = signatures.length > 0 ? 0 : null;
|
|
825
|
-
const activeParameter = activeSignature
|
|
981
|
+
const activeParameter = activeSignature !== null ? (_a = signatures[activeSignature]) === null || _a === void 0 ? void 0 : _a.index : null;
|
|
826
982
|
let results = {
|
|
827
983
|
signatures: signatures.map((s) => s.signature),
|
|
828
984
|
activeSignature: activeSignature,
|
|
@@ -840,42 +996,75 @@ class LanguageServer {
|
|
|
840
996
|
}
|
|
841
997
|
}
|
|
842
998
|
async onReferences(params) {
|
|
843
|
-
await this.
|
|
999
|
+
await this.waitAllProjectFirstRuns();
|
|
844
1000
|
const position = params.position;
|
|
845
1001
|
const srcPath = util_1.util.uriToPath(params.textDocument.uri);
|
|
846
|
-
const results = util_1.util.flatMap(await Promise.all(this.
|
|
847
|
-
return
|
|
848
|
-
})), c => c);
|
|
1002
|
+
const results = util_1.util.flatMap(await Promise.all(this.getProjects().map(project => {
|
|
1003
|
+
return project.builder.program.getReferences(srcPath, position);
|
|
1004
|
+
})), c => c !== null && c !== void 0 ? c : []);
|
|
849
1005
|
return results.filter((r) => r);
|
|
850
1006
|
}
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
this.
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
1007
|
+
onValidateSettled() {
|
|
1008
|
+
return Promise.all([
|
|
1009
|
+
//wait for the validator to start running (or timeout if it never did)
|
|
1010
|
+
this.validateThrottler.onRunOnce(100),
|
|
1011
|
+
//wait for the validator to stop running (or resolve immediately if it's already idle)
|
|
1012
|
+
this.validateThrottler.onIdleOnce(true)
|
|
1013
|
+
]);
|
|
1014
|
+
}
|
|
1015
|
+
async onFullSemanticTokens(params) {
|
|
1016
|
+
await this.waitAllProjectFirstRuns();
|
|
1017
|
+
//wait for the file to settle (in case there are multiple file changes in quick succession)
|
|
1018
|
+
await this.keyedThrottler.onIdleOnce(util_1.util.uriToPath(params.textDocument.uri), true);
|
|
1019
|
+
// make sure validation is complete
|
|
1020
|
+
await this.validateAllThrottled();
|
|
1021
|
+
//wait for the validation cycle to settle
|
|
1022
|
+
await this.onValidateSettled();
|
|
1023
|
+
const srcPath = util_1.util.uriToPath(params.textDocument.uri);
|
|
1024
|
+
for (const project of this.projects) {
|
|
1025
|
+
//find the first program that has this file, since it would be incredibly inefficient to generate semantic tokens for the same file multiple times.
|
|
1026
|
+
if (project.builder.program.hasFile(srcPath)) {
|
|
1027
|
+
let semanticTokens = project.builder.program.getSemanticTokens(srcPath);
|
|
1028
|
+
if (semanticTokens !== undefined) {
|
|
1029
|
+
return {
|
|
1030
|
+
data: (0, SemanticTokenUtils_1.encodeSemanticTokens)(semanticTokens)
|
|
1031
|
+
};
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
860
1034
|
}
|
|
861
1035
|
}
|
|
1036
|
+
async sendDiagnostics() {
|
|
1037
|
+
await this.sendDiagnosticsThrottler.run(async () => {
|
|
1038
|
+
//wait for all programs to finish running. This ensures the `Program` exists.
|
|
1039
|
+
await Promise.all(this.projects.map(x => x.firstRunPromise));
|
|
1040
|
+
//Get only the changes to diagnostics since the last time we sent them to the client
|
|
1041
|
+
const patch = this.diagnosticCollection.getPatch(this.projects);
|
|
1042
|
+
for (let filePath in patch) {
|
|
1043
|
+
const uri = vscode_uri_1.URI.file(filePath).toString();
|
|
1044
|
+
const diagnostics = patch[filePath].map(d => util_1.util.toDiagnostic(d, uri));
|
|
1045
|
+
await this.connection.sendDiagnostics({
|
|
1046
|
+
uri: uri,
|
|
1047
|
+
diagnostics: diagnostics
|
|
1048
|
+
});
|
|
1049
|
+
}
|
|
1050
|
+
});
|
|
1051
|
+
}
|
|
862
1052
|
async onExecuteCommand(params) {
|
|
863
|
-
await this.
|
|
1053
|
+
await this.waitAllProjectFirstRuns();
|
|
864
1054
|
if (params.command === CustomCommands.TranspileFile) {
|
|
865
|
-
|
|
1055
|
+
const result = await this.transpileFile(params.arguments[0]);
|
|
1056
|
+
//back-compat: include `pathAbsolute` property so older vscode versions still work
|
|
1057
|
+
result.pathAbsolute = result.srcPath;
|
|
1058
|
+
return result;
|
|
866
1059
|
}
|
|
867
1060
|
}
|
|
868
|
-
/**
|
|
869
|
-
* @param srcPath The absolute path to the source file on disk
|
|
870
|
-
*/
|
|
871
1061
|
async transpileFile(srcPath) {
|
|
872
1062
|
//wait all program first runs
|
|
873
|
-
await this.
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
return workspace.builder.program.getTranspiledFileContents(srcPath);
|
|
1063
|
+
await this.waitAllProjectFirstRuns();
|
|
1064
|
+
//find the first project that has this file
|
|
1065
|
+
for (let project of this.getProjects()) {
|
|
1066
|
+
if (project.builder.program.hasFile(srcPath)) {
|
|
1067
|
+
return project.builder.program.getTranspiledFileContents(srcPath);
|
|
879
1068
|
}
|
|
880
1069
|
}
|
|
881
1070
|
}
|
|
@@ -889,22 +1078,35 @@ __decorate([
|
|
|
889
1078
|
AddStackToErrorMessage
|
|
890
1079
|
], LanguageServer.prototype, "onInitialize", null);
|
|
891
1080
|
__decorate([
|
|
892
|
-
|
|
1081
|
+
TrackBusyStatus
|
|
1082
|
+
], LanguageServer.prototype, "getProjectPaths", null);
|
|
1083
|
+
__decorate([
|
|
1084
|
+
TrackBusyStatus
|
|
1085
|
+
], LanguageServer.prototype, "syncProjects", null);
|
|
1086
|
+
__decorate([
|
|
1087
|
+
AddStackToErrorMessage,
|
|
1088
|
+
TrackBusyStatus
|
|
893
1089
|
], LanguageServer.prototype, "onInitialized", null);
|
|
894
1090
|
__decorate([
|
|
895
|
-
|
|
1091
|
+
TrackBusyStatus
|
|
1092
|
+
], LanguageServer.prototype, "createProject", null);
|
|
1093
|
+
__decorate([
|
|
1094
|
+
AddStackToErrorMessage,
|
|
1095
|
+
TrackBusyStatus
|
|
896
1096
|
], LanguageServer.prototype, "onCompletion", null);
|
|
897
1097
|
__decorate([
|
|
898
1098
|
AddStackToErrorMessage
|
|
899
1099
|
], LanguageServer.prototype, "onCompletionResolve", null);
|
|
900
1100
|
__decorate([
|
|
901
|
-
AddStackToErrorMessage
|
|
1101
|
+
AddStackToErrorMessage,
|
|
1102
|
+
TrackBusyStatus
|
|
902
1103
|
], LanguageServer.prototype, "onCodeAction", null);
|
|
903
1104
|
__decorate([
|
|
904
1105
|
AddStackToErrorMessage
|
|
905
1106
|
], LanguageServer.prototype, "onDidChangeConfiguration", null);
|
|
906
1107
|
__decorate([
|
|
907
|
-
AddStackToErrorMessage
|
|
1108
|
+
AddStackToErrorMessage,
|
|
1109
|
+
TrackBusyStatus
|
|
908
1110
|
], LanguageServer.prototype, "onDidChangeWatchedFiles", null);
|
|
909
1111
|
__decorate([
|
|
910
1112
|
AddStackToErrorMessage
|
|
@@ -913,31 +1115,49 @@ __decorate([
|
|
|
913
1115
|
AddStackToErrorMessage
|
|
914
1116
|
], LanguageServer.prototype, "onDocumentClose", null);
|
|
915
1117
|
__decorate([
|
|
916
|
-
AddStackToErrorMessage
|
|
1118
|
+
AddStackToErrorMessage,
|
|
1119
|
+
TrackBusyStatus
|
|
917
1120
|
], LanguageServer.prototype, "validateTextDocument", null);
|
|
918
1121
|
__decorate([
|
|
919
|
-
|
|
1122
|
+
TrackBusyStatus
|
|
1123
|
+
], LanguageServer.prototype, "validateAll", null);
|
|
1124
|
+
__decorate([
|
|
1125
|
+
AddStackToErrorMessage,
|
|
1126
|
+
TrackBusyStatus
|
|
920
1127
|
], LanguageServer.prototype, "onWorkspaceSymbol", null);
|
|
921
1128
|
__decorate([
|
|
922
|
-
AddStackToErrorMessage
|
|
1129
|
+
AddStackToErrorMessage,
|
|
1130
|
+
TrackBusyStatus
|
|
923
1131
|
], LanguageServer.prototype, "onDocumentSymbol", null);
|
|
924
1132
|
__decorate([
|
|
925
|
-
AddStackToErrorMessage
|
|
1133
|
+
AddStackToErrorMessage,
|
|
1134
|
+
TrackBusyStatus
|
|
926
1135
|
], LanguageServer.prototype, "onDefinition", null);
|
|
927
1136
|
__decorate([
|
|
928
|
-
AddStackToErrorMessage
|
|
1137
|
+
AddStackToErrorMessage,
|
|
1138
|
+
TrackBusyStatus
|
|
929
1139
|
], LanguageServer.prototype, "onSignatureHelp", null);
|
|
930
1140
|
__decorate([
|
|
931
|
-
AddStackToErrorMessage
|
|
1141
|
+
AddStackToErrorMessage,
|
|
1142
|
+
TrackBusyStatus
|
|
932
1143
|
], LanguageServer.prototype, "onReferences", null);
|
|
933
1144
|
__decorate([
|
|
934
|
-
AddStackToErrorMessage
|
|
1145
|
+
AddStackToErrorMessage,
|
|
1146
|
+
TrackBusyStatus
|
|
1147
|
+
], LanguageServer.prototype, "onFullSemanticTokens", null);
|
|
1148
|
+
__decorate([
|
|
1149
|
+
AddStackToErrorMessage,
|
|
1150
|
+
TrackBusyStatus
|
|
935
1151
|
], LanguageServer.prototype, "onExecuteCommand", null);
|
|
936
1152
|
exports.LanguageServer = LanguageServer;
|
|
937
1153
|
var CustomCommands;
|
|
938
1154
|
(function (CustomCommands) {
|
|
939
1155
|
CustomCommands["TranspileFile"] = "TranspileFile";
|
|
940
1156
|
})(CustomCommands = exports.CustomCommands || (exports.CustomCommands = {}));
|
|
1157
|
+
var NotificationName;
|
|
1158
|
+
(function (NotificationName) {
|
|
1159
|
+
NotificationName["busyStatus"] = "busyStatus";
|
|
1160
|
+
})(NotificationName = exports.NotificationName || (exports.NotificationName = {}));
|
|
941
1161
|
/**
|
|
942
1162
|
* Wraps a method. If there's an error (either sync or via a promise),
|
|
943
1163
|
* this appends the error's stack trace at the end of the error message so that the connection will
|
|
@@ -969,4 +1189,16 @@ function AddStackToErrorMessage(target, propertyKey, descriptor) {
|
|
|
969
1189
|
}
|
|
970
1190
|
};
|
|
971
1191
|
}
|
|
1192
|
+
/**
|
|
1193
|
+
* An annotation used to wrap the method in a busyStatus tracking call
|
|
1194
|
+
*/
|
|
1195
|
+
function TrackBusyStatus(target, propertyKey, descriptor) {
|
|
1196
|
+
let originalMethod = descriptor.value;
|
|
1197
|
+
//wrapping the original method
|
|
1198
|
+
descriptor.value = function value(...args) {
|
|
1199
|
+
return this.busyStatusTracker.run(() => {
|
|
1200
|
+
return originalMethod.apply(this, args);
|
|
1201
|
+
}, originalMethod.name);
|
|
1202
|
+
};
|
|
1203
|
+
}
|
|
972
1204
|
//# sourceMappingURL=LanguageServer.js.map
|