[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, ); }