diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_primary_constructor_body.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_primary_constructor_body.dart new file mode 100644 index 00000000000..85be1fc2ab1 --- /dev/null +++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_primary_constructor_body.dart @@ -0,0 +1,35 @@ +// Copyright (c) 2026, 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:analysis_server_plugin/edit/dart/correction_producer.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 RemovePrimaryConstructorBody extends ResolvedCorrectionProducer { + new({required super.context}); + + @override + CorrectionApplicability get applicability => + CorrectionApplicability.automatically; + + @override + FixKind get fixKind => DartFixKind.removePrimaryConstructorBody; + + @override + FixKind get multiFixKind => DartFixKind.removePrimaryConstructorBodyMulti; + + @override + Future compute(ChangeBuilder builder) async { + var body = node.thisOrAncestorOfType(); + if (body == null) { + return; + } + + await builder.addDartFileEdit(file, (builder) { + builder.addDeletion(utils.getLinesRange(body.sourceRange)); + }); + } +} 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 5eddcd24b97..191a392c1fe 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 @@ -2584,9 +2584,7 @@ unnecessary_overrides: unnecessary_parenthesis: status: hasFix unnecessary_primary_constructor_body: - status: needsFix - notes: |- - The fix is to remove the body. + status: hasFix unnecessary_raw_strings: status: hasFix unnecessary_statements: diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart index 946c0a20eb6..6eaf5975369 100644 --- a/pkg/analysis_server/lib/src/services/correction/fix.dart +++ b/pkg/analysis_server/lib/src/services/correction/fix.dart @@ -1632,6 +1632,16 @@ abstract final class DartFixKind { DartFixKindPriority.standard, 'Remove parentheses in getter invocation', ); + static const removePrimaryConstructorBody = FixKind( + 'dart.fix.remove.primaryConstructorBody', + DartFixKindPriority.standard, + 'Remove primary constructor body', + ); + static const removePrimaryConstructorBodyMulti = FixKind( + 'dart.fix.remove.primaryConstructorBody.multi', + DartFixKindPriority.inFile, + 'Remove primary constructor bodies file', + ); static const removePrint = FixKind( 'dart.fix.remove.removePrint', DartFixKindPriority.standard, 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 cbce9f25343..ca98a348caf 100644 --- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart +++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart @@ -177,6 +177,7 @@ import 'package:analysis_server/src/services/correction/dart/remove_on_clause.da import 'package:analysis_server/src/services/correction/dart/remove_operator.dart'; import 'package:analysis_server/src/services/correction/dart/remove_parameters_in_getter_declaration.dart'; import 'package:analysis_server/src/services/correction/dart/remove_parentheses_in_getter_invocation.dart'; +import 'package:analysis_server/src/services/correction/dart/remove_primary_constructor_body.dart'; import 'package:analysis_server/src/services/correction/dart/remove_print.dart'; import 'package:analysis_server/src/services/correction/dart/remove_question_mark.dart'; import 'package:analysis_server/src/services/correction/dart/remove_required.dart'; @@ -472,6 +473,7 @@ final _builtInLintGenerators = >{ ], diag.unnecessaryOverrides: [RemoveMethodDeclaration.new], diag.unnecessaryParenthesis: [RemoveUnnecessaryParentheses.new], + diag.unnecessaryPrimaryConstructorBody: [RemovePrimaryConstructorBody.new], diag.unnecessaryRawStrings: [RemoveUnnecessaryRawString.new], diag.unnecessaryStringEscapes: [RemoveUnnecessaryStringEscape.new], diag.unnecessaryStringInterpolations: [ diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_primary_constructor_body_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_primary_constructor_body_test.dart new file mode 100644 index 00000000000..12cf2c538cf --- /dev/null +++ b/pkg/analysis_server/test/src/services/correction/fix/remove_primary_constructor_body_test.dart @@ -0,0 +1,72 @@ +// Copyright (c) 2026, 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(RemovePrimaryConstructorBodyBulkTest); + defineReflectiveTests(RemovePrimaryConstructorBodyTest); + }); +} + +@reflectiveTest +class RemovePrimaryConstructorBodyBulkTest extends BulkFixProcessorTest { + @override + String get lintCode => LintNames.unnecessary_primary_constructor_body; + + Future test_multiple() async { + await resolveTestCode(r''' +class A(final int i) { + this; +} +class B(final int i) { + this {} +} +'''); + await assertHasFix(r''' +class A(final int i) { +} +class B(final int i) { +} +'''); + } +} + +@reflectiveTest +class RemovePrimaryConstructorBodyTest extends FixProcessorLintTest { + @override + FixKind get kind => DartFixKind.removePrimaryConstructorBody; + + @override + String get lintCode => LintNames.unnecessary_primary_constructor_body; + + Future test_block() async { + await resolveTestCode(r''' +class C(final int i) { + this {} +} +'''); + await assertHasFix(r''' +class C(final int i) { +} +'''); + } + + Future test_semicolon() async { + await resolveTestCode(r''' +class C(final int i) { + this; +} +'''); + await assertHasFix(r''' +class C(final int i) { +} +'''); + } +} 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 e57cadf709e..0570c879f26 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 @@ -232,6 +232,8 @@ import 'remove_parameters_in_getter_declaration_test.dart' as remove_parameters_in_getter_declaration; import 'remove_parentheses_in_getter_invocation_test.dart' as remove_parentheses_in_getter_invocation; +import 'remove_primary_constructor_body_test.dart' + as remove_primary_constructor_body; import 'remove_print_test.dart' as remove_print; import 'remove_question_mark_test.dart' as remove_question_mark; import 'remove_required_test.dart' as remove_required; @@ -532,6 +534,7 @@ void main() { remove_operator.main(); remove_parameters_in_getter_declaration.main(); remove_parentheses_in_getter_invocation.main(); + remove_primary_constructor_body.main(); remove_print.main(); remove_question_mark.main(); remove_required.main();