[analyzer] Add fix for avoid_void_async lint
Closes https://github.com/dart-lang/sdk/issues/47959 Change-Id: I32838d7889cbaf9491d24672f19995cd6f75c2fa Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/231940 Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
+19
-1
@@ -12,16 +12,25 @@ class ReplaceReturnTypeFuture extends CorrectionProducer {
|
||||
/// The text for the type argument to 'Future'.
|
||||
String _typeArgument = '';
|
||||
|
||||
@override
|
||||
bool get canBeAppliedInBulk => true;
|
||||
|
||||
@override
|
||||
bool get canBeAppliedToFile => true;
|
||||
|
||||
@override
|
||||
List<Object>? get fixArguments => [_typeArgument];
|
||||
|
||||
@override
|
||||
FixKind get fixKind => DartFixKind.REPLACE_RETURN_TYPE_FUTURE;
|
||||
|
||||
@override
|
||||
FixKind get multiFixKind => DartFixKind.REPLACE_RETURN_TYPE_FUTURE_MULTI;
|
||||
|
||||
@override
|
||||
Future<void> compute(ChangeBuilder builder) async {
|
||||
// prepare the existing type
|
||||
var typeAnnotation = node.thisOrAncestorOfType<TypeAnnotation>();
|
||||
var typeAnnotation = _getTypeAnnotation(node);
|
||||
if (typeAnnotation == null) {
|
||||
return;
|
||||
}
|
||||
@@ -34,4 +43,13 @@ class ReplaceReturnTypeFuture extends CorrectionProducer {
|
||||
|
||||
/// Return an instance of this class. Used as a tear-off in `FixProcessor`.
|
||||
static ReplaceReturnTypeFuture newInstance() => ReplaceReturnTypeFuture();
|
||||
|
||||
static TypeAnnotation? _getTypeAnnotation(AstNode node) {
|
||||
var function = node.thisOrAncestorOfType<FunctionDeclaration>();
|
||||
if (function != null) {
|
||||
return function.returnType;
|
||||
}
|
||||
var method = node.thisOrAncestorOfType<MethodDeclaration>();
|
||||
return method?.returnType;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1288,6 +1288,11 @@ class DartFixKind {
|
||||
DartFixKindPriority.DEFAULT,
|
||||
"Return 'Future<{0}>'",
|
||||
);
|
||||
static const REPLACE_RETURN_TYPE_FUTURE_MULTI = FixKind(
|
||||
'dart.fix.replace.returnTypeFuture.multi',
|
||||
DartFixKindPriority.IN_FILE,
|
||||
"Return a 'Future' where required in file.",
|
||||
);
|
||||
static const REPLACE_RETURN_TYPE_ITERABLE = FixKind(
|
||||
'dart.fix.replace.returnTypeIterable',
|
||||
DartFixKindPriority.DEFAULT,
|
||||
|
||||
@@ -407,6 +407,9 @@ class FixProcessor extends BaseProcessor {
|
||||
LintNames.avoid_unnecessary_containers: [
|
||||
FlutterRemoveWidget.newInstance,
|
||||
],
|
||||
LintNames.avoid_void_async: [
|
||||
ReplaceReturnTypeFuture.newInstance,
|
||||
],
|
||||
LintNames.await_only_futures: [
|
||||
RemoveAwait.newInstance,
|
||||
],
|
||||
|
||||
@@ -42,6 +42,7 @@ class LintNames {
|
||||
'avoid_unused_constructor_parameters';
|
||||
static const String avoid_unnecessary_containers =
|
||||
'avoid_unnecessary_containers';
|
||||
static const String avoid_void_async = 'avoid_void_async';
|
||||
static const String await_only_futures = 'await_only_futures';
|
||||
static const String curly_braces_in_flow_control_structures =
|
||||
'curly_braces_in_flow_control_structures';
|
||||
|
||||
+121
@@ -3,6 +3,7 @@
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import 'package:analysis_server/src/services/correction/fix.dart';
|
||||
import 'package:analysis_server/src/services/linter/lint_names.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';
|
||||
@@ -11,10 +12,117 @@ import 'fix_processor.dart';
|
||||
|
||||
void main() {
|
||||
defineReflectiveSuite(() {
|
||||
defineReflectiveTests(ReplaceReturnTypeFutureLintBulkTest);
|
||||
defineReflectiveTests(ReplaceReturnTypeFutureLintTest);
|
||||
defineReflectiveTests(ReplaceReturnTypeFutureTest);
|
||||
});
|
||||
}
|
||||
|
||||
@reflectiveTest
|
||||
class ReplaceReturnTypeFutureLintBulkTest extends BulkFixProcessorTest {
|
||||
@override
|
||||
String get lintCode => LintNames.avoid_void_async;
|
||||
|
||||
Future<void> test_bulk() async {
|
||||
await resolveTestCode('''
|
||||
void f1() async {}
|
||||
|
||||
void f2() async => null;
|
||||
|
||||
class C {
|
||||
void m1() async {}
|
||||
|
||||
void m2() async => null;
|
||||
|
||||
void m3() async {
|
||||
void f() async {};
|
||||
f();
|
||||
}
|
||||
}
|
||||
''');
|
||||
await assertHasFix('''
|
||||
Future<void> f1() async {}
|
||||
|
||||
Future<void> f2() async => null;
|
||||
|
||||
class C {
|
||||
Future<void> m1() async {}
|
||||
|
||||
Future<void> m2() async => null;
|
||||
|
||||
Future<void> m3() async {
|
||||
Future<void> f() async {};
|
||||
f();
|
||||
}
|
||||
}
|
||||
''');
|
||||
}
|
||||
}
|
||||
|
||||
@reflectiveTest
|
||||
class ReplaceReturnTypeFutureLintTest extends FixProcessorLintTest {
|
||||
@override
|
||||
FixKind get kind => DartFixKind.REPLACE_RETURN_TYPE_FUTURE;
|
||||
|
||||
@override
|
||||
String get lintCode => LintNames.avoid_void_async;
|
||||
|
||||
Future<void> test_function() async {
|
||||
await resolveTestCode('void f() async {}');
|
||||
await assertHasFix('Future<void> f() async {}');
|
||||
}
|
||||
|
||||
Future<void> test_functionInMethod() async {
|
||||
await resolveTestCode('''
|
||||
class C {
|
||||
void m() {
|
||||
void f() async {};
|
||||
f();
|
||||
}
|
||||
}
|
||||
''');
|
||||
await assertHasFix('''
|
||||
class C {
|
||||
void m() {
|
||||
Future<void> f() async {};
|
||||
f();
|
||||
}
|
||||
}
|
||||
''');
|
||||
}
|
||||
|
||||
Future<void> test_functionReturnNull() async {
|
||||
await resolveTestCode('void f() async => null;');
|
||||
await assertHasFix('Future<void> f() async => null;');
|
||||
}
|
||||
|
||||
Future<void> test_method() async {
|
||||
await resolveTestCode('''
|
||||
class C {
|
||||
void m() async {}
|
||||
}
|
||||
''');
|
||||
await assertHasFix('''
|
||||
class C {
|
||||
Future<void> m() async {}
|
||||
}
|
||||
''');
|
||||
}
|
||||
|
||||
Future<void> test_methodReturnNull() async {
|
||||
await resolveTestCode('''
|
||||
class C {
|
||||
void m() async => null;
|
||||
}
|
||||
''');
|
||||
await assertHasFix('''
|
||||
class C {
|
||||
Future<void> m() async => null;
|
||||
}
|
||||
''');
|
||||
}
|
||||
}
|
||||
|
||||
@reflectiveTest
|
||||
class ReplaceReturnTypeFutureTest extends FixProcessorTest {
|
||||
@override
|
||||
@@ -55,6 +163,19 @@ al.Future<int> f() async {}
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> test_method() async {
|
||||
await resolveTestCode('''
|
||||
class C {
|
||||
int m() async {}
|
||||
}
|
||||
''');
|
||||
await assertHasFix('''
|
||||
class C {
|
||||
Future<int> m() async {}
|
||||
}
|
||||
''');
|
||||
}
|
||||
|
||||
Future<void> test_simpleTypeName_withImport() async {
|
||||
await resolveTestCode('''
|
||||
import 'dart:async';
|
||||
|
||||
Reference in New Issue
Block a user