Skip to content

Commit

Permalink
Version 3.6.0-127.0.dev
Browse files Browse the repository at this point in the history
Merge cc63001 into dev
  • Loading branch information
Dart CI committed Aug 8, 2024
2 parents 2e1b99a + cc63001 commit 76b463d
Show file tree
Hide file tree
Showing 40 changed files with 737 additions and 118 deletions.
40 changes: 21 additions & 19 deletions pkg/analysis_server/lib/src/analysis_server.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import 'package:analysis_server/src/lsp/client_capabilities.dart';
import 'package:analysis_server/src/lsp/client_configuration.dart';
import 'package:analysis_server/src/lsp/constants.dart' as lsp;
import 'package:analysis_server/src/lsp/handlers/handler_execute_command.dart';
import 'package:analysis_server/src/lsp/handlers/handler_states.dart';
import 'package:analysis_server/src/plugin/notification_manager.dart';
import 'package:analysis_server/src/plugin/plugin_manager.dart';
import 'package:analysis_server/src/plugin/plugin_watcher.dart';
Expand Down Expand Up @@ -226,10 +227,6 @@ abstract class AnalysisServer {
/// Starts completed and will be replaced each time a context rebuild starts.
Completer<void> analysisContextRebuildCompleter = Completer()..complete();

/// A completer for tracking LSP client initialization
/// (see [lspClientInitialized]).
final Completer<void> _lspClientInitializedCompleter = Completer();

/// The workspace for rename refactorings.
late final refactoringWorkspace =
RefactoringWorkspace(driverMap.values, searchEngine);
Expand All @@ -242,6 +239,9 @@ abstract class AnalysisServer {
/// are associated (can fix).
final Map<ProducerGenerator, Set<LintCode>> producerGeneratorsForLintRules;

/// A completer for [lspUninitialized].
final Completer<void> _lspUninitializedCompleter = Completer<void>();

AnalysisServer(
this.options,
this.sdkManager,
Expand Down Expand Up @@ -388,18 +388,18 @@ abstract class AnalysisServer {
/// by the client.
LspClientConfiguration get lspClientConfiguration;

/// A [Future] that completes once the client has initialized.
/// A [Future] that completes when the LSP server moves into the initialized
/// state and can handle normal LSP requests.
///
/// For the LSP server, this happens when the client sends the `initialized`
/// notification. For LSP-over-Legacy this happens when the first LSP request
/// triggers initializetion.
/// Completes with the [InitializedStateMessageHandler] that is active.
///
/// This future can be used by handlers requiring unit results to wait for
/// complete initialization even if the client sends the requests before
/// analysis roots have been initialized (for example because of async
/// requests to get configuration back from the client).
Future<void> get lspClientInitialized =>
_lspClientInitializedCompleter.future;
/// When the server leaves the initialized state, [lspUninitialized] will
/// complete.
FutureOr<InitializedStateMessageHandler> get lspInitialized;

/// A [Future] that completes once the server transitions out of an
/// initialized state.
Future<void> get lspUninitialized => _lspUninitializedCompleter.future;

/// Returns the function that can send `openUri` request to the client.
/// Returns `null` is the client does not support it.
Expand Down Expand Up @@ -480,11 +480,11 @@ abstract class AnalysisServer {
}
}

/// Completes [lspClientInitialized], signalling that LSP has finished
/// initializing.
void completeLspInitialization() {
if (!_lspClientInitializedCompleter.isCompleted) {
_lspClientInitializedCompleter.complete();
/// Completes [lspUninitialized], signalling that the server has moved out
/// of a state where it can handle standard LSP requests.
void completeLspUninitialization() {
if (!_lspUninitializedCompleter.isCompleted) {
_lspUninitializedCompleter.complete();
}
}

Expand Down Expand Up @@ -914,6 +914,8 @@ abstract class AnalysisServer {

@mustCallSuper
Future<void> shutdown() async {
completeLspUninitialization();

await analysisDriverSchedulerEventsSubscription?.cancel();
analysisDriverSchedulerEventsSubscription = null;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,16 @@ import 'package:language_server_protocol/protocol_special.dart';

/// The handler for the `lsp.handle` request.
class LspOverLegacyHandler extends LegacyHandler {
/// To match behaviour of the LSP server where only one
/// InitializedStateMessageHandler exists for a server (and handlers can be
/// stateful), we hand the handler off the server.
///
/// Using a static causes issues for in-process tests, so this ensures a new
/// server always gets a new handler.
final _handlers = Expando<InitializedStateMessageHandler>();

LspOverLegacyHandler(
super.server, super.request, super.cancellationToken, super.performance) {
_handlers[server] ??= InitializedStateMessageHandler(server);
}

InitializedStateMessageHandler get handler => _handlers[server]!;
super.server, super.request, super.cancellationToken, super.performance);

@override
bool get recordsOwnAnalytics => true;

@override
Future<void> handle() async {
server.initializeLsp();
server.initializeLspOverLegacy();

var params = LspHandleParams.fromRequest(request,
clientUriConverter: server.uriConverter);
var lspMessageJson = params.lspMessage;
Expand All @@ -54,10 +43,20 @@ class LspOverLegacyHandler extends LegacyHandler {
})
: null;

// Get the handler for LSP requests from the server.
// The value is a `FutureOr<>` because for the real LSP server it can be
// delayed (the client influences when we're in the initialized state) but
// since it's never a `Future` for the legacy server and we want to maintain
// request order here, skip the `await`.
var initializedLspHandler = server.lspInitialized;
var handler = initializedLspHandler is InitializedStateMessageHandler
? initializedLspHandler
: await server.lspInitialized;

if (lspMessage != null) {
server.analyticsManager.startedRequestMessage(
request: lspMessage, startTime: DateTime.now());
await handleRequest(lspMessage);
await handleRequest(handler, lspMessage);
} else {
var message = "The 'lspMessage' parameter was not a valid LSP request:\n"
"${reporter.errors.join('\n')}";
Expand All @@ -66,7 +65,10 @@ class LspOverLegacyHandler extends LegacyHandler {
}
}

Future<void> handleRequest(RequestMessage message) async {
Future<void> handleRequest(
InitializedStateMessageHandler handler,
RequestMessage message,
) async {
var messageInfo = lsp.MessageInfo(
performance: performance,
timeSinceRequest: request.timeSinceRequest,
Expand Down
16 changes: 12 additions & 4 deletions pkg/analysis_server/lib/src/legacy_analysis_server.dart
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ import 'package:analysis_server/src/handler/legacy/server_shutdown.dart';
import 'package:analysis_server/src/handler/legacy/unsupported_request.dart';
import 'package:analysis_server/src/lsp/client_capabilities.dart' as lsp;
import 'package:analysis_server/src/lsp/client_configuration.dart' as lsp;
import 'package:analysis_server/src/lsp/handlers/handler_states.dart';
import 'package:analysis_server/src/operation/operation_analysis.dart';
import 'package:analysis_server/src/plugin/notification_manager.dart';
import 'package:analysis_server/src/protocol_server.dart' as server;
Expand Down Expand Up @@ -256,6 +257,10 @@ class LegacyAnalysisServer extends AnalysisServer {
/// be sent.
final ServerCommunicationChannel channel;

@override
late final FutureOr<InitializedStateMessageHandler> lspInitialized =
InitializedStateMessageHandler(this);

/// A flag indicating the value of the 'analyzing' parameter sent in the last
/// status message to the client.
bool statusAnalyzing = false;
Expand Down Expand Up @@ -445,7 +450,7 @@ class LegacyAnalysisServer extends AnalysisServer {
// change notifications for) custom-scheme files.
uriConverter = ClientUriConverter.withVirtualFileSupport(
resourceProvider.pathContext);
initializeLsp();
initializeLspOverLegacy();
} else {
uriConverter = ClientUriConverter.noop(resourceProvider.pathContext);
}
Expand Down Expand Up @@ -629,13 +634,16 @@ class LegacyAnalysisServer extends AnalysisServer {
}
}

/// Initializes LSP support for the legacy server.
/// Initializes LSP support over the legacy server.
///
/// This method is called when the client sends an LSP request, or indicates
/// that it will use LSP-overy-Legacy via client capabilities.
void initializeLsp() {
///
/// This only applies to LSP over the legacy protocol and not DTD, since we
/// do not want a DTD-LSP client to trigger LSP notifications going to the
/// legacy protocol client, only the legacy protocol client should do that.
void initializeLspOverLegacy() {
sendLspNotifications = true;
completeLspInitialization();
}

/// Return `true` if the [path] is both absolute and normalized.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ class AugmentationHandler extends AbstractGoToHandler {
@override
Method get handlesMessage => CustomMethods.augmentation;

@override
bool get requiresTrustedCaller => false;

@override
Element? findRelatedElement(Element element) {
return element.augmentation;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ class AugmentedHandler extends AbstractGoToHandler {
@override
Method get handlesMessage => CustomMethods.augmented;

@override
bool get requiresTrustedCaller => false;

@override
Element? findRelatedElement(Element element) {
return switch (element) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ class SuperHandler extends AbstractGoToHandler {
@override
Method get handlesMessage => CustomMethods.super_;

@override
bool get requiresTrustedCaller => false;

@override
Element? findRelatedElement(Element element) {
return _SuperComputer().computeSuper(element);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ class IncomingCallHierarchyHandler extends _AbstractCallHierarchyCallsHandler<
LspJsonHandler<CallHierarchyIncomingCallsParams> get jsonHandler =>
CallHierarchyIncomingCallsParams.jsonHandler;

@override
bool get requiresTrustedCaller => false;

/// Fetches incoming calls from a [call_hierarchy.DartCallHierarchyComputer].
///
/// This method is invoked by the superclass which handles similar logic for
Expand Down Expand Up @@ -111,6 +114,9 @@ class OutgoingCallHierarchyHandler extends _AbstractCallHierarchyCallsHandler<
LspJsonHandler<CallHierarchyOutgoingCallsParams> get jsonHandler =>
CallHierarchyOutgoingCallsParams.jsonHandler;

@override
bool get requiresTrustedCaller => false;

/// Fetches outgoing calls from a [call_hierarchy.DartCallHierarchyComputer].
///
/// This method is invoked by the superclass which handles similar logic for
Expand Down Expand Up @@ -177,6 +183,9 @@ class PrepareCallHierarchyHandler extends SharedMessageHandler<
LspJsonHandler<CallHierarchyPrepareParams> get jsonHandler =>
CallHierarchyPrepareParams.jsonHandler;

@override
bool get requiresTrustedCaller => false;

@override
Future<ErrorOr<TextDocumentPrepareCallHierarchyResult>> handle(
CallHierarchyPrepareParams params,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ class CancelRequestHandler extends SharedMessageHandler<CancelParams, void> {
@override
LspJsonHandler<CancelParams> get jsonHandler => CancelParams.jsonHandler;

@override
// Cancellation is only currently supported for the native protocol clients.
// Supporting cancellation for other clients (such as over DTD) may require
// separation of requests so they can only cancel their own.
bool get requiresTrustedCaller => true;

void clearToken(RequestMessage message) {
_tokens.remove(message.id.toString());
}
Expand All @@ -31,8 +37,8 @@ class CancelRequestHandler extends SharedMessageHandler<CancelParams, void> {
ErrorOr<void> handle(
CancelParams params, MessageInfo message, CancellationToken token) {
// Don't assume this is in the map as it's possible the client sent a
// cancellation that we processed after already starting to send the response
// and cleared the token.
// cancellation that we processed after already starting to send the
// response and cleared the token.
_tokens[params.id.toString()]?.cancel();
return success(null);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ class CodeLensHandler
@override
LspJsonHandler<CodeLensParams> get jsonHandler => CodeLensParams.jsonHandler;

@override
bool get requiresTrustedCaller => false;

@override
Future<ErrorOr<List<CodeLens>>> handle(
CodeLensParams params,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ class DartTextDocumentContentProviderHandler extends SharedMessageHandler<
LspJsonHandler<DartTextDocumentContentParams> get jsonHandler =>
DartTextDocumentContentParams.jsonHandler;

@override
bool get requiresTrustedCaller => false;

@override
Future<ErrorOr<DartTextDocumentContent>> handle(
DartTextDocumentContentParams params,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ class DocumentColorHandler
LspJsonHandler<DocumentColorParams> get jsonHandler =>
DocumentColorParams.jsonHandler;

@override
bool get requiresTrustedCaller => false;

@override
Future<ErrorOr<List<ColorInformation>>> handle(DocumentColorParams params,
MessageInfo message, CancellationToken token) async {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ class DocumentColorPresentationHandler extends SharedMessageHandler<
LspJsonHandler<ColorPresentationParams> get jsonHandler =>
ColorPresentationParams.jsonHandler;

@override
bool get requiresTrustedCaller => false;

@override
Future<ErrorOr<List<ColorPresentation>>> handle(
ColorPresentationParams params,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ class DocumentHighlightsHandler extends SharedMessageHandler<
LspJsonHandler<TextDocumentPositionParams> get jsonHandler =>
TextDocumentPositionParams.jsonHandler;

@override
bool get requiresTrustedCaller => false;

@override
Future<ErrorOr<List<DocumentHighlight>?>> handle(
TextDocumentPositionParams params,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ class DocumentSymbolHandler extends SharedMessageHandler<DocumentSymbolParams,
LspJsonHandler<DocumentSymbolParams> get jsonHandler =>
DocumentSymbolParams.jsonHandler;

@override
bool get requiresTrustedCaller => false;

@override
Future<ErrorOr<TextDocumentDocumentSymbolResult>> handle(
DocumentSymbolParams params,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,17 @@ typedef StaticOptions = DocumentOnTypeFormattingOptions?;
class FormatOnTypeHandler extends SharedMessageHandler<
DocumentOnTypeFormattingParams, List<TextEdit>?> {
FormatOnTypeHandler(super.server);

@override
Method get handlesMessage => Method.textDocument_onTypeFormatting;

@override
LspJsonHandler<DocumentOnTypeFormattingParams> get jsonHandler =>
DocumentOnTypeFormattingParams.jsonHandler;

@override
bool get requiresTrustedCaller => false;

Future<ErrorOr<List<TextEdit>?>> formatFile(String path) async {
var file = server.resourceProvider.getFile(path);
if (!file.exists) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,17 @@ typedef StaticOptions = Either2<bool, DocumentRangeFormattingOptions>;
class FormatRangeHandler extends SharedMessageHandler<
DocumentRangeFormattingParams, List<TextEdit>?> {
FormatRangeHandler(super.server);

@override
Method get handlesMessage => Method.textDocument_rangeFormatting;

@override
LspJsonHandler<DocumentRangeFormattingParams> get jsonHandler =>
DocumentRangeFormattingParams.jsonHandler;

@override
bool get requiresTrustedCaller => false;

Future<ErrorOr<List<TextEdit>?>> formatRange(String path, Range range) async {
var file = server.resourceProvider.getFile(path);
if (!file.exists) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,17 @@ typedef StaticOptions = Either2<bool, DocumentFormattingOptions>;
class FormattingHandler
extends SharedMessageHandler<DocumentFormattingParams, List<TextEdit>?> {
FormattingHandler(super.server);

@override
Method get handlesMessage => Method.textDocument_formatting;

@override
LspJsonHandler<DocumentFormattingParams> get jsonHandler =>
DocumentFormattingParams.jsonHandler;

@override
bool get requiresTrustedCaller => false;

Future<ErrorOr<List<TextEdit>?>> formatFile(String path) async {
var file = server.resourceProvider.getFile(path);
if (!file.exists) {
Expand Down
Loading

0 comments on commit 76b463d

Please sign in to comment.