Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit ed1091a

Browse files
bwilkersoncommit-bot@chromium.org
authored andcommitted
Add two fixes for avoid_returning_null_for_future
Change-Id: I6ece892025233fe3dd51ececb7b92368be9669ae Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/138321 Reviewed-by: Konstantin Shcheglov <[email protected]> Commit-Queue: Brian Wilkerson <[email protected]>
1 parent 33d6e68 commit ed1091a

File tree

7 files changed

+113
-1
lines changed

7 files changed

+113
-1
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
6+
import 'package:analysis_server/src/services/correction/fix.dart';
7+
import 'package:analyzer/dart/ast/ast.dart';
8+
import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
9+
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
10+
import 'package:analyzer_plugin/utilities/range_factory.dart';
11+
12+
class WrapInFuture extends CorrectionProducer {
13+
@override
14+
FixKind get fixKind => DartFixKind.WRAP_IN_FUTURE;
15+
16+
@override
17+
Future<void> compute(DartChangeBuilder builder) async {
18+
//
19+
// Extract the information needed to build the edit.
20+
//
21+
Expression expression;
22+
if (node is ReturnStatement) {
23+
expression = (node as ReturnStatement).expression;
24+
} else if (node is Expression) {
25+
expression = node;
26+
} else {
27+
return;
28+
}
29+
var value = utils.getNodeText(expression);
30+
//
31+
// Build the edit.
32+
//
33+
await builder.addFileEdit(file, (DartFileEditBuilder builder) {
34+
builder.addSimpleReplacement(
35+
range.node(expression), 'Future.value($value)');
36+
});
37+
}
38+
}

pkg/analysis_server/lib/src/services/correction/fix.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,8 @@ class DartFixKind {
409409
"Use != null instead of 'is! Null' everywhere in file");
410410
static const USE_RETHROW =
411411
FixKind('USE_RETHROW', 50, 'Replace throw with rethrow');
412+
static const WRAP_IN_FUTURE =
413+
FixKind('WRAP_IN_FUTURE', 50, "Wrap in 'Future.value'");
412414
}
413415

414416
/// An enumeration of quick fix kinds for the errors found in an Android

pkg/analysis_server/lib/src/services/correction/fix_internal.dart

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import 'package:analysis_server/src/services/correction/dart/convert_to_where_ty
2121
import 'package:analysis_server/src/services/correction/dart/remove_dead_if_null.dart';
2222
import 'package:analysis_server/src/services/correction/dart/remove_if_null_operator.dart';
2323
import 'package:analysis_server/src/services/correction/dart/replace_with_eight_digit_hex.dart';
24+
import 'package:analysis_server/src/services/correction/dart/wrap_in_future.dart';
2425
import 'package:analysis_server/src/services/correction/fix.dart';
2526
import 'package:analysis_server/src/services/correction/fix/dart/top_level_declarations.dart';
2627
import 'package:analysis_server/src/services/correction/levenshtein.dart';
@@ -629,6 +630,9 @@ class FixProcessor extends BaseProcessor {
629630
if (name == LintNames.avoid_return_types_on_setters) {
630631
await _addFix_removeTypeAnnotation();
631632
}
633+
if (name == LintNames.avoid_returning_null_for_future) {
634+
await _addFix_addAsync();
635+
}
632636
if (name == LintNames.avoid_types_on_closure_parameters) {
633637
await _addFix_replaceWithIdentifier();
634638
}
@@ -4713,7 +4717,9 @@ class FixProcessor extends BaseProcessor {
47134717
await compute(RemoveDeadIfNull());
47144718
} else if (errorCode is LintCode) {
47154719
String name = errorCode.name;
4716-
if (name == LintNames.prefer_collection_literals) {
4720+
if (name == LintNames.avoid_returning_null_for_future) {
4721+
await compute(WrapInFuture());
4722+
} else if (name == LintNames.prefer_collection_literals) {
47174723
await compute(ConvertToListLiteral());
47184724
await compute(ConvertToMapLiteral());
47194725
await compute(ConvertToSetLiteral());

pkg/analysis_server/lib/src/services/linter/lint_names.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ class LintNames {
1919
static const String avoid_relative_lib_imports = 'avoid_relative_lib_imports';
2020
static const String avoid_return_types_on_setters =
2121
'avoid_return_types_on_setters';
22+
static const String avoid_returning_null_for_future =
23+
'avoid_returning_null_for_future';
2224
static const String avoid_types_on_closure_parameters =
2325
'avoid_types_on_closure_parameters';
2426
static const String await_only_futures = 'await_only_futures';

pkg/analysis_server/test/src/services/correction/fix/add_async_test.dart

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// BSD-style license that can be found in the LICENSE file.
44

55
import 'package:analysis_server/src/services/correction/fix.dart';
6+
import 'package:analysis_server/src/services/linter/lint_names.dart';
67
import 'package:analyzer/error/error.dart';
78
import 'package:analyzer/src/error/codes.dart';
89
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
@@ -13,6 +14,7 @@ import 'fix_processor.dart';
1314
void main() {
1415
defineReflectiveSuite(() {
1516
defineReflectiveTests(AddAsyncTest);
17+
defineReflectiveTests(AvoidReturningNullForFutureTest);
1618
});
1719
}
1820

@@ -183,3 +185,25 @@ main() async {
183185
''');
184186
}
185187
}
188+
189+
@reflectiveTest
190+
class AvoidReturningNullForFutureTest extends FixProcessorLintTest {
191+
@override
192+
FixKind get kind => DartFixKind.ADD_ASYNC;
193+
194+
@override
195+
String get lintCode => LintNames.avoid_returning_null_for_future;
196+
197+
Future<void> test_asyncFor() async {
198+
await resolveTestUnit('''
199+
Future<String> f() {
200+
return null;
201+
}
202+
''');
203+
await assertHasFix('''
204+
Future<String> f() async {
205+
return null;
206+
}
207+
''');
208+
}
209+
}

pkg/analysis_server/test/src/services/correction/fix/test_all.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ import 'use_eq_eq_null_test.dart' as use_eq_eq_null;
150150
import 'use_is_not_empty_test.dart' as use_is_not_empty;
151151
import 'use_not_eq_null_test.dart' as use_not_eq_null;
152152
import 'use_rethrow_test.dart' as use_rethrow;
153+
import 'wrap_in_future_test.dart' as wrap_in_future;
153154

154155
void main() {
155156
defineReflectiveSuite(() {
@@ -283,5 +284,6 @@ void main() {
283284
use_is_not_empty.main();
284285
use_not_eq_null.main();
285286
use_rethrow.main();
287+
wrap_in_future.main();
286288
}, name: 'fix');
287289
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'package:analysis_server/src/services/correction/fix.dart';
6+
import 'package:analysis_server/src/services/linter/lint_names.dart';
7+
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
8+
import 'package:test_reflective_loader/test_reflective_loader.dart';
9+
10+
import 'fix_processor.dart';
11+
12+
void main() {
13+
defineReflectiveSuite(() {
14+
defineReflectiveTests(WrapInFutureTest);
15+
});
16+
}
17+
18+
@reflectiveTest
19+
class WrapInFutureTest extends FixProcessorLintTest {
20+
@override
21+
FixKind get kind => DartFixKind.WRAP_IN_FUTURE;
22+
23+
@override
24+
String get lintCode => LintNames.avoid_returning_null_for_future;
25+
26+
Future<void> test_asyncFor() async {
27+
await resolveTestUnit('''
28+
Future<String> f() {
29+
return null;
30+
}
31+
''');
32+
await assertHasFix('''
33+
Future<String> f() {
34+
return Future.value(null);
35+
}
36+
''');
37+
}
38+
}

0 commit comments

Comments
 (0)