blob: 3db0c51450d98adc45a35392126f63197c472b88 [file] [log] [blame]
// Copyright (c) 2022, 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/protocol/protocol.dart';
import 'package:analysis_server/protocol/protocol_generated.dart';
import 'package:analysis_server/src/handler/legacy/legacy_handler.dart';
import 'package:analysis_server/src/legacy_analysis_server.dart';
import 'package:analysis_server/src/plugin/result_merger.dart';
import 'package:analysis_server/src/request_handler_mixin.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
import 'package:analyzer_plugin/src/utilities/navigation/navigation.dart';
import 'package:analyzer_plugin/src/utilities/navigation/navigation_dart.dart';
/// The handler for the `analysis.getNavigation` request.
class AnalysisGetNavigationHandler extends LegacyHandler
with RequestHandlerMixin<LegacyAnalysisServer> {
/// Initialize a newly created handler to be able to service requests for the
/// [server].
AnalysisGetNavigationHandler(
super.server,
super.request,
super.cancellationToken,
super.performance,
);
@override
Future<void> handle() async {
var params = AnalysisGetNavigationParams.fromRequest(
request,
clientUriConverter: server.uriConverter,
);
var file = params.file;
var offset = params.offset;
var length = params.length;
if (server.sendResponseErrorIfInvalidFilePath(request, file)) {
return;
}
var driver = server.getAnalysisDriver(file);
if (driver == null) {
sendResponse(Response.getNavigationInvalidFile(request));
} else {
//
// Allow plugins to start computing navigation data.
//
var requestParams = plugin.AnalysisGetNavigationParams(
file,
offset,
length,
);
var pluginFutures = server.broadcastRequestToPlugins(
requestParams,
driver,
);
//
// Compute navigation data generated by server.
//
var allResults = <AnalysisNavigationParams>[];
var result = await server.getResolvedUnit(file);
if (result != null) {
var collector = NavigationCollectorImpl();
computeDartNavigation(
server.resourceProvider,
collector,
result,
offset,
length,
);
collector.createRegions();
allResults.add(
AnalysisNavigationParams(
file,
collector.regions,
collector.targets,
collector.files,
),
);
}
//
// Add the navigation data produced by plugins to the server-generated
// navigation data.
//
var responses = await waitForResponses(
pluginFutures,
requestParameters: requestParams,
);
for (var response in responses) {
var result = plugin.AnalysisGetNavigationResult.fromResponse(response);
allResults.add(
AnalysisNavigationParams(
file,
result.regions,
result.targets,
result.files,
),
);
}
//
// Return the result.
//
var merger = ResultMerger();
var mergedResults = merger.mergeNavigation(allResults);
if (mergedResults == null) {
sendResult(
AnalysisGetNavigationResult(
<String>[],
<NavigationTarget>[],
<NavigationRegion>[],
),
);
} else {
sendResult(
AnalysisGetNavigationResult(
mergedResults.files,
mergedResults.targets,
mergedResults.regions,
),
);
}
}
}
}