Skip to content

Commit

Permalink
Version 3.8.0-41.0.dev
Browse files Browse the repository at this point in the history
Merge 1ec4ea7 into dev
  • Loading branch information
Dart CI committed Jan 27, 2025
2 parents d2af37f + 1ec4ea7 commit 2a7da83
Show file tree
Hide file tree
Showing 20 changed files with 472 additions and 111 deletions.
2 changes: 1 addition & 1 deletion pkg/analysis_server/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,4 @@ To run just the analysis server integration tests:


[building]: https://github.com/dart-lang/sdk/wiki/Building
[contributing]: https://github.com/dart-lang/sdk/wiki/Contributing
[contributing]: https://github.com/dart-lang/sdk/blob/master/CONTRIBUTING.md
55 changes: 43 additions & 12 deletions pkg/analysis_server/lib/src/lsp/completion_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,15 @@ Future<lsp.CompletionItem?> toLspCompletionItem(
label = filterText;
}

// If this suggestion is an override, we always want to include "override" at
// the start of the label even if it's not there (which may be because the
// user has already typed it). We set this _after_ setting filterText because
// in that case, we do not want the client to rank this item badly because
// it starts "override" and the user is typing something different.
if (suggestion is OverrideSuggestion && !label.startsWith('override ')) {
label = 'override $label';
}

