Skip to content

Commit 50527da

Browse files
scheglovCommit Queue
authored andcommitted
Elements. Migrate SubtypeHelper.
Change-Id: Iced0a394881f82937638caba4011cd8ac09ffa98 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/404280 Reviewed-by: Phil Quitslund <[email protected]> Commit-Queue: Konstantin Shcheglov <[email protected]>
1 parent d3c7590 commit 50527da

File tree

7 files changed

+191
-75
lines changed

7 files changed

+191
-75
lines changed

pkg/analyzer/lib/src/dart/element/element.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11367,7 +11367,8 @@ class TypeParameterElementImpl2 extends TypeDefiningElementImpl2
1136711367
TypeParameterType instantiate({
1136811368
required NullabilitySuffix nullabilitySuffix,
1136911369
}) {
11370-
return firstFragment.instantiate(
11370+
return TypeParameterTypeImpl.v2(
11371+
element: this,
1137111372
nullabilitySuffix: nullabilitySuffix,
1137211373
);
1137311374
}

pkg/analyzer/lib/src/dart/element/subtype.dart

Lines changed: 44 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,9 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5-
// ignore_for_file: analyzer_use_new_elements
6-
75
import 'package:_fe_analyzer_shared/src/type_inference/type_analyzer_operations.dart'
86
show Variance;
9-
import 'package:analyzer/dart/element/element.dart';
7+
import 'package:analyzer/dart/element/element2.dart';
108
import 'package:analyzer/dart/element/nullability_suffix.dart';
119
import 'package:analyzer/dart/element/type.dart';
1210
import 'package:analyzer/src/dart/element/element.dart';
@@ -92,7 +90,7 @@ class SubtypeHelper {
9290
T0 is TypeParameterTypeImpl) {
9391
var S = T0.promotedBound;
9492
if (S == null) {
95-
var B = T0.element.bound ?? _objectQuestion;
93+
var B = T0.element3.bound ?? _objectQuestion;
9694
return isSubtypeOf(B, _objectNone);
9795
} else {
9896
return isSubtypeOf(S, _objectNone);
@@ -115,7 +113,7 @@ class SubtypeHelper {
115113
return false;
116114
}
117115
// Extension types require explicit `Object` implementation.
118-
if (T0 is InterfaceTypeImpl && T0.element is ExtensionTypeElement) {
116+
if (T0 is InterfaceTypeImpl && T0.element3 is ExtensionTypeElement2) {
119117
for (var interface in T0.interfaces) {
120118
if (isSubtypeOf(interface, T1_)) {
121119
return true;
@@ -179,7 +177,7 @@ class SubtypeHelper {
179177
if (T0 is TypeParameterTypeImpl &&
180178
T1 is TypeParameterTypeImpl &&
181179
T1.promotedBound == null &&
182-
T0.element == T1.element) {
180+
T0.element3 == T1.element3) {
183181
return true;
184182
}
185183

@@ -188,8 +186,8 @@ class SubtypeHelper {
188186
if (T1 is TypeParameterTypeImpl) {
189187
var T1_promotedBound = T1.promotedBound;
190188
if (T1_promotedBound != null) {
191-
var X1 = TypeParameterTypeImpl(
192-
element: T1.element,
189+
var X1 = TypeParameterTypeImpl.v2(
190+
element: T1.element3,
193191
nullabilitySuffix: T1.nullabilitySuffix,
194192
);
195193
return isSubtypeOf(T0, X1) && isSubtypeOf(T0, T1_promotedBound);
@@ -221,7 +219,7 @@ class SubtypeHelper {
221219
if (S0 != null && isSubtypeOf(S0, T1)) {
222220
return true;
223221
}
224-
var B0 = T0.element.bound;
222+
var B0 = T0.element3.bound;
225223
if (B0 != null && isSubtypeOf(B0, T1)) {
226224
return true;
227225
}
@@ -249,7 +247,7 @@ class SubtypeHelper {
249247
if (S0 != null && isSubtypeOf(S0, T1)) {
250248
return true;
251249
}
252-
var B0 = T0.element.bound;
250+
var B0 = T0.element3.bound;
253251
if (B0 != null && isSubtypeOf(B0, T1)) {
254252
return true;
255253
}
@@ -275,7 +273,7 @@ class SubtypeHelper {
275273
return true;
276274
}
277275

278-
var B0 = T0.element.bound;
276+
var B0 = T0.element3.bound;
279277
if (B0 != null && isSubtypeOf(B0, T1)) {
280278
return true;
281279
}
@@ -305,19 +303,19 @@ class SubtypeHelper {
305303
}
306304

307305
bool _interfaceArguments(
308-
InterfaceElement element,
306+
InterfaceElement2 element,
309307
InterfaceType subType,
310308
InterfaceType superType,
311309
) {
312-
List<TypeParameterElement> parameters = element.typeParameters;
310+
List<TypeParameterElement2> parameters = element.typeParameters2;
313311
List<DartType> subArguments = subType.typeArguments;
314312
List<DartType> superArguments = superType.typeArguments;
315313

316314
assert(subArguments.length == superArguments.length);
317315
assert(parameters.length == subArguments.length);
318316

319317
for (int i = 0; i < subArguments.length; i++) {
320-
var parameter = parameters[i] as TypeParameterElementImpl;
318+
var parameter = parameters[i] as TypeParameterElementImpl2;
321319
var subArgument = subArguments[i];
322320
var superArgument = superArguments[i];
323321

@@ -347,7 +345,8 @@ class SubtypeHelper {
347345

348346
/// Check that [f] is a subtype of [g].
349347
bool _isFunctionSubtypeOf(FunctionType f, FunctionType g) {
350-
var fresh = _typeSystem.relateTypeParameters(f.typeFormals, g.typeFormals);
348+
var fresh =
349+
_typeSystem.relateTypeParameters2(f.typeParameters, g.typeParameters);
351350
if (fresh == null) {
352351
return false;
353352
}
@@ -359,8 +358,8 @@ class SubtypeHelper {
359358
return false;
360359
}
361360

362-
var fParameters = f.parameters;
363-
var gParameters = g.parameters;
361+
var fParameters = f.formalParameters;
362+
var gParameters = g.formalParameters;
364363

365364
var fIndex = 0;
366365
var gIndex = 0;
@@ -391,27 +390,33 @@ class SubtypeHelper {
391390
}
392391
} else if (fParameter.isNamed) {
393392
if (gParameter.isNamed) {
394-
var compareNames = fParameter.name.compareTo(gParameter.name);
395-
if (compareNames == 0) {
396-
if (fParameter.isRequiredNamed && !gParameter.isRequiredNamed) {
397-
return false;
398-
} else if (isSubtypeOf(gParameter.type, fParameter.type)) {
399-
fIndex++;
400-
gIndex++;
401-
} else {
402-
return false;
403-
}
404-
} else if (compareNames < 0) {
405-
if (fParameter.isRequiredNamed) {
406-
return false;
407-
} else {
408-
fIndex++;
409-
}
410-
} else {
411-
assert(compareNames > 0);
412-
// The subtype must accept all parameters of the supertype.
393+
var fName = fParameter.name3;
394+
var gName = gParameter.name3;
395+
if (fName == null || gName == null) {
413396
return false;
414397
}
398+
399+
var compareNames = fName.compareTo(gName);
400+
switch (compareNames) {
401+
case 0:
402+
if (fParameter.isRequiredNamed && !gParameter.isRequiredNamed) {
403+
return false;
404+
} else if (isSubtypeOf(gParameter.type, fParameter.type)) {
405+
fIndex++;
406+
gIndex++;
407+
} else {
408+
return false;
409+
}
410+
case < 0:
411+
if (fParameter.isRequiredNamed) {
412+
return false;
413+
} else {
414+
fIndex++;
415+
}
416+
default:
417+
// The subtype must accept all parameters of the supertype.
418+
return false;
419+
}
415420
} else {
416421
break;
417422
}
@@ -448,8 +453,8 @@ class SubtypeHelper {
448453
return false;
449454
}
450455

451-
var subElement = subType.element;
452-
var superElement = superType.element;
456+
var subElement = subType.element3;
457+
var superElement = superType.element3;
453458
if (identical(subElement, superElement)) {
454459
return _interfaceArguments(superElement, subType, superType);
455460
}
@@ -460,7 +465,7 @@ class SubtypeHelper {
460465
}
461466

462467
for (var interface in subElement.allSupertypes) {
463-
if (identical(interface.element, superElement)) {
468+
if (identical(interface.element3, superElement)) {
464469
var substitution = Substitution.fromInterfaceType(subType);
465470
var substitutedInterface =
466471
substitution.substituteType(interface) as InterfaceType;

pkg/analyzer/lib/src/dart/element/type.dart

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -207,14 +207,9 @@ class FunctionTypeImpl extends TypeImpl
207207
Null get element3 => null;
208208

209209
@override
210-
List<FormalParameterElement> get formalParameters => parameters
211-
.map((parameter) => switch (parameter) {
212-
FormalParameterFragment(:var element) => element,
213-
ParameterMember(:var element) => element,
214-
_ => throw UnsupportedError(
215-
'Unsupported type ${parameter.runtimeType}'),
216-
})
217-
.toList();
210+
List<FormalParameterElement> get formalParameters {
211+
return parameters.map((p) => p.asElement2).toList(growable: false);
212+
}
218213

219214
@Deprecated('Check element, or use getDisplayString()')
220215
@override

pkg/analyzer/lib/src/dart/element/type_system.dart

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import 'package:analyzer/src/dart/element/well_bounded.dart';
3939
import 'package:analyzer/src/dart/resolver/flow_analysis_visitor.dart';
4040
import 'package:analyzer/src/generated/inference_log.dart';
4141
import 'package:analyzer/src/utilities/extensions/collection.dart';
42+
import 'package:analyzer/src/utilities/extensions/element.dart';
4243
import 'package:meta/meta.dart';
4344

4445
class ExtensionTypeErasure extends ReplacementVisitor {
@@ -78,6 +79,19 @@ class RelatedTypeParameters {
7879
);
7980
}
8081

82+
/// Fresh type parameters created to unify two lists of type parameters.
83+
class RelatedTypeParameters2 {
84+
static final _empty = RelatedTypeParameters2._(const [], const []);
85+
86+
final List<TypeParameterElement2> typeParameters;
87+
final List<TypeParameterType> typeParameterTypes;
88+
89+
RelatedTypeParameters2._(
90+
this.typeParameters,
91+
this.typeParameterTypes,
92+
);
93+
}
94+
8195
/// The [TypeSystem] implementation.
8296
class TypeSystemImpl implements TypeSystem {
8397
/// The provider of types for the system.
@@ -1622,6 +1636,67 @@ class TypeSystemImpl implements TypeSystem {
16221636
);
16231637
}
16241638

1639+
/// Given two lists of type parameters, check that they have the same
1640+
/// number of elements, and their bounds are equal.
1641+
///
1642+
/// The return value will be a new list of fresh type parameters, that can
1643+
/// be used to instantiate both function types, allowing further comparison.
1644+
RelatedTypeParameters2? relateTypeParameters2(
1645+
List<TypeParameterElement2> typeParameters1,
1646+
List<TypeParameterElement2> typeParameters2,
1647+
) {
1648+
if (typeParameters1.length != typeParameters2.length) {
1649+
return null;
1650+
}
1651+
if (typeParameters1.isEmpty) {
1652+
return RelatedTypeParameters2._empty;
1653+
}
1654+
1655+
var length = typeParameters1.length;
1656+
var freshTypeParameters = List.generate(length, (index) {
1657+
return typeParameters1[index].freshCopy();
1658+
}, growable: false);
1659+
1660+
var freshTypeParameterTypes = List.generate(length, (index) {
1661+
return freshTypeParameters[index].instantiate(
1662+
nullabilitySuffix: NullabilitySuffix.none,
1663+
);
1664+
}, growable: false);
1665+
1666+
var substitution1 = Substitution.fromPairs2(
1667+
typeParameters1,
1668+
freshTypeParameterTypes,
1669+
);
1670+
var substitution2 = Substitution.fromPairs2(
1671+
typeParameters2,
1672+
freshTypeParameterTypes,
1673+
);
1674+
1675+
for (var i = 0; i < typeParameters1.length; i++) {
1676+
var bound1 = typeParameters1[i].bound;
1677+
var bound2 = typeParameters2[i].bound;
1678+
if (bound1 == null && bound2 == null) {
1679+
continue;
1680+
}
1681+
bound1 ??= DynamicTypeImpl.instance;
1682+
bound2 ??= DynamicTypeImpl.instance;
1683+
bound1 = substitution1.substituteType(bound1);
1684+
bound2 = substitution2.substituteType(bound2);
1685+
if (!isEqualTo(bound1, bound2)) {
1686+
return null;
1687+
}
1688+
1689+
if (bound1 is! DynamicType) {
1690+
freshTypeParameters[i].bound = bound1;
1691+
}
1692+
}
1693+
1694+
return RelatedTypeParameters2._(
1695+
freshTypeParameters,
1696+
freshTypeParameterTypes,
1697+
);
1698+
}
1699+
16251700
/// Replaces all covariant occurrences of `dynamic`, `void`, and `Object` or
16261701
/// `Object?` with `Null` or `Never` and all contravariant occurrences of
16271702
/// `Null` or `Never` with `Object` or `Object?`.

pkg/analyzer/lib/src/utilities/extensions/element.dart

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,17 @@ extension TypeParameterElement2Extension on TypeParameterElement2 {
550550
TypeParameterElement get asElement {
551551
return firstFragment as TypeParameterElement;
552552
}
553+
554+
TypeParameterElementImpl2 freshCopy() {
555+
return TypeParameterElementImpl2(
556+
firstFragment: TypeParameterElementImpl(
557+
name3 ?? '',
558+
-1,
559+
),
560+
name3: name3,
561+
bound: bound,
562+
);
563+
}
553564
}
554565

555566
extension TypeParameterElementExtension on TypeParameterElement {

0 commit comments

Comments
 (0)