blob: fb74ccaf85a47d226810e867e4c734afcc1ec6ae [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/services/completion/dart/completion_manager.dart';
import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
/// The handler for the `completion.getSuggestionDetails2` request.
class CompletionGetSuggestionDetails2Handler extends CompletionHandler {
/// The identifiers of the latest `getSuggestionDetails2` request.
/// We use it to abort previous requests.
int _latestGetSuggestionDetailsId = 0;
/// Initialize a newly created handler to be able to service requests for the
/// [server].
CompletionGetSuggestionDetails2Handler(
super.server, super.request, super.cancellationToken);
@override
Future<void> handle() async {
if (completionIsDisabled) {
return;
}
var params = CompletionGetSuggestionDetails2Params.fromRequest(request);
var file = params.file;
if (server.sendResponseErrorIfInvalidFilePath(request, file)) {
return;
}
var libraryUri = Uri.tryParse(params.libraryUri);
if (libraryUri == null) {
sendResponse(
Response.invalidParameter(request, 'libraryUri', 'Cannot parse'),
);
return;
}
var budget = CompletionBudget(
const Duration(milliseconds: 1000),
);
var id = ++_latestGetSuggestionDetailsId;
while (id == _latestGetSuggestionDetailsId && !budget.isEmpty) {
try {
var session = await server.getAnalysisSession(file);
if (session == null) {
sendResponse(Response.fileNotAnalyzed(request, file));
return;
}
var completion = params.completion;
var builder = ChangeBuilder(session: session);
await builder.addDartFileEdit(file, (builder) {
var result = builder.importLibraryElement(libraryUri);
if (result.prefix != null) {
completion = '${result.prefix}.$completion';
}
});
sendResult(CompletionGetSuggestionDetails2Result(
completion,
builder.sourceChange,
));
return;
} on InconsistentAnalysisException {
// Loop around to try again.
}
}
// Timeout or abort, send the empty response.
sendResult(CompletionGetSuggestionDetailsResult(''));
}
}