blob: 76af7e0c7fab661810d10f919c7ac9336cdb2a1e [file] [log] [blame]
// Copyright (c) 2018, 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 'dart:async';
import 'package:analysis_server/lsp_protocol/protocol.dart';
import 'package:analysis_server/src/analysis_server.dart';
import 'package:analysis_server/src/lsp/constants.dart';
import 'package:analysis_server/src/lsp/error_or.dart';
import 'package:analysis_server/src/lsp/handlers/custom/editable_arguments/handler_edit_argument.dart';
import 'package:analysis_server/src/lsp/handlers/custom/editable_arguments/handler_editable_arguments.dart';
import 'package:analysis_server/src/lsp/handlers/custom/handler_augmentation.dart';
import 'package:analysis_server/src/lsp/handlers/custom/handler_augmented.dart';
import 'package:analysis_server/src/lsp/handlers/custom/handler_connect_to_dtd.dart';
import 'package:analysis_server/src/lsp/handlers/custom/handler_dart_text_document_content_provider.dart';
import 'package:analysis_server/src/lsp/handlers/custom/handler_diagnostic_server.dart';
import 'package:analysis_server/src/lsp/handlers/custom/handler_experimental_echo.dart';
import 'package:analysis_server/src/lsp/handlers/custom/handler_imports.dart';
import 'package:analysis_server/src/lsp/handlers/custom/handler_reanalyze.dart';
import 'package:analysis_server/src/lsp/handlers/custom/handler_summary.dart';
import 'package:analysis_server/src/lsp/handlers/custom/handler_super.dart';
import 'package:analysis_server/src/lsp/handlers/custom/handler_update_diagnostic_information.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_completion_resolve.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_color_presentation.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_exit.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_initialize.dart';
import 'package:analysis_server/src/lsp/handlers/handler_initialized.dart';
import 'package:analysis_server/src/lsp/handlers/handler_inlay_hint.dart';
import 'package:analysis_server/src/lsp/handlers/handler_inline_value.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_shutdown.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/handlers/handlers.dart';
import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
typedef _RequestHandlerGenerator<T extends AnalysisServer> =
MessageHandler<Object?, Object?, T> Function(T);
/// The server moves to this state when a critical unrecoverable error (for
/// example, inconsistent document state between server/client) occurs and will
/// reject all messages.
class FailureStateMessageHandler extends ServerStateMessageHandler {
FailureStateMessageHandler(super.server);
@override
FutureOr<ErrorOr<Object?>> handleUnknownMessage(IncomingMessage message) {
return error(
ErrorCodes.InternalError,
'An unrecoverable error occurred and the server cannot process messages',
);
}
}
class InitializedLspStateMessageHandler extends InitializedStateMessageHandler {
/// Generators for handlers that require an [LspAnalysisServer].
static const lspHandlerGenerators =
<_RequestHandlerGenerator<LspAnalysisServer>>[
ShutdownMessageHandler.new,
ExitMessageHandler.new,
TextDocumentOpenHandler.new,
TextDocumentChangeHandler.new,
TextDocumentCloseHandler.new,
CompletionHandler.new,
CompletionResolveHandler.new,
DefinitionHandler.new,
DocumentLinkHandler.new,
ReferencesHandler.new,
ChangeWorkspaceFoldersHandler.new,
PrepareRenameHandler.new,
RenameHandler.new,
FoldingHandler.new,
DiagnosticServerHandler.new,
WorkspaceDidChangeConfigurationMessageHandler.new,
ReanalyzeHandler.new,
SelectionRangeHandler.new,
SemanticTokensFullHandler.new,
SemanticTokensRangeHandler.new,
InlayHintHandler.new,
];
InitializedLspStateMessageHandler(LspAnalysisServer server) : super(server) {
for (var generator in lspHandlerGenerators) {
registerHandler(generator(server));
}
}
}
/// A message handler for the initialized state that can be used by either
/// server.
///
/// Only handlers that can work with either server are available. Use
/// [InitializedLspStateMessageHandler] for full LSP support.
class InitializedStateMessageHandler extends ServerStateMessageHandler {
/// Generators for handlers that work with any [AnalysisServer].
static const sharedHandlerGenerators =
<_RequestHandlerGenerator<AnalysisServer>>[
AugmentationHandler.new,
AugmentedHandler.new,
CodeActionHandler.new,
CodeLensHandler.new,
ConnectToDtdHandler.new,
DartTextDocumentContentProviderHandler.new,
DocumentColorHandler.new,
DocumentColorPresentationHandler.new,
DocumentHighlightsHandler.new,
DocumentSymbolHandler.new,
EditableArgumentsHandler.new,
EditArgumentHandler.new,
ExecuteCommandHandler.new,
ExperimentalEchoHandler.new,
FormatOnTypeHandler.new,
FormatRangeHandler.new,
FormattingHandler.new,
HoverHandler.new,
ImportsHandler.new,
ImplementationHandler.new,
IncomingCallHierarchyHandler.new,
InlineValueHandler.new,
OutgoingCallHierarchyHandler.new,
PrepareCallHierarchyHandler.new,
PrepareTypeHierarchyHandler.new,
SignatureHelpHandler.new,
SummaryHandler.new,
SuperHandler.new,
TypeDefinitionHandler.new,
TypeHierarchySubtypesHandler.new,
TypeHierarchySupertypesHandler.new,
UpdateDiagnosticInformationHandler.new,
WillRenameFilesHandler.new,
WorkspaceSymbolHandler.new,
];
InitializedStateMessageHandler(AnalysisServer server) : super(server) {
reject(
Method.initialize,
ServerErrorCodes.ServerAlreadyInitialized,
'Server already initialized',
);
reject(
Method.initialized,
ServerErrorCodes.ServerAlreadyInitialized,
'Server already initialized',
);
for (var generator in sharedHandlerGenerators) {
registerHandler(generator(server));
}
}
}
class InitializingStateMessageHandler extends ServerStateMessageHandler {
InitializingStateMessageHandler(
LspAnalysisServer server,
List<String> openWorkspacePaths,
) : super(server) {
reject(
Method.initialize,
ServerErrorCodes.ServerAlreadyInitialized,
'Server already initialized',
);
registerHandler(ShutdownMessageHandler(server));
registerHandler(ExitMessageHandler(server));
registerHandler(InitializedMessageHandler(server, openWorkspacePaths));
}
@override
ErrorOr<Object?> handleUnknownMessage(IncomingMessage message) {
// Silently drop non-requests.
if (message is! RequestMessage) {
server.instrumentationService.logInfo(
'Ignoring ${message.method} message while initializing',
);
return success(null);
}
return error(
ErrorCodes.ServerNotInitialized,
'Unable to handle ${message.method} before the server is initialized '
'and the client has sent the initialized notification',
);
}
}
class ShuttingDownStateMessageHandler extends ServerStateMessageHandler {
ShuttingDownStateMessageHandler(LspAnalysisServer server) : super(server) {
registerHandler(ExitMessageHandler(server, clientDidCallShutdown: true));
}
@override
FutureOr<ErrorOr<Object?>> handleUnknownMessage(IncomingMessage message) {
// Silently drop non-requests.
if (message is! RequestMessage) {
server.instrumentationService.logInfo(
'Ignoring ${message.method} message while shutting down',
);
return success(null);
}
return error(
ErrorCodes.InvalidRequest,
'Unable to handle ${message.method} after shutdown request',
);
}
}
class UninitializedStateMessageHandler extends ServerStateMessageHandler {
UninitializedStateMessageHandler(LspAnalysisServer server) : super(server) {
registerHandler(ShutdownMessageHandler(server));
registerHandler(ExitMessageHandler(server));
registerHandler(InitializeMessageHandler(server));
}
@override
FutureOr<ErrorOr<Object?>> handleUnknownMessage(IncomingMessage message) {
// Silently drop non-requests.
if (message is! RequestMessage) {
server.instrumentationService.logInfo(
'Ignoring ${message.method} message while uninitialized',
);
return success(null);
}
return error(
ErrorCodes.ServerNotInitialized,
'Unable to handle ${message.method} before client has sent initialize request',
);
}
}