Add a quick fix for the MISSING_ENUM_CONSTANT_IN_SWITCH diagnostic (issue 36290)
Change-Id: I6a18fff7c61c93b3444899213da9c447122b76c2
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/97780
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index 3bb80d7..a83e2fe 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -133,6 +133,8 @@
appliedTogetherMessage: "Add all casts in file");
static const ADD_FIELD_FORMAL_PARAMETERS = const FixKind(
'ADD_FIELD_FORMAL_PARAMETERS', 70, "Add final field formal parameters");
+ static const ADD_MISSING_ENUM_CASE_CLAUSES = const FixKind(
+ 'ADD_MISSING_ENUM_CASE_CLAUSES', 50, 'Add missing case clauses');
static const ADD_MISSING_PARAMETER_NAMED = const FixKind(
'ADD_MISSING_PARAMETER_NAMED', 70, "Add named parameter '{0}'");
static const ADD_MISSING_PARAMETER_POSITIONAL = const FixKind(
diff --git a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
index 1aa5bbf..05d16f0 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -209,9 +209,6 @@
String get eol => utils.endOfLine;
Future<List<Fix>> compute() async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
-
node = new NodeLocator2(errorOffset).searchWithin(unit);
coveredNode = new NodeLocator2(errorOffset, errorOffset + errorLength - 1)
.searchWithin(unit);
@@ -561,6 +558,9 @@
CompileTimeErrorCode.MIXIN_APPLICATION_NOT_IMPLEMENTED_INTERFACE) {
await _addFix_extendClassForMixin();
}
+ if (errorCode == StaticWarningCode.MISSING_ENUM_CONSTANT_IN_SWITCH) {
+ await _addFix_addMissingEnumCaseClauses();
+ }
// lints
if (errorCode is LintCode) {
String name = errorCode.name;
@@ -785,6 +785,69 @@
}
}
+ Future<void> _addFix_addMissingEnumCaseClauses() async {
+ SwitchStatement statement = node as SwitchStatement;
+ String enumName;
+ List<String> enumConstantNames = [];
+ DartType expressionType = statement.expression.staticType;
+ if (expressionType is InterfaceType) {
+ ClassElement enumElement = expressionType.element;
+ if (enumElement.isEnum) {
+ enumName = enumElement.name;
+ for (FieldElement field in enumElement.fields) {
+ if (!field.isSynthetic) {
+ enumConstantNames.add(field.name);
+ }
+ }
+ }
+ }
+ if (enumName == null) {
+ return;
+ }
+ for (SwitchMember member in statement.members) {
+ if (member is SwitchCase) {
+ Expression expression = member.expression;
+ if (expression is Identifier) {
+ Element element = expression.staticElement;
+ if (element is PropertyAccessorElement) {
+ enumConstantNames.remove(element.name);
+ }
+ }
+ }
+ }
+ if (enumConstantNames.isEmpty) {
+ return;
+ }
+
+ String statementIndent = utils.getLinePrefix(statement.offset);
+ String singleIndent = utils.getIndent(1);
+
+ DartChangeBuilder changeBuilder = _newDartChangeBuilder();
+ await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addInsertion(utils.getLineThis(statement.end), (builder) {
+ for (String constantName in enumConstantNames) {
+ builder.write(statementIndent);
+ builder.write(singleIndent);
+ builder.write('case ');
+ builder.write(enumName);
+ builder.write('.');
+ builder.write(constantName);
+ builder.writeln(':');
+ builder.write(statementIndent);
+ builder.write(singleIndent);
+ builder.write(singleIndent);
+ builder.writeln('// TODO: Handle this case.');
+ builder.write(statementIndent);
+ builder.write(singleIndent);
+ builder.write(singleIndent);
+ builder.writeln('break;');
+ }
+ });
+ });
+ _addFixFromBuilder(
+ changeBuilder, DartFixKind.ADD_MISSING_ENUM_CASE_CLAUSES);
+ }
+
Future<void> _addFix_addMissingParameter() async {
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_missing_enum_case_clauses_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_missing_enum_case_clauses_test.dart
new file mode 100644
index 0000000..f796f39
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_missing_enum_case_clauses_test.dart
@@ -0,0 +1,88 @@
+// Copyright (c) 2019, 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/fix.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AddMissingEnumCaseClausesTest);
+ });
+}
+
+@reflectiveTest
+class AddMissingEnumCaseClausesTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.ADD_MISSING_ENUM_CASE_CLAUSES;
+
+ Future<void> assertHasFixWithFilter(String expected) async {
+ bool noError = true;
+ await assertHasFix(expected, errorFilter: (error) {
+ if (noError &&
+ error.errorCode ==
+ StaticWarningCode.MISSING_ENUM_CONSTANT_IN_SWITCH) {
+ noError = false;
+ return true;
+ }
+ return false;
+ });
+ }
+
+ test_empty() async {
+ await resolveTestUnit('''
+enum E {a, b, c}
+void f(E e) {
+ switch (e) {
+ }
+}
+''');
+ await assertHasFixWithFilter('''
+enum E {a, b, c}
+void f(E e) {
+ switch (e) {
+ case E.a:
+ // TODO: Handle this case.
+ break;
+ case E.b:
+ // TODO: Handle this case.
+ break;
+ case E.c:
+ // TODO: Handle this case.
+ break;
+ }
+}
+''');
+ }
+
+ test_nonEmpty() async {
+ await resolveTestUnit('''
+enum E {a, b, c}
+void f(E e) {
+ switch (e) {
+ case E.a:
+ break;
+ }
+}
+''');
+ await assertHasFixWithFilter('''
+enum E {a, b, c}
+void f(E e) {
+ switch (e) {
+ case E.a:
+ break;
+ case E.b:
+ // TODO: Handle this case.
+ break;
+ case E.c:
+ // TODO: Handle this case.
+ break;
+ }
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/test_all.dart b/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
index 1f49a54..e9ea84e 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
@@ -8,6 +8,8 @@
import 'add_await_test.dart' as add_await;
import 'add_explicit_cast_test.dart' as add_explicit_cast;
import 'add_field_formal_parameters_test.dart' as add_field_formal_parameters;
+import 'add_missing_enum_case_clauses_test.dart'
+ as add_missing_enum_case_clauses;
import 'add_missing_parameter_named_test.dart' as add_missing_parameter_named;
import 'add_missing_parameter_positional_test.dart'
as add_missing_parameter_positional;
@@ -110,6 +112,7 @@
add_await.main();
add_explicit_cast.main();
add_field_formal_parameters.main();
+ add_missing_enum_case_clauses.main();
add_missing_parameter_named.main();
add_missing_parameter_positional.main();
add_missing_parameter_required.main();