remove redundant @required annotations when adding required

Fixes: https://github.com/dart-lang/sdk/issues/43603

Change-Id: I21ccee4787695b72d5ac25195ade638e918d9550
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/171420
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Phil Quitslund <pquitslund@google.com>
This commit is contained in:
pq 2020-11-10 23:06:07 +00:00 committed by commit-bot@chromium.org
parent 3c12e4a659
commit d6a8505ba4
2 changed files with 142 additions and 2 deletions

View file

@ -4,6 +4,8 @@
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/source/source_range.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
@ -14,7 +16,25 @@ class AddRequiredKeyword extends CorrectionProducer {
@override
Future<void> compute(ChangeBuilder builder) async {
await builder.addDartFileEdit(file, (builder) {
builder.addSimpleInsertion(node.parent.offset, 'required ');
var insertOffset = node.parent.offset;
var parent = node.parent;
if (parent is FormalParameter) {
var metadata = parent.metadata;
// Check for redundant `@required` annotations.
if (metadata.isNotEmpty) {
for (var annotation in metadata) {
if (annotation.elementAnnotation.isRequired) {
var length = annotation.endToken.next.offset -
annotation.beginToken.offset;
builder.addDeletion(SourceRange(annotation.offset, length));
break;
}
}
insertOffset = metadata.endToken.next.offset;
}
}
builder.addSimpleInsertion(insertOffset, 'required ');
});
}

View file

@ -45,11 +45,131 @@ class AddRequiredWithNullSafetyTest extends FixProcessorTest
@override
FixKind get kind => DartFixKind.ADD_REQUIRED2;
Future<void> test_withAssert() async {
Future<void> test_nonNullable() async {
await resolveTestCode('''
void function({String param}) {}
''');
await assertHasFix('''
void function({required String param}) {}
''');
}
Future<void> test_withRequiredAnnotation() async {
writeTestPackageConfig(meta: true);
await resolveTestCode('''
import 'package:meta/meta.dart';
void function({@required String param}) {}
''');
await assertHasFix('''
import 'package:meta/meta.dart';
void function({required String param}) {}
''');
}
Future<void> test_withRequiredAnnotation_constructor() async {
writeTestPackageConfig(meta: true);
await resolveTestCode('''
import 'package:meta/meta.dart';
class A {
String foo;
A({@required this.foo});
}
''');
await assertHasFix('''
import 'package:meta/meta.dart';
class A {
String foo;
A({required this.foo});
}
''');
}
Future<void> test_withRequiredAnnotation_functionParam() async {
writeTestPackageConfig(meta: true);
await resolveTestCode('''
import 'package:meta/meta.dart';
void f({@required int g(String)}) { }
''');
await assertHasFix('''
import 'package:meta/meta.dart';
void f({required int g(String)}) { }
''');
}
Future<void> test_withRequiredAnnotationInList_first() async {
writeTestPackageConfig(meta: true);
await resolveTestCode('''
import 'package:meta/meta.dart';
class Foo {
const Foo();
}
const foo = Foo();
void function({@required @foo String param}) {}
''');
await assertHasFix('''
import 'package:meta/meta.dart';
class Foo {
const Foo();
}
const foo = Foo();
void function({@foo required String param}) {}
''');
}
Future<void> test_withRequiredAnnotationInList_last() async {
writeTestPackageConfig(meta: true);
await resolveTestCode('''
import 'package:meta/meta.dart';
class Foo {
const Foo();
}
const foo = Foo();
void function({@foo @required String param}) {}
''');
await assertHasFix('''
import 'package:meta/meta.dart';
class Foo {
const Foo();
}
const foo = Foo();
void function({@foo required String param}) {}
''');
}
Future<void> test_withRequiredAnnotationWithReason() async {
writeTestPackageConfig(meta: true);
await resolveTestCode('''
import 'package:meta/meta.dart';
void function({@Required('reason') String param}) {}
''');
await assertHasFix('''
import 'package:meta/meta.dart';
void function({required String param}) {}
''');
}