[analysis_server] Expose additional LSP handlers over legacy protocol

Change-Id: I8aae887eba3d35f8086b62f2e9b861e17e41555e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/318983
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
Danny Tuppeny 2023-08-08 15:21:53 +00:00 committed by Commit Queue
parent 700c7e3b3f
commit b6e7b7e536
14 changed files with 290 additions and 17 deletions

View file

@ -11,7 +11,7 @@ import 'package:analysis_server/src/protocol_server.dart' show Outline;
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/source/line_info.dart';
class DocumentSymbolHandler extends LspMessageHandler<DocumentSymbolParams,
class DocumentSymbolHandler extends SharedMessageHandler<DocumentSymbolParams,
TextDocumentDocumentSymbolResult> {
DocumentSymbolHandler(super.server);
@override

View file

@ -14,7 +14,7 @@ import 'package:analyzer/src/util/performance/operation_performance.dart';
import 'package:collection/collection.dart';
class ImplementationHandler
extends LspMessageHandler<TextDocumentPositionParams, List<Location>> {
extends SharedMessageHandler<TextDocumentPositionParams, List<Location>> {
ImplementationHandler(super.server);
@override
Method get handlesMessage => Method.textDocument_implementation;

View file

@ -11,7 +11,7 @@ import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/src/dartdoc/dartdoc_directive_info.dart';
class SignatureHelpHandler
extends LspMessageHandler<SignatureHelpParams, SignatureHelp?> {
extends SharedMessageHandler<SignatureHelpParams, SignatureHelp?> {
SignatureHelpHandler(super.server);
@override
Method get handlesMessage => Method.textDocument_signatureHelp;

View file

@ -75,24 +75,16 @@ class InitializedLspStateMessageHandler extends InitializedStateMessageHandler {
TextDocumentCloseHandler.new,
CompletionHandler.new,
CompletionResolveHandler.new,
SignatureHelpHandler.new,
DefinitionHandler.new,
TypeDefinitionHandler.new,
SuperHandler.new,
ReferencesHandler.new,
ImplementationHandler.new,
DocumentSymbolHandler.new,
CodeActionHandler.new,
ExecuteCommandHandler.new,
WorkspaceFoldersHandler.new,
PrepareRenameHandler.new,
RenameHandler.new,
PrepareTypeHierarchyHandler.new,
TypeHierarchySubtypesHandler.new,
TypeHierarchySupertypesHandler.new,
FoldingHandler.new,
DiagnosticServerHandler.new,
WorkspaceSymbolHandler.new,
WorkspaceDidChangeConfigurationMessageHandler.new,
ReanalyzeHandler.new,
WillRenameFilesHandler.new,
@ -123,13 +115,21 @@ class InitializedStateMessageHandler extends ServerStateMessageHandler {
DocumentColorHandler.new,
DocumentColorPresentationHandler.new,
DocumentHighlightsHandler.new,
DocumentSymbolHandler.new,
FormatOnTypeHandler.new,
FormatRangeHandler.new,
FormattingHandler.new,
HoverHandler.new,
ImplementationHandler.new,
IncomingCallHierarchyHandler.new,
OutgoingCallHierarchyHandler.new,
PrepareCallHierarchyHandler.new,
PrepareTypeHierarchyHandler.new,
SignatureHelpHandler.new,
TypeDefinitionHandler.new,
TypeHierarchySubtypesHandler.new,
TypeHierarchySupertypesHandler.new,
WorkspaceSymbolHandler.new,
];
InitializedStateMessageHandler(

View file

@ -17,7 +17,7 @@ import 'package:analyzer/src/dart/element/element.dart' as analyzer;
import 'package:analyzer_plugin/protocol/protocol_common.dart' as plugin;
import 'package:analyzer_plugin/utilities/analyzer_converter.dart';
class TypeDefinitionHandler extends LspMessageHandler<TypeDefinitionParams,
class TypeDefinitionHandler extends SharedMessageHandler<TypeDefinitionParams,
TextDocumentTypeDefinitionResult> with LspPluginRequestHandlerMixin {
static const _emptyResult = TextDocumentTypeDefinitionResult.t2([]);

View file

@ -26,7 +26,7 @@ import 'package:analyzer/src/dart/element/element.dart';
/// The target returned by this handler will be sent back to the server for
/// supertype/supertype items as the user navigates the type hierarchy in the
/// client.
class PrepareTypeHierarchyHandler extends LspMessageHandler<
class PrepareTypeHierarchyHandler extends SharedMessageHandler<
TypeHierarchyPrepareParams,
TextDocumentPrepareTypeHierarchyResult> with _TypeHierarchyUtils {
PrepareTypeHierarchyHandler(super.server);
@ -70,7 +70,7 @@ class PrepareTypeHierarchyHandler extends LspMessageHandler<
}
}
class TypeHierarchySubtypesHandler extends LspMessageHandler<
class TypeHierarchySubtypesHandler extends SharedMessageHandler<
TypeHierarchySubtypesParams,
TypeHierarchySubtypesResult> with _TypeHierarchyUtils {
TypeHierarchySubtypesHandler(super.server);
@ -106,7 +106,7 @@ class TypeHierarchySubtypesHandler extends LspMessageHandler<
}
}
class TypeHierarchySupertypesHandler extends LspMessageHandler<
class TypeHierarchySupertypesHandler extends SharedMessageHandler<
TypeHierarchySupertypesParams,
TypeHierarchySupertypesResult> with _TypeHierarchyUtils {
TypeHierarchySupertypesHandler(super.server);

View file

@ -7,8 +7,8 @@ import 'package:analysis_server/src/lsp/handlers/handlers.dart';
import 'package:analysis_server/src/lsp/mapping.dart';
import 'package:analyzer/src/dart/analysis/search.dart' as search;
class WorkspaceSymbolHandler
extends LspMessageHandler<WorkspaceSymbolParams, List<SymbolInformation>> {
class WorkspaceSymbolHandler extends SharedMessageHandler<WorkspaceSymbolParams,
List<SymbolInformation>> {
WorkspaceSymbolHandler(super.server);
@override
Method get handlesMessage => Method.workspace_symbol;

View file

@ -0,0 +1,35 @@
// Copyright (c) 2023, 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 'package:analyzer/src/test_utilities/test_code_format.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'abstract_lsp_over_legacy.dart';
void main() {
defineReflectiveSuite(() {
defineReflectiveTests(DocumentSymbolsTest);
});
}
@reflectiveTest
class DocumentSymbolsTest extends LspOverLegacyTest {
Future<void> test_symbols() async {
final content = '''
class Aaa {}
''';
final code = TestCode.parse(content);
newFile(testFilePath, code.code);
final results = await getDocumentSymbols(testFileUri);
final names = results.map(
(documentSymbols) =>
documentSymbols.map((documentSymbol) => documentSymbol.name),
(symbolInformation) =>
symbolInformation.map((symbolInformation) => symbolInformation.name),
);
expect(names, contains('Aaa'));
}
}

View file

@ -0,0 +1,42 @@
// Copyright (c) 2023, 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 'package:analyzer/src/test_utilities/test_code_format.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../utils/test_code_extensions.dart';
import 'abstract_lsp_over_legacy.dart';
void main() {
defineReflectiveSuite(() {
defineReflectiveTests(ImplementationTest);
});
}
@reflectiveTest
class ImplementationTest extends LspOverLegacyTest {
Future<void> test_implementations() async {
final content = '''
abstract class Base {
void f^();
}
class Impl extends Base {
@override
void [!f!]() {}
}
''';
final code = TestCode.parse(content);
newFile(testFilePath, code.code);
final results = await getImplementations(
testFileUri,
code.position.position,
);
final result = results.single;
expect(result.uri, testFileUri);
expect(result.range, code.range.range);
}
}

View file

@ -0,0 +1,43 @@
// Copyright (c) 2023, 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 'package:analyzer/src/test_utilities/test_code_format.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../utils/test_code_extensions.dart';
import 'abstract_lsp_over_legacy.dart';
void main() {
defineReflectiveSuite(() {
defineReflectiveTests(SignatureHelpTest);
});
}
@reflectiveTest
class SignatureHelpTest extends LspOverLegacyTest {
Future<void> test_signatureHelp() async {
final content = '''
/// My function.
void f(String a) {
f(^);
}
''';
final code = TestCode.parse(content);
newFile(testFilePath, code.code);
final results = await getSignatureHelp(
testFileUri,
code.position.position,
);
final result = results!.signatures.single;
expect(result.label, 'f(String a)');
expect(result.parameters!.single.label, 'String a');
final documentation = result.documentation?.map(
(markup) => markup.value,
(string) => string,
);
expect(documentation, 'My function.');
}
}

View file

@ -7,15 +7,27 @@ import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'call_hierarchy_test.dart' as call_hierarchy;
import 'document_color_test.dart' as document_color;
import 'document_highlights_test.dart' as document_highlights;
import 'document_symbols_test.dart' as document_symbols;
import 'format_test.dart' as format;
import 'hover_test.dart' as hover;
import 'implementation_test.dart' as implementation;
import 'signature_help_test.dart' as signature_help;
import 'type_definition_test.dart' as type_definition;
import 'type_hierarchy_test.dart' as type_hierarchy;
import 'workspace_symbols_test.dart' as workspace_symbols;
void main() {
defineReflectiveSuite(() {
call_hierarchy.main();
document_color.main;
document_highlights.main();
document_symbols.main();
format.main();
hover.main();
implementation.main();
signature_help.main();
type_definition.main();
type_hierarchy.main();
workspace_symbols.main();
}, name: 'lsp_over_legacy');
}

View file

@ -0,0 +1,37 @@
// Copyright (c) 2023, 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 'package:analyzer/src/test_utilities/test_code_format.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../utils/test_code_extensions.dart';
import 'abstract_lsp_over_legacy.dart';
void main() {
defineReflectiveSuite(() {
defineReflectiveTests(TypeDefinitionTest);
});
}
@reflectiveTest
class TypeDefinitionTest extends LspOverLegacyTest {
Future<void> test_typeDefinition() async {
final content = '''
class [!A!] {}
final a^ = A();
''';
final code = TestCode.parse(content);
newFile(testFilePath, code.code);
final results = await getTypeDefinitionAsLocation(
testFileUri,
code.position.position,
);
final result = results.single;
expect(result.range, code.range.range);
expect(result.uri, testFileUri);
}
}

View file

@ -0,0 +1,74 @@
// Copyright (c) 2023, 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 'package:analyzer/src/test_utilities/test_code_format.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../utils/test_code_extensions.dart';
import 'abstract_lsp_over_legacy.dart';
void main() {
defineReflectiveSuite(() {
defineReflectiveTests(TypeHierarchyTest);
});
}
@reflectiveTest
class TypeHierarchyTest extends LspOverLegacyTest {
Future<void> test_incoming() async {
final content = '''
class Ba^se {}
class [!Sub!] extends Base {}
''';
final code = TestCode.parse(content);
newFile(testFilePath, code.code);
final prepareResults = await prepareTypeHierarchy(
testFileUri,
code.position.position,
);
final prepareResult = prepareResults!.single;
final incomingResults = await typeHierarchySubtypes(prepareResult);
final incomingResult = incomingResults!.single;
expect(incomingResult.name, 'Sub');
expect(incomingResult.selectionRange, code.range.range);
}
Future<void> test_outgoing() async {
final content = '''
class [!Base!] {}
class Su^b extends Base {}
''';
final code = TestCode.parse(content);
newFile(testFilePath, code.code);
final prepareResults = await prepareTypeHierarchy(
testFileUri,
code.position.position,
);
final prepareResult = prepareResults!.single;
final outgoingResults = await typeHierarchySupertypes(prepareResult);
final outgoingResult = outgoingResults!.single;
expect(outgoingResult.name, 'Base');
expect(outgoingResult.selectionRange, code.range.range);
}
Future<void> test_prepare() async {
final content = '''
class A^ {}
''';
final code = TestCode.parse(content);
newFile(testFilePath, code.code);
final results = await prepareTypeHierarchy(
testFileUri,
code.position.position,
);
final result = results!.single;
expect(result.name, 'A');
}
}

View file

@ -0,0 +1,30 @@
// Copyright (c) 2023, 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 'package:analyzer/src/test_utilities/test_code_format.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'abstract_lsp_over_legacy.dart';
void main() {
defineReflectiveSuite(() {
defineReflectiveTests(WorkspaceSymbolsTest);
});
}
@reflectiveTest
class WorkspaceSymbolsTest extends LspOverLegacyTest {
Future<void> test_symbols() async {
final content = '''
class Aaa {}
''';
final code = TestCode.parse(content);
newFile(testFilePath, code.code);
final results = await getWorkspaceSymbols('Aa');
final names = results.map((result) => result.name);
expect(names, contains('Aaa'));
}
}