Skip to content

Commit 944ff08

Browse files
scheglovCommit Queue
authored andcommitted
Elements. Move more properties from TypeParameterFragmentImpl into TypeParameterElementImpl.
This change moves core properties like `bound`, `defaultType`, and `variance` from `TypeParameterFragmentImpl` to the `TypeParameterElementImpl` class. Previously, the element often delegated property access to its `firstFragment`. This refactoring centralizes the data, making the element the single source of truth for its own properties. This change simplifies the data model and improves code clarity by reducing the tight coupling between the element and fragment implementations. All call sites have been updated to reflect this new ownership, accessing properties directly from the element instance. Change-Id: I4f37f0d35aaa86e8f461020c0f5ad72b02627d0f Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/445125 Reviewed-by: Johnni Winther <[email protected]> Commit-Queue: Konstantin Shcheglov <[email protected]> Reviewed-by: Samuel Rawlins <[email protected]>
1 parent 3e36557 commit 944ff08

20 files changed

+123
-168
lines changed

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import 'package:analyzer/dart/element/type.dart';
1010
import 'package:analyzer/src/dart/element/element.dart';
1111
import 'package:analyzer/src/dart/element/type.dart';
1212
import 'package:analyzer/src/dart/element/type_algebra.dart';
13-
import 'package:analyzer/src/utilities/extensions/element.dart';
1413

1514
/// A class that builds a "display string" for [Element]s and [DartType]s.
1615
class ElementDisplayStringBuilder {
@@ -601,9 +600,9 @@ class ElementDisplayStringBuilder {
601600
name = typeParameter.name! + subscript;
602601
}
603602

604-
var newTypeParameter = TypeParameterFragmentImpl(name: name);
603+
var newTypeParameter = TypeParameterElementImpl.synthetic(name: name);
605604
newTypeParameter.bound = typeParameter.bound;
606-
newTypeParameters.add(newTypeParameter.asElement2);
605+
newTypeParameters.add(newTypeParameter);
607606
}
608607

609608
return replaceTypeParameters(type, newTypeParameters);

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

