mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 18:49:37 +00:00
[analysis_server] Record more granular timings for LSP textDocument/codeAction request
Change-Id: I29d16b4e4f077cc0bfa9bff6a930dce506ba100c Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/244100 Commit-Queue: Brian Wilkerson <brianwilkerson@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
parent
934f4802bd
commit
091454876e
|
@ -21,6 +21,7 @@ import 'package:analyzer/dart/analysis/session.dart'
|
|||
import 'package:analyzer/dart/element/element.dart';
|
||||
import 'package:analyzer/src/dart/ast/utilities.dart';
|
||||
import 'package:analyzer/src/util/file_paths.dart' as file_paths;
|
||||
import 'package:analyzer/src/util/performance/operation_performance.dart';
|
||||
import 'package:analyzer_plugin/protocol/protocol.dart' as plugin;
|
||||
import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
|
||||
import 'package:collection/collection.dart' show groupBy;
|
||||
|
@ -118,7 +119,10 @@ class CodeActionHandler extends MessageHandler<CodeActionParams,
|
|||
return endOffset.mapResult((endOffset) {
|
||||
final offset = startOffset;
|
||||
final length = endOffset - startOffset;
|
||||
return _getCodeActions(
|
||||
return message.performance.runAsync(
|
||||
'getCodeActions',
|
||||
(performance) => _getCodeActions(
|
||||
performance,
|
||||
shouldIncludeKind,
|
||||
supportsLiteralCodeActions,
|
||||
supportsApplyEdit,
|
||||
|
@ -127,7 +131,9 @@ class CodeActionHandler extends MessageHandler<CodeActionParams,
|
|||
params.range,
|
||||
offset,
|
||||
length,
|
||||
unit);
|
||||
unit,
|
||||
),
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -298,6 +304,7 @@ class CodeActionHandler extends MessageHandler<CodeActionParams,
|
|||
}
|
||||
|
||||
Future<ErrorOr<List<Either2<Command, CodeAction>>>> _getCodeActions(
|
||||
OperationPerformanceImpl performance,
|
||||
bool Function(CodeActionKind?) shouldIncludeKind,
|
||||
bool supportsLiterals,
|
||||
bool supportsWorkspaceApplyEdit,
|
||||
|
@ -309,14 +316,26 @@ class CodeActionHandler extends MessageHandler<CodeActionParams,
|
|||
ResolvedUnitResult unit,
|
||||
) async {
|
||||
final results = await Future.wait([
|
||||
_getSourceActions(shouldIncludeKind, supportsLiterals,
|
||||
supportsWorkspaceApplyEdit, path),
|
||||
_getAssistActions(shouldIncludeKind, supportsLiterals, path, range,
|
||||
offset, length, unit),
|
||||
_getRefactorActions(
|
||||
shouldIncludeKind, supportsLiterals, path, offset, length, unit),
|
||||
_getFixActions(shouldIncludeKind, supportsLiterals, path, offset,
|
||||
supportedDiagnosticTags, range, unit),
|
||||
performance.runAsync(
|
||||
'_getSourceActions',
|
||||
(_) => _getSourceActions(shouldIncludeKind, supportsLiterals,
|
||||
supportsWorkspaceApplyEdit, path),
|
||||
),
|
||||
performance.runAsync(
|
||||
'_getAssistActions',
|
||||
(_) => _getAssistActions(shouldIncludeKind, supportsLiterals, path,
|
||||
range, offset, length, unit),
|
||||
),
|
||||
performance.runAsync(
|
||||
'_getRefactorActions',
|
||||
(_) => _getRefactorActions(
|
||||
shouldIncludeKind, supportsLiterals, path, offset, length, unit),
|
||||
),
|
||||
performance.runAsync(
|
||||
'_getFixActions',
|
||||
(_) => _getFixActions(shouldIncludeKind, supportsLiterals, path, offset,
|
||||
supportedDiagnosticTags, range, unit),
|
||||
),
|
||||
]);
|
||||
final flatResults = results.expand((x) => x).toList();
|
||||
|
||||
|
@ -343,15 +362,15 @@ class CodeActionHandler extends MessageHandler<CodeActionParams,
|
|||
final pluginFuture = _getPluginFixActions(unit, offset);
|
||||
|
||||
try {
|
||||
var workspace = DartChangeWorkspace(
|
||||
await server.currentSessions,
|
||||
);
|
||||
for (final error in unit.errors) {
|
||||
// Server lineNumber is one-based so subtract one.
|
||||
var errorLine = lineInfo.getLocation(error.offset).lineNumber - 1;
|
||||
if (errorLine < range.start.line || errorLine > range.end.line) {
|
||||
continue;
|
||||
}
|
||||
var workspace = DartChangeWorkspace(
|
||||
await server.currentSessions,
|
||||
);
|
||||
var context = DartFixContextImpl(
|
||||
server.instrumentationService, workspace, unit, error);
|
||||
final fixes = await fixContributor.computeFixes(context);
|
||||
|
|
|
@ -110,7 +110,7 @@ class CompletionHandler extends MessageHandler<CompletionParams, CompletionList>
|
|||
CompletionPerformance? completionPerformance;
|
||||
if (fileExtension == '.dart' && !unit.isError) {
|
||||
final result = unit.result;
|
||||
var performance = OperationPerformanceImpl('<root>');
|
||||
var performance = message.performance;
|
||||
serverResultsFuture = performance.runAsync(
|
||||
'request',
|
||||
(performance) async {
|
||||
|
|
|
@ -16,6 +16,7 @@ import 'package:analysis_server/src/lsp/progress.dart';
|
|||
import 'package:analysis_server/src/request_handler_mixin.dart';
|
||||
import 'package:analyzer/dart/analysis/results.dart';
|
||||
import 'package:analyzer/source/line_info.dart';
|
||||
import 'package:analyzer/src/util/performance/operation_performance.dart';
|
||||
import 'package:analyzer/src/utilities/cancellation.dart';
|
||||
import 'package:analyzer_plugin/protocol/protocol.dart';
|
||||
import 'package:analyzer_plugin/src/protocol/protocol_internal.dart';
|
||||
|
@ -167,8 +168,8 @@ abstract class MessageHandler<P, R>
|
|||
/// Handle the given [message]. If the [message] is a [RequestMessage], then the
|
||||
/// return value will be sent back in a [ResponseMessage].
|
||||
/// [NotificationMessage]s are not expected to return results.
|
||||
FutureOr<ErrorOr<R>> handleMessage(
|
||||
IncomingMessage message, CancellationToken token) {
|
||||
FutureOr<ErrorOr<R>> handleMessage(IncomingMessage message,
|
||||
MessageInfo messageInfo, CancellationToken token) {
|
||||
final reporter = LspJsonReporter('params');
|
||||
final paramsJson = message.params as Map<String, Object?>?;
|
||||
if (!jsonHandler.validateParams(paramsJson, reporter)) {
|
||||
|
@ -183,7 +184,6 @@ abstract class MessageHandler<P, R>
|
|||
|
||||
final params =
|
||||
paramsJson != null ? jsonHandler.convertParams(paramsJson) : null as P;
|
||||
final messageInfo = MessageInfo(timeSinceRequest: message.timeSinceRequest);
|
||||
return handle(params, messageInfo, token);
|
||||
}
|
||||
}
|
||||
|
@ -195,7 +195,9 @@ class MessageInfo {
|
|||
/// request or `null` if the client did not provide [clientRequestTime].
|
||||
final int? timeSinceRequest;
|
||||
|
||||
MessageInfo({this.timeSinceRequest});
|
||||
OperationPerformanceImpl performance;
|
||||
|
||||
MessageInfo({required this.performance, this.timeSinceRequest});
|
||||
}
|
||||
|
||||
/// A message handler that handles all messages for a given server state.
|
||||
|
@ -213,14 +215,15 @@ abstract class ServerStateMessageHandler {
|
|||
/// Handle the given [message]. If the [message] is a [RequestMessage], then the
|
||||
/// return value will be sent back in a [ResponseMessage].
|
||||
/// [NotificationMessage]s are not expected to return results.
|
||||
FutureOr<ErrorOr<Object?>> handleMessage(IncomingMessage message) async {
|
||||
FutureOr<ErrorOr<Object?>> handleMessage(
|
||||
IncomingMessage message, MessageInfo messageInfo) async {
|
||||
final handler = _messageHandlers[message.method];
|
||||
if (handler == null) {
|
||||
return handleUnknownMessage(message);
|
||||
}
|
||||
|
||||
if (message is! RequestMessage) {
|
||||
return handler.handleMessage(message, _notCancelableToken);
|
||||
return handler.handleMessage(message, messageInfo, _notCancelableToken);
|
||||
}
|
||||
|
||||
// Create a cancellation token that will allow us to cancel this request if
|
||||
|
@ -228,7 +231,7 @@ abstract class ServerStateMessageHandler {
|
|||
// check the token after `await` points).
|
||||
final token = _cancelHandler.createToken(message);
|
||||
try {
|
||||
final result = await handler.handleMessage(message, token);
|
||||
final result = await handler.handleMessage(message, messageInfo, token);
|
||||
// Do a final check before returning the result, because if the request was
|
||||
// cancelled we can save the overhead of serialising everything to JSON
|
||||
// and the client to deserialising the same in order to read the ID to see
|
||||
|
|
|
@ -350,31 +350,32 @@ class LspAnalysisServer extends AbstractAnalysisServer {
|
|||
try {
|
||||
if (message is ResponseMessage) {
|
||||
handleClientResponse(message);
|
||||
} else if (message is RequestMessage) {
|
||||
} else if (message is IncomingMessage) {
|
||||
final incomingMessage = message as IncomingMessage;
|
||||
|
||||
// Record performance information for the request.
|
||||
final performance = OperationPerformanceImpl('<root>');
|
||||
await performance.runAsync('request', (performance) async {
|
||||
final requestPerformance = RequestPerformance(
|
||||
operation: message.method.toString(),
|
||||
operation: incomingMessage.method.toString(),
|
||||
performance: performance,
|
||||
requestLatency: message.timeSinceRequest,
|
||||
requestLatency: incomingMessage.timeSinceRequest,
|
||||
);
|
||||
recentPerformance.requests.add(requestPerformance);
|
||||
final result = await messageHandler.handleMessage(message);
|
||||
if (result.isError) {
|
||||
sendErrorResponse(message, result.error);
|
||||
|
||||
final messageInfo = MessageInfo(
|
||||
performance: performance,
|
||||
timeSinceRequest: incomingMessage.timeSinceRequest,
|
||||
);
|
||||
|
||||
if (message is RequestMessage) {
|
||||
await _handleRequestMessage(message, messageInfo);
|
||||
} else if (message is NotificationMessage) {
|
||||
await _handleNotificationMessage(message, messageInfo);
|
||||
} else {
|
||||
channel.sendResponse(ResponseMessage(
|
||||
id: message.id,
|
||||
result: result.result,
|
||||
jsonrpc: jsonRpcVersion));
|
||||
showErrorMessageToUser('Unknown incoming message type');
|
||||
}
|
||||
});
|
||||
} else if (message is NotificationMessage) {
|
||||
final result = await messageHandler.handleMessage(message);
|
||||
if (result.isError) {
|
||||
sendErrorResponse(message, result.error);
|
||||
}
|
||||
} else {
|
||||
showErrorMessageToUser('Unknown message type');
|
||||
}
|
||||
|
@ -783,6 +784,32 @@ class LspAnalysisServer extends AbstractAnalysisServer {
|
|||
];
|
||||
}
|
||||
|
||||
Future<void> _handleNotificationMessage(
|
||||
NotificationMessage message,
|
||||
MessageInfo messageInfo,
|
||||
) async {
|
||||
final result = await messageHandler.handleMessage(message, messageInfo);
|
||||
if (result.isError) {
|
||||
sendErrorResponse(message, result.error);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _handleRequestMessage(
|
||||
RequestMessage message,
|
||||
MessageInfo messageInfo,
|
||||
) async {
|
||||
final result = await messageHandler.handleMessage(message, messageInfo);
|
||||
if (result.isError) {
|
||||
sendErrorResponse(message, result.error);
|
||||
} else {
|
||||
channel.sendResponse(ResponseMessage(
|
||||
id: message.id,
|
||||
result: result.result,
|
||||
jsonrpc: jsonRpcVersion,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
void _onPluginsChanged() {
|
||||
capabilitiesComputer.performDynamicRegistration();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue