Skip to content

Commit 2e5f834

Browse files
authored
[Property Editor] Add APIs to support refactors from the Property Editor (#9202)
Work towards #8652 This PR: * Adds methods to `editor_client` and `api_classes` to call the APIs added in https://dart-review.googlesource.com/c/sdk/+/428784 to support refactors This does not update the UI to show the available refactors. That will be follow-up. Note: Fetching the available refactors is currently protected by the `propertyEditorRefactors` feature flag.
1 parent 24f43f1 commit 2e5f834

File tree

15 files changed

+1087
-114
lines changed

15 files changed

+1087
-114
lines changed

flutter-candidate.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
48f87a5fe76aa65f89f37cc716e50b34933e78e9
1+
dd671fae53d37eb15e0f8fc94cd52c2f2ff147ee

packages/devtools_app/.vscode/launch.json

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,20 @@
6161
"request": "attach",
6262
},
6363
{
64-
"name": "standalone_ui/property_editor_sidebar",
64+
"name": "property_editor_sidebar",
6565
"request": "launch",
6666
"type": "dart",
6767
"program": "test/test_infra/scenes/standalone_ui/property_editor_sidebar.stager_app.g.dart",
6868
},
69+
{
70+
"name": "property_editor_sidebar + experiments",
71+
"request": "launch",
72+
"type": "dart",
73+
"program": "test/test_infra/scenes/standalone_ui/property_editor_sidebar.stager_app.g.dart",
74+
"args": [
75+
"--dart-define=enable_experiments=true"
76+
]
77+
},
6978

7079
]
7180
}

