| // Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| import 'package:analysis_server/lsp_protocol/protocol.dart'; |
| import 'package:analysis_server/src/lsp/client_capabilities.dart'; |
| import 'package:analysis_server/src/lsp/client_configuration.dart'; |
| import 'package:analysis_server/src/lsp/handlers/custom/handler_dart_text_document_content_provider.dart'; |
| import 'package:analysis_server/src/lsp/handlers/handler_call_hierarchy.dart'; |
| import 'package:analysis_server/src/lsp/handlers/handler_change_workspace_folders.dart'; |
| import 'package:analysis_server/src/lsp/handlers/handler_code_actions.dart'; |
| import 'package:analysis_server/src/lsp/handlers/handler_code_lens.dart'; |
| import 'package:analysis_server/src/lsp/handlers/handler_completion.dart'; |
| import 'package:analysis_server/src/lsp/handlers/handler_definition.dart'; |
| import 'package:analysis_server/src/lsp/handlers/handler_document_color.dart'; |
| import 'package:analysis_server/src/lsp/handlers/handler_document_highlights.dart'; |
| import 'package:analysis_server/src/lsp/handlers/handler_document_link.dart'; |
| import 'package:analysis_server/src/lsp/handlers/handler_document_symbols.dart'; |
| import 'package:analysis_server/src/lsp/handlers/handler_execute_command.dart'; |
| import 'package:analysis_server/src/lsp/handlers/handler_folding.dart'; |
| import 'package:analysis_server/src/lsp/handlers/handler_format_on_type.dart'; |
| import 'package:analysis_server/src/lsp/handlers/handler_format_range.dart'; |
| import 'package:analysis_server/src/lsp/handlers/handler_formatting.dart'; |
| import 'package:analysis_server/src/lsp/handlers/handler_hover.dart'; |
| import 'package:analysis_server/src/lsp/handlers/handler_implementation.dart'; |
| import 'package:analysis_server/src/lsp/handlers/handler_inlay_hint.dart'; |
| import 'package:analysis_server/src/lsp/handlers/handler_references.dart'; |
| import 'package:analysis_server/src/lsp/handlers/handler_rename.dart'; |
| import 'package:analysis_server/src/lsp/handlers/handler_selection_range.dart'; |
| import 'package:analysis_server/src/lsp/handlers/handler_semantic_tokens.dart'; |
| import 'package:analysis_server/src/lsp/handlers/handler_signature_help.dart'; |
| import 'package:analysis_server/src/lsp/handlers/handler_text_document_changes.dart'; |
| import 'package:analysis_server/src/lsp/handlers/handler_type_definition.dart'; |
| import 'package:analysis_server/src/lsp/handlers/handler_type_hierarchy.dart'; |
| import 'package:analysis_server/src/lsp/handlers/handler_will_rename_files.dart'; |
| import 'package:analysis_server/src/lsp/handlers/handler_workspace_configuration.dart'; |
| import 'package:analysis_server/src/lsp/handlers/handler_workspace_symbols.dart'; |
| import 'package:analysis_server/src/lsp/server_capabilities_computer.dart'; |
| |
| typedef LspDynamicRegistration = (Method, ToJsonable?); |
| |
| /// Provides static/dynamic registration info for an LSP feature. |
| abstract class FeatureRegistration { |
| final RegistrationContext _context; |
| |
| FeatureRegistration(this._context); |
| |
| /// The capabilities of the client. |
| LspClientCapabilities get clientCapabilities => _context.clientCapabilities; |
| |
| /// The configuration provided by the client. |
| LspClientConfiguration get clientConfiguration => |
| _context.clientConfiguration; |
| |
| /// A helper to see which features the client supports dynamic registrations |
| /// for. This information is derived from the [ClientCapabilities]. |
| ClientDynamicRegistrations get clientDynamic => _context.clientDynamic; |
| |
| /// A set of filters for the currently supported Dart files. |
| List<TextDocumentFilterScheme> get dartFiles => _context.dartFilters; |
| |
| /// Gets all dynamic registrations for this feature. |
| /// |
| /// These registrations should only be used if [supportsDynamic] returns true. |
| List<LspDynamicRegistration> get dynamicRegistrations; |
| |
| /// Types of documents that are fully supported by the server. |
| /// |
| /// File types like pubspec.yaml, analysis_options.yaml and fix_data files are |
| /// not included here as their support is very limited and do not provide |
| /// functionality in most handlers. |
| List<TextDocumentFilterScheme> get fullySupportedTypes { |
| return {...dartFiles, ...pluginTypes}.toList(); |
| } |
| |
| /// Types of documents that loaded plugins are interested in. |
| List<TextDocumentFilterScheme> get pluginTypes => _context.pluginTypes; |
| |
| /// Whether both the client, and this feature, support dynamic registration. |
| bool get supportsDynamic; |
| } |
| |
| /// A helper to provide access to all feature registrations. |
| class LspFeatures { |
| final CallHierarchyRegistrations callHierarchy; |
| final ChangeWorkspaceFoldersRegistrations changeNotifications; |
| final CodeActionRegistrations codeActions; |
| final CodeLensRegistrations codeLens; |
| final CompletionRegistrations completion; |
| final DefinitionRegistrations definition; |
| final DocumentLinkRegistrations documentLink; |
| final DocumentColorRegistrations colors; |
| final DocumentHighlightsRegistrations documentHighlight; |
| final DocumentSymbolsRegistrations documentSymbol; |
| final ExecuteCommandRegistrations executeCommand; |
| final FoldingRegistrations foldingRange; |
| final FormatOnTypeRegistrations formatOnType; |
| final FormatRangeRegistrations formatRange; |
| final FormattingRegistrations format; |
| final HoverRegistrations hover; |
| final ImplementationRegistrations implementation; |
| final InlayHintRegistrations inlayHint; |
| final ReferencesRegistrations references; |
| final RenameRegistrations rename; |
| final SelectionRangeRegistrations selectionRange; |
| final SemanticTokensRegistrations semanticTokens; |
| final SignatureHelpRegistrations signatureHelp; |
| final TextDocumentRegistrations textDocumentSync; |
| final TypeDefinitionRegistrations typeDefinition; |
| final TypeHierarchyRegistrations typeHierarchy; |
| final WillRenameFilesRegistrations willRename; |
| final WorkspaceDidChangeConfigurationRegistrations |
| workspaceDidChangeConfiguration; |
| final WorkspaceSymbolRegistrations workspaceSymbol; |
| final DartTextDocumentContentProviderRegistrations |
| dartTextDocumentContentProvider; |
| |
| LspFeatures(RegistrationContext context) |
| : callHierarchy = CallHierarchyRegistrations(context), |
| changeNotifications = ChangeWorkspaceFoldersRegistrations(context), |
| codeActions = CodeActionRegistrations(context), |
| codeLens = CodeLensRegistrations(context), |
| colors = DocumentColorRegistrations(context), |
| completion = CompletionRegistrations(context), |
| definition = DefinitionRegistrations(context), |
| documentLink = DocumentLinkRegistrations(context), |
| format = FormattingRegistrations(context), |
| documentHighlight = DocumentHighlightsRegistrations(context), |
| formatOnType = FormatOnTypeRegistrations(context), |
| formatRange = FormatRangeRegistrations(context), |
| documentSymbol = DocumentSymbolsRegistrations(context), |
| executeCommand = ExecuteCommandRegistrations(context), |
| foldingRange = FoldingRegistrations(context), |
| hover = HoverRegistrations(context), |
| implementation = ImplementationRegistrations(context), |
| inlayHint = InlayHintRegistrations(context), |
| references = ReferencesRegistrations(context), |
| rename = RenameRegistrations(context), |
| selectionRange = SelectionRangeRegistrations(context), |
| semanticTokens = SemanticTokensRegistrations(context), |
| signatureHelp = SignatureHelpRegistrations(context), |
| textDocumentSync = TextDocumentRegistrations(context), |
| typeDefinition = TypeDefinitionRegistrations(context), |
| typeHierarchy = TypeHierarchyRegistrations(context), |
| willRename = WillRenameFilesRegistrations(context), |
| workspaceDidChangeConfiguration = |
| WorkspaceDidChangeConfigurationRegistrations(context), |
| workspaceSymbol = WorkspaceSymbolRegistrations(context), |
| dartTextDocumentContentProvider = |
| DartTextDocumentContentProviderRegistrations(context); |
| |
| List<FeatureRegistration> get allFeatures => [ |
| callHierarchy, |
| changeNotifications, |
| codeActions, |
| codeLens, |
| completion, |
| definition, |
| documentLink, |
| colors, |
| documentHighlight, |
| documentSymbol, |
| executeCommand, |
| foldingRange, |
| formatOnType, |
| formatRange, |
| format, |
| hover, |
| implementation, |
| inlayHint, |
| references, |
| rename, |
| selectionRange, |
| semanticTokens, |
| signatureHelp, |
| textDocumentSync, |
| typeDefinition, |
| typeHierarchy, |
| willRename, |
| workspaceDidChangeConfiguration, |
| workspaceSymbol, |
| ]; |
| } |
| |
| class RegistrationContext { |
| /// A helper to see which features the client supports dynamic registrations |
| /// for. This information is derived from the [ClientCapabilities]. |
| final ClientDynamicRegistrations clientDynamic; |
| |
| /// Types of documents that loaded plugins are interested in. |
| final List<TextDocumentFilterScheme> pluginTypes; |
| |
| /// The capabilities of the client. |
| final LspClientCapabilities clientCapabilities; |
| |
| /// The configuration provided by the client. |
| final LspClientConfiguration clientConfiguration; |
| |
| /// Filters for all Dart files supported by the current server. |
| final List<TextDocumentFilterScheme> dartFilters; |
| |
| /// Custom schemes supported for Dart files by the current server. |
| /// |
| /// 'file' is implied and not included. |
| final Set<String> customDartSchemes; |
| |
| RegistrationContext({ |
| required this.clientCapabilities, |
| required this.clientConfiguration, |
| required this.customDartSchemes, |
| required this.dartFilters, |
| required this.pluginTypes, |
| }) : clientDynamic = ClientDynamicRegistrations(clientCapabilities.raw); |
| } |
| |
| /// A helper mixin to simplify feature registrations that only provide a single |
| /// dynamic registration. |
| mixin SingleDynamicRegistration on FeatureRegistration { |
| @override |
| List<LspDynamicRegistration> get dynamicRegistrations { |
| return [(registrationMethod, options)]; |
| } |
| |
| /// The options to use for static registration if it is to be used. |
| ToJsonable? get options; |
| |
| /// The [Method] used for dynamic registration. |
| Method get registrationMethod; |
| } |
| |
| /// A helper that adds support for static registration of a feature. |
| mixin StaticRegistration<T> on FeatureRegistration { |
| /// The raw options used for static registration. This should be accessed via |
| /// [staticRegistration] to ensure it's only used when a) static registration |
| /// is supported/enabled and b) dynamic registration is not supported. |
| T get staticOptions; |
| |
| /// Only return static registration options if we support static and do not |
| /// support dynamic registration. |
| /// |
| /// Some features will override [supportsStatic] to check options, so we must |
| /// check [supportsDynamic] explicitly too. |
| T? get staticRegistration => |
| supportsStatic && !supportsDynamic ? staticOptions : null; |
| |
| /// Whether this feature supports static registration. |
| /// |
| /// This is usually `true`, but may be overridden by client settings. |
| bool get supportsStatic => true; |
| } |