Lines changed: 70 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -4762,7 +4762,6 @@ abstract class InterfaceElementImpl extends InstanceElementImpl
47624762
InterfaceTypeImpl get thisType {
47634763
if (_thisType == null) {
47644764
List<TypeImpl> typeArguments;
4765-
var typeParameters = firstFragment.typeParameters;
47664765
if (typeParameters.isNotEmpty) {
47674766
typeArguments =
47684767
typeParameters.map<TypeImpl>((t) {
@@ -9877,6 +9876,23 @@ class TypeParameterElementImpl extends ElementImpl
98779876
@override
98789877
final String? name;
98799878

9879+
/// The value representing the variance modifier keyword, or `null` if
9880+
/// there is no explicit variance modifier, meaning legacy covariance.
9881+
shared.Variance? _variance;
9882+
9883+
/// The type representing the bound associated with this type parameter,
9884+
/// or `null` if this type parameter does not have an explicit bound.
9885+
///
9886+
/// Being able to distinguish between an implicit and explicit bound is
9887+
/// needed by the instantiate to bounds algorithm.
9888+
@override
9889+
TypeImpl? bound;
9890+
9891+
/// The default value of the type parameter. It is used to provide the
9892+
/// corresponding missing type argument in type annotations and as the
9893+
/// fall-back type value in type inference.
9894+
TypeImpl? defaultType;
9895+
98809896
TypeParameterElementImpl({required this.firstFragment})
98819897
: name = firstFragment.name {
98829898
firstFragment.element = this;
@@ -9890,21 +9906,9 @@ class TypeParameterElementImpl extends ElementImpl
98909906
@override
98919907
TypeParameterElementImpl get baseElement => this;
98929908

9893-
@override
9894-
TypeImpl? get bound => firstFragment.bound;
9895-
9896-
set bound(TypeImpl? value) {
9897-
firstFragment.bound = value;
9898-
}
9899-
99009909
@override
99019910
TypeImpl? get boundShared => bound;
99029911

9903-
/// The default value of the type parameter. It is used to provide the
9904-
/// corresponding missing type argument in type annotations and as the
9905-
/// fall-back type value in type inference.
9906-
TypeImpl? get defaultType => firstFragment.defaultType;
9907-
99089912
@override
99099913
Element? get enclosingElement {
99109914
return firstFragment.enclosingFragment?.element;
@@ -9926,7 +9930,9 @@ class TypeParameterElementImpl extends ElementImpl
99269930
];
99279931
}
99289932

9929-
bool get isLegacyCovariant => firstFragment.isLegacyCovariant;
9933+
bool get isLegacyCovariant {
9934+
return _variance == null;
9935+
}
99309936

99319937
@override
99329938
bool get isSynthetic {
@@ -9957,12 +9963,12 @@ class TypeParameterElementImpl extends ElementImpl
99579963
@override
99589964
String? get name3 => name;
99599965

9960-
shared.Variance get variance => firstFragment.variance;
9961-
9962-
set variance(shared.Variance? value) {
9963-
firstFragment.variance = value;
9966+
shared.Variance get variance {
9967+
return _variance ?? shared.Variance.covariant;
99649968
}
99659969

9970+
set variance(shared.Variance? newVariance) => _variance = newVariance;
9971+
99669972
@override
99679973
T? accept<T>(ElementVisitor2<T> visitor) {
99689974
return visitor.visitTypeParameterElement(this);
@@ -9977,6 +9983,52 @@ class TypeParameterElementImpl extends ElementImpl
99779983
builder.writeTypeParameterElement(this);
99789984
}
99799985

9986+
/// Computes the variance of the type parameters in the [type].
9987+
shared.Variance computeVarianceInType(DartType type) {
9988+
if (type is TypeParameterTypeImpl) {
9989+
if (type.element == this) {
9990+
return shared.Variance.covariant;
9991+
} else {
9992+
return shared.Variance.unrelated;
9993+
}
9994+
} else if (type is InterfaceTypeImpl) {
9995+
var result = shared.Variance.unrelated;
9996+
for (int i = 0; i < type.typeArguments.length; ++i) {
9997+
var argument = type.typeArguments[i];
9998+
var parameter = type.element.typeParameters[i];
9999+
10000+
var parameterVariance = parameter.variance;
10001+
result = result.meet(
10002+
parameterVariance.combine(computeVarianceInType(argument)),
10003+
);
10004+
}
10005+
return result;
10006+
} else if (type is FunctionType) {
10007+
var result = computeVarianceInType(type.returnType);
10008+
10009+
for (var parameter in type.typeParameters) {
10010+
// If [parameter] is referenced in the bound at all, it makes the
10011+
// variance of [parameter] in the entire type invariant. The invocation
10012+
// of [computeVariance] below is made to simply figure out if [variable]
10013+
// occurs in the bound.
10014+
var bound = parameter.bound;
10015+
if (bound != null && !computeVarianceInType(bound).isUnrelated) {
10016+
result = shared.Variance.invariant;
10017+
}
10018+
}
10019+
10020+
for (var formalParameter in type.formalParameters) {
10021+
result = result.meet(
10022+
shared.Variance.contravariant.combine(
10023+
computeVarianceInType(formalParameter.type),
10024+
),
10025+
);
10026+
}
10027+
return result;
10028+
}
10029+
return shared.Variance.unrelated;
10030+
}
10031+
998010032
@override
998110033
TypeParameterTypeImpl instantiate({
998210034
required NullabilitySuffix nullabilitySuffix,
@@ -10003,19 +10055,6 @@ class TypeParameterFragmentImpl extends FragmentImpl
1000310055
@override
1000410056
int? nameOffset;
1000510057

10006-
/// The default value of the type parameter. It is used to provide the
10007-
/// corresponding missing type argument in type annotations and as the
10008-
/// fall-back type value in type inference.
10009-
TypeImpl? defaultType;
10010-
10011-
/// The type representing the bound associated with this parameter, or `null`
10012-
/// if this parameter does not have an explicit bound.
10013-
TypeImpl? _bound;
10014-
10015-
/// The value representing the variance modifier keyword, or `null` if
10016-
/// there is no explicit variance modifier, meaning legacy covariance.
10017-
shared.Variance? _variance;
10018-
1001910058
/// The element corresponding to this fragment.
1002010059
TypeParameterElementImpl? _element;
1002110060

@@ -10030,25 +10069,6 @@ class TypeParameterFragmentImpl extends FragmentImpl
1003010069
isSynthetic = true;
1003110070
}
1003210071

10033-
/// The type representing the bound associated with this parameter, or `null`
10034-
/// if this parameter does not have an explicit bound. Being able to
10035-
/// distinguish between an implicit and explicit bound is needed by the
10036-
/// instantiate to bounds algorithm.
10037-
TypeImpl? get bound {
10038-
return _bound;
10039-
}
10040-
10041-
set bound(DartType? bound) {
10042-
// TODO(paulberry): Change the type of the parameter `bound` so that this
10043-
// cast isn't needed.
10044-
_bound = bound as TypeImpl?;
10045-
if (_element case var element?) {
10046-
if (!identical(element.bound, bound)) {
10047-
element.bound = bound;
10048-
}
10049-
}
10050-
}
10051-
1005210072
@override
1005310073
List<Fragment> get children => const [];
1005410074

@@ -10082,10 +10102,6 @@ class TypeParameterFragmentImpl extends FragmentImpl
1008210102
_element = element;
1008310103
}
1008410104

10085-
bool get isLegacyCovariant {
10086-
return _variance == null;
10087-
}
10088-
1008910105
@override
1009010106
LibraryFragment? get libraryFragment {
1009110107
return enclosingFragment?.libraryFragment;
@@ -10105,66 +10121,6 @@ class TypeParameterFragmentImpl extends FragmentImpl
1010510121
@override
1010610122
// TODO(augmentations): Support chaining between the fragments.
1010710123
TypeParameterFragmentImpl? get previousFragment => null;
10108-
10109-
shared.Variance get variance {
10110-
return _variance ?? shared.Variance.covariant;
10111-
}
10112-
10113-
set variance(shared.Variance? newVariance) => _variance = newVariance;
10114-
10115-
/// Computes the variance of the type parameters in the [type].
10116-
shared.Variance computeVarianceInType(DartType type) {
10117-
if (type is TypeParameterTypeImpl) {
10118-
if (type.element == element) {
10119-
return shared.Variance.covariant;
10120-
} else {
10121-
return shared.Variance.unrelated;
10122-
}
10123-
} else if (type is InterfaceTypeImpl) {
10124-
var result = shared.Variance.unrelated;
10125-
for (int i = 0; i < type.typeArguments.length; ++i) {
10126-
var argument = type.typeArguments[i];
10127-
var parameter = type.element.typeParameters[i];
10128-
10129-
var parameterVariance = parameter.variance;
10130-
result = result.meet(
10131-
parameterVariance.combine(computeVarianceInType(argument)),
10132-
);
10133-
}
10134-
return result;
10135-
} else if (type is FunctionType) {
10136-
var result = computeVarianceInType(type.returnType);
10137-
10138-
for (var parameter in type.typeParameters) {
10139-
// If [parameter] is referenced in the bound at all, it makes the
10140-
// variance of [parameter] in the entire type invariant. The invocation
10141-
// of [computeVariance] below is made to simply figure out if [variable]
10142-
// occurs in the bound.
10143-
var bound = parameter.bound;
10144-
if (bound != null && !computeVarianceInType(bound).isUnrelated) {
10145-
result = shared.Variance.invariant;
10146-
}
10147-
}
10148-
10149-
for (var formalParameter in type.formalParameters) {
10150-
result = result.meet(
10151-
shared.Variance.contravariant.combine(
10152-
computeVarianceInType(formalParameter.type),
10153-
),
10154-
);
10155-
}
10156-
return result;
10157-
}
10158-
return shared.Variance.unrelated;
10159-
}
10160-
10161-
/// Creates the [TypeParameterType] with the given [nullabilitySuffix] for
10162-
/// this type parameter.
10163-
TypeParameterTypeImpl instantiate({
10164-
required NullabilitySuffix nullabilitySuffix,
10165-
}) {
10166-
return element.instantiate(nullabilitySuffix: nullabilitySuffix);
10167-
}
1016810124
}
1016910125

1017010126
/// Mixin representing an element which can have type parameters.

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,9 @@ class NormalizeHelper {
4444
FunctionTypeImpl _functionType(FunctionTypeImpl functionType) {
4545
var fresh = getFreshTypeParameters(functionType.typeParameters);
4646
for (var typeParameter in fresh.freshTypeParameters) {
47-
var bound = typeParameter.firstFragment.bound;
47+
var bound = typeParameter.bound;
4848
if (bound != null) {
49-
typeParameter.firstFragment.bound = _normalize(bound);
49+
typeParameter.bound = _normalize(bound);
5050
}
5151
}
5252

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,6 @@ class TopMergeHelper {
348348
bBound = bSubstitution.substituteType(bBound);
349349
var newBound = topMerge(aBound, bBound);
350350
newParameters[i].bound = newBound;
351-
newParameters[i].firstFragment.bound = newBound;
352351
} else {
353352
return null;
354353
}

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import 'package:analyzer/src/dart/element/member.dart';
1515
import 'package:analyzer/src/dart/element/type_algebra.dart';
1616
import 'package:analyzer/src/dart/element/type_system.dart';
1717
import 'package:analyzer/src/utilities/extensions/collection.dart';
18+
import 'package:analyzer/src/utilities/extensions/element.dart';
1819
import 'package:collection/collection.dart';
1920

2021
/// Returns a [List] of fixed length with given types.
@@ -443,9 +444,7 @@ class FunctionTypeImpl extends TypeImpl
443444
for (int i = 0; i < count; i++) {
444445
TypeParameterElement p1 = params1[i];
445446
TypeParameterElement p2 = params2[i];
446-
TypeParameterFragmentImpl pFresh = TypeParameterFragmentImpl.synthetic(
447-
name: p2.name,
448-
);
447+
var pFresh = p2.freshCopy();
449448

450449
TypeParameterTypeImpl variableFresh = pFresh.instantiate(
451450
nullabilitySuffix: NullabilitySuffix.none,
@@ -470,7 +469,7 @@ class FunctionTypeImpl extends TypeImpl
470469
}
471470

472471
if (bound2 is! DynamicType) {
473-
pFresh.bound = bound2;
472+
pFresh.bound = bound2 as TypeImpl;
474473
}
475474
}
476475
return variablesFresh;

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,13 @@ FreshTypeParameters getFreshTypeParameters(
4646
// variance is added to the interface.
4747
var typeParameter = typeParameters[i] as TypeParameterElementImpl;
4848
if (!typeParameter.isLegacyCovariant) {
49-
freshParameters[i].firstFragment.variance = typeParameter.variance;
49+
freshParameters[i].variance = typeParameter.variance;
5050
}
5151

5252
var bound = typeParameter.bound;
5353
if (bound != null) {
5454
var newBound = substitution.substituteType(bound);
55-
freshParameters[i].firstFragment.bound = newBound;
55+
freshParameters[i].bound = newBound;
5656
}
5757
}
5858

@@ -262,15 +262,15 @@ class _FreshTypeParametersSubstitutor extends _TypeSubstitutor {
262262

263263
var freshElements = List.generate(elements.length, (index) {
264264
var element = elements[index];
265-
var freshElement = TypeParameterFragmentImpl(name: element.name);
265+
var freshElement = element.freshCopy();
266266
var freshType = freshElement.instantiate(
267267
nullabilitySuffix: NullabilitySuffix.none,
268268
);
269269
substitution[element] = freshType;
270270
if (!element.isLegacyCovariant) {
271271
freshElement.variance = element.variance;
272272
}
273-
return freshElement.asElement2;
273+
return freshElement;
274274
}, growable: false);
275275

276276
for (var i = 0; i < freshElements.length; i++) {

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -275,13 +275,13 @@ class TypeConstraintGatherer
275275
// not contain any variables from `L`.
276276
var newTypeParameters = <TypeParameterElementImpl>[];
277277
for (var i = 0; i < P.typeParameters.length; i++) {
278-
var Z = TypeParameterFragmentImpl(name: 'Z$i');
278+
var Z = TypeParameterElementImpl.synthetic(name: 'Z$i');
279279
if (leftSchema) {
280280
Z.bound = P.typeParameters[i].bound;
281281
} else {
282282
Z.bound = Q.typeParameters[i].bound;
283283
}
284-
newTypeParameters.add(Z.element);
284+
newTypeParameters.add(Z);
285285
}
286286

287287
// And `F0[Z0/T0, ..., Zn/Tn]` is a subtype match for

pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1419,7 +1419,7 @@ class ResolutionVisitor extends RecursiveAstVisitor<void> {
14191419
if (boundNode != null) {
14201420
boundNode.accept(this);
14211421
if (_elementWalker == null) {
1422-
fragment.bound = boundNode.type;
1422+
fragment.element.bound = boundNode.type;
14231423
}
14241424
}
14251425
}

0 commit comments

Comments
 (0)