[analysis_server] AddExplicitCast to handle toSet

Bug: #49896
Change-Id: I8fdbe33c3e0c5af9f39324b7c537a85a55a918d1
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/259700
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
Ahmed Ashour
2022-09-19 16:28:33 +00:00
committed by Commit Bot
parent 8f29e846a4
commit facfb4d9aa
4 changed files with 54 additions and 12 deletions
@@ -49,8 +49,7 @@ class AddExplicitCast extends CorrectionProducer {
// because it's nullable, in which case a cast won't fix the problem.
return;
}
// TODO(brianwilkerson) Handle `toSet` in a manner similar to the below.
if (target.isToListMethodInvocation) {
if (target.isToListMethodInvocation || target.isToSetMethodInvocation) {
var targetTarget = (target as MethodInvocation).target;
if (targetTarget != null) {
var targetTargetType = targetTarget.typeOrThrow;
@@ -71,12 +70,11 @@ class AddExplicitCast extends CorrectionProducer {
final target_final = target;
var needsParentheses = target.precedence < Precedence.postfix;
if (((fromType.isDartCoreIterable || fromType.isDartCoreList) &&
toType is InterfaceType &&
toType.isDartCoreList) ||
(fromType.isDartCoreSet &&
toType is InterfaceType &&
toType.isDartCoreSet)) {
if (toType is InterfaceType &&
(((fromType.isDartCoreIterable || fromType.isDartCoreList) &&
toType.isDartCoreList) ||
(fromType.isDartCoreIterable || fromType.isDartCoreSet) &&
toType.isDartCoreSet)) {
if (target.isCastMethodInvocation) {
// TODO(brianwilkerson) Consider updating the type arguments to the
// `cast` invocation.
@@ -180,7 +180,7 @@ extension ExpressionExtensions on Expression {
}
/// Return `true` if this expression is an invocation of the method `toList`
/// from either `Iterable` or `List`.
/// from `Iterable`.
bool get isToListMethodInvocation {
if (this is MethodInvocation) {
var element = (this as MethodInvocation).methodName.staticElement;
@@ -188,6 +188,16 @@ extension ExpressionExtensions on Expression {
}
return false;
}
/// Return `true` if this expression is an invocation of the method `toSet`
/// from `Iterable`.
bool get isToSetMethodInvocation {
if (this is MethodInvocation) {
var element = (this as MethodInvocation).methodName.staticElement;
return element is MethodElement && element.isToSetMethod;
}
return false;
}
}
extension FunctionBodyExtensions on FunctionBody {
@@ -79,8 +79,8 @@ extension MethodElementExtensions on MethodElement {
definingClass.isDartCoreSet;
}
/// Return `true` if this element represents the method `toList` from either
/// `Iterable` or `List`.
/// Return `true` if this element represents the method `toList` from
/// `Iterable`.
bool get isToListMethod {
if (name != 'toList') {
return false;
@@ -89,6 +89,19 @@ extension MethodElementExtensions on MethodElement {
if (definingClass is! ClassElement) {
return false;
}
return definingClass.isDartCoreIterable || definingClass.isDartCoreList;
return definingClass.isDartCoreIterable;
}
/// Return `true` if this element represents the method `toSet` from
/// `Iterable`.
bool get isToSetMethod {
if (name != 'toSet') {
return false;
}
var definingClass = enclosingElement3;
if (definingClass is! ClassElement) {
return false;
}
return definingClass.isDartCoreIterable;
}
}
@@ -76,6 +76,27 @@ class B {}
''');
}
Future<void> test_assignment_iterable_to_set() async {
await resolveTestCode('''
f(List<A> a) {
Set<B> b;
b = a.where((e) => e is B).toSet();
print(b);
}
class A {}
class B {}
''');
await assertHasFix('''
f(List<A> a) {
Set<B> b;
b = a.where((e) => e is B).cast<B>().toSet();
print(b);
}
class A {}
class B {}
''');
}
Future<void> test_assignment_list() async {
await resolveTestCode('''
f(List<A> a) {