From eafaa1173823e238eff5c9508a2e326da604ab7b Mon Sep 17 00:00:00 2001 From: Konstantin Shcheglov Date: Tue, 14 Jan 2025 10:27:18 -0800 Subject: [PATCH] Elements. Store InterfaceElementImpl2 in InterfaceTypeImpl. Change-Id: Id7cf5dd51abb331c851b0244e9be0f0db15b73ee Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/404380 Commit-Queue: Konstantin Shcheglov Reviewed-by: Brian Wilkerson --- .../lib/src/dart/element/element.dart | 95 ++++++------- pkg/analyzer/lib/src/dart/element/type.dart | 127 +++++++++--------- .../src/test_utilities/mock_sdk_elements.dart | 13 +- .../lib/src/utilities/extensions/element.dart | 18 +++ 4 files changed, 135 insertions(+), 118 deletions(-) diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart index bc58040214cc..0f3c27a5b5cf 100644 --- a/pkg/analyzer/lib/src/dart/element/element.dart +++ b/pkg/analyzer/lib/src/dart/element/element.dart @@ -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 _constructors = _Sentinel.constructorElement; /// Initialize a newly created class element to have the given [name] at the @@ -6275,43 +6267,10 @@ abstract class InterfaceElementImpl extends InstanceElementImpl required List 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 @@ -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 interfaces = []; @@ -6633,12 +6600,48 @@ abstract class InterfaceElementImpl2 extends InstanceElementImpl2 } @override - InterfaceType instantiate({ + InterfaceTypeImpl instantiate({ required List 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( diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart index 043b454c82ca..bd50bec8803a 100644 --- a/pkg/analyzer/lib/src/dart/element/type.dart +++ b/pkg/analyzer/lib/src/dart/element/type.dart @@ -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; @@ -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, @@ -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 typeArguments; @@ -587,30 +587,20 @@ class InterfaceTypeImpl extends TypeImpl implements InterfaceType { /// Cached [MethodElement]s - members or raw elements. List? _methods; - factory InterfaceTypeImpl( - {required InterfaceElement element, - required List typeArguments, - required NullabilitySuffix nullabilitySuffix, - InstantiatedTypeAliasElement? alias}) { + factory InterfaceTypeImpl({ + required InterfaceElement element, + required List 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({ @@ -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); } @@ -708,7 +700,7 @@ class InterfaceTypeImpl extends TypeImpl implements InterfaceType { .toList(); @override - InterfaceElementImpl2 get element3 => element.element; + InterfaceElementImpl get element => element3.asElement; @override List get getters => accessors @@ -1341,7 +1333,10 @@ class NeverTypeImpl extends TypeImpl implements NeverType { /// no type parameters and no nullability suffix. class NullTypeImpl extends InterfaceTypeImpl implements SharedNullTypeStructure { - NullTypeImpl({required super.element, super.alias}) : super._null(); + NullTypeImpl({ + required super.element3, + super.alias, + }) : super._null(); @override bool get isDartCoreNull => true; diff --git a/pkg/analyzer/lib/src/test_utilities/mock_sdk_elements.dart b/pkg/analyzer/lib/src/test_utilities/mock_sdk_elements.dart index 951041f944e8..0e90aac6a889 100644 --- a/pkg/analyzer/lib/src/test_utilities/mock_sdk_elements.dart +++ b/pkg/analyzer/lib/src/test_utilities/mock_sdk_elements.dart @@ -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; @@ -979,13 +979,14 @@ class _MockSdkElementsBuilder { List typeParameters = const [], required CompilationUnitElementImpl unit, }) { - var element = ClassElementImpl(name, 0); - element.typeParameters = typeParameters; - element.constructors = [ + var fragment = ClassElementImpl(name, 0); + ClassElementImpl2(Reference.root(), fragment); + fragment.typeParameters = typeParameters; + fragment.constructors = [ _constructor(), ]; - unit.encloseElement(element); - return element; + unit.encloseElement(fragment); + return fragment; } ConstructorElementImpl _constructor({ diff --git a/pkg/analyzer/lib/src/utilities/extensions/element.dart b/pkg/analyzer/lib/src/utilities/extensions/element.dart index f79211b10d64..916d5571e5b5 100644 --- a/pkg/analyzer/lib/src/utilities/extensions/element.dart +++ b/pkg/analyzer/lib/src/utilities/extensions/element.dart @@ -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) { @@ -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;