Skip to content

Commit

Permalink
Elements. Store InterfaceElementImpl2 in InterfaceTypeImpl.
Browse files Browse the repository at this point in the history
Change-Id: Id7cf5dd51abb331c851b0244e9be0f0db15b73ee
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/404380
Commit-Queue: Konstantin Shcheglov <[email protected]>
Reviewed-by: Brian Wilkerson <[email protected]>
  • Loading branch information
scheglov authored and Commit Queue committed Jan 14, 2025
1 parent 6aeb1bf commit eafaa11
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 118 deletions.
95 changes: 49 additions & 46 deletions pkg/analyzer/lib/src/dart/element/element.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6091,14 +6091,6 @@ abstract class InterfaceElementImpl extends InstanceElementImpl
/// of this class have been inferred.
bool hasBeenInferred = false;

/// The non-nullable instance of this element, without alias.
/// Should be used only when the element has no type parameters.
InterfaceTypeImpl? _nonNullableInstance;

/// The nullable instance of this element, without alias.
/// Should be used only when the element has no type parameters.
InterfaceTypeImpl? _nullableInstance;

List<ConstructorElementImpl> _constructors = _Sentinel.constructorElement;

/// Initialize a newly created class element to have the given [name] at the
Expand Down Expand Up @@ -6275,43 +6267,10 @@ abstract class InterfaceElementImpl extends InstanceElementImpl
required List<DartType> typeArguments,
required NullabilitySuffix nullabilitySuffix,
}) {
assert(typeArguments.length == typeParameters.length);

if (typeArguments.isEmpty) {
switch (nullabilitySuffix) {
case NullabilitySuffix.none:
if (_nonNullableInstance case var instance?) {
return instance;
}
case NullabilitySuffix.question:
if (_nullableInstance case var instance?) {
return instance;
}
case NullabilitySuffix.star:
// TODO(scheglov): remove together with `star`
break;
}
}

var result = InterfaceTypeImpl(
element: this,
return element.instantiate(
typeArguments: typeArguments,
nullabilitySuffix: nullabilitySuffix,
);

if (typeArguments.isEmpty) {
switch (nullabilitySuffix) {
case NullabilitySuffix.none:
_nonNullableInstance = result;
case NullabilitySuffix.question:
_nullableInstance = result;
case NullabilitySuffix.star:
// TODO(scheglov): remove together with `star`
break;
}
}

return result;
}

@override
Expand Down Expand Up @@ -6535,6 +6494,14 @@ abstract class InterfaceElementImpl extends InstanceElementImpl
abstract class InterfaceElementImpl2 extends InstanceElementImpl2
with _HasSinceSdkVersionMixin
implements AugmentedInterfaceElement, InterfaceElement2 {
/// The non-nullable instance of this element, without alias.
/// Should be used only when the element has no type parameters.
InterfaceTypeImpl? _nonNullableInstance;

/// The nullable instance of this element, without alias.
/// Should be used only when the element has no type parameters.
InterfaceTypeImpl? _nullableInstance;

@override
List<InterfaceType> interfaces = [];

Expand Down Expand Up @@ -6633,12 +6600,48 @@ abstract class InterfaceElementImpl2 extends InstanceElementImpl2
}

@override
InterfaceType instantiate({
InterfaceTypeImpl instantiate({
required List<DartType> typeArguments,
required NullabilitySuffix nullabilitySuffix,
}) =>
firstFragment.instantiate(
typeArguments: typeArguments, nullabilitySuffix: nullabilitySuffix);
}) {
assert(typeArguments.length == typeParameters2.length);

if (typeArguments.isEmpty) {
switch (nullabilitySuffix) {
case NullabilitySuffix.none:
if (_nonNullableInstance case var instance?) {
return instance;
}
case NullabilitySuffix.question:
if (_nullableInstance case var instance?) {
return instance;
}
case NullabilitySuffix.star:
// TODO(scheglov): remove together with `star`
break;
}
}

var result = InterfaceTypeImpl.v2(
element: this,
typeArguments: typeArguments,
nullabilitySuffix: nullabilitySuffix,
);

if (typeArguments.isEmpty) {
switch (nullabilitySuffix) {
case NullabilitySuffix.none:
_nonNullableInstance = result;
case NullabilitySuffix.question:
_nullableInstance = result;
case NullabilitySuffix.star:
// TODO(scheglov): remove together with `star`
break;
}
}

return result;
}

@override
MethodElement2? lookUpConcreteMethod(
Expand Down
127 changes: 61 additions & 66 deletions pkg/analyzer/lib/src/dart/element/type.dart
Original file line number Diff line number Diff line change
Expand Up @@ -526,12 +526,12 @@ class FunctionTypeImpl extends TypeImpl
/// A concrete implementation of [DartType] representing types of the form
/// `FutureOr<...>`.
class FutureOrTypeImpl extends InterfaceTypeImpl {
FutureOrTypeImpl(
{required super.element,
required super.typeArgument,
required super.nullabilitySuffix,
super.alias})
: super._futureOr();
FutureOrTypeImpl({
required super.element3,
required super.typeArgument,
required super.nullabilitySuffix,
super.alias,
}) : super._futureOr();

@override
bool get isDartAsyncFutureOr => true;
Expand All @@ -543,7 +543,7 @@ class FutureOrTypeImpl extends InterfaceTypeImpl {
if (this.nullabilitySuffix == nullabilitySuffix) return this;

return FutureOrTypeImpl(
element: element,
element3: element3,
typeArgument: typeArgument,
nullabilitySuffix: nullabilitySuffix,
alias: alias,
Expand All @@ -570,7 +570,7 @@ class InstantiatedTypeAliasElementImpl implements InstantiatedTypeAliasElement {
/// A concrete implementation of an [InterfaceType].
class InterfaceTypeImpl extends TypeImpl implements InterfaceType {
@override
final InterfaceElementImpl element;
final InterfaceElementImpl2 element3;

@override
final List<DartType> typeArguments;
Expand All @@ -587,30 +587,20 @@ class InterfaceTypeImpl extends TypeImpl implements InterfaceType {
/// Cached [MethodElement]s - members or raw elements.
List<MethodElement>? _methods;

factory InterfaceTypeImpl(
{required InterfaceElement element,
required List<DartType> typeArguments,
required NullabilitySuffix nullabilitySuffix,
InstantiatedTypeAliasElement? alias}) {
factory InterfaceTypeImpl({
required InterfaceElement element,
required List<DartType> typeArguments,
required NullabilitySuffix nullabilitySuffix,
InstantiatedTypeAliasElement? alias,
}) {
// TODO(paulberry): avoid this cast by changing the type of `element`
element as InterfaceElementImpl;
if (element.name == 'FutureOr' && element.library.isDartAsync) {
return FutureOrTypeImpl(
element: element,
typeArgument: typeArguments.isNotEmpty
? typeArguments[0]
: InvalidTypeImpl.instance,
nullabilitySuffix: nullabilitySuffix,
alias: alias);
} else if (element.name == 'Null' && element.library.isDartCore) {
return NullTypeImpl(element: element, alias: alias);
} else {
return InterfaceTypeImpl._(
element: element,
typeArguments: typeArguments,
nullabilitySuffix: nullabilitySuffix,
alias: alias);
}
return InterfaceTypeImpl.v2(
element: element.asElement2,
typeArguments: typeArguments,
nullabilitySuffix: nullabilitySuffix,
alias: alias,
);
}

factory InterfaceTypeImpl.v2({
Expand All @@ -619,51 +609,53 @@ class InterfaceTypeImpl extends TypeImpl implements InterfaceType {
required NullabilitySuffix nullabilitySuffix,
InstantiatedTypeAliasElement? alias,
}) {
return InterfaceTypeImpl(
element: element.asElement,
typeArguments: typeArguments,
nullabilitySuffix: nullabilitySuffix,
alias: alias,
);
if (element.name3 == 'FutureOr' && element.library2.isDartAsync) {
return FutureOrTypeImpl(
element3: element,
typeArgument: typeArguments.isNotEmpty
? typeArguments[0]
: InvalidTypeImpl.instance,
nullabilitySuffix: nullabilitySuffix,
alias: alias,
);
} else if (element.name3 == 'Null' && element.library2.isDartCore) {
return NullTypeImpl(
element3: element,
alias: alias,
);
} else {
return InterfaceTypeImpl._(
element3: element,
typeArguments: typeArguments,
nullabilitySuffix: nullabilitySuffix,
alias: alias,
);
}
}

InterfaceTypeImpl._({
required this.element,
required this.element3,
required this.typeArguments,
required this.nullabilitySuffix,
required super.alias,
}) {
if (element.augmentationTarget != null) {
throw ArgumentError(
'InterfaceType(s) can only be created for declarations',
);
}
var typeParameters = element.typeParameters;
if (typeArguments.length != typeParameters.length) {
throw ArgumentError(
'[typeParameters.length: ${typeParameters.length}]'
'[typeArguments.length: ${typeArguments.length}]'
'[element: $element]'
'[typeParameters: $typeParameters]'
'[typeArguments: $typeArguments]',
);
}
}
});

InterfaceTypeImpl._futureOr(
{required this.element,
required DartType typeArgument,
required this.nullabilitySuffix,
super.alias})
: typeArguments = [typeArgument] {
assert(element.name == 'FutureOr' && element.library.isDartAsync);
InterfaceTypeImpl._futureOr({
required this.element3,
required DartType typeArgument,
required this.nullabilitySuffix,
super.alias,
}) : typeArguments = [typeArgument] {
assert(element3.name3 == 'FutureOr' && element3.library2.isDartAsync);
assert(this is FutureOrTypeImpl);
}

InterfaceTypeImpl._null({required this.element, super.alias})
: typeArguments = const [],
InterfaceTypeImpl._null({
required this.element3,
super.alias,
}) : typeArguments = const [],
nullabilitySuffix = NullabilitySuffix.none {
assert(element.name == 'Null' && element.library.isDartCore);
assert(element3.name3 == 'Null' && element3.library2.isDartCore);
assert(this is NullTypeImpl);
}

Expand Down Expand Up @@ -708,7 +700,7 @@ class InterfaceTypeImpl extends TypeImpl implements InterfaceType {
.toList();

@override
InterfaceElementImpl2 get element3 => element.element;
InterfaceElementImpl get element => element3.asElement;

@override
List<GetterElement> get getters => accessors
Expand Down Expand Up @@ -1341,7 +1333,10 @@ class NeverTypeImpl extends TypeImpl implements NeverType {
/// no type parameters and no nullability suffix.
class NullTypeImpl extends InterfaceTypeImpl
implements SharedNullTypeStructure<DartType> {
NullTypeImpl({required super.element, super.alias}) : super._null();
NullTypeImpl({
required super.element3,
super.alias,
}) : super._null();

@override
bool get isDartCoreNull => true;
Expand Down
13 changes: 7 additions & 6 deletions pkg/analyzer/lib/src/test_utilities/mock_sdk_elements.dart
Original file line number Diff line number Diff line change
Expand Up @@ -943,7 +943,7 @@ class _MockSdkElementsBuilder {
}

void _buildClassElement(ClassElementImpl fragment) {
var element = ClassElementImpl2(Reference.root(), fragment);
var element = fragment.element;
element.mixins = fragment.mixins;
element.interfaces = fragment.interfaces;
element.fields = fragment.fields;
Expand Down Expand Up @@ -979,13 +979,14 @@ class _MockSdkElementsBuilder {
List<TypeParameterElementImpl> typeParameters = const [],
required CompilationUnitElementImpl unit,
}) {
var element = ClassElementImpl(name, 0);
element.typeParameters = typeParameters;
element.constructors = <ConstructorElementImpl>[
var fragment = ClassElementImpl(name, 0);
ClassElementImpl2(Reference.root(), fragment);
fragment.typeParameters = typeParameters;
fragment.constructors = <ConstructorElementImpl>[
_constructor(),
];
unit.encloseElement(element);
return element;
unit.encloseElement(fragment);
return fragment;
}

ConstructorElementImpl _constructor({
Expand Down
18 changes: 18 additions & 0 deletions pkg/analyzer/lib/src/utilities/extensions/element.dart
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,12 @@ extension EnumElementExtension on EnumElement {
}
}

extension EnumElementImplExtension on EnumElementImpl {
EnumElementImpl2 get asElement2 {
return element;
}
}

extension ExecutableElement2Extension on ExecutableElement2 {
ExecutableElement get asElement {
if (this case ExecutableMember member) {
Expand Down Expand Up @@ -380,6 +386,18 @@ extension InterfaceElementExtension on InterfaceElement {
}
}

extension InterfaceElementImpl2Extension on InterfaceElementImpl2 {
InterfaceElementImpl get asElement {
return firstFragment;
}
}

extension InterfaceElementImplExtension on InterfaceElementImpl {
InterfaceElementImpl2 get asElement2 {
return element;
}
}

extension LabelElement2Extension on LabelElement2 {
LabelElement get asElement {
return firstFragment as LabelElement;
Expand Down

0 comments on commit eafaa11

Please sign in to comment.