mirror of
https://github.com/dart-lang/sdk
synced 2024-11-05 18:22:09 +00:00
add quick fix for cast_nullable_to_non_nullable
See: https://github.com/dart-lang/lints/issues/28 Change-Id: Ic0dac81467a3a3fbe7f7bf805ee59e3844edb6a1 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/303681 Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Commit-Queue: Phil Quitslund <pquitslund@google.com>
This commit is contained in:
parent
1b9198c679
commit
1178e96bc1
5 changed files with 58 additions and 3 deletions
|
@ -16,12 +16,25 @@ import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
|
|||
import 'package:analyzer_plugin/utilities/range_factory.dart';
|
||||
|
||||
class AddNullCheck extends CorrectionProducer {
|
||||
final bool skipAssignabilityCheck;
|
||||
|
||||
@override
|
||||
final bool canBeAppliedInBulk;
|
||||
|
||||
@override
|
||||
FixKind fixKind = DartFixKind.ADD_NULL_CHECK;
|
||||
|
||||
@override
|
||||
List<Object>? fixArguments;
|
||||
|
||||
AddNullCheck()
|
||||
: skipAssignabilityCheck = false,
|
||||
canBeAppliedInBulk = false;
|
||||
|
||||
AddNullCheck.withoutAssignabilityCheck()
|
||||
: skipAssignabilityCheck = true,
|
||||
canBeAppliedInBulk = true;
|
||||
|
||||
@override
|
||||
Future<void> compute(ChangeBuilder builder) async {
|
||||
if (!unit.featureSet.isEnabled(Feature.non_nullable)) {
|
||||
|
@ -80,6 +93,8 @@ class AddNullCheck extends CorrectionProducer {
|
|||
target = coveredNode.rightOperand;
|
||||
}
|
||||
}
|
||||
} else if (coveredNode is AsExpression) {
|
||||
target = coveredNode.expression;
|
||||
}
|
||||
|
||||
if (target == null) {
|
||||
|
@ -103,6 +118,8 @@ class AddNullCheck extends CorrectionProducer {
|
|||
var parent = target.parent;
|
||||
if (parent is AssignmentExpression && target == parent.rightHandSide) {
|
||||
toType = parent.writeType;
|
||||
} else if (parent is AsExpression) {
|
||||
toType = parent.staticType;
|
||||
} else if (parent is VariableDeclaration && target == parent.initializer) {
|
||||
toType = parent.declaredElement?.type;
|
||||
} else if (parent is ArgumentList) {
|
||||
|
@ -156,6 +173,7 @@ class AddNullCheck extends CorrectionProducer {
|
|||
return;
|
||||
}
|
||||
if (toType != null &&
|
||||
!skipAssignabilityCheck &&
|
||||
!typeSystem.isAssignableTo(
|
||||
typeSystem.promoteToNonNull(fromType), toType)) {
|
||||
// The reason that `fromType` can't be assigned to `toType` is more than
|
||||
|
|
|
@ -1989,9 +1989,7 @@ LintCode.cancel_subscriptions:
|
|||
LintCode.cascade_invocations:
|
||||
status: hasFix
|
||||
LintCode.cast_nullable_to_non_nullable:
|
||||
status: needsFix
|
||||
notes: |-
|
||||
The fix is to add an explicit null check (`!`).
|
||||
status: hasFix
|
||||
LintCode.close_sinks:
|
||||
status: noFix
|
||||
LintCode.collection_methods_unrelated_type:
|
||||
|
|
|
@ -486,6 +486,9 @@ class FixProcessor extends BaseProcessor {
|
|||
LintNames.cascade_invocations: [
|
||||
ConvertToCascade.new,
|
||||
],
|
||||
LintNames.cast_nullable_to_non_nullable: [
|
||||
AddNullCheck.withoutAssignabilityCheck,
|
||||
],
|
||||
LintNames.combinators_ordering: [
|
||||
SortCombinators.new,
|
||||
],
|
||||
|
|
|
@ -52,6 +52,8 @@ class LintNames {
|
|||
static const String avoid_void_async = 'avoid_void_async';
|
||||
static const String await_only_futures = 'await_only_futures';
|
||||
static const String cascade_invocations = 'cascade_invocations';
|
||||
static const String cast_nullable_to_non_nullable =
|
||||
'cast_nullable_to_non_nullable';
|
||||
static const String combinators_ordering = 'combinators_ordering';
|
||||
static const String curly_braces_in_flow_control_structures =
|
||||
'curly_braces_in_flow_control_structures';
|
||||
|
|
|
@ -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/error/error.dart';
|
||||
import 'package:analyzer/src/error/codes.dart';
|
||||
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
|
||||
|
@ -14,6 +15,7 @@ void main() {
|
|||
defineReflectiveSuite(() {
|
||||
defineReflectiveTests(AddNullCheckTest);
|
||||
defineReflectiveTests(AddNullCheckReplaceWithNullAwareTest);
|
||||
defineReflectiveTests(CastNullableToNonNullableTest);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -646,3 +648,35 @@ Iterable<String> f(List<String>? args) sync* {
|
|||
error.errorCode != CompileTimeErrorCode.YIELD_EACH_OF_INVALID_TYPE);
|
||||
}
|
||||
}
|
||||
|
||||
@reflectiveTest
|
||||
class CastNullableToNonNullableTest extends FixProcessorLintTest {
|
||||
@override
|
||||
FixKind get kind => DartFixKind.ADD_NULL_CHECK;
|
||||
|
||||
@override
|
||||
String get lintCode => LintNames.cast_nullable_to_non_nullable;
|
||||
|
||||
Future<void> test_castNullable() async {
|
||||
await resolveTestCode(r'''
|
||||
num? n;
|
||||
var i = n as int;
|
||||
''');
|
||||
await assertHasFix(r'''
|
||||
num? n;
|
||||
var i = n! as int;
|
||||
''');
|
||||
}
|
||||
|
||||
Future<void> test_castNullable_unnecessaryCast() async {
|
||||
// todo(pq): consider removing unnecessary 'as String' cast
|
||||
await resolveTestCode(r'''
|
||||
String? s;
|
||||
var a = s as String;
|
||||
''');
|
||||
await assertHasFix(r'''
|
||||
String? s;
|
||||
var a = s! as String;
|
||||
''');
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue