From 928b6443c4697a4982655ec20fc43f73370f704d Mon Sep 17 00:00:00 2001 From: Ahmed Ashour Date: Wed, 8 Sep 2021 22:30:12 +0000 Subject: [PATCH] Add a quick fix for `ABSTRACT_CLASS_MEMBER` Fixes #46025 Change-Id: I716d620e7c77c09cf27f922069f57466f3df76ec Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/212574 Reviewed-by: Brian Wilkerson Commit-Queue: Brian Wilkerson --- .../correction/dart/remove_abstract.dart | 37 +++++++++ .../lib/src/services/correction/fix.dart | 10 +++ .../src/services/correction/fix_internal.dart | 5 ++ .../correction/fix/remove_abstract_test.dart | 83 +++++++++++++++++++ .../src/services/correction/fix/test_all.dart | 2 + 5 files changed, 137 insertions(+) create mode 100644 pkg/analysis_server/lib/src/services/correction/dart/remove_abstract.dart create mode 100644 pkg/analysis_server/test/src/services/correction/fix/remove_abstract_test.dart diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_abstract.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_abstract.dart new file mode 100644 index 00000000000..7a6dc30bb4b --- /dev/null +++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_abstract.dart @@ -0,0 +1,37 @@ +// Copyright (c) 2021, 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/source/source_range.dart'; +import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart'; +import 'package:analyzer_plugin/utilities/fixes/fixes.dart'; + +class RemoveAbstract extends CorrectionProducerWithDiagnostic { + @override + bool get canBeAppliedToFile => true; + + @override + FixKind get fixKind => DartFixKind.REMOVE_ABSTRACT; + + @override + FixKind get multiFixKind => DartFixKind.REMOVE_ABSTRACT_MULTI; + + @override + Future compute(ChangeBuilder builder) async { + // 'abstract' keyword does not exist in AST + var offset = diagnostic.problemMessage.offset; + var content = resolvedResult.content; + var i = offset + 'abstract '.length; + while (content[i].trim().isEmpty) { + i++; + } + await builder.addDartFileEdit(file, (builder) { + builder.addDeletion(SourceRange(offset, i - offset)); + }); + } + + /// Return an instance of this class. Used as a tear-off in `FixProcessor`. + static RemoveAbstract newInstance() => RemoveAbstract(); +} diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart index aa33c8e5be8..1c03c654e34 100644 --- a/pkg/analysis_server/lib/src/services/correction/fix.dart +++ b/pkg/analysis_server/lib/src/services/correction/fix.dart @@ -713,6 +713,16 @@ class DartFixKind { DartFixKindPriority.DEFAULT, "Use '{0}'", ); + static const REMOVE_ABSTRACT = FixKind( + 'dart.fix.remove.abstract', + DartFixKindPriority.DEFAULT, + "Remove the 'abstract' keyword", + ); + static const REMOVE_ABSTRACT_MULTI = FixKind( + 'dart.fix.remove.abstract.multi', + DartFixKindPriority.IN_FILE, + "Remove the 'abstract' keyword everywhere in file", + ); static const REMOVE_ANNOTATION = FixKind( 'dart.fix.remove.annotation', 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 b6f1aff8772..3633b992837 100644 --- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart +++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart @@ -178,6 +178,8 @@ import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dar import 'package:analyzer_plugin/utilities/change_builder/conflicting_edit_exception.dart'; import 'package:analyzer_plugin/utilities/fixes/fixes.dart' hide FixContributor; +import 'dart/remove_abstract.dart'; + /// A function that can be executed to create a multi-correction producer. typedef MultiProducerGenerator = MultiCorrectionProducer Function(); @@ -1217,6 +1219,9 @@ class FixProcessor extends BaseProcessor { HintCode.UNUSED_SHOWN_NAME: [ RemoveNameFromCombinator.newInstance, ], + ParserErrorCode.ABSTRACT_CLASS_MEMBER: [ + RemoveAbstract.newInstance, + ], ParserErrorCode.EXPECTED_TOKEN: [ InsertSemicolon.newInstance, ], diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_abstract_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_abstract_test.dart new file mode 100644 index 00000000000..f1cab1e340d --- /dev/null +++ b/pkg/analysis_server/test/src/services/correction/fix/remove_abstract_test.dart @@ -0,0 +1,83 @@ +// Copyright (c) 2021, 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/dart/error/syntactic_errors.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(RemoveAbstractBulkTest); + defineReflectiveTests(RemoveAbstractTest); + }); +} + +@reflectiveTest +class RemoveAbstractBulkTest extends FixProcessorTest { + @override + FixKind get kind => DartFixKind.REMOVE_ABSTRACT_MULTI; + + Future test_bulk() async { + await resolveTestCode(''' +class MyClass { + abstract void m1() {} + abstract void m2() {} +} +'''); + await assertHasFixAllFix(ParserErrorCode.ABSTRACT_CLASS_MEMBER, ''' +class MyClass { + void m1() {} + void m2() {} +} +'''); + } +} + +@reflectiveTest +class RemoveAbstractTest extends FixProcessorTest { + @override + FixKind get kind => DartFixKind.REMOVE_ABSTRACT; + + Future test_extension() async { + await resolveTestCode(''' +extension E on String { + abstract void m() {} +} +'''); + await assertHasFix(''' +extension E on String { + void m() {} +} +'''); + } + + Future test_mixin() async { + await resolveTestCode(''' +mixin M { + abstract void m() {} +} +'''); + await assertHasFix(''' +mixin M { + void m() {} +} +'''); + } + + Future test_spaces() async { + await resolveTestCode(''' +abstract class MyClass { + abstract void m1(); +} +'''); + await assertHasFix(''' +abstract class MyClass { + void m1(); +} +'''); + } +} 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 642939fa9e2..bd0d10c149f 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 @@ -112,6 +112,7 @@ import 'move_type_arguments_to_class_test.dart' as move_type_arguments_to_class; import 'organize_imports_test.dart' as organize_imports; import 'pubspec/test_all.dart' as pubspec; import 'qualify_reference_test.dart' as qualify_reference; +import 'remove_abstract_test.dart' as remove_abstract; import 'remove_annotation_test.dart' as remove_annotation; import 'remove_argument_test.dart' as remove_argument; import 'remove_await_test.dart' as remove_await; @@ -296,6 +297,7 @@ void main() { organize_imports.main(); pubspec.main(); qualify_reference.main(); + remove_abstract.main(); remove_annotation.main(); remove_argument.main(); remove_await.main();