brighterscript 1.0.0-alpha.50 → 1.0.0-alpha.51
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/README.md +3 -0
- package/bsconfig.schema.json +75 -0
- package/dist/BsConfig.d.ts +90 -5
- package/dist/CodeActionUtil.d.ts +17 -0
- package/dist/CodeActionUtil.js.map +1 -1
- package/dist/CommentFlagProcessor.d.ts +16 -12
- package/dist/CommentFlagProcessor.js +141 -59
- package/dist/CommentFlagProcessor.js.map +1 -1
- package/dist/CrossScopeValidator.js +13 -5
- package/dist/CrossScopeValidator.js.map +1 -1
- package/dist/DiagnosticManager.d.ts +1 -0
- package/dist/DiagnosticManager.js +25 -9
- package/dist/DiagnosticManager.js.map +1 -1
- package/dist/DiagnosticMessages.d.ts +61 -17
- package/dist/DiagnosticMessages.js +78 -24
- package/dist/DiagnosticMessages.js.map +1 -1
- package/dist/LanguageServer.d.ts +39 -2
- package/dist/LanguageServer.js +142 -5
- package/dist/LanguageServer.js.map +1 -1
- package/dist/Program.d.ts +62 -1
- package/dist/Program.js +185 -13
- package/dist/Program.js.map +1 -1
- package/dist/ProgramBuilder.d.ts +1 -8
- package/dist/ProgramBuilder.js +31 -11
- package/dist/ProgramBuilder.js.map +1 -1
- package/dist/Scope.d.ts +87 -6
- package/dist/Scope.js +76 -31
- package/dist/Scope.js.map +1 -1
- package/dist/ScopeNamespaceLookup.d.ts +73 -0
- package/dist/ScopeNamespaceLookup.js +242 -0
- package/dist/ScopeNamespaceLookup.js.map +1 -0
- package/dist/SymbolTable.d.ts +9 -2
- package/dist/SymbolTable.js +24 -14
- package/dist/SymbolTable.js.map +1 -1
- package/dist/astUtils/CachedLookups.js +3 -0
- package/dist/astUtils/CachedLookups.js.map +1 -1
- package/dist/astUtils/reflection.d.ts +4 -1
- package/dist/astUtils/reflection.js +24 -4
- package/dist/astUtils/reflection.js.map +1 -1
- package/dist/astUtils/visitors.d.ts +2 -1
- package/dist/astUtils/visitors.js.map +1 -1
- package/dist/bscPlugin/BscPlugin.d.ts +4 -2
- package/dist/bscPlugin/BscPlugin.js +10 -2
- package/dist/bscPlugin/BscPlugin.js.map +1 -1
- package/dist/bscPlugin/CallExpressionInfo.d.ts +1 -1
- package/dist/bscPlugin/CallExpressionInfo.js +1 -2
- package/dist/bscPlugin/CallExpressionInfo.js.map +1 -1
- package/dist/bscPlugin/FileWriter.d.ts +13 -0
- package/dist/bscPlugin/FileWriter.js +56 -1
- package/dist/bscPlugin/FileWriter.js.map +1 -1
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.d.ts +106 -5
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.js +630 -126
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.js.map +1 -1
- package/dist/bscPlugin/codeActions/FixAllCodeActionsProcessor.d.ts +17 -0
- package/dist/bscPlugin/codeActions/FixAllCodeActionsProcessor.js +66 -0
- package/dist/bscPlugin/codeActions/FixAllCodeActionsProcessor.js.map +1 -0
- package/dist/bscPlugin/codeActions/codeActionHelpers.d.ts +18 -0
- package/dist/bscPlugin/codeActions/codeActionHelpers.js +31 -0
- package/dist/bscPlugin/codeActions/codeActionHelpers.js.map +1 -0
- package/dist/bscPlugin/completions/CompletionsProcessor.d.ts +1 -1
- package/dist/bscPlugin/completions/CompletionsProcessor.js +5 -5
- package/dist/bscPlugin/completions/CompletionsProcessor.js.map +1 -1
- package/dist/bscPlugin/definition/DefinitionProvider.js +8 -0
- package/dist/bscPlugin/definition/DefinitionProvider.js.map +1 -1
- package/dist/bscPlugin/hover/HoverProcessor.js +11 -3
- package/dist/bscPlugin/hover/HoverProcessor.js.map +1 -1
- package/dist/bscPlugin/selectionRanges/SelectionRangesProcessor.d.ts +7 -0
- package/dist/bscPlugin/selectionRanges/SelectionRangesProcessor.js +77 -0
- package/dist/bscPlugin/selectionRanges/SelectionRangesProcessor.js.map +1 -0
- package/dist/bscPlugin/serialize/FileSerializer.d.ts +1 -1
- package/dist/bscPlugin/serialize/FileSerializer.js +12 -7
- package/dist/bscPlugin/serialize/FileSerializer.js.map +1 -1
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.d.ts +7 -0
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.js +87 -1
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.js.map +1 -1
- package/dist/bscPlugin/validation/BrsFileValidator.d.ts +14 -0
- package/dist/bscPlugin/validation/BrsFileValidator.js +97 -21
- package/dist/bscPlugin/validation/BrsFileValidator.js.map +1 -1
- package/dist/bscPlugin/validation/ScopeValidator.d.ts +17 -0
- package/dist/bscPlugin/validation/ScopeValidator.js +162 -4
- package/dist/bscPlugin/validation/ScopeValidator.js.map +1 -1
- package/dist/bscPlugin/validation/XmlFileValidator.js +14 -0
- package/dist/bscPlugin/validation/XmlFileValidator.js.map +1 -1
- package/dist/cli.js +13 -0
- package/dist/cli.js.map +1 -1
- package/dist/diagnosticUtils.d.ts +51 -1
- package/dist/diagnosticUtils.js +222 -1
- package/dist/diagnosticUtils.js.map +1 -1
- package/dist/files/BrsFile.d.ts +18 -2
- package/dist/files/BrsFile.js +87 -6
- package/dist/files/BrsFile.js.map +1 -1
- package/dist/files/XmlFile.js +2 -1
- package/dist/files/XmlFile.js.map +1 -1
- package/dist/interfaces.d.ts +68 -23
- package/dist/interfaces.js.map +1 -1
- package/dist/lexer/Lexer.js +4 -5
- package/dist/lexer/Lexer.js.map +1 -1
- package/dist/lexer/Token.d.ts +1 -1
- package/dist/lexer/TokenKind.d.ts +8 -0
- package/dist/lexer/TokenKind.js +21 -1
- package/dist/lexer/TokenKind.js.map +1 -1
- package/dist/lsp/LspProject.d.ts +49 -1
- package/dist/lsp/Project.d.ts +33 -1
- package/dist/lsp/Project.js +129 -4
- package/dist/lsp/Project.js.map +1 -1
- package/dist/lsp/ProjectManager.d.ts +48 -2
- package/dist/lsp/ProjectManager.js +152 -9
- package/dist/lsp/ProjectManager.js.map +1 -1
- package/dist/lsp/worker/WorkerThreadProject.d.ts +27 -2
- package/dist/lsp/worker/WorkerThreadProject.js +16 -0
- package/dist/lsp/worker/WorkerThreadProject.js.map +1 -1
- package/dist/parser/AstNode.d.ts +3 -1
- package/dist/parser/AstNode.js +2 -0
- package/dist/parser/AstNode.js.map +1 -1
- package/dist/parser/Expression.d.ts +54 -5
- package/dist/parser/Expression.js +112 -7
- package/dist/parser/Expression.js.map +1 -1
- package/dist/parser/Parser.d.ts +24 -1
- package/dist/parser/Parser.js +180 -41
- package/dist/parser/Parser.js.map +1 -1
- package/dist/parser/SGParser.d.ts +1 -0
- package/dist/parser/SGParser.js +9 -0
- package/dist/parser/SGParser.js.map +1 -1
- package/dist/parser/Statement.d.ts +6 -1
- package/dist/parser/Statement.js +22 -14
- package/dist/parser/Statement.js.map +1 -1
- package/dist/parser/TranspileState.d.ts +4 -2
- package/dist/parser/TranspileState.js +10 -4
- package/dist/parser/TranspileState.js.map +1 -1
- package/dist/roku-types/data.json +210 -3
- package/dist/types/ArrayType.js +6 -1
- package/dist/types/ArrayType.js.map +1 -1
- package/dist/types/BooleanType.js +1 -1
- package/dist/types/BooleanType.js.map +1 -1
- package/dist/types/CallFuncableType.d.ts +1 -1
- package/dist/types/ClassType.js +3 -0
- package/dist/types/ClassType.js.map +1 -1
- package/dist/types/ComponentType.js +3 -0
- package/dist/types/ComponentType.js.map +1 -1
- package/dist/types/EnumType.js +3 -0
- package/dist/types/EnumType.js.map +1 -1
- package/dist/types/IntersectionType.js +3 -0
- package/dist/types/IntersectionType.js.map +1 -1
- package/dist/types/ReferenceType.js +6 -0
- package/dist/types/ReferenceType.js.map +1 -1
- package/dist/types/TypeStatementType.d.ts +1 -0
- package/dist/types/TypeStatementType.js +12 -1
- package/dist/types/TypeStatementType.js.map +1 -1
- package/dist/types/TypedFunctionType.js +20 -10
- package/dist/types/TypedFunctionType.js.map +1 -1
- package/dist/types/UnionType.js +3 -0
- package/dist/types/UnionType.js.map +1 -1
- package/dist/types/helpers.js +6 -0
- package/dist/types/helpers.js.map +1 -1
- package/dist/util.d.ts +42 -3
- package/dist/util.js +131 -7
- package/dist/util.js.map +1 -1
- package/package.json +24 -26
- package/dist/astUtils/CachedLookups.spec.d.ts +0 -1
- package/dist/astUtils/CachedLookups.spec.js +0 -39
- package/dist/astUtils/CachedLookups.spec.js.map +0 -1
- package/dist/astUtils/Editor.spec.d.ts +0 -1
- package/dist/astUtils/Editor.spec.js +0 -258
- package/dist/astUtils/Editor.spec.js.map +0 -1
- package/dist/astUtils/creators.spec.d.ts +0 -1
- package/dist/astUtils/creators.spec.js +0 -21
- package/dist/astUtils/creators.spec.js.map +0 -1
- package/dist/astUtils/reflection.spec.d.ts +0 -1
- package/dist/astUtils/reflection.spec.js +0 -392
- package/dist/astUtils/reflection.spec.js.map +0 -1
- package/dist/astUtils/stackedVisitor.spec.d.ts +0 -1
- package/dist/astUtils/stackedVisitor.spec.js +0 -79
- package/dist/astUtils/stackedVisitor.spec.js.map +0 -1
- package/dist/astUtils/visitors.spec.d.ts +0 -1
- package/dist/astUtils/visitors.spec.js +0 -1432
- package/dist/astUtils/visitors.spec.js.map +0 -1
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.d.ts +0 -1
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js +0 -311
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js.map +0 -1
- package/dist/bscPlugin/completions/CompletionsProcessor.spec.d.ts +0 -1
- package/dist/bscPlugin/completions/CompletionsProcessor.spec.js +0 -2512
- package/dist/bscPlugin/completions/CompletionsProcessor.spec.js.map +0 -1
- package/dist/bscPlugin/definition/DefinitionProvider.spec.d.ts +0 -1
- package/dist/bscPlugin/definition/DefinitionProvider.spec.js +0 -87
- package/dist/bscPlugin/definition/DefinitionProvider.spec.js.map +0 -1
- package/dist/bscPlugin/hover/HoverProcessor.spec.d.ts +0 -1
- package/dist/bscPlugin/hover/HoverProcessor.spec.js +0 -991
- package/dist/bscPlugin/hover/HoverProcessor.spec.js.map +0 -1
- package/dist/bscPlugin/references/ReferencesProvider.spec.d.ts +0 -1
- package/dist/bscPlugin/references/ReferencesProvider.spec.js +0 -51
- package/dist/bscPlugin/references/ReferencesProvider.spec.js.map +0 -1
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.d.ts +0 -1
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js +0 -564
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js.map +0 -1
- package/dist/bscPlugin/serialize/BslibInjector.spec.d.ts +0 -1
- package/dist/bscPlugin/serialize/BslibInjector.spec.js +0 -33
- package/dist/bscPlugin/serialize/BslibInjector.spec.js.map +0 -1
- package/dist/bscPlugin/symbols/DocumentSymbolProcessor.spec.d.ts +0 -1
- package/dist/bscPlugin/symbols/DocumentSymbolProcessor.spec.js +0 -291
- package/dist/bscPlugin/symbols/DocumentSymbolProcessor.spec.js.map +0 -1
- package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.spec.d.ts +0 -1
- package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.spec.js +0 -245
- package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.spec.js.map +0 -1
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.spec.d.ts +0 -1
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.spec.js +0 -75
- package/dist/bscPlugin/transpile/BrsFileTranspileProcessor.spec.js.map +0 -1
- package/dist/bscPlugin/validation/BrsFileValidator.spec.d.ts +0 -1
- package/dist/bscPlugin/validation/BrsFileValidator.spec.js +0 -1517
- package/dist/bscPlugin/validation/BrsFileValidator.spec.js.map +0 -1
- package/dist/bscPlugin/validation/ScopeValidator.spec.d.ts +0 -1
- package/dist/bscPlugin/validation/ScopeValidator.spec.js +0 -6135
- package/dist/bscPlugin/validation/ScopeValidator.spec.js.map +0 -1
- package/dist/common/Sequencer.spec.d.ts +0 -1
- package/dist/common/Sequencer.spec.js +0 -75
- package/dist/common/Sequencer.spec.js.map +0 -1
- package/dist/files/BrsFile.Class.spec.d.ts +0 -1
- package/dist/files/BrsFile.Class.spec.js +0 -2035
- package/dist/files/BrsFile.Class.spec.js.map +0 -1
- package/dist/files/BrsFile.spec.d.ts +0 -1
- package/dist/files/BrsFile.spec.js +0 -5848
- package/dist/files/BrsFile.spec.js.map +0 -1
- package/dist/files/LazyFileData.spec.d.ts +0 -1
- package/dist/files/LazyFileData.spec.js +0 -27
- package/dist/files/LazyFileData.spec.js.map +0 -1
- package/dist/files/XmlFile.spec.d.ts +0 -1
- package/dist/files/XmlFile.spec.js +0 -1173
- package/dist/files/XmlFile.spec.js.map +0 -1
- package/dist/files/tests/imports.spec.d.ts +0 -1
- package/dist/files/tests/imports.spec.js +0 -251
- package/dist/files/tests/imports.spec.js.map +0 -1
- package/dist/files/tests/optionalChaning.spec.d.ts +0 -1
- package/dist/files/tests/optionalChaning.spec.js +0 -152
- package/dist/files/tests/optionalChaning.spec.js.map +0 -1
- package/dist/lexer/Character.spec.d.ts +0 -1
- package/dist/lexer/Character.spec.js +0 -27
- package/dist/lexer/Character.spec.js.map +0 -1
- package/dist/lexer/Lexer.spec.d.ts +0 -1
- package/dist/lexer/Lexer.spec.js +0 -1345
- package/dist/lexer/Lexer.spec.js.map +0 -1
- package/dist/lsp/ActionQueue.spec.d.ts +0 -1
- package/dist/lsp/ActionQueue.spec.js +0 -80
- package/dist/lsp/ActionQueue.spec.js.map +0 -1
- package/dist/lsp/DocumentManager.spec.d.ts +0 -1
- package/dist/lsp/DocumentManager.spec.js +0 -103
- package/dist/lsp/DocumentManager.spec.js.map +0 -1
- package/dist/lsp/PathFilterer.spec.d.ts +0 -1
- package/dist/lsp/PathFilterer.spec.js +0 -182
- package/dist/lsp/PathFilterer.spec.js.map +0 -1
- package/dist/lsp/Project.spec.d.ts +0 -1
- package/dist/lsp/Project.spec.js +0 -267
- package/dist/lsp/Project.spec.js.map +0 -1
- package/dist/lsp/ProjectManager.spec.d.ts +0 -1
- package/dist/lsp/ProjectManager.spec.js +0 -913
- package/dist/lsp/ProjectManager.spec.js.map +0 -1
- package/dist/lsp/worker/MessageHandler.spec.d.ts +0 -1
- package/dist/lsp/worker/MessageHandler.spec.js +0 -64
- package/dist/lsp/worker/MessageHandler.spec.js.map +0 -1
- package/dist/lsp/worker/WorkerPool.spec.d.ts +0 -1
- package/dist/lsp/worker/WorkerPool.spec.js +0 -59
- package/dist/lsp/worker/WorkerPool.spec.js.map +0 -1
- package/dist/lsp/worker/WorkerThreadProject.spec.d.ts +0 -2
- package/dist/lsp/worker/WorkerThreadProject.spec.js +0 -71
- package/dist/lsp/worker/WorkerThreadProject.spec.js.map +0 -1
- package/dist/parser/AstNode.spec.d.ts +0 -1
- package/dist/parser/AstNode.spec.js +0 -1455
- package/dist/parser/AstNode.spec.js.map +0 -1
- package/dist/parser/BrightScriptDocParser.spec.d.ts +0 -1
- package/dist/parser/BrightScriptDocParser.spec.js +0 -310
- package/dist/parser/BrightScriptDocParser.spec.js.map +0 -1
- package/dist/parser/Expression.spec.d.ts +0 -1
- package/dist/parser/Expression.spec.js +0 -40
- package/dist/parser/Expression.spec.js.map +0 -1
- package/dist/parser/Parser.Class.spec.d.ts +0 -1
- package/dist/parser/Parser.Class.spec.js +0 -520
- package/dist/parser/Parser.Class.spec.js.map +0 -1
- package/dist/parser/Parser.spec.d.ts +0 -6
- package/dist/parser/Parser.spec.js +0 -2802
- package/dist/parser/Parser.spec.js.map +0 -1
- package/dist/parser/SGParser.spec.d.ts +0 -1
- package/dist/parser/SGParser.spec.js +0 -130
- package/dist/parser/SGParser.spec.js.map +0 -1
- package/dist/parser/Statement.spec.d.ts +0 -1
- package/dist/parser/Statement.spec.js +0 -191
- package/dist/parser/Statement.spec.js.map +0 -1
- package/dist/parser/tests/Parser.spec.d.ts +0 -12
- package/dist/parser/tests/Parser.spec.js +0 -29
- package/dist/parser/tests/Parser.spec.js.map +0 -1
- package/dist/parser/tests/controlFlow/For.spec.d.ts +0 -1
- package/dist/parser/tests/controlFlow/For.spec.js +0 -169
- package/dist/parser/tests/controlFlow/For.spec.js.map +0 -1
- package/dist/parser/tests/controlFlow/ForEach.spec.d.ts +0 -1
- package/dist/parser/tests/controlFlow/ForEach.spec.js +0 -140
- package/dist/parser/tests/controlFlow/ForEach.spec.js.map +0 -1
- package/dist/parser/tests/controlFlow/If.spec.d.ts +0 -1
- package/dist/parser/tests/controlFlow/If.spec.js +0 -694
- package/dist/parser/tests/controlFlow/If.spec.js.map +0 -1
- package/dist/parser/tests/controlFlow/While.spec.d.ts +0 -1
- package/dist/parser/tests/controlFlow/While.spec.js +0 -114
- package/dist/parser/tests/controlFlow/While.spec.js.map +0 -1
- package/dist/parser/tests/expression/Additive.spec.d.ts +0 -1
- package/dist/parser/tests/expression/Additive.spec.js +0 -107
- package/dist/parser/tests/expression/Additive.spec.js.map +0 -1
- package/dist/parser/tests/expression/ArrayLiterals.spec.d.ts +0 -1
- package/dist/parser/tests/expression/ArrayLiterals.spec.js +0 -304
- package/dist/parser/tests/expression/ArrayLiterals.spec.js.map +0 -1
- package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.d.ts +0 -1
- package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js +0 -342
- package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js.map +0 -1
- package/dist/parser/tests/expression/Boolean.spec.d.ts +0 -1
- package/dist/parser/tests/expression/Boolean.spec.js +0 -90
- package/dist/parser/tests/expression/Boolean.spec.js.map +0 -1
- package/dist/parser/tests/expression/Call.spec.d.ts +0 -1
- package/dist/parser/tests/expression/Call.spec.js +0 -252
- package/dist/parser/tests/expression/Call.spec.js.map +0 -1
- package/dist/parser/tests/expression/Exponential.spec.d.ts +0 -1
- package/dist/parser/tests/expression/Exponential.spec.js +0 -37
- package/dist/parser/tests/expression/Exponential.spec.js.map +0 -1
- package/dist/parser/tests/expression/Function.spec.d.ts +0 -1
- package/dist/parser/tests/expression/Function.spec.js +0 -412
- package/dist/parser/tests/expression/Function.spec.js.map +0 -1
- package/dist/parser/tests/expression/Indexing.spec.d.ts +0 -1
- package/dist/parser/tests/expression/Indexing.spec.js +0 -302
- package/dist/parser/tests/expression/Indexing.spec.js.map +0 -1
- package/dist/parser/tests/expression/Multiplicative.spec.d.ts +0 -1
- package/dist/parser/tests/expression/Multiplicative.spec.js +0 -67
- package/dist/parser/tests/expression/Multiplicative.spec.js.map +0 -1
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.d.ts +0 -1
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js +0 -346
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js.map +0 -1
- package/dist/parser/tests/expression/PrefixUnary.spec.d.ts +0 -1
- package/dist/parser/tests/expression/PrefixUnary.spec.js +0 -111
- package/dist/parser/tests/expression/PrefixUnary.spec.js.map +0 -1
- package/dist/parser/tests/expression/Primary.spec.d.ts +0 -1
- package/dist/parser/tests/expression/Primary.spec.js +0 -165
- package/dist/parser/tests/expression/Primary.spec.js.map +0 -1
- package/dist/parser/tests/expression/RegexLiteralExpression.spec.d.ts +0 -1
- package/dist/parser/tests/expression/RegexLiteralExpression.spec.js +0 -171
- package/dist/parser/tests/expression/RegexLiteralExpression.spec.js.map +0 -1
- package/dist/parser/tests/expression/Relational.spec.d.ts +0 -1
- package/dist/parser/tests/expression/Relational.spec.js +0 -83
- package/dist/parser/tests/expression/Relational.spec.js.map +0 -1
- package/dist/parser/tests/expression/SourceLiteralExpression.spec.d.ts +0 -1
- package/dist/parser/tests/expression/SourceLiteralExpression.spec.js +0 -201
- package/dist/parser/tests/expression/SourceLiteralExpression.spec.js.map +0 -1
- package/dist/parser/tests/expression/TemplateStringExpression.spec.d.ts +0 -1
- package/dist/parser/tests/expression/TemplateStringExpression.spec.js +0 -389
- package/dist/parser/tests/expression/TemplateStringExpression.spec.js.map +0 -1
- package/dist/parser/tests/expression/TernaryExpression.spec.d.ts +0 -1
- package/dist/parser/tests/expression/TernaryExpression.spec.js +0 -878
- package/dist/parser/tests/expression/TernaryExpression.spec.js.map +0 -1
- package/dist/parser/tests/expression/TypeExpression.spec.d.ts +0 -1
- package/dist/parser/tests/expression/TypeExpression.spec.js +0 -126
- package/dist/parser/tests/expression/TypeExpression.spec.js.map +0 -1
- package/dist/parser/tests/expression/UnaryExpression.spec.d.ts +0 -1
- package/dist/parser/tests/expression/UnaryExpression.spec.js +0 -52
- package/dist/parser/tests/expression/UnaryExpression.spec.js.map +0 -1
- package/dist/parser/tests/statement/AssignmentOperators.spec.d.ts +0 -1
- package/dist/parser/tests/statement/AssignmentOperators.spec.js +0 -79
- package/dist/parser/tests/statement/AssignmentOperators.spec.js.map +0 -1
- package/dist/parser/tests/statement/ConstStatement.spec.d.ts +0 -1
- package/dist/parser/tests/statement/ConstStatement.spec.js +0 -500
- package/dist/parser/tests/statement/ConstStatement.spec.js.map +0 -1
- package/dist/parser/tests/statement/Continue.spec.d.ts +0 -1
- package/dist/parser/tests/statement/Continue.spec.js +0 -119
- package/dist/parser/tests/statement/Continue.spec.js.map +0 -1
- package/dist/parser/tests/statement/Declaration.spec.d.ts +0 -1
- package/dist/parser/tests/statement/Declaration.spec.js +0 -114
- package/dist/parser/tests/statement/Declaration.spec.js.map +0 -1
- package/dist/parser/tests/statement/Dim.spec.d.ts +0 -1
- package/dist/parser/tests/statement/Dim.spec.js +0 -80
- package/dist/parser/tests/statement/Dim.spec.js.map +0 -1
- package/dist/parser/tests/statement/Enum.spec.d.ts +0 -1
- package/dist/parser/tests/statement/Enum.spec.js +0 -744
- package/dist/parser/tests/statement/Enum.spec.js.map +0 -1
- package/dist/parser/tests/statement/For.spec.d.ts +0 -1
- package/dist/parser/tests/statement/For.spec.js +0 -45
- package/dist/parser/tests/statement/For.spec.js.map +0 -1
- package/dist/parser/tests/statement/ForEach.spec.d.ts +0 -1
- package/dist/parser/tests/statement/ForEach.spec.js +0 -36
- package/dist/parser/tests/statement/ForEach.spec.js.map +0 -1
- package/dist/parser/tests/statement/Function.spec.d.ts +0 -1
- package/dist/parser/tests/statement/Function.spec.js +0 -343
- package/dist/parser/tests/statement/Function.spec.js.map +0 -1
- package/dist/parser/tests/statement/Goto.spec.d.ts +0 -1
- package/dist/parser/tests/statement/Goto.spec.js +0 -51
- package/dist/parser/tests/statement/Goto.spec.js.map +0 -1
- package/dist/parser/tests/statement/Increment.spec.d.ts +0 -1
- package/dist/parser/tests/statement/Increment.spec.js +0 -120
- package/dist/parser/tests/statement/Increment.spec.js.map +0 -1
- package/dist/parser/tests/statement/InterfaceStatement.spec.d.ts +0 -1
- package/dist/parser/tests/statement/InterfaceStatement.spec.js +0 -110
- package/dist/parser/tests/statement/InterfaceStatement.spec.js.map +0 -1
- package/dist/parser/tests/statement/LibraryStatement.spec.d.ts +0 -1
- package/dist/parser/tests/statement/LibraryStatement.spec.js +0 -74
- package/dist/parser/tests/statement/LibraryStatement.spec.js.map +0 -1
- package/dist/parser/tests/statement/Misc.spec.d.ts +0 -1
- package/dist/parser/tests/statement/Misc.spec.js +0 -292
- package/dist/parser/tests/statement/Misc.spec.js.map +0 -1
- package/dist/parser/tests/statement/PrintStatement.spec.d.ts +0 -1
- package/dist/parser/tests/statement/PrintStatement.spec.js +0 -200
- package/dist/parser/tests/statement/PrintStatement.spec.js.map +0 -1
- package/dist/parser/tests/statement/ReturnStatement.spec.d.ts +0 -1
- package/dist/parser/tests/statement/ReturnStatement.spec.js +0 -97
- package/dist/parser/tests/statement/ReturnStatement.spec.js.map +0 -1
- package/dist/parser/tests/statement/Set.spec.d.ts +0 -1
- package/dist/parser/tests/statement/Set.spec.js +0 -232
- package/dist/parser/tests/statement/Set.spec.js.map +0 -1
- package/dist/parser/tests/statement/Stop.spec.d.ts +0 -1
- package/dist/parser/tests/statement/Stop.spec.js +0 -38
- package/dist/parser/tests/statement/Stop.spec.js.map +0 -1
- package/dist/parser/tests/statement/Throw.spec.d.ts +0 -1
- package/dist/parser/tests/statement/Throw.spec.js +0 -38
- package/dist/parser/tests/statement/Throw.spec.js.map +0 -1
- package/dist/parser/tests/statement/TryCatch.spec.d.ts +0 -1
- package/dist/parser/tests/statement/TryCatch.spec.js +0 -151
- package/dist/parser/tests/statement/TryCatch.spec.js.map +0 -1
- package/dist/preprocessor/Manifest.spec.d.ts +0 -1
- package/dist/preprocessor/Manifest.spec.js +0 -80
- package/dist/preprocessor/Manifest.spec.js.map +0 -1
- package/dist/types/ArrayType.spec.d.ts +0 -1
- package/dist/types/ArrayType.spec.js +0 -58
- package/dist/types/ArrayType.spec.js.map +0 -1
- package/dist/types/BooleanType.spec.d.ts +0 -1
- package/dist/types/BooleanType.spec.js +0 -18
- package/dist/types/BooleanType.spec.js.map +0 -1
- package/dist/types/BuiltInInterfaceAdder.spec.d.ts +0 -1
- package/dist/types/BuiltInInterfaceAdder.spec.js +0 -115
- package/dist/types/BuiltInInterfaceAdder.spec.js.map +0 -1
- package/dist/types/ClassType.spec.d.ts +0 -1
- package/dist/types/ClassType.spec.js +0 -76
- package/dist/types/ClassType.spec.js.map +0 -1
- package/dist/types/DoubleType.spec.d.ts +0 -1
- package/dist/types/DoubleType.spec.js +0 -20
- package/dist/types/DoubleType.spec.js.map +0 -1
- package/dist/types/DynamicType.spec.d.ts +0 -1
- package/dist/types/DynamicType.spec.js +0 -23
- package/dist/types/DynamicType.spec.js.map +0 -1
- package/dist/types/EnumType.spec.d.ts +0 -1
- package/dist/types/EnumType.spec.js +0 -33
- package/dist/types/EnumType.spec.js.map +0 -1
- package/dist/types/FloatType.spec.d.ts +0 -1
- package/dist/types/FloatType.spec.js +0 -12
- package/dist/types/FloatType.spec.js.map +0 -1
- package/dist/types/IntegerType.spec.d.ts +0 -1
- package/dist/types/IntegerType.spec.js +0 -16
- package/dist/types/IntegerType.spec.js.map +0 -1
- package/dist/types/InterfaceType.spec.d.ts +0 -1
- package/dist/types/InterfaceType.spec.js +0 -227
- package/dist/types/InterfaceType.spec.js.map +0 -1
- package/dist/types/IntersectionType.spec.d.ts +0 -1
- package/dist/types/IntersectionType.spec.js +0 -150
- package/dist/types/IntersectionType.spec.js.map +0 -1
- package/dist/types/InvalidType.spec.d.ts +0 -1
- package/dist/types/InvalidType.spec.js +0 -16
- package/dist/types/InvalidType.spec.js.map +0 -1
- package/dist/types/LongIntegerType.spec.d.ts +0 -1
- package/dist/types/LongIntegerType.spec.js +0 -18
- package/dist/types/LongIntegerType.spec.js.map +0 -1
- package/dist/types/ObjectType.spec.d.ts +0 -1
- package/dist/types/ObjectType.spec.js +0 -12
- package/dist/types/ObjectType.spec.js.map +0 -1
- package/dist/types/ReferenceType.spec.d.ts +0 -1
- package/dist/types/ReferenceType.spec.js +0 -151
- package/dist/types/ReferenceType.spec.js.map +0 -1
- package/dist/types/StringType.spec.d.ts +0 -1
- package/dist/types/StringType.spec.js +0 -12
- package/dist/types/StringType.spec.js.map +0 -1
- package/dist/types/TypedFunctionType.spec.d.ts +0 -1
- package/dist/types/TypedFunctionType.spec.js +0 -122
- package/dist/types/TypedFunctionType.spec.js.map +0 -1
- package/dist/types/UnionType.spec.d.ts +0 -1
- package/dist/types/UnionType.spec.js +0 -205
- package/dist/types/UnionType.spec.js.map +0 -1
- package/dist/types/VoidType.spec.d.ts +0 -1
- package/dist/types/VoidType.spec.js +0 -12
- package/dist/types/VoidType.spec.js.map +0 -1
- package/dist/types/helper.spec.d.ts +0 -1
- package/dist/types/helper.spec.js +0 -174
- package/dist/types/helper.spec.js.map +0 -1
- package/dist/types/roFunctionType.spec.d.ts +0 -1
- package/dist/types/roFunctionType.spec.js +0 -20
- package/dist/types/roFunctionType.spec.js.map +0 -1
|
@@ -7,47 +7,324 @@ const DiagnosticMessages_1 = require("../../DiagnosticMessages");
|
|
|
7
7
|
const Parser_1 = require("../../parser/Parser");
|
|
8
8
|
const util_1 = require("../../util");
|
|
9
9
|
const reflection_1 = require("../../astUtils/reflection");
|
|
10
|
+
const visitors_1 = require("../../astUtils/visitors");
|
|
10
11
|
const TokenKind_1 = require("../../lexer/TokenKind");
|
|
12
|
+
const codeActionHelpers_1 = require("./codeActionHelpers");
|
|
13
|
+
const SGParser_1 = require("../../parser/SGParser");
|
|
11
14
|
class CodeActionsProcessor {
|
|
12
15
|
constructor(event) {
|
|
13
16
|
this.event = event;
|
|
14
17
|
this.suggestedImports = new Set();
|
|
15
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* Processes all diagnostics in the event and emits code actions for each recognized diagnostic code.
|
|
21
|
+
*/
|
|
16
22
|
process() {
|
|
23
|
+
// First pass: individual fixes for each diagnostic at the cursor position
|
|
17
24
|
for (const diagnostic of this.event.diagnostics) {
|
|
18
25
|
if (diagnostic.code === DiagnosticMessages_1.DiagnosticCodeMap.cannotFindName || diagnostic.code === DiagnosticMessages_1.DiagnosticCodeMap.cannotFindFunction) {
|
|
19
|
-
this.
|
|
26
|
+
this.suggestCannotFindNameQuickFix(diagnostic);
|
|
20
27
|
}
|
|
21
28
|
else if (diagnostic.code === DiagnosticMessages_1.DiagnosticCodeMap.xmlComponentMissingExtendsAttribute) {
|
|
22
|
-
this.
|
|
29
|
+
this.suggestMissingExtendsQuickFix(diagnostic);
|
|
23
30
|
}
|
|
24
31
|
else if (diagnostic.code === DiagnosticMessages_1.DiagnosticCodeMap.voidFunctionMayNotReturnValue) {
|
|
25
|
-
this.
|
|
32
|
+
this.suggestVoidFunctionReturnQuickFixes([diagnostic]);
|
|
26
33
|
}
|
|
27
34
|
else if (diagnostic.code === DiagnosticMessages_1.DiagnosticCodeMap.nonVoidFunctionMustReturnValue) {
|
|
28
|
-
this.
|
|
35
|
+
this.suggestNonVoidFunctionReturnQuickFixes([diagnostic]);
|
|
36
|
+
}
|
|
37
|
+
else if (diagnostic.code === DiagnosticMessages_1.DiagnosticCodeMap.referencedFileDoesNotExist) {
|
|
38
|
+
this.suggestRemoveScriptImportQuickFixes([diagnostic]);
|
|
39
|
+
}
|
|
40
|
+
else if (diagnostic.code === DiagnosticMessages_1.DiagnosticCodeMap.unnecessaryScriptImportInChildFromParent) {
|
|
41
|
+
this.suggestRemoveScriptImportQuickFixes([diagnostic]);
|
|
42
|
+
}
|
|
43
|
+
else if (diagnostic.code === DiagnosticMessages_1.DiagnosticCodeMap.unnecessaryCodebehindScriptImport) {
|
|
44
|
+
this.suggestRemoveScriptImportQuickFixes([diagnostic]);
|
|
45
|
+
}
|
|
46
|
+
else if (diagnostic.code === DiagnosticMessages_1.DiagnosticCodeMap.scriptImportCaseMismatch) {
|
|
47
|
+
this.suggestScriptImportCasingQuickFixes([diagnostic]);
|
|
48
|
+
}
|
|
49
|
+
else if (diagnostic.code === DiagnosticMessages_1.DiagnosticCodeMap.missingOverrideKeyword) {
|
|
50
|
+
this.suggestMissingOverrideQuickFixes([diagnostic]);
|
|
51
|
+
}
|
|
52
|
+
else if (diagnostic.code === DiagnosticMessages_1.DiagnosticCodeMap.cannotUseOverrideKeywordOnConstructorFunction) {
|
|
53
|
+
this.suggestRemoveOverrideFromConstructorQuickFixes([diagnostic]);
|
|
54
|
+
}
|
|
55
|
+
else if ((0, DiagnosticMessages_1.isDiagnosticOfType)(diagnostic, 'mismatchedEndingToken')) {
|
|
56
|
+
this.suggestMismatchedEndingTokenQuickFixes([diagnostic]);
|
|
29
57
|
}
|
|
30
58
|
}
|
|
59
|
+
// Second pass: fix-all actions for any code that appeared in the event.
|
|
60
|
+
// Also makes sure that fix-all actions appear after individual fixes
|
|
61
|
+
const eventCodes = new Set(this.event.diagnostics.map(d => d.code));
|
|
62
|
+
const fixAllDiagsByCode = this.collectFixAllDiagnostics(eventCodes);
|
|
63
|
+
// only offer fix-all when there are multiple instances of the same issue in the file
|
|
64
|
+
for (const [code, allInFile] of fixAllDiagsByCode) {
|
|
65
|
+
if (allInFile.length > 1) {
|
|
66
|
+
if (code === DiagnosticMessages_1.DiagnosticCodeMap.voidFunctionMayNotReturnValue) {
|
|
67
|
+
this.suggestVoidFunctionReturnQuickFixes(allInFile);
|
|
68
|
+
}
|
|
69
|
+
else if (code === DiagnosticMessages_1.DiagnosticCodeMap.nonVoidFunctionMustReturnValue) {
|
|
70
|
+
this.suggestNonVoidFunctionReturnQuickFixes(allInFile);
|
|
71
|
+
}
|
|
72
|
+
else if (code === DiagnosticMessages_1.DiagnosticCodeMap.cannotUseOverrideKeywordOnConstructorFunction) {
|
|
73
|
+
this.suggestRemoveOverrideFromConstructorQuickFixes(allInFile);
|
|
74
|
+
}
|
|
75
|
+
else if (code === DiagnosticMessages_1.DiagnosticCodeMap.referencedFileDoesNotExist) {
|
|
76
|
+
this.suggestRemoveScriptImportQuickFixes(allInFile);
|
|
77
|
+
}
|
|
78
|
+
else if (code === DiagnosticMessages_1.DiagnosticCodeMap.unnecessaryScriptImportInChildFromParent) {
|
|
79
|
+
this.suggestRemoveScriptImportQuickFixes(allInFile);
|
|
80
|
+
}
|
|
81
|
+
else if (code === DiagnosticMessages_1.DiagnosticCodeMap.unnecessaryCodebehindScriptImport) {
|
|
82
|
+
this.suggestRemoveScriptImportQuickFixes(allInFile);
|
|
83
|
+
}
|
|
84
|
+
else if (code === DiagnosticMessages_1.DiagnosticCodeMap.scriptImportCaseMismatch) {
|
|
85
|
+
this.suggestScriptImportCasingQuickFixes(allInFile);
|
|
86
|
+
}
|
|
87
|
+
else if (code === DiagnosticMessages_1.DiagnosticCodeMap.missingOverrideKeyword) {
|
|
88
|
+
this.suggestMissingOverrideQuickFixes(allInFile);
|
|
89
|
+
}
|
|
90
|
+
else if (code === DiagnosticMessages_1.DiagnosticCodeMap.mismatchedEndingToken) {
|
|
91
|
+
this.suggestMismatchedEndingTokenQuickFixes(allInFile);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// Import fix-all aggregates across multiple codes so it runs as its own step
|
|
96
|
+
if (eventCodes.has(DiagnosticMessages_1.DiagnosticCodeMap.cannotFindName) ||
|
|
97
|
+
eventCodes.has(DiagnosticMessages_1.DiagnosticCodeMap.cannotFindFunction)) {
|
|
98
|
+
this.suggestMissingImportsFixAllQuickFix();
|
|
99
|
+
}
|
|
100
|
+
// Suppression actions appear last so real fixes are surfaced first
|
|
101
|
+
for (const diagnostic of this.event.diagnostics) {
|
|
102
|
+
this.suggestDisableDiagnosticQuickFixes(diagnostic);
|
|
103
|
+
}
|
|
104
|
+
this.suggestedImports.clear();
|
|
31
105
|
}
|
|
32
106
|
/**
|
|
33
|
-
*
|
|
107
|
+
* For any diagnostic with a code, offers two quick-fix actions:
|
|
108
|
+
* - "Disable {code} for this line": adds the code to an existing `bs:disable-line` or
|
|
109
|
+
* `bs:disable-next-line` directive on/above the diagnostic if present, otherwise inserts
|
|
110
|
+
* a new `bs:disable-next-line: {code}` comment on the line above.
|
|
111
|
+
* - "Disable {code} for this file": adds the code to an existing header-level `bs:disable`
|
|
112
|
+
* directive if present, otherwise inserts a new `bs:disable: {code}` at the top of the file.
|
|
113
|
+
*
|
|
114
|
+
* Comment placement and the line-vs-next-line preference are centralized here so they can be
|
|
115
|
+
* revisited without touching the directive parser.
|
|
116
|
+
*/
|
|
117
|
+
suggestDisableDiagnosticQuickFixes(diagnostic) {
|
|
118
|
+
var _a;
|
|
119
|
+
const code = diagnostic.code;
|
|
120
|
+
if (code === undefined || code === null) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
const file = this.event.file;
|
|
124
|
+
if (!(0, reflection_1.isBrsFile)(file) && !(0, reflection_1.isXmlFile)(file)) {
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
const codeStr = String(code);
|
|
128
|
+
const isXml = (0, reflection_1.isXmlFile)(file);
|
|
129
|
+
//existing.forLine: any line/next-line directive on or above the diagnostic line that the line action could extend
|
|
130
|
+
//existing.forFile: any header-level bs:disable that the file action could extend
|
|
131
|
+
const existing = this.findExistingDisableDirectives(file, (_a = diagnostic.location) === null || _a === void 0 ? void 0 : _a.range.start.line);
|
|
132
|
+
//format helpers wrap the directive body in the right comment syntax (`'` for brs, `<!-- -->` for xml)
|
|
133
|
+
const formatLineDirective = (token, codes) => {
|
|
134
|
+
const body = `bs:disable-${token}: ${codes.join(' ')}`;
|
|
135
|
+
return isXml ? `<!-- ${body} -->` : `' ${body}`;
|
|
136
|
+
};
|
|
137
|
+
const formatBlockDirective = (codes) => {
|
|
138
|
+
const body = `bs:disable: ${codes.join(' ')}`;
|
|
139
|
+
return isXml ? `<!-- ${body} -->` : `' ${body}`;
|
|
140
|
+
};
|
|
141
|
+
// ---- "disable for this line" ----
|
|
142
|
+
//the two lambdas passed to getDiagnosticSuppressionChange are the "extend existing" and "insert fresh" branches:
|
|
143
|
+
// 1) rebuild the existing directive comment with the new code merged into its code list (preserving line vs next-line)
|
|
144
|
+
// 2) insert a fresh `bs:disable-next-line: {code}` on the line above the diagnostic, matching its indent
|
|
145
|
+
const indent = ' '.repeat(diagnostic.location.range.start.character);
|
|
146
|
+
const lineAction = this.getDiagnosticSuppressionChange(existing.forLine, codeStr, () => { var _a; return formatLineDirective(existing.forLine.type, this.mergeCodes((_a = existing.forLine) === null || _a === void 0 ? void 0 : _a.codes, codeStr)); }, () => ({
|
|
147
|
+
position: util_1.util.createPosition(diagnostic.location.range.start.line, 0),
|
|
148
|
+
newText: `${indent}${formatLineDirective('next-line', [codeStr])}\n`
|
|
149
|
+
}));
|
|
150
|
+
if (lineAction) {
|
|
151
|
+
this.event.codeActions.push(CodeActionUtil_1.codeActionUtil.createCodeAction({
|
|
152
|
+
title: `Disable ${code} for this line: ${diagnostic.message}`,
|
|
153
|
+
diagnostics: [diagnostic],
|
|
154
|
+
kind: vscode_languageserver_1.CodeActionKind.QuickFix,
|
|
155
|
+
changes: [lineAction]
|
|
156
|
+
}));
|
|
157
|
+
}
|
|
158
|
+
// ---- "disable for this file" ----
|
|
159
|
+
//same pattern as above, but operating on the header-level bs:disable directive:
|
|
160
|
+
// 1) rebuild the existing header directive with the new code appended
|
|
161
|
+
// 2) insert a fresh `bs:disable: {code}` at the file header (top of brs, or after `<?xml ?>` for xml)
|
|
162
|
+
const fileAction = this.getDiagnosticSuppressionChange(existing.forFile, codeStr, () => { var _a; return formatBlockDirective(this.mergeCodes((_a = existing.forFile) === null || _a === void 0 ? void 0 : _a.codes, codeStr)); }, () => {
|
|
163
|
+
const headerInsert = this.getDisableFileInsertion(file);
|
|
164
|
+
return {
|
|
165
|
+
position: headerInsert.position,
|
|
166
|
+
newText: headerInsert.prefix + formatBlockDirective([codeStr]) + headerInsert.suffix
|
|
167
|
+
};
|
|
168
|
+
});
|
|
169
|
+
if (fileAction) {
|
|
170
|
+
this.event.codeActions.push(CodeActionUtil_1.codeActionUtil.createCodeAction({
|
|
171
|
+
title: `Disable ${code} for this file: ${diagnostic.message}`,
|
|
172
|
+
diagnostics: [diagnostic],
|
|
173
|
+
kind: vscode_languageserver_1.CodeActionKind.QuickFix,
|
|
174
|
+
changes: [fileAction]
|
|
175
|
+
}));
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Returns the file change that suppresses `codeStr` via a directive comment, or `null` when no
|
|
180
|
+
* change is needed (the existing directive already covers the code, or already suppresses
|
|
181
|
+
* everything). When `existing` is set, the result is a replace that swaps the directive comment
|
|
182
|
+
* for the text from `buildReplacementText`. When `existing` is null, the result is an insert
|
|
183
|
+
* built from `buildInsert`.
|
|
184
|
+
*/
|
|
185
|
+
getDiagnosticSuppressionChange(existing, codeStr, buildReplacementText, buildInsert) {
|
|
186
|
+
if (existing) {
|
|
187
|
+
//existing directive without specific codes already suppresses everything; no-op
|
|
188
|
+
if (existing.codes.length === 0) {
|
|
189
|
+
return null;
|
|
190
|
+
}
|
|
191
|
+
//the new code is already in the directive; no-op
|
|
192
|
+
if (existing.codes.some(c => c.toLowerCase() === codeStr.toLowerCase())) {
|
|
193
|
+
return null;
|
|
194
|
+
}
|
|
195
|
+
return {
|
|
196
|
+
type: 'replace',
|
|
197
|
+
filePath: this.event.file.srcPath,
|
|
198
|
+
range: existing.range,
|
|
199
|
+
newText: buildReplacementText()
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
const insert = buildInsert();
|
|
203
|
+
return {
|
|
204
|
+
type: 'insert',
|
|
205
|
+
filePath: this.event.file.srcPath,
|
|
206
|
+
position: insert.position,
|
|
207
|
+
newText: insert.newText
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
mergeCodes(existingCodes, newCode) {
|
|
211
|
+
return [...(existingCodes !== null && existingCodes !== void 0 ? existingCodes : []), newCode];
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Walks the file's tokens and returns existing `bs:disable-{line,next-line}` and header-level
|
|
215
|
+
* `bs:disable` directives that would cover the diagnostic on `diagLine`. Used so the suppression
|
|
216
|
+
* quick fixes can extend an existing directive instead of stacking new ones.
|
|
34
217
|
*/
|
|
35
|
-
|
|
218
|
+
findExistingDisableDirectives(file, diagLine) {
|
|
36
219
|
var _a, _b, _c, _d, _e;
|
|
220
|
+
const isXml = (0, reflection_1.isXmlFile)(file);
|
|
221
|
+
const tokens = (_b = (_a = file.parser) === null || _a === void 0 ? void 0 : _a.tokens) !== null && _b !== void 0 ? _b : [];
|
|
222
|
+
let inHeader = true;
|
|
223
|
+
let forLine = null;
|
|
224
|
+
let forFile = null;
|
|
225
|
+
for (const token of tokens) {
|
|
226
|
+
const isComment = isXml ? ((_c = token.tokenType) === null || _c === void 0 ? void 0 : _c.name) === 'Comment' : (_d = token.leadingTrivia) === null || _d === void 0 ? void 0 : _d.some(t => t.kind === TokenKind_1.TokenKind.Comment);
|
|
227
|
+
if (!isComment) {
|
|
228
|
+
if (isXml) {
|
|
229
|
+
if (((_e = token.tokenType) === null || _e === void 0 ? void 0 : _e.name) === 'OPEN') {
|
|
230
|
+
inHeader = false;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
else if (token.kind !== TokenKind_1.TokenKind.Newline && token.kind !== TokenKind_1.TokenKind.Whitespace && token.kind !== TokenKind_1.TokenKind.Eof) {
|
|
234
|
+
inHeader = false;
|
|
235
|
+
}
|
|
236
|
+
continue;
|
|
237
|
+
}
|
|
238
|
+
const commentTokens = isXml ? [token] : token.leadingTrivia.filter(t => t.kind === TokenKind_1.TokenKind.Comment);
|
|
239
|
+
for (const commentToken of commentTokens) {
|
|
240
|
+
const tokenRange = isXml ? (0, SGParser_1.rangeFromTokenValue)(commentToken) : commentToken.location.range;
|
|
241
|
+
const tokenText = isXml ? commentToken.image : commentToken.text;
|
|
242
|
+
const parsed = parseDisableComment(tokenText);
|
|
243
|
+
if (!parsed) {
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
246
|
+
const directive = { type: parsed.directiveType, codes: parsed.codes, range: tokenRange };
|
|
247
|
+
if (!forLine && parsed.directiveType === 'line' && tokenRange.start.line === diagLine) {
|
|
248
|
+
forLine = directive;
|
|
249
|
+
}
|
|
250
|
+
else if (!forLine && parsed.directiveType === 'next-line' && tokenRange.start.line === diagLine - 1) {
|
|
251
|
+
forLine = directive;
|
|
252
|
+
}
|
|
253
|
+
else if (!forFile && parsed.directiveType === 'block' && inHeader) {
|
|
254
|
+
//only header-level `bs:disable` directives are extended for the file-level quick fix
|
|
255
|
+
forFile = directive;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
return { forLine: forLine, forFile: forFile };
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Decides where in the file a header-level `bs:disable` directive should be inserted, returning
|
|
263
|
+
* the position plus any prefix/suffix needed so the directive lands on its own line in
|
|
264
|
+
* the header (before the first executable statement / root XML element).
|
|
265
|
+
*/
|
|
266
|
+
getDisableFileInsertion(file) {
|
|
267
|
+
var _a;
|
|
268
|
+
if ((0, reflection_1.isXmlFile)(file)) {
|
|
269
|
+
//insert after the `<?xml ?>` declaration if present, otherwise at the very top
|
|
270
|
+
const declCloseToken = (_a = file.parser.tokens) === null || _a === void 0 ? void 0 : _a.find(t => { var _a; return ((_a = t.tokenType) === null || _a === void 0 ? void 0 : _a.name) === 'SPECIAL_CLOSE'; });
|
|
271
|
+
if (declCloseToken) {
|
|
272
|
+
const endLine = declCloseToken.endLine - 1;
|
|
273
|
+
const endColumn = declCloseToken.endColumn;
|
|
274
|
+
return {
|
|
275
|
+
position: util_1.util.createPosition(endLine, endColumn),
|
|
276
|
+
prefix: '\n',
|
|
277
|
+
suffix: ''
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
return {
|
|
282
|
+
position: util_1.util.createPosition(0, 0),
|
|
283
|
+
prefix: '',
|
|
284
|
+
suffix: '\n'
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Builds a map of diagnostic code → all matching diagnostics in the current file for each
|
|
289
|
+
* code in `eventCodes`. Scope-level codes are not present in `file.getDiagnostics()` so they
|
|
290
|
+
* are sourced from `program.getDiagnostics()` (fetched lazily, only when needed).
|
|
291
|
+
*/
|
|
292
|
+
collectFixAllDiagnostics(eventCodes) {
|
|
293
|
+
var _a;
|
|
294
|
+
const fileUri = util_1.util.pathToUri(this.event.file.srcPath);
|
|
295
|
+
const fileDiagnostics = this.event.program.getDiagnostics().filter(d => { var _a; return ((_a = d.location) === null || _a === void 0 ? void 0 : _a.uri) === fileUri; });
|
|
296
|
+
const fileDiagsByCode = new Map();
|
|
297
|
+
for (const d of fileDiagnostics) {
|
|
298
|
+
if (!fileDiagsByCode.has(d.code)) {
|
|
299
|
+
fileDiagsByCode.set(d.code, []);
|
|
300
|
+
}
|
|
301
|
+
fileDiagsByCode.get(d.code).push(d);
|
|
302
|
+
}
|
|
303
|
+
const result = new Map();
|
|
304
|
+
for (const code of eventCodes) {
|
|
305
|
+
result.set(code, (_a = fileDiagsByCode.get(code)) !== null && _a !== void 0 ? _a : []);
|
|
306
|
+
}
|
|
307
|
+
return result;
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Generic import suggestion function. Shouldn't be called directly from the main loop, but instead called by more specific diagnostic handlers
|
|
311
|
+
*/
|
|
312
|
+
suggestImportQuickFix(diagnostic, key, files) {
|
|
313
|
+
var _a, _b, _c;
|
|
37
314
|
//skip if we already have this suggestion
|
|
38
|
-
if (this.suggestedImports.has(key)
|
|
315
|
+
if (this.suggestedImports.has(key)) {
|
|
39
316
|
return;
|
|
40
317
|
}
|
|
41
318
|
this.suggestedImports.add(key);
|
|
42
319
|
// eslint-disable-next-line @typescript-eslint/dot-notation
|
|
43
320
|
const importStatements = this.event.file['_cachedLookups'].importStatements;
|
|
44
321
|
//find the position of the first import statement, or the top of the file if there is none
|
|
45
|
-
const insertPosition = (
|
|
322
|
+
const insertPosition = (_c = (_b = (_a = importStatements[importStatements.length - 1]) === null || _a === void 0 ? void 0 : _a.tokens.import.location.range) === null || _b === void 0 ? void 0 : _b.start) !== null && _c !== void 0 ? _c : util_1.util.createPosition(0, 0);
|
|
46
323
|
//find all files that reference this function
|
|
47
324
|
for (const file of files) {
|
|
48
|
-
const
|
|
325
|
+
const pkgPath = util_1.util.sanitizePkgPath(file.destPath);
|
|
49
326
|
this.event.codeActions.push(CodeActionUtil_1.codeActionUtil.createCodeAction({
|
|
50
|
-
title: `import "${
|
|
327
|
+
title: `import "${pkgPath}"`,
|
|
51
328
|
diagnostics: [diagnostic],
|
|
52
329
|
isPreferred: false,
|
|
53
330
|
kind: vscode_languageserver_1.CodeActionKind.QuickFix,
|
|
@@ -55,32 +332,93 @@ class CodeActionsProcessor {
|
|
|
55
332
|
type: 'insert',
|
|
56
333
|
filePath: this.event.file.srcPath,
|
|
57
334
|
position: insertPosition,
|
|
58
|
-
newText: `import "${
|
|
335
|
+
newText: `import "${pkgPath}"\n`
|
|
59
336
|
}]
|
|
60
337
|
}));
|
|
61
338
|
}
|
|
62
339
|
}
|
|
63
|
-
|
|
64
|
-
|
|
340
|
+
/**
|
|
341
|
+
* Suggests import statements for an unresolved name (function, class, namespace, or enum).
|
|
342
|
+
*/
|
|
343
|
+
suggestCannotFindNameQuickFix(diagnostic) {
|
|
344
|
+
var _a;
|
|
65
345
|
//skip if not a BrighterScript file
|
|
66
|
-
|
|
67
|
-
if (!file || file.parseMode !== Parser_1.ParseMode.BrighterScript) {
|
|
346
|
+
if (!(0, reflection_1.isBrsFile)(this.event.file) || this.event.file.parseMode !== Parser_1.ParseMode.BrighterScript) {
|
|
68
347
|
return;
|
|
69
348
|
}
|
|
70
|
-
const lowerName = ((
|
|
71
|
-
this.
|
|
349
|
+
const lowerName = ((_a = diagnostic.data.fullName) !== null && _a !== void 0 ? _a : diagnostic.data.name).toLowerCase();
|
|
350
|
+
this.suggestImportQuickFix(diagnostic, lowerName, [
|
|
72
351
|
...this.event.program.findFilesForFunction(lowerName),
|
|
73
352
|
...this.event.program.findFilesForClass(lowerName),
|
|
74
353
|
...this.event.program.findFilesForNamespace(lowerName),
|
|
75
354
|
...this.event.program.findFilesForEnum(lowerName)
|
|
76
355
|
]);
|
|
77
356
|
}
|
|
78
|
-
|
|
79
|
-
|
|
357
|
+
/**
|
|
358
|
+
* Scans all import-related diagnostics in the file and emits a single composite
|
|
359
|
+
* "Fix all: Add missing imports" action when 2+ unambiguous imports are needed.
|
|
360
|
+
* Ambiguous names (multiple possible source files) are excluded since we cannot
|
|
361
|
+
* automatically choose one.
|
|
362
|
+
*/
|
|
363
|
+
suggestMissingImportsFixAllQuickFix() {
|
|
364
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
365
|
+
if (!(0, reflection_1.isBrsFile)(this.event.file) || this.event.file.parseMode !== Parser_1.ParseMode.BrighterScript) {
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
const file = this.event.file;
|
|
369
|
+
// eslint-disable-next-line @typescript-eslint/dot-notation
|
|
370
|
+
const importStatements = file['_cachedLookups'].importStatements;
|
|
371
|
+
const insertPosition = (_c = (_b = (_a = importStatements[importStatements.length - 1]) === null || _a === void 0 ? void 0 : _a.tokens.import.location.range) === null || _b === void 0 ? void 0 : _b.start) !== null && _c !== void 0 ? _c : util_1.util.createPosition(0, 0);
|
|
372
|
+
const changes = [];
|
|
373
|
+
const addedPaths = new Set();
|
|
374
|
+
// cannotFindName/classCouldNotBeFound are scope-level diagnostics, so we must
|
|
375
|
+
// use program.getDiagnostics() (filtered by file) rather than file.getDiagnostics().
|
|
376
|
+
const fileUri = util_1.util.pathToUri(file.srcPath);
|
|
377
|
+
const allFileDiagnostics = this.event.program.getDiagnostics().filter(d => { var _a; return ((_a = d.location) === null || _a === void 0 ? void 0 : _a.uri) === fileUri; });
|
|
378
|
+
for (const diagnostic of allFileDiagnostics) {
|
|
379
|
+
let files = [];
|
|
380
|
+
if (diagnostic.code === DiagnosticMessages_1.DiagnosticCodeMap.cannotFindName || diagnostic.code === DiagnosticMessages_1.DiagnosticCodeMap.cannotFindFunction) {
|
|
381
|
+
const cannotFindNameDiagnostic = diagnostic;
|
|
382
|
+
const lowerName = (_g = ((_e = (_d = cannotFindNameDiagnostic.data) === null || _d === void 0 ? void 0 : _d.fullName) !== null && _e !== void 0 ? _e : (_f = cannotFindNameDiagnostic.data) === null || _f === void 0 ? void 0 : _f.name)) === null || _g === void 0 ? void 0 : _g.toLowerCase();
|
|
383
|
+
if (lowerName) {
|
|
384
|
+
files = [
|
|
385
|
+
...this.event.program.findFilesForFunction(lowerName),
|
|
386
|
+
...this.event.program.findFilesForClass(lowerName),
|
|
387
|
+
...this.event.program.findFilesForNamespace(lowerName),
|
|
388
|
+
...this.event.program.findFilesForEnum(lowerName)
|
|
389
|
+
];
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
//skip ambiguous names; we can't choose a file automatically
|
|
393
|
+
if (files.length !== 1) {
|
|
394
|
+
continue;
|
|
395
|
+
}
|
|
396
|
+
const pkgPath = util_1.util.sanitizePkgPath(files[0].destPath);
|
|
397
|
+
if (!addedPaths.has(pkgPath)) {
|
|
398
|
+
addedPaths.add(pkgPath);
|
|
399
|
+
changes.push({
|
|
400
|
+
type: 'insert',
|
|
401
|
+
filePath: file.srcPath,
|
|
402
|
+
position: insertPosition,
|
|
403
|
+
newText: `import "${pkgPath}"\n`
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
if (changes.length > 1) {
|
|
408
|
+
this.event.codeActions.push(CodeActionUtil_1.codeActionUtil.createCodeAction({
|
|
409
|
+
title: `Fix all: Auto fixable missing imports`,
|
|
410
|
+
kind: vscode_languageserver_1.CodeActionKind.QuickFix,
|
|
411
|
+
changes: changes
|
|
412
|
+
}));
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* Adds code actions to insert a missing `extends` attribute on an XML component tag.
|
|
417
|
+
* Offers Group, Task, and ContentNode as common choices.
|
|
418
|
+
*/
|
|
419
|
+
suggestMissingExtendsQuickFix(diagnostic) {
|
|
80
420
|
const srcPath = this.event.file.srcPath;
|
|
81
|
-
const
|
|
82
|
-
//inject new attribute after the final attribute, or after the `<component` if there are no attributes
|
|
83
|
-
const pos = (_c = (_b = ((_a = componentElement.attributes[componentElement.attributes.length - 1]) !== null && _a !== void 0 ? _a : componentElement.tokens.startTagName)) === null || _b === void 0 ? void 0 : _b.location) === null || _c === void 0 ? void 0 : _c.range.end;
|
|
421
|
+
const pos = (0, codeActionHelpers_1.getMissingExtendsInsertPosition)(this.event.file);
|
|
84
422
|
this.event.codeActions.push(CodeActionUtil_1.codeActionUtil.createCodeAction({
|
|
85
423
|
title: `Extend "Group"`,
|
|
86
424
|
diagnostics: [diagnostic],
|
|
@@ -116,19 +454,17 @@ class CodeActionsProcessor {
|
|
|
116
454
|
}]
|
|
117
455
|
}));
|
|
118
456
|
}
|
|
119
|
-
|
|
457
|
+
/**
|
|
458
|
+
* Adds code actions to resolve a `voidFunctionMayNotReturnValue` diagnostic.
|
|
459
|
+
* Offers removing the return value, converting sub→function, or removing an `as void` return type.
|
|
460
|
+
*/
|
|
461
|
+
suggestVoidFunctionReturnQuickFixes(diagnostics) {
|
|
120
462
|
var _a, _b, _c;
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
type: 'delete',
|
|
127
|
-
filePath: this.event.file.srcPath,
|
|
128
|
-
range: util_1.util.createRange(diagnostic.location.range.start.line, diagnostic.location.range.start.character + 'return'.length, diagnostic.location.range.end.line, diagnostic.location.range.end.character)
|
|
129
|
-
}]
|
|
130
|
-
}));
|
|
131
|
-
if ((0, reflection_1.isBrsFile)(this.event.file)) {
|
|
463
|
+
const changes = diagnostics.map(d => this.getRemoveReturnValueChange(d));
|
|
464
|
+
this.emitOrFixAll(`Remove return value`, `Fix all: Remove void return values`, changes, diagnostics[0]);
|
|
465
|
+
//contextual BrsFile actions only apply to the individual (single-violation) case
|
|
466
|
+
if (changes.length === 1 && (0, reflection_1.isBrsFile)(this.event.file)) {
|
|
467
|
+
const diagnostic = diagnostics[0];
|
|
132
468
|
const expression = this.event.file.getClosestExpression(diagnostic.location.range.start);
|
|
133
469
|
const func = expression.findAncestor(reflection_1.isFunctionExpression);
|
|
134
470
|
//if we're in a sub and we do not have a return type, suggest converting to a function
|
|
@@ -145,117 +481,285 @@ class CodeActionsProcessor {
|
|
|
145
481
|
kind: vscode_languageserver_1.CodeActionKind.QuickFix,
|
|
146
482
|
changes: [
|
|
147
483
|
//function
|
|
148
|
-
{
|
|
149
|
-
type: 'replace',
|
|
150
|
-
filePath: this.event.file.srcPath,
|
|
151
|
-
range: func.tokens.functionType.location.range,
|
|
152
|
-
newText: functionTypeText
|
|
153
|
-
},
|
|
484
|
+
{ type: 'replace', filePath: this.event.file.srcPath, range: func.tokens.functionType.location.range, newText: functionTypeText },
|
|
154
485
|
//end function
|
|
155
|
-
{
|
|
156
|
-
type: 'replace',
|
|
157
|
-
filePath: this.event.file.srcPath,
|
|
158
|
-
range: func.tokens.endFunctionType.location.range,
|
|
159
|
-
newText: endFunctionTypeText
|
|
160
|
-
}
|
|
486
|
+
{ type: 'replace', filePath: this.event.file.srcPath, range: func.tokens.endFunctionType.location.range, newText: endFunctionTypeText }
|
|
161
487
|
]
|
|
162
488
|
}));
|
|
163
489
|
}
|
|
164
490
|
//function `as void` return type. Suggest removing the return type
|
|
165
|
-
if (func.tokens.functionType.kind === TokenKind_1.TokenKind.Function && (0, reflection_1.isVoidType)(func.returnTypeExpression.getType({ flags: 2 /* SymbolTypeFlag.typetime */ }))) {
|
|
491
|
+
if (func.tokens.functionType.kind === TokenKind_1.TokenKind.Function && func.returnTypeExpression && (0, reflection_1.isVoidType)(func.returnTypeExpression.getType({ flags: 2 /* SymbolTypeFlag.typetime */ }))) {
|
|
166
492
|
this.event.codeActions.push(CodeActionUtil_1.codeActionUtil.createCodeAction({
|
|
167
493
|
title: `Remove return type from function declaration`,
|
|
168
494
|
diagnostics: [diagnostic],
|
|
169
495
|
kind: vscode_languageserver_1.CodeActionKind.QuickFix,
|
|
170
|
-
changes: [
|
|
171
|
-
type: 'delete',
|
|
172
|
-
filePath: this.event.file.srcPath,
|
|
173
|
-
// )| as void|
|
|
174
|
-
range: util_1.util.createRange(func.tokens.rightParen.location.range.start.line, func.tokens.rightParen.location.range.start.character + 1, func.returnTypeExpression.location.range.end.line, func.returnTypeExpression.location.range.end.character)
|
|
175
|
-
}]
|
|
496
|
+
changes: [this.getRemoveFunctionReturnTypeChange(func)]
|
|
176
497
|
}));
|
|
177
498
|
}
|
|
178
499
|
}
|
|
179
500
|
}
|
|
180
|
-
|
|
501
|
+
/**
|
|
502
|
+
* Adds code actions to resolve a `nonVoidFunctionMustReturnValue` diagnostic.
|
|
503
|
+
* Offers removing the return type from a sub, adding `as void` to a function, or converting function→sub.
|
|
504
|
+
*/
|
|
505
|
+
suggestNonVoidFunctionReturnQuickFixes(diagnostics) {
|
|
506
|
+
if (!(0, reflection_1.isBrsFile)(this.event.file)) {
|
|
507
|
+
return;
|
|
508
|
+
}
|
|
509
|
+
const file = this.event.file;
|
|
510
|
+
//find tokens for `as`, `void`, `sub`, `end sub` in the file if possible
|
|
511
|
+
let asText;
|
|
512
|
+
let voidText;
|
|
513
|
+
let subText;
|
|
514
|
+
let endSubText;
|
|
515
|
+
for (const token of file.parser.tokens) {
|
|
516
|
+
if (asText && voidText && subText && endSubText) {
|
|
517
|
+
break;
|
|
518
|
+
}
|
|
519
|
+
if ((token === null || token === void 0 ? void 0 : token.kind) === TokenKind_1.TokenKind.As) {
|
|
520
|
+
asText = token === null || token === void 0 ? void 0 : token.text;
|
|
521
|
+
}
|
|
522
|
+
else if ((token === null || token === void 0 ? void 0 : token.kind) === TokenKind_1.TokenKind.Void) {
|
|
523
|
+
voidText = token === null || token === void 0 ? void 0 : token.text;
|
|
524
|
+
}
|
|
525
|
+
else if ((token === null || token === void 0 ? void 0 : token.kind) === TokenKind_1.TokenKind.Sub) {
|
|
526
|
+
subText = token === null || token === void 0 ? void 0 : token.text;
|
|
527
|
+
}
|
|
528
|
+
else if ((token === null || token === void 0 ? void 0 : token.kind) === TokenKind_1.TokenKind.EndSub) {
|
|
529
|
+
endSubText = token === null || token === void 0 ? void 0 : token.text;
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
// Build per-fix-type change arrays, deduplicating by enclosing function so that one
|
|
533
|
+
// function with multiple bare returns only contributes one change.
|
|
534
|
+
const removeReturnTypeChanges = [];
|
|
535
|
+
const addVoidChanges = [];
|
|
536
|
+
const seenFunctions = new Set();
|
|
537
|
+
for (const d of diagnostics) {
|
|
538
|
+
const expr = file.getClosestExpression(d.location.range.start);
|
|
539
|
+
const fn = expr === null || expr === void 0 ? void 0 : expr.findAncestor(reflection_1.isFunctionExpression);
|
|
540
|
+
if (!fn) {
|
|
541
|
+
continue;
|
|
542
|
+
}
|
|
543
|
+
const fnKey = `${fn.location.range.start.line}:${fn.location.range.start.character}`;
|
|
544
|
+
if (seenFunctions.has(fnKey)) {
|
|
545
|
+
continue;
|
|
546
|
+
}
|
|
547
|
+
seenFunctions.add(fnKey);
|
|
548
|
+
if (fn.tokens.functionType.kind === TokenKind_1.TokenKind.Sub && fn.returnTypeExpression && !(0, reflection_1.isVoidType)(fn.returnTypeExpression.getType({ flags: 2 /* SymbolTypeFlag.typetime */ }))) {
|
|
549
|
+
removeReturnTypeChanges.push(this.getRemoveFunctionReturnTypeChange(fn));
|
|
550
|
+
}
|
|
551
|
+
else if (fn.tokens.functionType.kind === TokenKind_1.TokenKind.Function && !fn.returnTypeExpression) {
|
|
552
|
+
addVoidChanges.push({
|
|
553
|
+
type: 'insert',
|
|
554
|
+
filePath: this.event.file.srcPath,
|
|
555
|
+
position: fn.tokens.rightParen.location.range.end,
|
|
556
|
+
newText: ` ${asText !== null && asText !== void 0 ? asText : 'as'} ${voidText !== null && voidText !== void 0 ? voidText : 'void'}`
|
|
557
|
+
});
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
this.emitOrFixAll(`Remove return type from sub declaration`, `Fix all: Remove return type from sub declarations`, removeReturnTypeChanges, diagnostics[0]);
|
|
561
|
+
this.emitOrFixAll(`Add void return type to function declaration`, `Fix all: Add void return type to function declarations`, addVoidChanges, diagnostics[0]);
|
|
562
|
+
//'Convert function to sub' has no fix-all variant; only add it for the individual case
|
|
563
|
+
if (addVoidChanges.length === 1 && diagnostics.length === 1) {
|
|
564
|
+
const func = file.getClosestExpression(diagnostics[0].location.range.start).findAncestor(reflection_1.isFunctionExpression);
|
|
565
|
+
this.event.codeActions.push(CodeActionUtil_1.codeActionUtil.createCodeAction({
|
|
566
|
+
title: `Convert function to sub`,
|
|
567
|
+
diagnostics: [diagnostics[0]],
|
|
568
|
+
kind: vscode_languageserver_1.CodeActionKind.QuickFix,
|
|
569
|
+
changes: [
|
|
570
|
+
{ type: 'replace', filePath: file.srcPath, range: func.tokens.functionType.location.range, newText: subText !== null && subText !== void 0 ? subText : 'sub' },
|
|
571
|
+
{ type: 'replace', filePath: file.srcPath, range: func.tokens.endFunctionType.location.range, newText: endSubText !== null && endSubText !== void 0 ? endSubText : 'end sub' }
|
|
572
|
+
]
|
|
573
|
+
}));
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
// ---- script import fixes ----
|
|
577
|
+
/**
|
|
578
|
+
* Adds code actions to delete one or more unnecessary or broken script import lines.
|
|
579
|
+
*/
|
|
580
|
+
suggestRemoveScriptImportQuickFixes(diagnostics) {
|
|
581
|
+
var _a, _b;
|
|
582
|
+
const titles = {
|
|
583
|
+
[DiagnosticMessages_1.DiagnosticCodeMap.unnecessaryScriptImportInChildFromParent]: ['Remove redundant script import', 'Fix all: Remove redundant script imports'],
|
|
584
|
+
[DiagnosticMessages_1.DiagnosticCodeMap.unnecessaryCodebehindScriptImport]: ['Remove unnecessary codebehind import', 'Fix all: Remove unnecessary codebehind imports']
|
|
585
|
+
};
|
|
586
|
+
const [singleTitle, fixAllTitle] = (_b = titles[(_a = diagnostics[0]) === null || _a === void 0 ? void 0 : _a.code]) !== null && _b !== void 0 ? _b : ['Remove script import', 'Fix all: Remove script imports'];
|
|
587
|
+
const changes = diagnostics.map(diagnostic => {
|
|
588
|
+
return {
|
|
589
|
+
type: 'delete',
|
|
590
|
+
filePath: this.event.file.srcPath,
|
|
591
|
+
range: util_1.util.createRange(diagnostic.location.range.start.line, 0, diagnostic.location.range.start.line + 1, 0)
|
|
592
|
+
};
|
|
593
|
+
});
|
|
594
|
+
this.emitOrFixAll(singleTitle, fixAllTitle, changes, diagnostics[0]);
|
|
595
|
+
}
|
|
596
|
+
/**
|
|
597
|
+
* Adds code actions to correct the casing of script import paths to match the actual file name on disk.
|
|
598
|
+
*/
|
|
599
|
+
suggestScriptImportCasingQuickFixes(diagnostics) {
|
|
181
600
|
var _a;
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
const
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
//has a return type
|
|
188
|
-
func.returnTypeExpression &&
|
|
189
|
-
//is not `as void`
|
|
190
|
-
!((0, reflection_1.isVariableExpression)(func.returnTypeExpression.expression) && ((_a = func.returnTypeExpression.expression.tokens.name.text) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === 'void')) {
|
|
191
|
-
this.event.codeActions.push(CodeActionUtil_1.codeActionUtil.createCodeAction({
|
|
192
|
-
title: `Remove return type from sub declaration`,
|
|
193
|
-
diagnostics: [diagnostic],
|
|
194
|
-
kind: vscode_languageserver_1.CodeActionKind.QuickFix,
|
|
195
|
-
changes: [{
|
|
196
|
-
type: 'delete',
|
|
197
|
-
filePath: this.event.file.srcPath,
|
|
198
|
-
// )| as void|
|
|
199
|
-
range: util_1.util.createRange(func.tokens.rightParen.location.range.start.line, func.tokens.rightParen.location.range.start.character + 1, func.returnTypeExpression.location.range.end.line, func.returnTypeExpression.location.range.end.character)
|
|
200
|
-
}]
|
|
201
|
-
}));
|
|
601
|
+
const changes = [];
|
|
602
|
+
for (const diagnostic of diagnostics) {
|
|
603
|
+
const correctFilePath = (_a = diagnostic.data) === null || _a === void 0 ? void 0 : _a.correctFilePath;
|
|
604
|
+
if (!correctFilePath) {
|
|
605
|
+
continue;
|
|
202
606
|
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
607
|
+
changes.push({
|
|
608
|
+
type: 'replace',
|
|
609
|
+
filePath: this.event.file.srcPath,
|
|
610
|
+
range: diagnostic.location.range,
|
|
611
|
+
newText: correctFilePath
|
|
612
|
+
});
|
|
613
|
+
}
|
|
614
|
+
this.emitOrFixAll('Fix script import path casing', 'Fix all: Fix script import path casing', changes, diagnostics[0]);
|
|
615
|
+
}
|
|
616
|
+
// ---- override keyword fixes ----
|
|
617
|
+
/**
|
|
618
|
+
* Adds code actions to insert the missing `override` keyword before a method declaration.
|
|
619
|
+
*/
|
|
620
|
+
suggestMissingOverrideQuickFixes(diagnostics) {
|
|
621
|
+
if (!(0, reflection_1.isBrsFile)(this.event.file)) {
|
|
622
|
+
return;
|
|
623
|
+
}
|
|
624
|
+
const file = this.event.file;
|
|
625
|
+
const changes = [];
|
|
626
|
+
for (const diagnostic of diagnostics) {
|
|
627
|
+
let insertPosition;
|
|
628
|
+
file.ast.walk((node) => {
|
|
629
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
630
|
+
if ((0, reflection_1.isMethodStatement)(node) &&
|
|
631
|
+
((_c = (_b = (_a = node.location) === null || _a === void 0 ? void 0 : _a.range) === null || _b === void 0 ? void 0 : _b.start) === null || _c === void 0 ? void 0 : _c.line) === diagnostic.location.range.start.line &&
|
|
632
|
+
((_f = (_e = (_d = node.location) === null || _d === void 0 ? void 0 : _d.range) === null || _e === void 0 ? void 0 : _e.start) === null || _f === void 0 ? void 0 : _f.character) === diagnostic.location.range.start.character) {
|
|
633
|
+
insertPosition = (_j = (_h = (_g = node.func.tokens.functionType) === null || _g === void 0 ? void 0 : _g.location) === null || _h === void 0 ? void 0 : _h.range) === null || _j === void 0 ? void 0 : _j.start;
|
|
226
634
|
}
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
position: func.tokens.rightParen.location.range.end,
|
|
236
|
-
newText: ` ${asText !== null && asText !== void 0 ? asText : 'as'} ${voidText !== null && voidText !== void 0 ? voidText : 'void'}`
|
|
237
|
-
}]
|
|
238
|
-
}));
|
|
239
|
-
//suggest converting to sub
|
|
240
|
-
this.event.codeActions.push(CodeActionUtil_1.codeActionUtil.createCodeAction({
|
|
241
|
-
title: `Convert function to sub`,
|
|
242
|
-
diagnostics: [diagnostic],
|
|
243
|
-
kind: vscode_languageserver_1.CodeActionKind.QuickFix,
|
|
244
|
-
changes: [{
|
|
245
|
-
type: 'replace',
|
|
246
|
-
filePath: this.event.file.srcPath,
|
|
247
|
-
range: func.tokens.functionType.location.range,
|
|
248
|
-
newText: subText !== null && subText !== void 0 ? subText : 'sub'
|
|
249
|
-
}, {
|
|
250
|
-
type: 'replace',
|
|
251
|
-
filePath: this.event.file.srcPath,
|
|
252
|
-
range: func.tokens.endFunctionType.location.range,
|
|
253
|
-
newText: endSubText !== null && endSubText !== void 0 ? endSubText : 'end sub'
|
|
254
|
-
}]
|
|
255
|
-
}));
|
|
635
|
+
}, { walkMode: visitors_1.WalkMode.visitStatementsRecursive });
|
|
636
|
+
if (insertPosition) {
|
|
637
|
+
changes.push({
|
|
638
|
+
type: 'insert',
|
|
639
|
+
filePath: file.srcPath,
|
|
640
|
+
position: insertPosition,
|
|
641
|
+
newText: 'override '
|
|
642
|
+
});
|
|
256
643
|
}
|
|
257
644
|
}
|
|
645
|
+
this.emitOrFixAll(`Add missing 'override' keyword`, `Fix all: Add missing 'override' keywords`, changes, diagnostics[0]);
|
|
646
|
+
}
|
|
647
|
+
/**
|
|
648
|
+
* Adds one code action per legal terminator. The first entry of `expected` is marked
|
|
649
|
+
* `isPreferred`, matching the parser's convention of listing the canonical terminator first.
|
|
650
|
+
*/
|
|
651
|
+
suggestMismatchedEndingTokenQuickFixes(diagnostics) {
|
|
652
|
+
const { expected, found } = diagnostics[0].data;
|
|
653
|
+
for (let index = 0; index < expected.length; index++) {
|
|
654
|
+
const replacement = expected[index];
|
|
655
|
+
const changes = diagnostics.map(diagnostic => ({
|
|
656
|
+
type: 'replace',
|
|
657
|
+
filePath: this.event.file.srcPath,
|
|
658
|
+
range: diagnostic.location.range,
|
|
659
|
+
newText: replacement
|
|
660
|
+
}));
|
|
661
|
+
this.emitOrFixAll(`Convert '${found}' to '${replacement}'`, `Fix all: Convert '${found}' to '${replacement}'`, changes, diagnostics[0], index === 0);
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
/**
|
|
665
|
+
* Adds code actions to remove the invalid `override` keyword from a constructor method.
|
|
666
|
+
*/
|
|
667
|
+
suggestRemoveOverrideFromConstructorQuickFixes(diagnostics) {
|
|
668
|
+
const changes = diagnostics.map(d => ({
|
|
669
|
+
type: 'delete',
|
|
670
|
+
filePath: this.event.file.srcPath,
|
|
671
|
+
// delete "override " (the keyword token plus the trailing space before function/sub)
|
|
672
|
+
range: util_1.util.createRange(d.location.range.start.line, d.location.range.start.character, d.location.range.end.line, d.location.range.end.character + 1)
|
|
673
|
+
}));
|
|
674
|
+
this.emitOrFixAll(`Remove 'override' from constructor`, `Fix all: Remove 'override' from constructors`, changes, diagnostics[0]);
|
|
675
|
+
}
|
|
676
|
+
// ---- change helpers ----
|
|
677
|
+
/**
|
|
678
|
+
* Builds a delete change that removes the return value from a `return <expr>` statement,
|
|
679
|
+
* leaving just a bare `return`.
|
|
680
|
+
*/
|
|
681
|
+
getRemoveReturnValueChange(diagnostic) {
|
|
682
|
+
return {
|
|
683
|
+
type: 'delete',
|
|
684
|
+
filePath: this.event.file.srcPath,
|
|
685
|
+
range: util_1.util.createRange(diagnostic.location.range.start.line, diagnostic.location.range.start.character + 'return'.length, diagnostic.location.range.end.line, diagnostic.location.range.end.character)
|
|
686
|
+
};
|
|
687
|
+
}
|
|
688
|
+
/**
|
|
689
|
+
* Builds the change that deletes `) as <type>` from a function/sub declaration.
|
|
690
|
+
* Used for both `as void` on a function and any return type on a sub.
|
|
691
|
+
*/
|
|
692
|
+
getRemoveFunctionReturnTypeChange(func) {
|
|
693
|
+
return {
|
|
694
|
+
type: 'delete',
|
|
695
|
+
filePath: this.event.file.srcPath,
|
|
696
|
+
// )| as <type>|
|
|
697
|
+
range: util_1.util.createRange(func.tokens.rightParen.location.range.start.line, func.tokens.rightParen.location.range.start.character + 1, func.returnTypeExpression.location.range.end.line, func.returnTypeExpression.location.range.end.character)
|
|
698
|
+
};
|
|
699
|
+
}
|
|
700
|
+
/**
|
|
701
|
+
* Emits a single code action when there is exactly one change, or a "fix all" composite
|
|
702
|
+
* action when there are multiple changes (same pattern as ESLint's "Fix all X problems").
|
|
703
|
+
* Does nothing when the changes array is empty.
|
|
704
|
+
*/
|
|
705
|
+
emitOrFixAll(singleTitle, fixAllTitle, changes, diagnostic, isPreferred) {
|
|
706
|
+
if (changes.length === 0) {
|
|
707
|
+
return;
|
|
708
|
+
}
|
|
709
|
+
if (changes.length === 1) {
|
|
710
|
+
this.event.codeActions.push(CodeActionUtil_1.codeActionUtil.createCodeAction(Object.assign(Object.assign({ title: singleTitle, diagnostics: [diagnostic] }, (isPreferred ? { isPreferred: true } : {})), { kind: vscode_languageserver_1.CodeActionKind.QuickFix, changes: changes })));
|
|
711
|
+
}
|
|
712
|
+
else {
|
|
713
|
+
this.event.codeActions.push(CodeActionUtil_1.codeActionUtil.createCodeAction(Object.assign(Object.assign({ title: fixAllTitle }, (isPreferred ? { isPreferred: true } : {})), { kind: vscode_languageserver_1.CodeActionKind.QuickFix, changes: changes })));
|
|
714
|
+
}
|
|
258
715
|
}
|
|
259
716
|
}
|
|
260
717
|
exports.CodeActionsProcessor = CodeActionsProcessor;
|
|
718
|
+
/**
|
|
719
|
+
* Parses a comment's text and returns the directive details if it is one. Recognizes
|
|
720
|
+
* `'`, `rem`, and `<!-- -->` comment styles. Returns `null` for comments that aren't directives.
|
|
721
|
+
* `block` covers `bs:disable`. The `bs:enable` partner isn't surfaced since the quick fix only
|
|
722
|
+
* extends `bs:disable` directives.
|
|
723
|
+
*/
|
|
724
|
+
function parseDisableComment(text) {
|
|
725
|
+
let inner = text;
|
|
726
|
+
if (inner.startsWith('<!--')) {
|
|
727
|
+
inner = inner.slice('<!--'.length);
|
|
728
|
+
if (inner.endsWith('-->')) {
|
|
729
|
+
inner = inner.slice(0, -('-->'.length));
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
else if (inner.startsWith(`'`)) {
|
|
733
|
+
inner = inner.slice(1);
|
|
734
|
+
}
|
|
735
|
+
else if (/^rem\b/i.test(inner)) {
|
|
736
|
+
inner = inner.slice('rem'.length);
|
|
737
|
+
}
|
|
738
|
+
inner = inner.trimStart();
|
|
739
|
+
const lower = inner.toLowerCase();
|
|
740
|
+
//match longest-prefix first so `bs:disable-line` doesn't get parsed as `bs:disable`
|
|
741
|
+
let directiveType;
|
|
742
|
+
let prefixLength;
|
|
743
|
+
if (lower.startsWith('bs:disable-next-line')) {
|
|
744
|
+
directiveType = 'next-line';
|
|
745
|
+
prefixLength = 'bs:disable-next-line'.length;
|
|
746
|
+
}
|
|
747
|
+
else if (lower.startsWith('bs:disable-line')) {
|
|
748
|
+
directiveType = 'line';
|
|
749
|
+
prefixLength = 'bs:disable-line'.length;
|
|
750
|
+
}
|
|
751
|
+
else if (lower.startsWith('bs:disable')) {
|
|
752
|
+
directiveType = 'block';
|
|
753
|
+
prefixLength = 'bs:disable'.length;
|
|
754
|
+
}
|
|
755
|
+
else {
|
|
756
|
+
return null;
|
|
757
|
+
}
|
|
758
|
+
inner = inner.slice(prefixLength);
|
|
759
|
+
if (inner.startsWith(':')) {
|
|
760
|
+
inner = inner.slice(1);
|
|
761
|
+
}
|
|
762
|
+
const codes = inner.trim().length === 0 ? [] : inner.trim().split(/\s+/);
|
|
763
|
+
return { directiveType: directiveType, codes: codes };
|
|
764
|
+
}
|
|
261
765
|
//# sourceMappingURL=CodeActionsProcessor.js.map
|