Skip to content

Commit

Permalink
Elements. Migrate NormalizeHelper.
Browse files Browse the repository at this point in the history
Change-Id: I6a6bed4ef30e17297faa3828a1c55d52df982a8b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/403929
Reviewed-by: Phil Quitslund <[email protected]>
Commit-Queue: Konstantin Shcheglov <[email protected]>
  • Loading branch information
scheglov authored and Commit Queue committed Jan 13, 2025
1 parent a5c3b34 commit 01f5956
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 18 deletions.
19 changes: 19 additions & 0 deletions pkg/analyzer/lib/src/dart/element/extensions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,25 @@ extension ExecutableElementExtensionQuestion on ExecutableElement? {
}
}

extension FormalParameterElementExtension on FormalParameterElement {
/// Returns [FormalParameterElementImpl] with the specified properties
/// replaced.
FormalParameterElementImpl copyWith({
DartType? type,
ParameterKind? kind,
bool? isCovariant,
}) {
var firstFragment = this.firstFragment as ParameterElement;
return FormalParameterElementImpl(
firstFragment.copyWith(
type: type,
kind: kind,
isCovariant: isCovariant,
),
);
}
}

extension InterfaceTypeExtension on InterfaceType {
bool get isDartCoreObjectNone {
return isDartCoreObject && nullabilitySuffix == NullabilitySuffix.none;
Expand Down
34 changes: 16 additions & 18 deletions pkg/analyzer/lib/src/dart/element/normalize.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// ignore_for_file: analyzer_use_new_elements

import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/element2.dart';
import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/extensions.dart';
Expand All @@ -22,7 +20,7 @@ class NormalizeHelper {
final TypeSystemImpl typeSystem;
final TypeProviderImpl typeProvider;

final Set<TypeParameterElement> _typeParameters = {};
final Set<TypeParameterElement2> _typeParameters = {};

NormalizeHelper(this.typeSystem) : typeProvider = typeSystem.typeProvider;

Expand All @@ -35,7 +33,7 @@ class NormalizeHelper {
/// * and B1 = NORM(B)
/// * and S1 = NORM(S)
FunctionTypeImpl _functionType(FunctionType functionType) {
var fresh = getFreshTypeParameters(functionType.typeFormals);
var fresh = getFreshTypeParameters2(functionType.typeParameters);
for (var typeParameter in fresh.freshTypeParameters) {
var bound = typeParameter.firstFragment.bound;
if (bound != null) {
Expand All @@ -45,9 +43,9 @@ class NormalizeHelper {

functionType = fresh.applyToFunctionType(functionType);

return FunctionTypeImpl(
typeFormals: functionType.typeFormals,
parameters: functionType.parameters.map((e) {
return FunctionTypeImpl.v2(
typeParameters: functionType.typeParameters,
formalParameters: functionType.formalParameters.map((e) {
return e.copyWith(
type: _normalize(e.type),
);
Expand Down Expand Up @@ -134,7 +132,7 @@ class NormalizeHelper {

// NORM(C<T0, ..., Tn>) = C<R0, ..., Rn> where Ri is NORM(Ti)
if (T is InterfaceType) {
return T.element.instantiate(
return T.element3.instantiate(
typeArguments: T.typeArguments.map(_normalize).toFixedList(),
nullabilitySuffix: NullabilitySuffix.none,
);
Expand Down Expand Up @@ -202,7 +200,7 @@ class NormalizeHelper {
/// NORM(X & T)
/// NORM(X extends T)
DartType _typeParameterType(TypeParameterTypeImpl T) {
var element = T.element;
var element = T.element3;

// NORM(X & T)
var promotedBound = T.promotedBound;
Expand Down Expand Up @@ -237,45 +235,45 @@ class NormalizeHelper {

/// NORM(X & T)
/// * let S be NORM(T)
DartType _typeParameterType_promoted(TypeParameterElement X, DartType S) {
DartType _typeParameterType_promoted(TypeParameterElement2 X, DartType S) {
// * if S is Never then Never
if (identical(S, NeverTypeImpl.instance)) {
return NeverTypeImpl.instance;
}

// * if S is a top type then X
if (typeSystem.isTop(S)) {
return X.declaration.instantiate(
return X.instantiate(
nullabilitySuffix: NullabilitySuffix.none,
);
}

// * if S is X then X
if (S is TypeParameterType &&
S.nullabilitySuffix == NullabilitySuffix.none &&
S.element == X.declaration) {
return X.declaration.instantiate(
S.element3 == X) {
return X.instantiate(
nullabilitySuffix: NullabilitySuffix.none,
);
}

// * if S is Object and NORM(B) is Object where B is the bound of X then X
if (S.nullabilitySuffix == NullabilitySuffix.none && S.isDartCoreObject) {
var B = X.declaration.bound;
var B = X.bound;
if (B != null) {
var B_norm = _normalize(B);
if (B_norm.nullabilitySuffix == NullabilitySuffix.none &&
B_norm.isDartCoreObject) {
return X.declaration.instantiate(
return X.instantiate(
nullabilitySuffix: NullabilitySuffix.none,
);
}
}
}

// * else X & S
return TypeParameterTypeImpl(
element: X.declaration,
return TypeParameterTypeImpl.v2(
element: X,
nullabilitySuffix: NullabilitySuffix.none,
promotedBound: S,
);
Expand Down
16 changes: 16 additions & 0 deletions pkg/analyzer/lib/src/dart/element/type.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1707,6 +1707,22 @@ class TypeParameterTypeImpl extends TypeImpl implements TypeParameterType {
super.alias,
});

/// Initialize a newly created type parameter type to be declared by the given
/// [element] and to have the given name.
factory TypeParameterTypeImpl.v2({
required TypeParameterElement2 element,
required NullabilitySuffix nullabilitySuffix,
DartType? promotedBound,
InstantiatedTypeAliasElement? alias,
}) {
return TypeParameterTypeImpl(
element: element.asElement,
nullabilitySuffix: nullabilitySuffix,
promotedBound: promotedBound,
alias: alias,
);
}

@override
DartType get bound =>
promotedBound ?? element.bound ?? DynamicTypeImpl.instance;
Expand Down
59 changes: 59 additions & 0 deletions pkg/analyzer/lib/src/dart/element/type_algebra.dart
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,55 @@ FreshTypeParameters getFreshTypeParameters(
return FreshTypeParameters(freshParameters, substitution);
}

/// Generates a fresh copy of the given type parameters, with their bounds
/// substituted to reference the new parameters.
///
/// The returned object contains the fresh type parameter list as well as a
/// mapping to be used for replacing other types to use the new type parameters.
FreshTypeParameters getFreshTypeParameters2(
List<TypeParameterElement2> typeParameters) {
var freshParameters = List<TypeParameterElementImpl2>.generate(
typeParameters.length,
(i) {
var name = typeParameters[i].name3;
var fragment = TypeParameterElementImpl(name ?? '', -1);
return TypeParameterElementImpl2(
firstFragment: fragment,
name3: name,
bound: null,
);
},
growable: false,
);

var map = <TypeParameterElement2, DartType>{};
for (int i = 0; i < typeParameters.length; ++i) {
map[typeParameters[i]] = TypeParameterTypeImpl.v2(
element: freshParameters[i],
nullabilitySuffix: NullabilitySuffix.none,
);
}

var substitution = Substitution.fromMap2(map);

for (int i = 0; i < typeParameters.length; ++i) {
// TODO(kallentu): : Clean up TypeParameterElementImpl casting once
// variance is added to the interface.
var typeParameter = typeParameters[i] as TypeParameterElementImpl2;
if (!typeParameter.isLegacyCovariant) {
freshParameters[i].firstFragment.variance = typeParameter.variance;
}

var bound = typeParameter.bound;
if (bound != null) {
var newBound = substitution.substituteType(bound);
freshParameters[i].firstFragment.bound = newBound;
}
}

return FreshTypeParameters(freshParameters, substitution);
}

/// Given a generic function [type] of a class member (so that it does not
/// carry its element and type arguments), substitute its type parameters with
/// the [newTypeParameters] in the formal parameters and return type.
Expand Down Expand Up @@ -200,6 +249,16 @@ abstract class Substitution {
return _MapSubstitution(map);
}

/// Substitutes each parameter to the type it maps to in [map].
static MapSubstitution fromMap2(Map<TypeParameterElement2, DartType> map) {
if (map.isEmpty) {
return _NullSubstitution.instance;
}
return _MapSubstitution(
map.map((key, value) => MapEntry(key.asElement, value)),
);
}

/// Substitutes the Nth parameter in [parameters] with the Nth type in
/// [types].
static MapSubstitution fromPairs(
Expand Down

0 comments on commit 01f5956

Please sign in to comment.