brighterscript 1.0.0-alpha.2 → 1.0.0-alpha.22
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 +643 -253
- package/README.md +33 -9
- package/bsconfig.schema.json +22 -2
- package/dist/BsConfig.d.ts +9 -0
- package/dist/Cache.d.ts +5 -6
- package/dist/Cache.js +12 -11
- package/dist/Cache.js.map +1 -1
- 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 +4 -4
- package/dist/CommentFlagProcessor.js +5 -3
- package/dist/CommentFlagProcessor.js.map +1 -1
- package/dist/DependencyGraph.d.ts +2 -2
- package/dist/DependencyGraph.js +20 -7
- package/dist/DependencyGraph.js.map +1 -1
- package/dist/DiagnosticCollection.d.ts +3 -3
- package/dist/DiagnosticCollection.js +11 -11
- package/dist/DiagnosticCollection.js.map +1 -1
- package/dist/DiagnosticFilterer.js +5 -4
- package/dist/DiagnosticFilterer.js.map +1 -1
- package/dist/DiagnosticMessages.d.ts +59 -4
- package/dist/DiagnosticMessages.js +65 -7
- package/dist/DiagnosticMessages.js.map +1 -1
- package/dist/LanguageServer.d.ts +51 -39
- package/dist/LanguageServer.js +316 -232
- package/dist/LanguageServer.js.map +1 -1
- package/dist/Logger.d.ts +2 -0
- package/dist/Logger.js +10 -8
- package/dist/Logger.js.map +1 -1
- package/dist/PluginInterface.d.ts +7 -3
- package/dist/PluginInterface.js +9 -0
- package/dist/PluginInterface.js.map +1 -1
- package/dist/Program.d.ts +43 -25
- package/dist/Program.js +212 -95
- package/dist/Program.js.map +1 -1
- package/dist/ProgramBuilder.d.ts +4 -0
- package/dist/ProgramBuilder.js +36 -20
- package/dist/ProgramBuilder.js.map +1 -1
- package/dist/Scope.d.ts +126 -29
- package/dist/Scope.js +433 -156
- 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/SymbolTable.d.ts +10 -4
- package/dist/SymbolTable.js +55 -13
- package/dist/SymbolTable.js.map +1 -1
- package/dist/XmlScope.d.ts +7 -2
- package/dist/XmlScope.js +65 -27
- package/dist/XmlScope.js.map +1 -1
- package/dist/astUtils/AstEditor.d.ts +65 -0
- package/dist/astUtils/AstEditor.js +239 -0
- package/dist/astUtils/AstEditor.js.map +1 -0
- package/dist/{types/FunctionType.spec.d.ts → astUtils/AstEditor.spec.d.ts} +0 -0
- package/dist/astUtils/AstEditor.spec.js +254 -0
- package/dist/astUtils/AstEditor.spec.js.map +1 -0
- package/dist/astUtils/creators.d.ts +28 -6
- package/dist/astUtils/creators.js +137 -19
- package/dist/astUtils/creators.js.map +1 -1
- package/dist/astUtils/creators.spec.js +14 -4
- package/dist/astUtils/creators.spec.js.map +1 -1
- package/dist/astUtils/reflection.d.ts +32 -10
- package/dist/astUtils/reflection.js +82 -7
- package/dist/astUtils/reflection.js.map +1 -1
- package/dist/astUtils/reflection.spec.js +130 -119
- package/dist/astUtils/reflection.spec.js.map +1 -1
- package/dist/astUtils/stackedVisitor.js.map +1 -1
- package/dist/astUtils/stackedVisitor.spec.js +13 -13
- package/dist/astUtils/stackedVisitor.spec.js.map +1 -1
- package/dist/astUtils/visitors.d.ts +76 -51
- package/dist/astUtils/visitors.js +31 -11
- package/dist/astUtils/visitors.js.map +1 -1
- package/dist/astUtils/visitors.spec.js +126 -32
- package/dist/astUtils/visitors.spec.js.map +1 -1
- package/dist/astUtils/xml.d.ts +4 -3
- package/dist/astUtils/xml.js +8 -3
- package/dist/astUtils/xml.js.map +1 -1
- package/dist/bscPlugin/BscPlugin.d.ts +7 -1
- package/dist/bscPlugin/BscPlugin.js +28 -0
- package/dist/bscPlugin/BscPlugin.js.map +1 -1
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.js +4 -4
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.js.map +1 -1
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js +26 -26
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js.map +1 -1
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.d.ts +9 -0
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js +108 -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 +130 -0
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js.map +1 -0
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.d.ts +8 -0
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.js +52 -0
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.js.map +1 -0
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.d.ts +1 -0
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.js +32 -0
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.js.map +1 -0
- package/dist/bscPlugin/validation/BrsFileValidator.d.ts +9 -0
- package/dist/bscPlugin/validation/BrsFileValidator.js +66 -0
- package/dist/bscPlugin/validation/BrsFileValidator.js.map +1 -0
- package/dist/bscPlugin/validation/ScopeValidator.d.ts +29 -0
- package/dist/bscPlugin/validation/ScopeValidator.js +183 -0
- package/dist/bscPlugin/validation/ScopeValidator.js.map +1 -0
- package/dist/cli.js +10 -3
- package/dist/cli.js.map +1 -1
- package/dist/diagnosticUtils.d.ts +1 -0
- package/dist/diagnosticUtils.js +15 -8
- package/dist/diagnosticUtils.js.map +1 -1
- package/dist/examples/plugins/removePrint.js +12 -14
- package/dist/examples/plugins/removePrint.js.map +1 -1
- package/dist/files/BrsFile.Class.spec.js +717 -147
- package/dist/files/BrsFile.Class.spec.js.map +1 -1
- package/dist/files/BrsFile.d.ts +70 -30
- package/dist/files/BrsFile.js +719 -353
- package/dist/files/BrsFile.js.map +1 -1
- package/dist/files/BrsFile.spec.js +1238 -449
- package/dist/files/BrsFile.spec.js.map +1 -1
- package/dist/files/XmlFile.d.ts +6 -5
- package/dist/files/XmlFile.js +38 -30
- package/dist/files/XmlFile.js.map +1 -1
- package/dist/files/XmlFile.spec.js +302 -237
- package/dist/files/XmlFile.spec.js.map +1 -1
- package/dist/files/tests/imports.spec.js +44 -42
- 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 +88 -0
- package/dist/files/tests/optionalChaning.spec.js.map +1 -0
- package/dist/globalCallables.d.ts +3 -1
- package/dist/globalCallables.js +424 -152
- package/dist/globalCallables.js.map +1 -1
- package/dist/index.d.ts +13 -3
- package/dist/index.js +28 -5
- package/dist/index.js.map +1 -1
- package/dist/interfaces.d.ts +133 -16
- package/dist/lexer/Lexer.d.ts +19 -1
- package/dist/lexer/Lexer.js +127 -21
- package/dist/lexer/Lexer.js.map +1 -1
- package/dist/lexer/Lexer.spec.js +657 -536
- package/dist/lexer/Lexer.spec.js.map +1 -1
- package/dist/lexer/Token.d.ts +2 -2
- package/dist/lexer/TokenKind.d.ts +13 -1
- package/dist/lexer/TokenKind.js +60 -3
- package/dist/lexer/TokenKind.js.map +1 -1
- package/dist/parser/BrsTranspileState.d.ts +9 -0
- package/dist/parser/BrsTranspileState.js +14 -0
- package/dist/parser/BrsTranspileState.js.map +1 -1
- package/dist/parser/Expression.d.ts +150 -34
- package/dist/parser/Expression.js +335 -165
- package/dist/parser/Expression.js.map +1 -1
- package/dist/parser/Parser.Class.spec.js +189 -89
- package/dist/parser/Parser.Class.spec.js.map +1 -1
- package/dist/parser/Parser.d.ts +153 -30
- package/dist/parser/Parser.js +1100 -503
- package/dist/parser/Parser.js.map +1 -1
- package/dist/parser/Parser.spec.js +687 -266
- package/dist/parser/Parser.spec.js.map +1 -1
- package/dist/parser/SGParser.d.ts +41 -4
- package/dist/parser/SGParser.js +186 -175
- package/dist/parser/SGParser.js.map +1 -1
- package/dist/parser/SGParser.spec.js +35 -22
- package/dist/parser/SGParser.spec.js.map +1 -1
- package/dist/parser/SGTypes.d.ts +206 -38
- package/dist/parser/SGTypes.js +470 -161
- package/dist/parser/SGTypes.js.map +1 -1
- package/dist/parser/SGTypes.spec.d.ts +1 -0
- package/dist/parser/SGTypes.spec.js +351 -0
- package/dist/parser/SGTypes.spec.js.map +1 -0
- package/dist/parser/Statement.d.ts +202 -48
- package/dist/parser/Statement.js +648 -193
- package/dist/parser/Statement.js.map +1 -1
- package/dist/parser/Statement.spec.js +11 -11
- package/dist/parser/Statement.spec.js.map +1 -1
- package/dist/parser/TranspileState.d.ts +1 -1
- package/dist/parser/TranspileState.js +15 -7
- 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 +15 -11
- package/dist/parser/tests/Parser.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/For.spec.js +60 -60
- package/dist/parser/tests/controlFlow/For.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/ForEach.spec.js +40 -39
- package/dist/parser/tests/controlFlow/ForEach.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/If.spec.js +213 -194
- package/dist/parser/tests/controlFlow/If.spec.js.map +1 -1
- package/dist/parser/tests/controlFlow/While.spec.js +37 -37
- package/dist/parser/tests/controlFlow/While.spec.js.map +1 -1
- package/dist/parser/tests/expression/Additive.spec.js +30 -30
- package/dist/parser/tests/expression/Additive.spec.js.map +1 -1
- package/dist/parser/tests/expression/ArrayLiterals.spec.js +119 -119
- package/dist/parser/tests/expression/ArrayLiterals.spec.js.map +1 -1
- package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js +162 -138
- package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js.map +1 -1
- package/dist/parser/tests/expression/Boolean.spec.js +24 -24
- package/dist/parser/tests/expression/Boolean.spec.js.map +1 -1
- package/dist/parser/tests/expression/Call.spec.js +41 -40
- package/dist/parser/tests/expression/Call.spec.js.map +1 -1
- package/dist/parser/tests/expression/Exponential.spec.js +17 -17
- package/dist/parser/tests/expression/Exponential.spec.js.map +1 -1
- package/dist/parser/tests/expression/Function.spec.js +256 -256
- package/dist/parser/tests/expression/Function.spec.js.map +1 -1
- package/dist/parser/tests/expression/Indexing.spec.js +87 -87
- package/dist/parser/tests/expression/Indexing.spec.js.map +1 -1
- package/dist/parser/tests/expression/Multiplicative.spec.js +37 -37
- package/dist/parser/tests/expression/Multiplicative.spec.js.map +1 -1
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js +75 -63
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/PrefixUnary.spec.js +41 -41
- package/dist/parser/tests/expression/PrefixUnary.spec.js.map +1 -1
- package/dist/parser/tests/expression/Primary.spec.js +41 -41
- 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 +43 -43
- package/dist/parser/tests/expression/Relational.spec.js.map +1 -1
- package/dist/parser/tests/expression/SourceLiteralExpression.spec.js +9 -9
- package/dist/parser/tests/expression/SourceLiteralExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/TemplateStringExpression.spec.js +28 -28
- package/dist/parser/tests/expression/TemplateStringExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/TernaryExpression.spec.js +102 -102
- package/dist/parser/tests/expression/TernaryExpression.spec.js.map +1 -1
- package/dist/parser/tests/statement/AssignmentOperators.spec.js +36 -36
- package/dist/parser/tests/statement/AssignmentOperators.spec.js.map +1 -1
- package/dist/parser/tests/statement/Declaration.spec.js +44 -44
- package/dist/parser/tests/statement/Declaration.spec.js.map +1 -1
- package/dist/parser/tests/statement/Dim.spec.js +21 -21
- 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 +840 -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 +46 -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 +37 -0
- package/dist/parser/tests/statement/ForEach.spec.js.map +1 -0
- package/dist/parser/tests/statement/Function.spec.js +198 -197
- package/dist/parser/tests/statement/Function.spec.js.map +1 -1
- package/dist/parser/tests/statement/Goto.spec.js +15 -14
- package/dist/parser/tests/statement/Goto.spec.js.map +1 -1
- package/dist/parser/tests/statement/Increment.spec.js +50 -50
- 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 +254 -0
- package/dist/parser/tests/statement/InterfaceStatement.spec.js.map +1 -0
- package/dist/parser/tests/statement/LibraryStatement.spec.js +17 -17
- package/dist/parser/tests/statement/LibraryStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/Misc.spec.js +108 -106
- package/dist/parser/tests/statement/Misc.spec.js.map +1 -1
- package/dist/parser/tests/statement/PrintStatement.spec.js +40 -40
- package/dist/parser/tests/statement/PrintStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/ReturnStatement.spec.js +46 -46
- package/dist/parser/tests/statement/ReturnStatement.spec.js.map +1 -1
- package/dist/parser/tests/statement/Set.spec.js +83 -83
- package/dist/parser/tests/statement/Set.spec.js.map +1 -1
- package/dist/parser/tests/statement/Stop.spec.js +12 -11
- package/dist/parser/tests/statement/Stop.spec.js.map +1 -1
- package/dist/parser/tests/statement/Throw.spec.js +5 -5
- package/dist/parser/tests/statement/Throw.spec.js.map +1 -1
- package/dist/parser/tests/statement/TryCatch.spec.js +15 -13
- package/dist/parser/tests/statement/TryCatch.spec.js.map +1 -1
- package/dist/preprocessor/Chunk.d.ts +1 -1
- package/dist/preprocessor/Chunk.js.map +1 -1
- package/dist/preprocessor/Manifest.d.ts +5 -5
- package/dist/preprocessor/Manifest.js +14 -35
- 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/preprocessor/Preprocessor.d.ts +1 -1
- package/dist/preprocessor/Preprocessor.js +8 -8
- package/dist/preprocessor/Preprocessor.js.map +1 -1
- package/dist/preprocessor/Preprocessor.spec.js +49 -49
- package/dist/preprocessor/Preprocessor.spec.js.map +1 -1
- package/dist/preprocessor/PreprocessorParser.spec.js +72 -72
- package/dist/preprocessor/PreprocessorParser.spec.js.map +1 -1
- package/dist/roku-types/data.json +21891 -0
- package/dist/roku-types/index.d.ts +6776 -0
- package/dist/roku-types/index.js +11 -0
- package/dist/roku-types/index.js.map +1 -0
- package/dist/types/ArrayType.d.ts +8 -5
- package/dist/types/ArrayType.js +52 -12
- package/dist/types/ArrayType.js.map +1 -1
- package/dist/types/ArrayType.spec.js +72 -11
- package/dist/types/ArrayType.spec.js.map +1 -1
- package/dist/types/BooleanType.d.ts +4 -2
- package/dist/types/BooleanType.js +9 -4
- package/dist/types/BooleanType.js.map +1 -1
- package/dist/types/BooleanType.spec.js +5 -3
- package/dist/types/BooleanType.spec.js.map +1 -1
- package/dist/types/BscType.d.ts +20 -5
- package/dist/types/BscType.js +24 -0
- package/dist/types/BscType.js.map +1 -1
- package/dist/types/CustomType.d.ts +8 -6
- package/dist/types/CustomType.js +20 -11
- package/dist/types/CustomType.js.map +1 -1
- package/dist/types/DoubleType.d.ts +2 -0
- package/dist/types/DoubleType.js +14 -9
- package/dist/types/DoubleType.js.map +1 -1
- package/dist/types/DoubleType.spec.js +5 -3
- package/dist/types/DoubleType.spec.js.map +1 -1
- package/dist/types/DynamicType.d.ts +2 -0
- package/dist/types/DynamicType.js +6 -2
- package/dist/types/DynamicType.js.map +1 -1
- package/dist/types/DynamicType.spec.js +2 -2
- package/dist/types/DynamicType.spec.js.map +1 -1
- package/dist/types/EnumType.d.ts +22 -0
- package/dist/types/EnumType.js +55 -0
- package/dist/types/EnumType.js.map +1 -0
- package/dist/types/FloatType.d.ts +2 -0
- package/dist/types/FloatType.js +14 -9
- package/dist/types/FloatType.js.map +1 -1
- package/dist/types/FloatType.spec.js +4 -2
- package/dist/types/FloatType.spec.js.map +1 -1
- package/dist/types/FunctionType.d.ts +7 -31
- package/dist/types/FunctionType.js +11 -57
- package/dist/types/FunctionType.js.map +1 -1
- package/dist/types/IntegerType.d.ts +2 -0
- package/dist/types/IntegerType.js +14 -9
- package/dist/types/IntegerType.js.map +1 -1
- package/dist/types/IntegerType.spec.js +5 -3
- package/dist/types/IntegerType.spec.js.map +1 -1
- package/dist/types/InterfaceType.d.ts +13 -4
- package/dist/types/InterfaceType.js +48 -8
- package/dist/types/InterfaceType.js.map +1 -1
- package/dist/types/InterfaceType.spec.d.ts +1 -0
- package/dist/types/InterfaceType.spec.js +194 -0
- package/dist/types/InterfaceType.spec.js.map +1 -0
- package/dist/types/InvalidType.d.ts +4 -2
- package/dist/types/InvalidType.js +10 -5
- package/dist/types/InvalidType.js.map +1 -1
- package/dist/types/InvalidType.spec.js +4 -2
- package/dist/types/InvalidType.spec.js.map +1 -1
- package/dist/types/LazyType.d.ts +8 -7
- package/dist/types/LazyType.js +22 -10
- package/dist/types/LazyType.js.map +1 -1
- package/dist/types/LongIntegerType.d.ts +2 -0
- package/dist/types/LongIntegerType.js +14 -9
- package/dist/types/LongIntegerType.js.map +1 -1
- package/dist/types/LongIntegerType.spec.js +4 -2
- package/dist/types/LongIntegerType.spec.js.map +1 -1
- package/dist/types/ObjectType.d.ts +8 -4
- package/dist/types/ObjectType.js +9 -4
- package/dist/types/ObjectType.js.map +1 -1
- package/dist/types/ObjectType.spec.js +2 -2
- package/dist/types/ObjectType.spec.js.map +1 -1
- package/dist/types/StringType.d.ts +4 -2
- package/dist/types/StringType.js +9 -4
- package/dist/types/StringType.js.map +1 -1
- package/dist/types/StringType.spec.js +4 -2
- package/dist/types/StringType.spec.js.map +1 -1
- package/dist/types/TypedFunctionType.d.ts +28 -0
- package/dist/types/TypedFunctionType.js +88 -0
- package/dist/types/TypedFunctionType.js.map +1 -0
- package/dist/types/TypedFunctionType.spec.d.ts +1 -0
- package/dist/types/TypedFunctionType.spec.js +37 -0
- package/dist/types/TypedFunctionType.spec.js.map +1 -0
- package/dist/types/UninitializedType.js +3 -3
- package/dist/types/UninitializedType.js.map +1 -1
- package/dist/types/VoidType.d.ts +4 -2
- package/dist/types/VoidType.js +8 -4
- package/dist/types/VoidType.js.map +1 -1
- package/dist/types/VoidType.spec.js +2 -2
- package/dist/types/VoidType.spec.js.map +1 -1
- package/dist/types/helpers.d.ts +42 -0
- package/dist/types/helpers.js +118 -0
- package/dist/types/helpers.js.map +1 -0
- package/dist/util.d.ts +91 -21
- package/dist/util.js +364 -114
- package/dist/util.js.map +1 -1
- package/dist/validators/ClassValidator.d.ts +19 -2
- package/dist/validators/ClassValidator.js +164 -103
- package/dist/validators/ClassValidator.js.map +1 -1
- package/package.json +30 -19
- 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/index.d.ts +0 -3
- package/dist/preprocessor/index.js +0 -16
- package/dist/preprocessor/index.js.map +0 -1
- package/dist/types/FunctionType.spec.js +0 -23
- package/dist/types/FunctionType.spec.js.map +0 -1
package/dist/LanguageServer.js
CHANGED
|
@@ -8,10 +8,10 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
9
|
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");
|
|
@@ -23,22 +23,22 @@ const Throttler_1 = require("./Throttler");
|
|
|
23
23
|
const KeyedThrottler_1 = require("./KeyedThrottler");
|
|
24
24
|
const DiagnosticCollection_1 = require("./DiagnosticCollection");
|
|
25
25
|
const reflection_1 = require("./astUtils/reflection");
|
|
26
|
+
const SemanticTokenUtils_1 = require("./SemanticTokenUtils");
|
|
26
27
|
class LanguageServer {
|
|
27
28
|
constructor() {
|
|
28
|
-
//cast undefined as any to get around strictNullChecks...it's ok in this case
|
|
29
29
|
this.connection = undefined;
|
|
30
|
-
this.
|
|
30
|
+
this.projects = [];
|
|
31
31
|
/**
|
|
32
32
|
* The number of milliseconds that should be used for language server typing debouncing
|
|
33
33
|
*/
|
|
34
34
|
this.debounceTimeout = 150;
|
|
35
35
|
/**
|
|
36
|
-
* These
|
|
37
|
-
* in any of the workspace projects.
|
|
38
|
-
* Basically these are single-file
|
|
36
|
+
* These projects are created on the fly whenever a file is opened that is not included
|
|
37
|
+
* in any of the workspace-based projects.
|
|
38
|
+
* Basically these are single-file projects to at least get parsing for standalone files.
|
|
39
39
|
* Also, they should only be created when the file is opened, and destroyed when the file is closed.
|
|
40
40
|
*/
|
|
41
|
-
this.
|
|
41
|
+
this.standaloneFileProjects = {};
|
|
42
42
|
this.hasConfigurationCapability = false;
|
|
43
43
|
/**
|
|
44
44
|
* Indicates whether the client supports workspace folders
|
|
@@ -48,14 +48,14 @@ class LanguageServer {
|
|
|
48
48
|
* Create a simple text document manager.
|
|
49
49
|
* The text document manager supports full document sync only
|
|
50
50
|
*/
|
|
51
|
-
this.documents = new
|
|
51
|
+
this.documents = new node_1.TextDocuments(vscode_languageserver_textdocument_1.TextDocument);
|
|
52
52
|
this.keyedThrottler = new KeyedThrottler_1.KeyedThrottler(this.debounceTimeout);
|
|
53
53
|
this.validateThrottler = new Throttler_1.Throttler(0);
|
|
54
54
|
this.boundValidateAll = this.validateAll.bind(this);
|
|
55
55
|
this.diagnosticCollection = new DiagnosticCollection_1.DiagnosticCollection();
|
|
56
56
|
}
|
|
57
57
|
createConnection() {
|
|
58
|
-
return
|
|
58
|
+
return (0, node_1.createConnection)(node_1.ProposedFeatures.all);
|
|
59
59
|
}
|
|
60
60
|
validateAllThrottled() {
|
|
61
61
|
return this.validateThrottler.run(this.boundValidateAll);
|
|
@@ -77,17 +77,11 @@ class LanguageServer {
|
|
|
77
77
|
// when the text document is first opened, when its content has changed,
|
|
78
78
|
// or when document is closed without saving (original contents are sent as a change)
|
|
79
79
|
//
|
|
80
|
-
this.documents.onDidChangeContent(
|
|
81
|
-
await this.validateTextDocument(change.document);
|
|
82
|
-
});
|
|
80
|
+
this.documents.onDidChangeContent(this.validateTextDocument.bind(this));
|
|
83
81
|
//whenever a document gets closed
|
|
84
|
-
this.documents.onDidClose(
|
|
85
|
-
await this.onDocumentClose(change.document);
|
|
86
|
-
});
|
|
82
|
+
this.documents.onDidClose(this.onDocumentClose.bind(this));
|
|
87
83
|
// This handler provides the initial list of the completion items.
|
|
88
|
-
this.connection.onCompletion(
|
|
89
|
-
return this.onCompletion(params.textDocument.uri, params.position);
|
|
90
|
-
});
|
|
84
|
+
this.connection.onCompletion(this.onCompletion.bind(this));
|
|
91
85
|
// This handler resolves additional information for the item selected in
|
|
92
86
|
// the completion list.
|
|
93
87
|
this.connection.onCompletionResolve(this.onCompletionResolve.bind(this));
|
|
@@ -99,6 +93,8 @@ class LanguageServer {
|
|
|
99
93
|
this.connection.onSignatureHelp(this.onSignatureHelp.bind(this));
|
|
100
94
|
this.connection.onReferences(this.onReferences.bind(this));
|
|
101
95
|
this.connection.onCodeAction(this.onCodeAction.bind(this));
|
|
96
|
+
//TODO switch to a more specific connection function call once they actually add it
|
|
97
|
+
this.connection.onRequest(node_1.SemanticTokensRequest.method, this.onFullSemanticTokens.bind(this));
|
|
102
98
|
/*
|
|
103
99
|
this.connection.onDidOpenTextDocument((params) => {
|
|
104
100
|
// A text document got opened in VSCode.
|
|
@@ -136,7 +132,7 @@ class LanguageServer {
|
|
|
136
132
|
//return the capabilities of the server
|
|
137
133
|
return {
|
|
138
134
|
capabilities: {
|
|
139
|
-
textDocumentSync:
|
|
135
|
+
textDocumentSync: node_1.TextDocumentSyncKind.Full,
|
|
140
136
|
// Tell the client that the server supports code completion
|
|
141
137
|
completionProvider: {
|
|
142
138
|
resolveProvider: true,
|
|
@@ -146,9 +142,13 @@ class LanguageServer {
|
|
|
146
142
|
},
|
|
147
143
|
documentSymbolProvider: true,
|
|
148
144
|
workspaceSymbolProvider: true,
|
|
145
|
+
semanticTokensProvider: {
|
|
146
|
+
legend: SemanticTokenUtils_1.semanticTokensLegend,
|
|
147
|
+
full: true
|
|
148
|
+
},
|
|
149
149
|
referencesProvider: true,
|
|
150
150
|
codeActionProvider: {
|
|
151
|
-
codeActionKinds: [
|
|
151
|
+
codeActionKinds: [node_1.CodeActionKind.Refactor]
|
|
152
152
|
},
|
|
153
153
|
signatureHelpProvider: {
|
|
154
154
|
triggerCharacters: ['(', ',']
|
|
@@ -163,42 +163,118 @@ class LanguageServer {
|
|
|
163
163
|
}
|
|
164
164
|
};
|
|
165
165
|
}
|
|
166
|
+
/**
|
|
167
|
+
* Ask the client for the list of `files.exclude` patterns. Useful when determining if we should process a file
|
|
168
|
+
*/
|
|
169
|
+
async getWorkspaceExcludeGlobs(workspaceFolder) {
|
|
170
|
+
var _a;
|
|
171
|
+
//get any `files.exclude` globs to use to filter
|
|
172
|
+
let config = await this.connection.workspace.getConfiguration({
|
|
173
|
+
scopeUri: workspaceFolder,
|
|
174
|
+
section: 'files'
|
|
175
|
+
});
|
|
176
|
+
return Object
|
|
177
|
+
.keys((_a = config === null || config === void 0 ? void 0 : config.exclude) !== null && _a !== void 0 ? _a : {})
|
|
178
|
+
.filter(x => { var _a; return (_a = config === null || config === void 0 ? void 0 : config.exclude) === null || _a === void 0 ? void 0 : _a[x]; })
|
|
179
|
+
//vscode files.exclude patterns support ignoring folders without needing to add `**/*`. So for our purposes, we need to
|
|
180
|
+
//append **/* to everything without a file extension or magic at the end
|
|
181
|
+
.map(pattern => [
|
|
182
|
+
//send the pattern as-is (this handles weird cases and exact file matches)
|
|
183
|
+
pattern,
|
|
184
|
+
//treat the pattern as a directory (no harm in doing this because if it's a file, the pattern will just never match anything)
|
|
185
|
+
`${pattern}/**/*`
|
|
186
|
+
])
|
|
187
|
+
.flat(1)
|
|
188
|
+
.concat([
|
|
189
|
+
//always ignore projects from node_modules
|
|
190
|
+
'**/node_modules/**/*'
|
|
191
|
+
]);
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Scan the workspace for all `bsconfig.json` files. If at least one is found, then only folders who have bsconfig.json are returned.
|
|
195
|
+
* If none are found, then the workspaceFolder itself is treated as a project
|
|
196
|
+
*/
|
|
197
|
+
async getProjectPaths(workspaceFolder) {
|
|
198
|
+
const excludes = (await this.getWorkspaceExcludeGlobs(workspaceFolder)).map(x => (0, util_1.standardizePath) `!${x}`);
|
|
199
|
+
const files = await roku_deploy_1.rokuDeploy.getFilePaths([
|
|
200
|
+
'**/bsconfig.json',
|
|
201
|
+
//exclude all files found in `files.exclude`
|
|
202
|
+
...excludes
|
|
203
|
+
], workspaceFolder);
|
|
204
|
+
//if we found at least one bsconfig.json, then ALL projects must have a bsconfig.json.
|
|
205
|
+
if (files.length > 0) {
|
|
206
|
+
return files.map(file => (0, util_1.standardizePath) `${path.dirname(file.src)}`);
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
//treat the workspace folder as a brightscript project itself
|
|
210
|
+
return [workspaceFolder];
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Find all folders with bsconfig.json files in them, and treat each as a project.
|
|
215
|
+
* Treat workspaces that don't have a bsconfig.json as a project.
|
|
216
|
+
* Handle situations where bsconfig.json files were added or removed (to elevate/lower workspaceFolder projects accordingly)
|
|
217
|
+
* Leave existing projects alone if they are not affected by these changes
|
|
218
|
+
*/
|
|
219
|
+
async syncProjects() {
|
|
220
|
+
const workspacePaths = await this.getWorkspacePaths();
|
|
221
|
+
let projectPaths = (await Promise.all(workspacePaths.map(async (workspacePath) => {
|
|
222
|
+
const projectPaths = await this.getProjectPaths(workspacePath);
|
|
223
|
+
return projectPaths.map(projectPath => ({
|
|
224
|
+
projectPath: projectPath,
|
|
225
|
+
workspacePath: workspacePath
|
|
226
|
+
}));
|
|
227
|
+
}))).flat(1);
|
|
228
|
+
//delete projects not represented in the list
|
|
229
|
+
for (const project of this.getProjects()) {
|
|
230
|
+
if (!projectPaths.find(x => x.projectPath === project.projectPath)) {
|
|
231
|
+
this.removeProject(project);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
//exclude paths to projects we already have
|
|
235
|
+
projectPaths = projectPaths.filter(x => {
|
|
236
|
+
//only keep this project path if there's not a project with that path
|
|
237
|
+
return !this.projects.find(project => project.projectPath === x.projectPath);
|
|
238
|
+
});
|
|
239
|
+
//dedupe by project path
|
|
240
|
+
projectPaths = [
|
|
241
|
+
...projectPaths.reduce((acc, x) => acc.set(x.projectPath, x), new Map()).values()
|
|
242
|
+
];
|
|
243
|
+
//create missing projects
|
|
244
|
+
await Promise.all(projectPaths.map(x => this.createProject(x.projectPath, x.workspacePath)));
|
|
245
|
+
//flush diagnostics
|
|
246
|
+
await this.sendDiagnostics();
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Get all workspace paths from the client
|
|
250
|
+
*/
|
|
251
|
+
async getWorkspacePaths() {
|
|
252
|
+
var _a;
|
|
253
|
+
let workspaceFolders = (_a = await this.connection.workspace.getWorkspaceFolders()) !== null && _a !== void 0 ? _a : [];
|
|
254
|
+
return workspaceFolders.map((x) => {
|
|
255
|
+
return util_1.util.uriToPath(x.uri);
|
|
256
|
+
});
|
|
257
|
+
}
|
|
166
258
|
/**
|
|
167
259
|
* Called when the client has finished initializing
|
|
168
260
|
* @param params
|
|
169
261
|
*/
|
|
170
262
|
async onInitialized() {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
this.initialWorkspacesCreated = workspaceCreatedDeferred.promise;
|
|
263
|
+
let projectCreatedDeferred = new deferred_1.Deferred();
|
|
264
|
+
this.initialProjectsCreated = projectCreatedDeferred.promise;
|
|
174
265
|
try {
|
|
175
266
|
if (this.hasConfigurationCapability) {
|
|
176
267
|
// Register for all configuration changes.
|
|
177
|
-
await this.connection.client.register(
|
|
268
|
+
await this.connection.client.register(node_1.DidChangeConfigurationNotification.type, undefined);
|
|
178
269
|
}
|
|
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);
|
|
270
|
+
await this.syncProjects();
|
|
185
271
|
if (this.clientHasWorkspaceFolderCapability) {
|
|
186
272
|
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)));
|
|
273
|
+
await this.syncProjects();
|
|
198
274
|
});
|
|
199
275
|
}
|
|
200
|
-
await this.
|
|
201
|
-
|
|
276
|
+
await this.waitAllProjectFirstRuns(false);
|
|
277
|
+
projectCreatedDeferred.resolve();
|
|
202
278
|
await this.sendDiagnostics();
|
|
203
279
|
}
|
|
204
280
|
catch (e) {
|
|
@@ -218,34 +294,25 @@ class LanguageServer {
|
|
|
218
294
|
/**
|
|
219
295
|
* Wait for all programs' first run to complete
|
|
220
296
|
*/
|
|
221
|
-
async
|
|
297
|
+
async waitAllProjectFirstRuns(waitForFirstWorkSpace = true) {
|
|
222
298
|
if (waitForFirstWorkSpace) {
|
|
223
|
-
await this.
|
|
299
|
+
await this.initialProjectsCreated;
|
|
224
300
|
}
|
|
225
301
|
let status;
|
|
226
|
-
let
|
|
227
|
-
for (let workspace of workspaces) {
|
|
302
|
+
for (let project of this.getProjects()) {
|
|
228
303
|
try {
|
|
229
|
-
await
|
|
304
|
+
await project.firstRunPromise;
|
|
230
305
|
}
|
|
231
306
|
catch (e) {
|
|
232
307
|
status = 'critical-error';
|
|
233
308
|
//the first run failed...that won't change unless we reload the workspace, so replace with resolved promise
|
|
234
309
|
//so we don't show this error again
|
|
235
|
-
|
|
310
|
+
project.firstRunPromise = Promise.resolve();
|
|
236
311
|
this.sendCriticalFailure(`BrighterScript language server failed to start: \n${e.message}`);
|
|
237
312
|
}
|
|
238
313
|
}
|
|
239
314
|
this.connection.sendNotification('build-status', status ? status : 'success');
|
|
240
315
|
}
|
|
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
|
-
}
|
|
249
316
|
/**
|
|
250
317
|
* Event handler for when the program wants to load file contents.
|
|
251
318
|
* anytime the program wants to load a file, check with our in-memory document cache first
|
|
@@ -278,7 +345,7 @@ class LanguageServer {
|
|
|
278
345
|
return configFilePath;
|
|
279
346
|
}
|
|
280
347
|
else {
|
|
281
|
-
this.sendCriticalFailure(`Cannot find config file specified in user/workspace settings at '${configFilePath}'`);
|
|
348
|
+
this.sendCriticalFailure(`Cannot find config file specified in user / workspace settings at '${configFilePath}'`);
|
|
282
349
|
}
|
|
283
350
|
}
|
|
284
351
|
//default to config file path found in the root of the workspace
|
|
@@ -294,10 +361,11 @@ class LanguageServer {
|
|
|
294
361
|
//no config file could be found
|
|
295
362
|
return undefined;
|
|
296
363
|
}
|
|
297
|
-
async
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
if
|
|
364
|
+
async createProject(projectPath, workspacePath = projectPath) {
|
|
365
|
+
workspacePath !== null && workspacePath !== void 0 ? workspacePath : (workspacePath = projectPath);
|
|
366
|
+
let project = this.projects.find((x) => x.projectPath === projectPath);
|
|
367
|
+
//skip this project if we already have it
|
|
368
|
+
if (project) {
|
|
301
369
|
return;
|
|
302
370
|
}
|
|
303
371
|
let builder = new ProgramBuilder_1.ProgramBuilder();
|
|
@@ -305,8 +373,8 @@ class LanguageServer {
|
|
|
305
373
|
builder.allowConsoleClearing = false;
|
|
306
374
|
//look for files in our in-memory cache before going to the file system
|
|
307
375
|
builder.addFileResolver(this.documentFileResolver.bind(this));
|
|
308
|
-
let configFilePath = await this.getConfigFilePath(
|
|
309
|
-
let cwd =
|
|
376
|
+
let configFilePath = await this.getConfigFilePath(projectPath);
|
|
377
|
+
let cwd = projectPath;
|
|
310
378
|
//if the config file exists, use it and its folder as cwd
|
|
311
379
|
if (configFilePath && await util_1.util.pathExists(configFilePath)) {
|
|
312
380
|
cwd = path.dirname(configFilePath);
|
|
@@ -327,22 +395,23 @@ class LanguageServer {
|
|
|
327
395
|
firstRunPromise.catch((err) => {
|
|
328
396
|
console.error(err);
|
|
329
397
|
});
|
|
330
|
-
let
|
|
398
|
+
let newProject = {
|
|
331
399
|
builder: builder,
|
|
332
400
|
firstRunPromise: firstRunPromise,
|
|
401
|
+
projectPath: projectPath,
|
|
333
402
|
workspacePath: workspacePath,
|
|
334
403
|
isFirstRunComplete: false,
|
|
335
404
|
isFirstRunSuccessful: false,
|
|
336
405
|
configFilePath: configFilePath,
|
|
337
|
-
|
|
406
|
+
isStandaloneFileProject: false
|
|
338
407
|
};
|
|
339
|
-
this.
|
|
408
|
+
this.projects.push(newProject);
|
|
340
409
|
await firstRunPromise.then(() => {
|
|
341
|
-
|
|
342
|
-
|
|
410
|
+
newProject.isFirstRunComplete = true;
|
|
411
|
+
newProject.isFirstRunSuccessful = true;
|
|
343
412
|
}).catch(() => {
|
|
344
|
-
|
|
345
|
-
|
|
413
|
+
newProject.isFirstRunComplete = true;
|
|
414
|
+
newProject.isFirstRunSuccessful = false;
|
|
346
415
|
}).then(() => {
|
|
347
416
|
//if we found a deprecated brsconfig.json, add a diagnostic warning the user
|
|
348
417
|
if (configFilePath && path.basename(configFilePath) === 'brsconfig.json') {
|
|
@@ -351,13 +420,10 @@ class LanguageServer {
|
|
|
351
420
|
}
|
|
352
421
|
});
|
|
353
422
|
}
|
|
354
|
-
|
|
355
|
-
* @param srcPath The absolute path to the source file on disk
|
|
356
|
-
*/
|
|
357
|
-
async createStandaloneFileWorkspace(srcPath) {
|
|
423
|
+
async createStandaloneFileProject(srcPath) {
|
|
358
424
|
//skip this workspace if we already have it
|
|
359
|
-
if (this.
|
|
360
|
-
return this.
|
|
425
|
+
if (this.standaloneFileProjects[srcPath]) {
|
|
426
|
+
return this.standaloneFileProjects[srcPath];
|
|
361
427
|
}
|
|
362
428
|
let builder = new ProgramBuilder_1.ProgramBuilder();
|
|
363
429
|
//prevent clearing the console on run...this isn't the CLI so we want to keep a full log of everything
|
|
@@ -384,45 +450,46 @@ class LanguageServer {
|
|
|
384
450
|
] })).catch((err) => {
|
|
385
451
|
console.error(err);
|
|
386
452
|
});
|
|
387
|
-
let
|
|
453
|
+
let newProject = {
|
|
388
454
|
builder: builder,
|
|
389
455
|
firstRunPromise: firstRunPromise,
|
|
456
|
+
projectPath: srcPath,
|
|
390
457
|
workspacePath: srcPath,
|
|
391
458
|
isFirstRunComplete: false,
|
|
392
459
|
isFirstRunSuccessful: false,
|
|
393
460
|
configFilePath: configFilePath,
|
|
394
|
-
|
|
461
|
+
isStandaloneFileProject: true
|
|
395
462
|
};
|
|
396
|
-
this.
|
|
463
|
+
this.standaloneFileProjects[srcPath] = newProject;
|
|
397
464
|
await firstRunPromise.then(() => {
|
|
398
|
-
|
|
399
|
-
|
|
465
|
+
newProject.isFirstRunComplete = true;
|
|
466
|
+
newProject.isFirstRunSuccessful = true;
|
|
400
467
|
}).catch(() => {
|
|
401
|
-
|
|
402
|
-
|
|
468
|
+
newProject.isFirstRunComplete = true;
|
|
469
|
+
newProject.isFirstRunSuccessful = false;
|
|
403
470
|
});
|
|
404
|
-
return
|
|
471
|
+
return newProject;
|
|
405
472
|
}
|
|
406
|
-
|
|
407
|
-
let
|
|
408
|
-
for (let key in this.
|
|
409
|
-
|
|
473
|
+
getProjects() {
|
|
474
|
+
let projects = this.projects.slice();
|
|
475
|
+
for (let key in this.standaloneFileProjects) {
|
|
476
|
+
projects.push(this.standaloneFileProjects[key]);
|
|
410
477
|
}
|
|
411
|
-
return
|
|
478
|
+
return projects;
|
|
412
479
|
}
|
|
413
480
|
/**
|
|
414
481
|
* Provide a list of completion items based on the current cursor position
|
|
415
482
|
* @param textDocumentPosition
|
|
416
483
|
*/
|
|
417
|
-
async onCompletion(
|
|
484
|
+
async onCompletion(params) {
|
|
418
485
|
//ensure programs are initialized
|
|
419
|
-
await this.
|
|
420
|
-
let filePath = util_1.util.uriToPath(uri);
|
|
486
|
+
await this.waitAllProjectFirstRuns();
|
|
487
|
+
let filePath = util_1.util.uriToPath(params.textDocument.uri);
|
|
421
488
|
//wait until the file has settled
|
|
422
489
|
await this.keyedThrottler.onIdleOnce(filePath, true);
|
|
423
490
|
let completions = this
|
|
424
|
-
.
|
|
425
|
-
.flatMap(workspace => workspace.builder.program.getCompletions(filePath, position));
|
|
491
|
+
.getProjects()
|
|
492
|
+
.flatMap(workspace => workspace.builder.program.getCompletions(filePath, params.position));
|
|
426
493
|
for (let completion of completions) {
|
|
427
494
|
completion.commitCharacters = ['.'];
|
|
428
495
|
}
|
|
@@ -445,12 +512,12 @@ class LanguageServer {
|
|
|
445
512
|
}
|
|
446
513
|
async onCodeAction(params) {
|
|
447
514
|
//ensure programs are initialized
|
|
448
|
-
await this.
|
|
515
|
+
await this.waitAllProjectFirstRuns();
|
|
449
516
|
let srcPath = util_1.util.uriToPath(params.textDocument.uri);
|
|
450
517
|
//wait until the file has settled
|
|
451
518
|
await this.keyedThrottler.onIdleOnce(srcPath, true);
|
|
452
519
|
const codeActions = this
|
|
453
|
-
.
|
|
520
|
+
.getProjects()
|
|
454
521
|
//skip programs that don't have this file
|
|
455
522
|
.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
523
|
.flatMap(workspace => workspace.builder.program.getCodeActions(srcPath, params.range));
|
|
@@ -463,38 +530,42 @@ class LanguageServer {
|
|
|
463
530
|
return codeActions;
|
|
464
531
|
}
|
|
465
532
|
/**
|
|
466
|
-
*
|
|
533
|
+
* Remove a project from the language server
|
|
534
|
+
*/
|
|
535
|
+
removeProject(project) {
|
|
536
|
+
var _a;
|
|
537
|
+
const idx = this.projects.indexOf(project);
|
|
538
|
+
if (idx > -1) {
|
|
539
|
+
this.projects.splice(idx, 1);
|
|
540
|
+
}
|
|
541
|
+
(_a = project === null || project === void 0 ? void 0 : project.builder) === null || _a === void 0 ? void 0 : _a.dispose();
|
|
542
|
+
}
|
|
543
|
+
/**
|
|
544
|
+
* Reload each of the specified workspaces
|
|
467
545
|
*/
|
|
468
|
-
async
|
|
469
|
-
|
|
470
|
-
await Promise.all(workspaces.map(async (workspace) => {
|
|
546
|
+
async reloadProjects(projects) {
|
|
547
|
+
await Promise.all(projects.map(async (project) => {
|
|
471
548
|
//ensure the workspace has finished starting up
|
|
472
549
|
try {
|
|
473
|
-
await
|
|
550
|
+
await project.firstRunPromise;
|
|
474
551
|
}
|
|
475
552
|
catch (e) { }
|
|
476
553
|
//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
|
-
}
|
|
554
|
+
if (project.isStandaloneFileProject === false) {
|
|
555
|
+
this.removeProject(project);
|
|
485
556
|
//create a new workspace/brs program
|
|
486
|
-
await this.
|
|
557
|
+
await this.createProject(project.projectPath, project.workspacePath);
|
|
487
558
|
//handle temp workspace
|
|
488
559
|
}
|
|
489
560
|
else {
|
|
490
|
-
|
|
491
|
-
delete this.
|
|
492
|
-
await this.
|
|
561
|
+
project.builder.dispose();
|
|
562
|
+
delete this.standaloneFileProjects[project.projectPath];
|
|
563
|
+
await this.createStandaloneFileProject(project.projectPath);
|
|
493
564
|
}
|
|
494
565
|
}));
|
|
495
|
-
if (
|
|
566
|
+
if (projects.length > 0) {
|
|
496
567
|
//wait for all of the programs to finish starting up
|
|
497
|
-
await this.
|
|
568
|
+
await this.waitAllProjectFirstRuns();
|
|
498
569
|
// valdiate all workspaces
|
|
499
570
|
this.validateAllThrottled(); //eslint-disable-line
|
|
500
571
|
}
|
|
@@ -511,42 +582,42 @@ class LanguageServer {
|
|
|
511
582
|
*
|
|
512
583
|
* Sometimes files that used to be included are now excluded, so those open files need to be re-processed as standalone
|
|
513
584
|
*/
|
|
514
|
-
async
|
|
585
|
+
async synchronizeStandaloneProjects() {
|
|
515
586
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
516
587
|
//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 =
|
|
588
|
+
for (let standaloneFilePath in this.standaloneFileProjects) {
|
|
589
|
+
let standaloneProject = this.standaloneFileProjects[standaloneFilePath];
|
|
590
|
+
for (let project of this.projects) {
|
|
591
|
+
await standaloneProject.firstRunPromise;
|
|
592
|
+
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
593
|
//destroy this standalone workspace because the file has now been included in an actual workspace,
|
|
523
594
|
//or if the workspace wants the file
|
|
524
|
-
if (((_f = (_e =
|
|
525
|
-
|
|
526
|
-
delete this.
|
|
595
|
+
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) {
|
|
596
|
+
standaloneProject.builder.dispose();
|
|
597
|
+
delete this.standaloneFileProjects[standaloneFilePath];
|
|
527
598
|
}
|
|
528
599
|
}
|
|
529
600
|
}
|
|
530
|
-
//create standalone
|
|
601
|
+
//create standalone projects for open files that no longer have a project
|
|
531
602
|
let textDocuments = this.documents.all();
|
|
532
603
|
outer: for (let textDocument of textDocuments) {
|
|
533
604
|
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) {
|
|
605
|
+
for (let project of this.getProjects()) {
|
|
606
|
+
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));
|
|
607
|
+
//if this project has the file, or it wants the file, do NOT make a standaloneProject for this file
|
|
608
|
+
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
609
|
continue outer;
|
|
540
610
|
}
|
|
541
611
|
}
|
|
542
612
|
//if we got here, no workspace has this file, so make a standalone file workspace
|
|
543
|
-
let
|
|
544
|
-
await
|
|
613
|
+
let project = await this.createStandaloneFileProject(filePath);
|
|
614
|
+
await project.firstRunPromise;
|
|
545
615
|
}
|
|
546
616
|
}
|
|
547
617
|
async onDidChangeConfiguration() {
|
|
548
618
|
if (this.hasConfigurationCapability) {
|
|
549
|
-
|
|
619
|
+
//if the user changes any config value, just mass-reload all projects
|
|
620
|
+
await this.reloadProjects(this.getProjects());
|
|
550
621
|
// Reset all cached document settings
|
|
551
622
|
}
|
|
552
623
|
else {
|
|
@@ -564,14 +635,14 @@ class LanguageServer {
|
|
|
564
635
|
*/
|
|
565
636
|
async onDidChangeWatchedFiles(params) {
|
|
566
637
|
//ensure programs are initialized
|
|
567
|
-
await this.
|
|
638
|
+
await this.waitAllProjectFirstRuns();
|
|
568
639
|
this.connection.sendNotification('build-status', 'building');
|
|
569
|
-
let
|
|
640
|
+
let projects = this.getProjects();
|
|
570
641
|
//convert all file paths to absolute paths
|
|
571
642
|
let changes = params.changes.map(x => {
|
|
572
643
|
return {
|
|
573
644
|
type: x.type,
|
|
574
|
-
srcPath: util_1.standardizePath `${vscode_uri_1.URI.parse(x.uri).fsPath}`
|
|
645
|
+
srcPath: (0, util_1.standardizePath) `${vscode_uri_1.URI.parse(x.uri).fsPath}`
|
|
575
646
|
};
|
|
576
647
|
});
|
|
577
648
|
let keys = changes.map(x => x.srcPath);
|
|
@@ -579,28 +650,32 @@ class LanguageServer {
|
|
|
579
650
|
changes = changes.filter(x => keys.includes(x.srcPath));
|
|
580
651
|
//if we have changes to work with
|
|
581
652
|
if (changes.length > 0) {
|
|
653
|
+
//if any bsconfig files were added or deleted, re-sync all projects instead of the more specific approach below
|
|
654
|
+
if (changes.find(x => (x.type === node_1.FileChangeType.Created || x.type === node_1.FileChangeType.Deleted) && path.basename(x.srcPath).toLowerCase() === 'bsconfig.json')) {
|
|
655
|
+
return this.syncProjects();
|
|
656
|
+
}
|
|
582
657
|
//reload any workspace whose bsconfig.json file has changed
|
|
583
658
|
{
|
|
584
|
-
let
|
|
659
|
+
let projectsToReload = [];
|
|
585
660
|
//get the file paths as a string array
|
|
586
661
|
let filePaths = changes.map((x) => x.srcPath);
|
|
587
|
-
for (let
|
|
588
|
-
if (
|
|
589
|
-
|
|
662
|
+
for (let project of projects) {
|
|
663
|
+
if (project.configFilePath && filePaths.includes(project.configFilePath)) {
|
|
664
|
+
projectsToReload.push(project);
|
|
590
665
|
}
|
|
591
666
|
}
|
|
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.
|
|
667
|
+
if (projectsToReload.length > 0) {
|
|
668
|
+
//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
|
|
669
|
+
//reload any projects that need to be reloaded
|
|
670
|
+
await this.reloadProjects(projectsToReload);
|
|
596
671
|
}
|
|
597
|
-
//
|
|
598
|
-
|
|
672
|
+
//reassign `projects` to the non-reloaded projects
|
|
673
|
+
projects = projects.filter(x => !projectsToReload.includes(x));
|
|
599
674
|
}
|
|
600
675
|
//convert created folders into a list of files of their contents
|
|
601
676
|
const directoryChanges = changes
|
|
602
677
|
//get only creation items
|
|
603
|
-
.filter(change => change.type ===
|
|
678
|
+
.filter(change => change.type === node_1.FileChangeType.Created)
|
|
604
679
|
//keep only the directories
|
|
605
680
|
.filter(change => util_1.util.isDirectorySync(change.srcPath));
|
|
606
681
|
//remove the created directories from the changes array (we will add back each of their files next)
|
|
@@ -613,22 +688,22 @@ class LanguageServer {
|
|
|
613
688
|
.filter(dirPath => !dirPath.includes('.roku-deploy-staging'))
|
|
614
689
|
//get the files for each folder recursively
|
|
615
690
|
.flatMap(dirPath => {
|
|
616
|
-
//
|
|
617
|
-
let
|
|
618
|
-
|
|
619
|
-
|
|
691
|
+
//look up all files
|
|
692
|
+
let files = fastGlob.sync('**/*', {
|
|
693
|
+
absolute: true,
|
|
694
|
+
cwd: roku_deploy_1.util.toForwardSlashes(dirPath)
|
|
620
695
|
});
|
|
621
696
|
return files.map(x => {
|
|
622
697
|
return {
|
|
623
|
-
type:
|
|
624
|
-
srcPath: util_1.standardizePath `${x}`
|
|
698
|
+
type: node_1.FileChangeType.Created,
|
|
699
|
+
srcPath: (0, util_1.standardizePath) `${x}`
|
|
625
700
|
};
|
|
626
701
|
});
|
|
627
702
|
});
|
|
628
703
|
//add the new file changes to the changes array.
|
|
629
704
|
changes.push(...newFileChanges);
|
|
630
705
|
//give every workspace the chance to handle file changes
|
|
631
|
-
await Promise.all(
|
|
706
|
+
await Promise.all(projects.map((project) => this.handleFileChanges(project, changes)));
|
|
632
707
|
}
|
|
633
708
|
this.connection.sendNotification('build-status', 'success');
|
|
634
709
|
}
|
|
@@ -637,13 +712,13 @@ class LanguageServer {
|
|
|
637
712
|
* any file changes you receive with no unexpected side-effects
|
|
638
713
|
* @param changes
|
|
639
714
|
*/
|
|
640
|
-
async handleFileChanges(
|
|
715
|
+
async handleFileChanges(project, changes) {
|
|
641
716
|
//this loop assumes paths are both file paths and folder paths, which eliminates the need to detect.
|
|
642
717
|
//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
718
|
let consumeCount = 0;
|
|
644
719
|
await Promise.all(changes.map(async (change) => {
|
|
645
720
|
await this.keyedThrottler.run(change.srcPath, async () => {
|
|
646
|
-
consumeCount += await this.handleFileChange(
|
|
721
|
+
consumeCount += await this.handleFileChange(project, change) ? 1 : 0;
|
|
647
722
|
});
|
|
648
723
|
}));
|
|
649
724
|
if (consumeCount > 0) {
|
|
@@ -655,14 +730,12 @@ class LanguageServer {
|
|
|
655
730
|
* any file changes you receive with no unexpected side-effects
|
|
656
731
|
* @param changes
|
|
657
732
|
*/
|
|
658
|
-
async handleFileChange(
|
|
659
|
-
const program =
|
|
660
|
-
const options = workspace.builder.options;
|
|
661
|
-
const rootDir = workspace.builder.rootDir;
|
|
733
|
+
async handleFileChange(project, change) {
|
|
734
|
+
const { program, options, rootDir } = project.builder;
|
|
662
735
|
//deleted
|
|
663
|
-
if (change.type ===
|
|
736
|
+
if (change.type === node_1.FileChangeType.Deleted) {
|
|
664
737
|
//try to act on this path as a directory
|
|
665
|
-
|
|
738
|
+
project.builder.program.removeFilesInFolder(change.srcPath);
|
|
666
739
|
//if this is a file loaded in the program, remove it
|
|
667
740
|
if (program.hasFile(change.srcPath)) {
|
|
668
741
|
program.removeFile(change.srcPath);
|
|
@@ -673,16 +746,16 @@ class LanguageServer {
|
|
|
673
746
|
}
|
|
674
747
|
//created
|
|
675
748
|
}
|
|
676
|
-
else if (change.type ===
|
|
749
|
+
else if (change.type === node_1.FileChangeType.Created) {
|
|
677
750
|
// thanks to `onDidChangeWatchedFiles`, we can safely assume that all "Created" changes are file paths, (not directories)
|
|
678
751
|
//get the dest path for this file.
|
|
679
|
-
let destPath = rokuDeploy.getDestPath(change.srcPath, options.files, rootDir);
|
|
752
|
+
let destPath = roku_deploy_1.rokuDeploy.getDestPath(change.srcPath, options.files, rootDir);
|
|
680
753
|
//if we got a dest path, then the program wants this file
|
|
681
754
|
if (destPath) {
|
|
682
|
-
program.
|
|
755
|
+
program.setFile({
|
|
683
756
|
src: change.srcPath,
|
|
684
|
-
dest: rokuDeploy.getDestPath(change.srcPath, options.files, rootDir)
|
|
685
|
-
}, await
|
|
757
|
+
dest: roku_deploy_1.rokuDeploy.getDestPath(change.srcPath, options.files, rootDir)
|
|
758
|
+
}, await project.builder.getFileContents(change.srcPath));
|
|
686
759
|
return true;
|
|
687
760
|
}
|
|
688
761
|
else {
|
|
@@ -695,10 +768,10 @@ class LanguageServer {
|
|
|
695
768
|
//sometimes "changed" events are emitted on files that were actually deleted,
|
|
696
769
|
//so determine file existance and act accordingly
|
|
697
770
|
if (await util_1.util.pathExists(change.srcPath)) {
|
|
698
|
-
program.
|
|
771
|
+
program.setFile({
|
|
699
772
|
src: change.srcPath,
|
|
700
|
-
dest: rokuDeploy.getDestPath(change.srcPath, options.files, rootDir)
|
|
701
|
-
}, await
|
|
773
|
+
dest: roku_deploy_1.rokuDeploy.getDestPath(change.srcPath, options.files, rootDir)
|
|
774
|
+
}, await project.builder.getFileContents(change.srcPath));
|
|
702
775
|
}
|
|
703
776
|
else {
|
|
704
777
|
program.removeFile(change.srcPath);
|
|
@@ -708,84 +781,77 @@ class LanguageServer {
|
|
|
708
781
|
}
|
|
709
782
|
async onHover(params) {
|
|
710
783
|
//ensure programs are initialized
|
|
711
|
-
await this.
|
|
712
|
-
|
|
713
|
-
let
|
|
714
|
-
let hovers = await Promise.all(Array.prototype.concat.call([],
|
|
784
|
+
await this.waitAllProjectFirstRuns();
|
|
785
|
+
const srcPath = util_1.util.uriToPath(params.textDocument.uri);
|
|
786
|
+
let projects = this.getProjects();
|
|
787
|
+
let hovers = await Promise.all(Array.prototype.concat.call([], projects.map(async (x) => x.builder.program.getHover(srcPath, params.position))));
|
|
715
788
|
//return the first non-falsey hover. TODO is there a way to handle multiple hover results?
|
|
716
789
|
let hover = hovers.filter((x) => !!x)[0];
|
|
717
|
-
//TODO improve this to support more than just .brs files
|
|
718
|
-
if (hover === null || hover === void 0 ? void 0 : hover.contents) {
|
|
719
|
-
//create fenced code block to get colorization
|
|
720
|
-
hover.contents = {
|
|
721
|
-
//TODO - make the program.getHover call figure out what language this is for
|
|
722
|
-
language: 'brightscript',
|
|
723
|
-
value: hover.contents
|
|
724
|
-
};
|
|
725
|
-
}
|
|
726
790
|
return hover;
|
|
727
791
|
}
|
|
728
|
-
async onDocumentClose(
|
|
729
|
-
|
|
730
|
-
let
|
|
792
|
+
async onDocumentClose(event) {
|
|
793
|
+
const { document } = event;
|
|
794
|
+
let filePath = vscode_uri_1.URI.parse(document.uri).fsPath;
|
|
795
|
+
let standaloneFileProject = this.standaloneFileProjects[filePath];
|
|
731
796
|
//if this was a temp file, close it
|
|
732
|
-
if (
|
|
733
|
-
await
|
|
734
|
-
|
|
735
|
-
delete this.
|
|
797
|
+
if (standaloneFileProject) {
|
|
798
|
+
await standaloneFileProject.firstRunPromise;
|
|
799
|
+
standaloneFileProject.builder.dispose();
|
|
800
|
+
delete this.standaloneFileProjects[filePath];
|
|
736
801
|
await this.sendDiagnostics();
|
|
737
802
|
}
|
|
738
803
|
}
|
|
739
|
-
async validateTextDocument(
|
|
804
|
+
async validateTextDocument(event) {
|
|
805
|
+
const { document } = event;
|
|
740
806
|
//ensure programs are initialized
|
|
741
|
-
await this.
|
|
742
|
-
let filePath = vscode_uri_1.URI.parse(
|
|
807
|
+
await this.waitAllProjectFirstRuns();
|
|
808
|
+
let filePath = vscode_uri_1.URI.parse(document.uri).fsPath;
|
|
743
809
|
try {
|
|
744
810
|
//throttle file processing. first call is run immediately, and then the last call is processed.
|
|
745
811
|
await this.keyedThrottler.run(filePath, () => {
|
|
746
812
|
var _a;
|
|
747
813
|
this.connection.sendNotification('build-status', 'building');
|
|
748
|
-
let documentText =
|
|
749
|
-
for (const
|
|
814
|
+
let documentText = document.getText();
|
|
815
|
+
for (const project of this.getProjects()) {
|
|
750
816
|
//only add or replace existing files. All of the files in the project should
|
|
751
817
|
//have already been loaded by other means
|
|
752
|
-
if (
|
|
753
|
-
let rootDir = (_a =
|
|
754
|
-
let dest = rokuDeploy.getDestPath(filePath,
|
|
755
|
-
|
|
818
|
+
if (project.builder.program.hasFile(filePath)) {
|
|
819
|
+
let rootDir = (_a = project.builder.program.options.rootDir) !== null && _a !== void 0 ? _a : project.builder.program.options.cwd;
|
|
820
|
+
let dest = roku_deploy_1.rokuDeploy.getDestPath(filePath, project.builder.program.options.files, rootDir);
|
|
821
|
+
project.builder.program.setFile({
|
|
756
822
|
src: filePath,
|
|
757
823
|
dest: dest
|
|
758
824
|
}, documentText);
|
|
759
825
|
}
|
|
760
826
|
}
|
|
761
827
|
});
|
|
762
|
-
// validate all
|
|
828
|
+
// validate all projects
|
|
763
829
|
await this.validateAllThrottled();
|
|
764
830
|
}
|
|
765
831
|
catch (e) {
|
|
766
|
-
this.sendCriticalFailure(`Critical error parsing/ validating ${filePath}: ${e.message}`);
|
|
832
|
+
this.sendCriticalFailure(`Critical error parsing / validating ${filePath}: ${e.message}`);
|
|
767
833
|
}
|
|
768
834
|
}
|
|
769
835
|
async validateAll() {
|
|
770
836
|
var _a;
|
|
771
837
|
try {
|
|
772
838
|
//synchronize parsing for open files that were included/excluded from projects
|
|
773
|
-
await this.
|
|
774
|
-
let
|
|
839
|
+
await this.synchronizeStandaloneProjects();
|
|
840
|
+
let projects = this.getProjects();
|
|
775
841
|
//validate all programs
|
|
776
|
-
await Promise.all(
|
|
842
|
+
await Promise.all(projects.map((x) => x.builder.program.validate()));
|
|
777
843
|
await this.sendDiagnostics();
|
|
778
844
|
}
|
|
779
845
|
catch (e) {
|
|
780
846
|
this.connection.console.error(e);
|
|
781
|
-
this.sendCriticalFailure(`Critical error validating
|
|
847
|
+
this.sendCriticalFailure(`Critical error validating project: ${e.message}${(_a = e.stack) !== null && _a !== void 0 ? _a : ''}`);
|
|
782
848
|
}
|
|
783
849
|
this.connection.sendNotification('build-status', 'success');
|
|
784
850
|
}
|
|
785
851
|
async onWorkspaceSymbol(params) {
|
|
786
|
-
await this.
|
|
787
|
-
const results = util_1.util.flatMap(await Promise.all(this.
|
|
788
|
-
return
|
|
852
|
+
await this.waitAllProjectFirstRuns();
|
|
853
|
+
const results = util_1.util.flatMap(await Promise.all(this.getProjects().map(project => {
|
|
854
|
+
return project.builder.program.getWorkspaceSymbols();
|
|
789
855
|
})), c => c);
|
|
790
856
|
// Remove duplicates
|
|
791
857
|
const allSymbols = Object.values(results.reduce((map, symbol) => {
|
|
@@ -796,31 +862,31 @@ class LanguageServer {
|
|
|
796
862
|
return allSymbols;
|
|
797
863
|
}
|
|
798
864
|
async onDocumentSymbol(params) {
|
|
799
|
-
await this.
|
|
865
|
+
await this.waitAllProjectFirstRuns();
|
|
800
866
|
await this.keyedThrottler.onIdleOnce(util_1.util.uriToPath(params.textDocument.uri), true);
|
|
801
867
|
const srcPath = util_1.util.uriToPath(params.textDocument.uri);
|
|
802
|
-
for (const
|
|
803
|
-
const file =
|
|
804
|
-
if (reflection_1.isBrsFile(file)) {
|
|
868
|
+
for (const project of this.getProjects()) {
|
|
869
|
+
const file = project.builder.program.getFile(srcPath);
|
|
870
|
+
if ((0, reflection_1.isBrsFile)(file)) {
|
|
805
871
|
return file.getDocumentSymbols();
|
|
806
872
|
}
|
|
807
873
|
}
|
|
808
874
|
}
|
|
809
875
|
async onDefinition(params) {
|
|
810
|
-
await this.
|
|
876
|
+
await this.waitAllProjectFirstRuns();
|
|
811
877
|
const srcPath = util_1.util.uriToPath(params.textDocument.uri);
|
|
812
|
-
const results = util_1.util.flatMap(await Promise.all(this.
|
|
813
|
-
return
|
|
878
|
+
const results = util_1.util.flatMap(await Promise.all(this.getProjects().map(project => {
|
|
879
|
+
return project.builder.program.getDefinition(srcPath, params.position);
|
|
814
880
|
})), c => c);
|
|
815
881
|
return results;
|
|
816
882
|
}
|
|
817
883
|
async onSignatureHelp(params) {
|
|
818
884
|
var _a, _b, _c;
|
|
819
|
-
await this.
|
|
885
|
+
await this.waitAllProjectFirstRuns();
|
|
820
886
|
const filepath = util_1.util.uriToPath(params.textDocument.uri);
|
|
821
887
|
await this.keyedThrottler.onIdleOnce(filepath, true);
|
|
822
888
|
try {
|
|
823
|
-
const signatures = util_1.util.flatMap(await Promise.all(this.
|
|
889
|
+
const signatures = util_1.util.flatMap(await Promise.all(this.getProjects().map(project => project.builder.program.getSignatureHelp(filepath, params.position))), c => c);
|
|
824
890
|
const activeSignature = signatures.length > 0 ? 0 : null;
|
|
825
891
|
const activeParameter = activeSignature >= 0 ? (_a = signatures[activeSignature]) === null || _a === void 0 ? void 0 : _a.index : null;
|
|
826
892
|
let results = {
|
|
@@ -840,17 +906,31 @@ class LanguageServer {
|
|
|
840
906
|
}
|
|
841
907
|
}
|
|
842
908
|
async onReferences(params) {
|
|
843
|
-
await this.
|
|
909
|
+
await this.waitAllProjectFirstRuns();
|
|
844
910
|
const position = params.position;
|
|
845
911
|
const srcPath = util_1.util.uriToPath(params.textDocument.uri);
|
|
846
|
-
const results = util_1.util.flatMap(await Promise.all(this.
|
|
847
|
-
return
|
|
912
|
+
const results = util_1.util.flatMap(await Promise.all(this.getProjects().map(project => {
|
|
913
|
+
return project.builder.program.getReferences(srcPath, position);
|
|
848
914
|
})), c => c);
|
|
849
915
|
return results.filter((r) => r);
|
|
850
916
|
}
|
|
917
|
+
async onFullSemanticTokens(params) {
|
|
918
|
+
await this.waitAllProjectFirstRuns();
|
|
919
|
+
await this.keyedThrottler.onIdleOnce(util_1.util.uriToPath(params.textDocument.uri), true);
|
|
920
|
+
const srcPath = util_1.util.uriToPath(params.textDocument.uri);
|
|
921
|
+
for (const project of this.projects) {
|
|
922
|
+
//find the first program that has this file, since it would be incredibly inefficient to generate semantic tokens for the same file multiple times.
|
|
923
|
+
if (project.builder.program.hasFile(srcPath)) {
|
|
924
|
+
let semanticTokens = project.builder.program.getSemanticTokens(srcPath);
|
|
925
|
+
return {
|
|
926
|
+
data: (0, SemanticTokenUtils_1.encodeSemanticTokens)(semanticTokens)
|
|
927
|
+
};
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
}
|
|
851
931
|
async sendDiagnostics() {
|
|
852
932
|
//Get only the changes to diagnostics since the last time we sent them to the client
|
|
853
|
-
const patch = await this.diagnosticCollection.getPatch(this.
|
|
933
|
+
const patch = await this.diagnosticCollection.getPatch(this.projects);
|
|
854
934
|
for (let filePath in patch) {
|
|
855
935
|
const diagnostics = patch[filePath].map(d => util_1.util.toDiagnostic(d));
|
|
856
936
|
this.connection.sendDiagnostics({
|
|
@@ -860,9 +940,11 @@ class LanguageServer {
|
|
|
860
940
|
}
|
|
861
941
|
}
|
|
862
942
|
async onExecuteCommand(params) {
|
|
863
|
-
await this.
|
|
943
|
+
await this.waitAllProjectFirstRuns();
|
|
864
944
|
if (params.command === CustomCommands.TranspileFile) {
|
|
865
|
-
|
|
945
|
+
const result = await this.transpileFile(params.arguments[0]);
|
|
946
|
+
//back-compat: include `pathAbsolute` property so older vscode versions still work
|
|
947
|
+
result.pathAbsolute = result.srcPath;
|
|
866
948
|
}
|
|
867
949
|
}
|
|
868
950
|
/**
|
|
@@ -870,12 +952,11 @@ class LanguageServer {
|
|
|
870
952
|
*/
|
|
871
953
|
async transpileFile(srcPath) {
|
|
872
954
|
//wait all program first runs
|
|
873
|
-
await this.
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
return workspace.builder.program.getTranspiledFileContents(srcPath);
|
|
955
|
+
await this.waitAllProjectFirstRuns();
|
|
956
|
+
//find the first project that has this file
|
|
957
|
+
for (let project of this.getProjects()) {
|
|
958
|
+
if (project.builder.program.hasFile(srcPath)) {
|
|
959
|
+
return project.builder.program.getTranspiledFileContents(srcPath);
|
|
879
960
|
}
|
|
880
961
|
}
|
|
881
962
|
}
|
|
@@ -930,6 +1011,9 @@ __decorate([
|
|
|
930
1011
|
__decorate([
|
|
931
1012
|
AddStackToErrorMessage
|
|
932
1013
|
], LanguageServer.prototype, "onReferences", null);
|
|
1014
|
+
__decorate([
|
|
1015
|
+
AddStackToErrorMessage
|
|
1016
|
+
], LanguageServer.prototype, "onFullSemanticTokens", null);
|
|
933
1017
|
__decorate([
|
|
934
1018
|
AddStackToErrorMessage
|
|
935
1019
|
], LanguageServer.prototype, "onExecuteCommand", null);
|