Skip to content

Commit ee0a316

Browse files
DanTupCommit Queue
authored andcommitted
[analysis_server] Suppress snippet support for Command CodeActions
We support a non-standard mechanism (https://github.com/rust-lang/rust-analyzer/blob/b35559a2460e7f0b2b79a7029db0c5d4e0acdb44/docs/dev/lsp-extensions.md#snippet-textedit) for having snippets on edits for Code Actions. This is only specified for edits returned from `codeAction` requests (and only implemented in Dart-Code for the same), so we should not return snippets when applying edits via `workspace/applyEdit` (eg. when code actions are returned as commands). This prevents snippet markup being inserted literally into the editor if codeActions are executed over DTD (eg. from property editor). Change-Id: I7882bffb8038671459e7487dc2e944020395f128 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/429340 Reviewed-by: Brian Wilkerson <[email protected]> Reviewed-by: Samuel Rawlins <[email protected]> Commit-Queue: Brian Wilkerson <[email protected]>
1 parent 0dd4a95 commit ee0a316

File tree

10 files changed

+103
-3
lines changed

10 files changed

+103
-3
lines changed

pkg/analysis_server/lib/src/lsp/handlers/code_actions/abstract_code_actions_producer.dart

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,14 @@ abstract class AbstractCodeActionsProducer
3939
final int length;
4040
final bool Function(CodeActionKind?) shouldIncludeKind;
4141

42+
/// Whether non-standard LSP snippets are allowed in edits produced.
43+
///
44+
/// This is usually true for the `textDocument/codeAction` request (because we
45+
/// support it for [CodeActionLiteral]s) but `false` for the
46+
/// [Commands.applyCodeAction] handler because it's not supported for
47+
/// `workspace/applyEdit` reverse requests.
48+
final bool allowSnippets;
49+
4250
/// The capabilities of the caller making the request for [CodeAction]s.
4351
final LspClientCapabilities callerCapabilities;
4452

@@ -78,6 +86,7 @@ abstract class AbstractCodeActionsProducer
7886
required this.editorCapabilities,
7987
required this.allowCommands,
8088
required this.allowCodeActionLiterals,
89+
required this.allowSnippets,
8190
required this.analysisOptions,
8291
});
8392

@@ -139,7 +148,7 @@ abstract class AbstractCodeActionsProducer
139148
server,
140149
editorCapabilities,
141150
change,
142-
allowSnippets: true,
151+
allowSnippets: allowSnippets,
143152
filePath: path,
144153
lineInfo: lineInfo,
145154
),

pkg/analysis_server/lib/src/lsp/handlers/code_actions/analysis_options.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class AnalysisOptionsCodeActionsProducer extends AbstractCodeActionsProducer {
3131
required super.allowCodeActionLiterals,
3232
required super.allowCommands,
3333
required super.analysisOptions,
34+
required super.allowSnippets,
3435
});
3536

3637
@override

pkg/analysis_server/lib/src/lsp/handlers/code_actions/code_action_computer.dart

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,14 @@ class CodeActionComputer with HandlerHelperMixin<AnalysisServer> {
4646
/// How the request was triggered.
4747
final CodeActionTriggerKind? triggerKind;
4848

49+
/// Whether non-standard LSP snippets are allowed in edits produced.
50+
///
51+
/// This is usually true for the `textDocument/codeAction` request (because we
52+
/// support it for [CodeActionLiteral]s) but `false` for the
53+
/// [Commands.applyCodeAction] handler because it's not supported for
54+
/// `workspace/applyEdit` reverse requests.
55+
final bool allowSnippets;
56+
4957
/// Whether [CodeAction]s can be [Command]s or not.
5058
///
5159
/// This is usually true (because there is no capability for this), however
@@ -92,6 +100,7 @@ class CodeActionComputer with HandlerHelperMixin<AnalysisServer> {
92100
required this.triggerKind,
93101
required this.allowCommands,
94102
required this.allowCodeActionLiterals,
103+
required this.allowSnippets,
95104
required this.performance,
96105
});
97106

@@ -237,8 +246,9 @@ class CodeActionComputer with HandlerHelperMixin<AnalysisServer> {
237246
callerCapabilities: callerCapabilities,
238247
allowCodeActionLiterals: allowCodeActionLiterals,
239248
allowCommands: allowCommands,
240-
triggerKind: triggerKind,
249+
allowSnippets: allowSnippets,
241250
analysisOptions: analysisOptions,
251+
triggerKind: triggerKind,
242252
willBeDeduplicated: true,
243253
),
244254
if (isPubspec)
@@ -254,6 +264,7 @@ class CodeActionComputer with HandlerHelperMixin<AnalysisServer> {
254264
callerCapabilities: callerCapabilities,
255265
allowCodeActionLiterals: allowCodeActionLiterals,
256266
allowCommands: allowCommands,
267+
allowSnippets: allowSnippets,
257268
analysisOptions: analysisOptions,
258269
),
259270
if (isAnalysisOptions)
@@ -269,6 +280,7 @@ class CodeActionComputer with HandlerHelperMixin<AnalysisServer> {
269280
callerCapabilities: callerCapabilities,
270281
allowCodeActionLiterals: allowCodeActionLiterals,
271282
allowCommands: allowCommands,
283+
allowSnippets: allowSnippets,
272284
analysisOptions: analysisOptions,
273285
),
274286
PluginCodeActionsProducer(
@@ -283,6 +295,7 @@ class CodeActionComputer with HandlerHelperMixin<AnalysisServer> {
283295
callerCapabilities: callerCapabilities,
284296
allowCodeActionLiterals: allowCodeActionLiterals,
285297
allowCommands: allowCommands,
298+
allowSnippets: allowSnippets,
286299
analysisOptions: analysisOptions,
287300
),
288301
];

pkg/analysis_server/lib/src/lsp/handlers/code_actions/dart.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ class DartCodeActionsProducer extends AbstractCodeActionsProducer {
5555
required super.callerCapabilities,
5656
required super.allowCodeActionLiterals,
5757
required super.allowCommands,
58+
required super.allowSnippets,
5859
required super.analysisOptions,
5960
required this.triggerKind,
6061
required this.willBeDeduplicated,

pkg/analysis_server/lib/src/lsp/handlers/code_actions/plugins.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ class PluginCodeActionsProducer extends AbstractCodeActionsProducer {
3030
required super.allowCodeActionLiterals,
3131
required super.allowCommands,
3232
required super.analysisOptions,
33+
required super.allowSnippets,
3334
}) : driver = server.getAnalysisDriver(file.path);
3435

3536
@override

pkg/analysis_server/lib/src/lsp/handlers/code_actions/pubspec.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class PubspecCodeActionsProducer extends AbstractCodeActionsProducer {
2828
required super.allowCodeActionLiterals,
2929
required super.allowCommands,
3030
required super.analysisOptions,
31+
required super.allowSnippets,
3132
});
3233

3334
@override

pkg/analysis_server/lib/src/lsp/handlers/commands/apply_code_action.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,10 @@ class ApplyCodeActionCommandHandler
147147
// ability to applyEdit has been checked at the top of this method.
148148
allowCommands: false,
149149
allowCodeActionLiterals: true,
150+
151+
// We don't support non-standard snippets for `workspace/applyEdit`, only
152+
// CodeActionLiterals.
153+
allowSnippets: false,
150154
);
151155
var actions = await computer.compute();
152156

pkg/analysis_server/lib/src/lsp/handlers/handler_code_actions.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ class CodeActionHandler
5757
triggerKind: params.context.triggerKind,
5858
allowCommands: true,
5959
allowCodeActionLiterals: supportsLiterals,
60+
allowSnippets: true, // We allow snippets from code actions requests.
6061
performance: performance,
6162
);
6263

pkg/analysis_server/test/shared/shared_code_actions_assists_tests.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ Widget build() {
126126
>>>>>>>>>> lib/test.dart
127127
import 'package:flutter/widgets.dart';
128128
Widget build() {
129-
return Center($0child: Text(''));
129+
return Center(child: Text(''));
130130
}
131131
''';
132132

pkg/analysis_server/test/shared/shared_code_actions_fixes_tests.dart

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -701,6 +701,38 @@ name: $testPackageName
701701
);
702702
}
703703

704+
Future<void> test_snippets() async {
705+
setSnippetTextEditSupport();
706+
707+
const content = '''
708+
abstract class A {
709+
void m();
710+
}
711+
712+
class ^B extends A {}
713+
''';
714+
715+
const expectedContent = r'''
716+
abstract class A {
717+
void m();
718+
}
719+
720+
class B extends A {
721+
@override
722+
void m() {
723+
// TODO: implement m$0
724+
}
725+
}
726+
''';
727+
728+
await verifyCodeActionLiteralEdits(
729+
content,
730+
expectedContent,
731+
kind: CodeActionKind('quickfix.create.missingOverrides'),
732+
title: 'Create 1 missing override',
733+
);
734+
}
735+
704736
Future<void> test_snippets_createMethod_functionTypeNestedParameters() async {
705737
const content = '''
706738
class A {
@@ -788,6 +820,43 @@ useFunction(int g(a, b)) {}
788820
);
789821
}
790822

823+
/// The non-standard snippets we supported are only supported for
824+
/// [CodeActionLiteral]s and not for [Command]s (which go via
825+
/// workspace/applyEdit) so even if enabled, they should not be returned.
826+
Future<void> test_snippets_unsupportedForCommands() async {
827+
setSupportedCodeActionKinds(null); // no codeActionLiteralSupport
828+
setSnippetTextEditSupport(); // will be ignored
829+
830+
const content = '''
831+
abstract class A {
832+
void m();
833+
}
834+
835+
class ^B extends A {}
836+
''';
837+
838+
// No $0 placeholder in this content (unlike in `test_snippets`).
839+
const expectedContent = r'''
840+
abstract class A {
841+
void m();
842+
}
843+
844+
class B extends A {
845+
@override
846+
void m() {
847+
// TODO: implement m
848+
}
849+
}
850+
''';
851+
852+
await verifyCommandCodeActionEdits(
853+
content,
854+
expectedContent,
855+
command: Commands.applyCodeAction,
856+
title: 'Create 1 missing override',
857+
);
858+
}
859+
791860
void _enableLints(List<String> lintNames) {
792861
registerLintRules();
793862
var lintsYaml = lintNames.map((name) => ' - $name\n').join();

0 commit comments

Comments
 (0)