packages/devtools_app/lib/src/shared/analytics/constants/_property_editor_sidebar_constants.dart

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,6 @@ extension PropertyEditorSidebar on Never {
99
/// Analytics id to track events that come from the DTD editor sidebar.
1010
static String get id => 'propertyEditorSidebar';
1111

12-
/// Identifier for errors returned from the getEditableArguments API.
13-
static String get getEditableArgumentsIdentifier =>
14-
'${id}Error-getEditableArguments';
15-
16-
/// Identifier for errors returned from the editArgument API.
17-
static String get editArgumentIdentifier => '${id}Error-editArgument';
18-
1912
/// Analytics id for opening the documentation.
2013
static String get documentationLink => 'propertyEditorDocumentation';
2114

packages/devtools_app/lib/src/shared/editor/api_classes.dart

Lines changed: 93 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,36 @@ enum EditorMethod {
3131
/// TODO(https://github.com/flutter/devtools/issues/8824): Add tests that these
3232
/// are in-sync with analysis_server.
3333
enum LspMethod {
34+
codeAction(methodName: 'textDocument/codeAction'),
3435
editableArguments(methodName: 'dart/textDocument/editableArguments'),
35-
editArgument(methodName: 'dart/textDocument/editArgument');
36+
editArgument(methodName: 'dart/textDocument/editArgument'),
37+
executeCommand(methodName: 'workspace/executeCommand');
3638

3739
const LspMethod({required this.methodName});
3840

41+
/// Returns the [LspMethod] for the given [methodName].
42+
///
43+
/// If the [methodName] does not exist, returns null.
44+
static LspMethod? fromMethodName(String methodName) =>
45+
_methodNameToMethodLookup[methodName];
46+
3947
final String methodName;
4048

41-
String get experimentalMethodName => 'experimental/$methodName';
49+
static final _methodNameToMethodLookup = <String, LspMethod>{
50+
for (final method in LspMethod.values) method.methodName: method,
51+
};
52+
53+
static final _registrationStatus = <LspMethod, bool>{
54+
for (final method in LspMethod.values) method: false,
55+
};
56+
57+
/// Sets the registration status for this LSP method.
58+
set isRegistered(bool isRegistered) {
59+
_registrationStatus[this] = isRegistered;
60+
}
61+
62+
/// Gets the current registration status of this LSP method.
63+
bool get isRegistered => _registrationStatus[this] ?? false;
4264
}
4365

4466
/// Known kinds of events that may come from the editor.
@@ -82,12 +104,14 @@ enum EditorEventKind {
82104
/// Constants for all fields used in JSON maps to avoid literal strings that
83105
/// may have typos sprinkled throughout the API classes.
84106
abstract class Field {
107+
static const actions = 'actions';
85108
static const active = 'active';
86109
static const anchor = 'anchor';
87110
static const arguments = 'arguments';
88111
static const backgroundColor = 'backgroundColor';
89112
static const category = 'category';
90113
static const character = 'character';
114+
static const command = 'command';
91115
static const debuggerType = 'debuggerType';
92116
static const debugSession = 'debugSession';
93117
static const debugSessionId = 'debugSessionId';
@@ -115,6 +139,7 @@ abstract class Field {
115139
static const isEditable = 'isEditable';
116140
static const isNullable = 'isNullable';
117141
static const isRequired = 'isRequired';
142+
static const kind = 'kind';
118143
static const line = 'line';
119144
static const name = 'name';
120145
static const options = 'options';
@@ -133,6 +158,7 @@ abstract class Field {
133158
static const supportsForceExternal = 'supportsForceExternal';
134159
static const textDocument = 'textDocument';
135160
static const theme = 'theme';
161+
static const title = 'title';
136162
static const type = 'type';
137163
static const uri = 'uri';
138164
static const value = 'value';
@@ -501,6 +527,63 @@ class EditableArgumentsResult with Serializable {
501527
};
502528
}
503529

530+
/// Constants for [CodeActionCommand] prefixes used to filter the results
531+
/// returned by an [LspMethod.codeAction] request.
532+
abstract class CodeActionPrefixes {
533+
static const flutterWrap = 'refactor.flutter.wrap';
534+
}
535+
536+
/// The result of an [LspMethod.codeAction] request to the Analysis Server.
537+
///
538+
/// Contains a list of [CodeActionCommand]s that can be performed.
539+
class CodeActionResult with Serializable {
540+
CodeActionResult({required this.actions});
541+
542+
CodeActionResult.fromJson(List<Map<String, Object?>> list)
543+
: this(actions: list.map(CodeActionCommand.fromJson).toList());
544+
545+
final List<CodeActionCommand> actions;
546+
547+
@override
548+
Map<String, Object?> toJson() => {Field.actions: actions};
549+
}
550+
551+
/// A code action (also known as a "Refactor" or "Quick Fix") that can be called
552+
/// via an [LspMethod.executeCommand] request.
553+
///
554+
/// For example, "Wrap with Center" or "Wrap with Container".
555+
class CodeActionCommand with Serializable {
556+
CodeActionCommand({
557+
required this.command,
558+
required this.title,
559+
required this.args,
560+
});
561+
562+
CodeActionCommand.fromJson(Map<String, Object?> map)
563+
: this(
564+
command: map[Field.command] as String,
565+
title: map[Field.title] as String,
566+
args: map[Field.arguments] as List<Object?>? ?? <Object?>[],
567+
);
568+
569+
/// The command identifier to send to [LspMethod.executeCommand].
570+
final String command;
571+
572+
/// The human-readable title of the command, e.g., "Wrap with Center".
573+
final String title;
574+
575+
/// Arguments that should be passed to [LspMethod.executeCommand] when
576+
/// invoking this action.
577+
final List<Object?> args;
578+
579+
@override
580+
Map<String, Object?> toJson() => {
581+
Field.command: command,
582+
Field.title: title,
583+
Field.arguments: args,
584+
};
585+
}
586+
504587
/// Errors that the Analysis Server returns for failed argument edits.
505588
///
506589
/// These should be kept in sync with the error coes defined at
@@ -554,16 +637,17 @@ enum EditArgumentError {
554637
}
555638
}
556639

557-
/// Response to an edit argument request.
558-
class EditArgumentResponse {
559-
EditArgumentResponse({required this.success, this.errorMessage, errorCode})
560-
: _errorCode = errorCode;
640+
/// Generic response representing whether a request was a [success].
641+
class GenericApiResponse {
642+
GenericApiResponse({
643+
required this.success,
644+
this.errorMessage,
645+
this.errorCode,
646+
});
561647

562648
final bool success;
563649
final String? errorMessage;
564-
final int? _errorCode;
565-
566-
EditArgumentError? get errorType => EditArgumentError.fromCode(_errorCode);
650+
final int? errorCode;
567651
}
568652

569653
/// Information about a single editable argument of a widget.

0 commit comments

Comments
 (0)