// Trim any trailing comma from the (displayed) label.
if (label.endsWith(',')) {
label = label.substring(0, label.length - 1);
Expand Down Expand Up @@ -528,15 +537,25 @@ CompletionDetail _getCompletionDetail(
? (suggestion as ElementBasedSuggestion).element
: null;

// Usually getter/setters look the same in completion because they insert the
// same text. This is not the case for overrides because they will insert
// getter or setter stub code. To make this clear, we'll include get/set in
// the signature.
bool isGetterOverride = false, isSetterOverride = false;
if (suggestion is OverrideSuggestion) {
isGetterOverride = element is GetterElement;
isSetterOverride = element is SetterElement;
}

if (suggestion is NamedArgumentSuggestion) {
element = suggestion.parameter;
}
String? parameters;
if (element != null) {
parameters = getParametersString2(element);
// Prefer the element return type (because it may be more specific
// for overrides) and fall back to the parameter type or return type from the
// suggestion (handles records).
// for overrides) and fall back to the parameter type or return type from
// the suggestion (handles records).
String? parameterType;
if (element is FormalParameterElement) {
parameterType = element.type.getDisplayString();
Expand All @@ -558,19 +577,31 @@ CompletionDetail _getCompletionDetail(
'()' => '()',
_ => '(…)',
};
var fullSignature = switch ((parameters, returnType)) {
(null, _) => returnType ?? '',
(var parameters?, null) => parameters,
(var parameters?, '') => parameters,
(var parameters?, _) => '$parameters → $returnType',
var fullSignature = switch ((
parameters,
returnType,
isGetterOverride,
isSetterOverride,
)) {
(_, var returnType?, true, _) => '$returnType get',
(_, var returnType?, _, true) => 'set ($returnType)',
(null, _, _, _) => returnType ?? '',
(var parameters?, null || '', _, _) => parameters,
(var parameters?, var returnType?, _, _) => '$parameters → $returnType',
};
var truncatedSignature = switch ((parameters, returnType)) {
(null, null) => '',
var truncatedSignature = switch ((
parameters,
returnType,
isGetterOverride,
isSetterOverride,
)) {
// Include a leading space when no parameters so return type isn't right
// against the completion label.
(null, var returnType?) => ' $returnType',
(_, null) || (_, '') => truncatedParameters,
(_, var returnType?) => '$truncatedParameters → $returnType',
(_, var returnType?, true, _) => ' $returnType get',
(_, var returnType?, _, true) => ' set ($returnType)',
(null, var returnType?, _, _) => ' $returnType',
(_, null || '', _, _) => truncatedParameters,
(_, var returnType?, _, _) => '$truncatedParameters → $returnType',
};

// Use the full signature in the details popup.
Expand Down
44 changes: 29 additions & 15 deletions pkg/analysis_server/lib/src/utilities/mocks.dart
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,11 @@ class MockServerChannel implements ServerCommunicationChannel {

String? name;

MockServerChannel();
/// True if we are printing out messages exchanged with the server.
final bool printMessages;

MockServerChannel({bool? printMessages})
: printMessages = printMessages ?? false;

/// Return the broadcast stream of notifications.
Stream<Notification> get notifications {
Expand Down Expand Up @@ -99,12 +103,14 @@ class MockServerChannel implements ServerCommunicationChannel {

@override
void sendRequest(Request request) {
var jsonString = jsonEncode(request.toJson());
if (printMessages) {
print('<== $jsonString');
}

// Round-trip via JSON to ensure all types are fully serialized as they
// would be in a real setup.
request =
Request.fromJson(
jsonDecode(jsonEncode(request.toJson())) as Map<String, Object?>,
)!;
request = Request.fromJson(jsonDecode(jsonString) as Map<String, Object?>)!;

serverRequestsSent.add(request);
responseController.add(request);
Expand All @@ -117,12 +123,15 @@ class MockServerChannel implements ServerCommunicationChannel {
return;
}

var jsonString = jsonEncode(response.toJson());
if (printMessages) {
print('<== $jsonString');
}

// Round-trip via JSON to ensure all types are fully serialized as they
// would be in a real setup.
response =
Response.fromJson(
jsonDecode(jsonEncode(response.toJson())) as Map<String, Object?>,
)!;
Response.fromJson(jsonDecode(jsonString) as Map<String, Object?>)!;

responsesReceived.add(response);
responseController.add(response);
Expand All @@ -138,12 +147,14 @@ class MockServerChannel implements ServerCommunicationChannel {
throw Exception('simulateRequestFromClient after connection closed');
}

var jsonString = jsonEncode(request.toJson());
if (printMessages) {
print('==> $jsonString');
}

// Round-trip via JSON to ensure all types are fully serialized as they
// would be in a real setup.
request =
Request.fromJson(
jsonDecode(jsonEncode(request)) as Map<String, Object?>,
)!;
request = Request.fromJson(jsonDecode(jsonString) as Map<String, Object?>)!;

requestController.add(request);
var response = await waitForResponse(request);
Expand All @@ -166,12 +177,15 @@ class MockServerChannel implements ServerCommunicationChannel {
throw Exception('simulateRequestFromClient after connection closed');
}

var jsonString = jsonEncode(response.toJson());
if (printMessages) {
print('==> $jsonString');
}

// Round-trip via JSON to ensure all types are fully serialized as they
// would be in a real setup.
response =
Response.fromJson(
jsonDecode(jsonEncode(response)) as Map<String, Object?>,
)!;
Response.fromJson(jsonDecode(jsonString) as Map<String, Object?>)!;

requestController.add(response);
}
Expand Down
3 changes: 2 additions & 1 deletion pkg/analysis_server/test/analysis_server_base.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import 'package:meta/meta.dart';
import 'package:test/test.dart';
import 'package:unified_analytics/unified_analytics.dart';

import 'constants.dart';
import 'mocks.dart';
import 'support/configuration_files.dart';
import 'test_macros.dart';
Expand Down Expand Up @@ -189,7 +190,7 @@ abstract class ContextResolutionTest with ResourceProviderMixin {

@mustCallSuper
void setUp() {
serverChannel = MockServerChannel();
serverChannel = MockServerChannel(printMessages: debugPrintCommunication);

createMockSdk(resourceProvider: resourceProvider, root: sdkRoot);

Expand Down
4 changes: 3 additions & 1 deletion pkg/analysis_server/test/analysis_server_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:unified_analytics/unified_analytics.dart';

import 'constants.dart';

void main() {
defineReflectiveSuite(() {
defineReflectiveTests(AnalysisServerTest);
Expand All @@ -41,7 +43,7 @@ class AnalysisServerTest with ResourceProviderMixin {
late LegacyAnalysisServer server;

void setUp() {
channel = MockServerChannel();
channel = MockServerChannel(printMessages: debugPrintCommunication);

// Create an SDK in the mock file system.
var sdkRoot = newFolder('/sdk');
Expand Down
5 changes: 5 additions & 0 deletions pkg/analysis_server/test/constants.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ const String CODE = 'code';
const String COMPLETION_RESULTS = 'completion.results';
const String CONTEXT_MESSAGES = 'contextMessages';
const String CORRECTION = 'correction';

/// Useful for debugging locally, setting this to true will cause all JSON
/// communication to be printed to stdout.
const debugPrintCommunication = false;

const String EDITS = 'edits';
const String END_COLUMN = 'endColumn';
const String END_LINE = 'endLine';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import 'dart:async';
import 'package:stream_channel/stream_channel.dart';
import 'package:web_socket_channel/web_socket_channel.dart';

import '../../lsp/server_abstract.dart';
import '../../constants.dart';

/// Creates a [StreamChannel] for a connection to a WebSocket at [wsUri] that
/// prints all communication if [debugPrintCommunication] is `true`.
Expand Down
Loading

0 comments on commit 2a7da83

Please sign in to comment.