mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 16:55:08 +00:00
Add quick assist to convert SwitchStatement (with patterns) into if-case chain.
Bug: https://github.com/dart-lang/sdk/issues/52068 Change-Id: Ia20b943dfc5212764f31cd94f4f8cce8755628bc Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/297140 Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Commit-Queue: Konstantin Shcheglov <scheglov@google.com> Reviewed-by: Phil Quitslund <pquitslund@google.com>
This commit is contained in:
parent
529adda42e
commit
b5d63cb67f
|
@ -146,6 +146,11 @@ class DartAssistKind {
|
|||
DartAssistKindPriority.DEFAULT,
|
||||
"Convert to 'if-case' statement",
|
||||
);
|
||||
static const CONVERT_TO_IF_CASE_STATEMENT_CHAIN = AssistKind(
|
||||
'dart.assist.convert.ifCaseStatementChain',
|
||||
DartAssistKindPriority.DEFAULT,
|
||||
"Convert to 'if-case' statement chain",
|
||||
);
|
||||
static const CONVERT_TO_IF_ELEMENT = AssistKind(
|
||||
'dart.assist.convert.toIfElement',
|
||||
DartAssistKindPriority.DEFAULT,
|
||||
|
|
|
@ -31,6 +31,7 @@ import 'package:analysis_server/src/services/correction/dart/convert_to_expressi
|
|||
import 'package:analysis_server/src/services/correction/dart/convert_to_field_parameter.dart';
|
||||
import 'package:analysis_server/src/services/correction/dart/convert_to_generic_function_syntax.dart';
|
||||
import 'package:analysis_server/src/services/correction/dart/convert_to_if_case_statement.dart';
|
||||
import 'package:analysis_server/src/services/correction/dart/convert_to_if_case_statement_chain.dart';
|
||||
import 'package:analysis_server/src/services/correction/dart/convert_to_int_literal.dart';
|
||||
import 'package:analysis_server/src/services/correction/dart/convert_to_map_literal.dart';
|
||||
import 'package:analysis_server/src/services/correction/dart/convert_to_multiline_string.dart';
|
||||
|
@ -116,6 +117,7 @@ class AssistProcessor extends BaseProcessor {
|
|||
ConvertToFieldParameter.new,
|
||||
ConvertToGenericFunctionSyntax.new,
|
||||
ConvertToIfCaseStatement.new,
|
||||
ConvertToIfCaseStatementChain.new,
|
||||
ConvertToIntLiteral.new,
|
||||
ConvertToMapLiteral.new,
|
||||
ConvertToMultilineString.new,
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import 'package:analysis_server/src/services/correction/assist.dart';
|
||||
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
|
||||
import 'package:analyzer/dart/ast/ast.dart';
|
||||
import 'package:analyzer_plugin/utilities/assist/assist.dart';
|
||||
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
|
||||
import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
|
||||
import 'package:analyzer_plugin/utilities/range_factory.dart';
|
||||
|
||||
class ConvertToIfCaseStatementChain extends CorrectionProducer {
|
||||
@override
|
||||
AssistKind get assistKind =>
|
||||
DartAssistKind.CONVERT_TO_IF_CASE_STATEMENT_CHAIN;
|
||||
|
||||
@override
|
||||
Future<void> compute(ChangeBuilder builder) async {
|
||||
final switchStatement = node;
|
||||
if (switchStatement is! SwitchStatement) {
|
||||
return;
|
||||
}
|
||||
|
||||
final ifIndent = utils.getLinePrefix(switchStatement.offset);
|
||||
final expressionCode = utils.getNodeText(switchStatement.expression);
|
||||
|
||||
final switchPatternCases = <SwitchPatternCase>[];
|
||||
SwitchDefault? defaultCase;
|
||||
for (final member in switchStatement.members) {
|
||||
switch (member) {
|
||||
case SwitchPatternCase():
|
||||
switchPatternCases.add(member);
|
||||
case SwitchDefault():
|
||||
defaultCase = member;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
await builder.addDartFileEdit(file, (builder) {
|
||||
builder.addReplacement(range.node(switchStatement), (builder) {
|
||||
var isFirst = true;
|
||||
for (final case_ in switchPatternCases) {
|
||||
if (isFirst) {
|
||||
isFirst = false;
|
||||
} else {
|
||||
builder.write(' else ');
|
||||
}
|
||||
final patternCode = utils.getNodeText(case_.guardedPattern);
|
||||
builder.writeln('if ($expressionCode case $patternCode) {');
|
||||
_writeStatements(
|
||||
builder: builder,
|
||||
blockIndent: ifIndent,
|
||||
statements: case_.statements,
|
||||
);
|
||||
builder.write('$ifIndent}');
|
||||
}
|
||||
if (defaultCase case final defaultCase?) {
|
||||
builder.writeln(' else {');
|
||||
_writeStatements(
|
||||
builder: builder,
|
||||
blockIndent: ifIndent,
|
||||
statements: defaultCase.statements,
|
||||
);
|
||||
builder.write('$ifIndent}');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void _writeStatements({
|
||||
required DartEditBuilder builder,
|
||||
required List<Statement> statements,
|
||||
required String blockIndent,
|
||||
}) {
|
||||
final range = utils.getLinesRangeStatements(statements);
|
||||
|
||||
final firstIndent = utils.getLinePrefix(statements.first.offset);
|
||||
final singleIndent = utils.getIndent(1);
|
||||
|
||||
final code = utils.replaceSourceRangeIndent(
|
||||
range,
|
||||
firstIndent,
|
||||
blockIndent + singleIndent,
|
||||
);
|
||||
builder.write(code);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import 'package:analysis_server/src/services/correction/assist.dart';
|
||||
import 'package:analyzer_plugin/utilities/assist/assist.dart';
|
||||
import 'package:test_reflective_loader/test_reflective_loader.dart';
|
||||
|
||||
import 'assist_processor.dart';
|
||||
|
||||
void main() {
|
||||
defineReflectiveSuite(() {
|
||||
defineReflectiveTests(ConvertToIfCaseStatementChainTest);
|
||||
});
|
||||
}
|
||||
|
||||
@reflectiveTest
|
||||
class ConvertToIfCaseStatementChainTest extends AssistProcessorTest {
|
||||
@override
|
||||
AssistKind get kind => DartAssistKind.CONVERT_TO_IF_CASE_STATEMENT_CHAIN;
|
||||
|
||||
Future<void> test_noDefault() async {
|
||||
await resolveTestCode('''
|
||||
void f(Object? x) {
|
||||
switch (x) {
|
||||
case int():
|
||||
0;
|
||||
case double():
|
||||
1;
|
||||
}
|
||||
}
|
||||
''');
|
||||
await assertHasAssistAt('switch', '''
|
||||
void f(Object? x) {
|
||||
if (x case int()) {
|
||||
0;
|
||||
} else if (x case double()) {
|
||||
1;
|
||||
}
|
||||
}
|
||||
''');
|
||||
}
|
||||
|
||||
Future<void> test_withDefault() async {
|
||||
await resolveTestCode('''
|
||||
void f(Object? x) {
|
||||
switch (x) {
|
||||
case int():
|
||||
0;
|
||||
case double():
|
||||
1;
|
||||
default:
|
||||
2;
|
||||
}
|
||||
}
|
||||
''');
|
||||
await assertHasAssistAt('switch', '''
|
||||
void f(Object? x) {
|
||||
if (x case int()) {
|
||||
0;
|
||||
} else if (x case double()) {
|
||||
1;
|
||||
} else {
|
||||
2;
|
||||
}
|
||||
}
|
||||
''');
|
||||
}
|
||||
}
|
|
@ -30,6 +30,8 @@ import 'convert_to_double_quoted_string_test.dart'
|
|||
as convert_to_double_quoted_string;
|
||||
import 'convert_to_field_parameter_test.dart' as convert_to_field_parameter;
|
||||
import 'convert_to_for_element_test.dart' as convert_to_for_element;
|
||||
import 'convert_to_if_case_statement_chain_test.dart'
|
||||
as convert_to_if_case_statement_chain;
|
||||
import 'convert_to_if_case_statement_test.dart' as convert_to_if_case_statement;
|
||||
import 'convert_to_if_element_test.dart' as convert_to_if_element;
|
||||
import 'convert_to_int_literal_test.dart' as convert_to_int_literal;
|
||||
|
@ -119,6 +121,7 @@ void main() {
|
|||
convert_to_double_quoted_string.main();
|
||||
convert_to_field_parameter.main();
|
||||
convert_to_for_element.main();
|
||||
convert_to_if_case_statement_chain.main();
|
||||
convert_to_if_case_statement.main();
|
||||
convert_to_if_element.main();
|
||||
convert_to_int_literal.main();
|
||||
|
|
Loading…
Reference in a new issue