quick fix for `MIXIN_SUBTYPE_OF_BASE_IS_NOT_BASE`
Change-Id: I0a397f3aa1fd697014ff20debfbe08a1ea2f62e2
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/368181
Auto-Submit: Phil Quitslund <pquitslund@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_class_modifier.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_class_modifier.dart
new file mode 100644
index 0000000..6ac2b08
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_class_modifier.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2024, 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/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+
+class AddClassModifier extends ResolvedCorrectionProducer {
+ final String _modifier;
+
+ AddClassModifier.base() : this._('base');
+
+ AddClassModifier._(this._modifier);
+
+ @override
+ CorrectionApplicability get applicability =>
+ CorrectionApplicability.acrossSingleFile;
+
+ @override
+ List<String> get fixArguments => [_modifier];
+
+ @override
+ FixKind get fixKind => DartFixKind.ADD_CLASS_MODIFIER;
+
+ @override
+ FixKind get multiFixKind => DartFixKind.ADD_CLASS_MODIFIER_MULTI;
+
+ @override
+ Future<void> compute(ChangeBuilder builder) async {
+ var node = this.node;
+ if (node is! NamedCompilationUnitMember) return;
+
+ await builder.addDartFileEdit(file, (builder) {
+ builder.addSimpleInsertion(
+ node.firstTokenAfterCommentAndMetadata.offset, '$_modifier ');
+ });
+ }
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml b/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml
index c143e98..8c2e1ac 100644
--- a/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml
+++ b/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml
@@ -45,8 +45,8 @@
#
# Stats:
# - 42 "needsEvaluation"
-# - 360 "needsFix"
-# - 391 "hasFix"
+# - 359 "needsFix"
+# - 392 "hasFix"
# - 516 "noFix"
AnalysisOptionsErrorCode.INCLUDED_FILE_PARSE_ERROR:
@@ -1118,9 +1118,7 @@
CompileTimeErrorCode.MIXIN_ON_TYPE_ALIAS_EXPANDS_TO_TYPE_PARAMETER:
status: noFix
CompileTimeErrorCode.MIXIN_SUBTYPE_OF_BASE_IS_NOT_BASE:
- status: needsFix
- notes: |-
- Add `base`.
+ status: hasFix
CompileTimeErrorCode.MIXIN_SUBTYPE_OF_FINAL_IS_NOT_BASE:
status: needsFix
notes: |-
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index f0c2d69..33069c6 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -61,6 +61,16 @@
DartFixKindPriority.IN_FILE,
'Add empty argument lists everywhere in file',
);
+ static const ADD_CLASS_MODIFIER = FixKind(
+ 'dart.fix.add.class.modifier',
+ DartFixKindPriority.DEFAULT,
+ "Add ''{0}'' modifier",
+ );
+ static const ADD_CLASS_MODIFIER_MULTI = FixKind(
+ 'dart.fix.add.class.modifier.multi',
+ DartFixKindPriority.IN_FILE,
+ "Add ''{0}'' modifier everywhere in file",
+ );
static const ADD_CONST = FixKind(
'dart.fix.add.const',
DartFixKindPriority.DEFAULT,
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 641a979..55edad2 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -6,6 +6,7 @@
import 'package:analysis_server/src/services/correction/dart/add_async.dart';
import 'package:analysis_server/src/services/correction/dart/add_await.dart';
import 'package:analysis_server/src/services/correction/dart/add_call_super.dart';
+import 'package:analysis_server/src/services/correction/dart/add_class_modifier.dart';
import 'package:analysis_server/src/services/correction/dart/add_const.dart';
import 'package:analysis_server/src/services/correction/dart/add_diagnostic_property_reference.dart';
import 'package:analysis_server/src/services/correction/dart/add_empty_argument_list.dart';
@@ -1057,6 +1058,9 @@
CompileTimeErrorCode.MIXIN_CLASS_DECLARATION_EXTENDS_NOT_OBJECT: [
RemoveExtendsClause.new,
],
+ CompileTimeErrorCode.MIXIN_SUBTYPE_OF_BASE_IS_NOT_BASE: [
+ AddClassModifier.base,
+ ],
CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS: [
RemoveNameFromDeclarationClause.new,
],
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_class_modifier_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_class_modifier_test.dart
new file mode 100644
index 0000000..b00c2f3
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_class_modifier_test.dart
@@ -0,0 +1,45 @@
+// Copyright (c) 2024, 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_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+void main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AddClassModifierTest);
+ });
+}
+
+@reflectiveTest
+class AddClassModifierTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.ADD_CLASS_MODIFIER;
+
+ Future<void> test_mixinSubtypeOfBaseIsNotBase() async {
+ await resolveTestCode('''
+base class A {}
+mixin B implements A {}
+''');
+ await assertHasFix('''
+base class A {}
+base mixin B implements A {}
+''');
+ }
+
+ Future<void> test_mixinSubtypeOfBaseIsNotBase_withDoc() async {
+ await resolveTestCode('''
+base class A {}
+// Doc.
+mixin B implements A {}
+''');
+ await assertHasFix('''
+base class A {}
+// Doc.
+base mixin B implements A {}
+''');
+ }
+}
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 595e1ad..b48d0f5 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
@@ -7,6 +7,7 @@
import 'add_async_test.dart' as add_async;
import 'add_await_test.dart' as add_await;
import 'add_call_super_test.dart' as add_call_super;
+import 'add_class_modifier_test.dart' as add_class_modifier;
import 'add_const_test.dart' as add_const;
import 'add_curly_braces_test.dart' as add_curly_braces;
import 'add_diagnostic_property_reference_test.dart'
@@ -295,6 +296,7 @@
add_async.main();
add_await.main();
add_call_super.main();
+ add_class_modifier.main();
add_const.main();
add_curly_braces.main();
add_diagnostic_property_reference.main();