[analysis_server] Add 'range' to EditableArguments response
See https://github.com/flutter/devtools/issues/9035
Change-Id: Ia2cadea05f10f16e00d1dbf0240b16761c0c6b0f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/419600
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Elliott Brooks <elliottbrooks@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/custom/editable_arguments/editable_arguments_mixin.dart b/pkg/analysis_server/lib/src/lsp/handlers/custom/editable_arguments/editable_arguments_mixin.dart
index 2889807..ad855c5 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/custom/editable_arguments/editable_arguments_mixin.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/custom/editable_arguments/editable_arguments_mixin.dart
@@ -15,6 +15,7 @@
/// Information about the arguments and parameters for an invocation.
typedef EditableInvocationInfo =
({
+ AstNode invocation,
String? widgetName,
String? widgetDocumentation,
List<FormalParameterElement> parameters,
@@ -51,6 +52,10 @@
};
});
+ if (invocation == null) {
+ return null;
+ }
+
String? widgetName, widgetDocumentation;
if (invocation is InstanceCreationExpression) {
widgetName = invocation.constructorName.type.name2.lexeme;
@@ -106,6 +111,7 @@
};
return (
+ invocation: invocation,
widgetName: widgetName,
widgetDocumentation: widgetDocumentation,
parameters: parameters,
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/custom/editable_arguments/handler_edit_argument.dart b/pkg/analysis_server/lib/src/lsp/handlers/custom/editable_arguments/handler_edit_argument.dart
index 7c205d4..0c15c1c 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/custom/editable_arguments/handler_edit_argument.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/custom/editable_arguments/handler_edit_argument.dart
@@ -83,8 +83,8 @@
}
// Locate the invocation we're editing.
- var invocation = getInvocationInfo(result, offset);
- if (invocation == null) {
+ var invocationInfo = getInvocationInfo(result, offset);
+ if (invocationInfo == null) {
return error(
ServerErrorCodes.EditArgumentInvalidPosition,
'No invocation was found at the provided position',
@@ -92,6 +92,7 @@
}
var (
+ invocation: _,
:widgetName,
:widgetDocumentation,
:parameters,
@@ -100,7 +101,7 @@
:argumentList,
:numPositionals,
:numSuppliedPositionals,
- ) = invocation;
+ ) = invocationInfo;
// Find the parameter we're editing the argument for.
var parameterName = params.edit.name;
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/custom/editable_arguments/handler_editable_arguments.dart b/pkg/analysis_server/lib/src/lsp/handlers/custom/editable_arguments/handler_editable_arguments.dart
index 5603076..741a9ad 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/custom/editable_arguments/handler_editable_arguments.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/custom/editable_arguments/handler_editable_arguments.dart
@@ -90,14 +90,15 @@
TextDocumentIdentifier textDocument,
int offset,
) {
- var invocation = getInvocationInfo(result, offset);
- if (invocation == null) {
+ var invocationInfo = getInvocationInfo(result, offset);
+ if (invocationInfo == null) {
return null;
}
var textDocument = server.getVersionedDocumentIdentifier(result.path);
var (
+ :invocation,
:widgetName,
:widgetDocumentation,
:parameters,
@@ -106,7 +107,7 @@
:argumentList,
:numPositionals,
:numSuppliedPositionals,
- ) = invocation;
+ ) = invocationInfo;
// Build the complete list of editable arguments.
//
@@ -135,6 +136,7 @@
name: widgetName,
documentation: widgetDocumentation,
arguments: editableArguments.nonNulls.toList(),
+ range: toRange(result.lineInfo, invocation.offset, invocation.length),
);
}
diff --git a/pkg/analysis_server/test/shared/shared_editable_arguments_tests.dart b/pkg/analysis_server/test/shared/shared_editable_arguments_tests.dart
index 256956b..f7808c9 100644
--- a/pkg/analysis_server/test/shared/shared_editable_arguments_tests.dart
+++ b/pkg/analysis_server/test/shared/shared_editable_arguments_tests.dart
@@ -1058,6 +1058,18 @@
);
}
+ Future<void> test_range() async {
+ var result = await getEditableArgumentsFor(r'''
+class MyWidget extends StatelessWidget {
+ const MyWidget({int? a = null});
+
+ @override
+ Widget build(BuildContext context) => [!MyW^idget(a: 1)!];
+}
+''');
+ expect(result!.range, code.range.range);
+ }
+
Future<void> test_textDocument_unopenedFile() async {
var result = await getEditableArgumentsFor('''
class MyWidget extends StatelessWidget {
diff --git a/pkg/analysis_server/tool/lsp_spec/generate_all.dart b/pkg/analysis_server/tool/lsp_spec/generate_all.dart
index 82278c2..68b711a 100644
--- a/pkg/analysis_server/tool/lsp_spec/generate_all.dart
+++ b/pkg/analysis_server/tool/lsp_spec/generate_all.dart
@@ -425,6 +425,7 @@
field('documentation', type: 'string', canBeUndefined: true),
// TODO(dantup): field('refactors', ...),
field('arguments', type: 'EditableArgument', array: true),
+ field('range', type: 'Range', comment: 'The range of the invocation.'),
]),
interface('EditableArgument', [
field(
diff --git a/third_party/pkg/language_server_protocol/lib/protocol_custom_generated.dart b/third_party/pkg/language_server_protocol/lib/protocol_custom_generated.dart
index 4c5658b..30bdfcc 100644
--- a/third_party/pkg/language_server_protocol/lib/protocol_custom_generated.dart
+++ b/third_party/pkg/language_server_protocol/lib/protocol_custom_generated.dart
@@ -1693,11 +1693,15 @@
final String? documentation;
final String? name;
+
+ /// The range of the invocation.
+ final Range range;
final TextDocumentIdentifier textDocument;
EditableArguments({
required this.arguments,
this.documentation,
this.name,
+ required this.range,
required this.textDocument,
});
@override
@@ -1705,6 +1709,7 @@
lspHashCode(arguments),
documentation,
name,
+ range,
textDocument,
);
@@ -1715,6 +1720,7 @@
const DeepCollectionEquality().equals(arguments, other.arguments) &&
documentation == other.documentation &&
name == other.name &&
+ range == other.range &&
textDocument == other.textDocument;
}
@@ -1728,6 +1734,7 @@
if (name != null) {
result['name'] = name;
}
+ result['range'] = range.toJson();
result['textDocument'] = textDocument.toJson();
return result;
}
@@ -1749,6 +1756,10 @@
allowsUndefined: true, allowsNull: false)) {
return false;
}
+ if (!_canParseRange(obj, reporter, 'range',
+ allowsUndefined: false, allowsNull: false)) {
+ return false;
+ }
return _canParseTextDocumentIdentifier(obj, reporter, 'textDocument',
allowsUndefined: false, allowsNull: false);
} else {
@@ -1766,6 +1777,8 @@
final documentation = documentationJson as String?;
final nameJson = json['name'];
final name = nameJson as String?;
+ final rangeJson = json['range'];
+ final range = Range.fromJson(rangeJson as Map<String, Object?>);
final textDocumentJson = json['textDocument'];
final textDocument = TextDocumentIdentifier.fromJson(
textDocumentJson as Map<String, Object?>);
@@ -1773,6 +1786,7 @@
arguments: arguments,
documentation: documentation,
name: name,
+ range: range,
textDocument: textDocument,
);
}