| // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| // 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. |
| |
| import 'package:analyzer/dart/analysis/session.dart'; |
| import 'package:analyzer/dart/constant/value.dart'; |
| 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/source/source.dart'; |
| import 'package:analyzer/src/dart/element/display_string_builder.dart'; |
| import 'package:analyzer/src/dart/element/element.dart'; |
| import 'package:analyzer/src/dart/element/type.dart'; |
| import 'package:analyzer/src/dart/element/type_algebra.dart'; |
| import 'package:analyzer/src/generated/engine.dart' show AnalysisContext; |
| import 'package:analyzer/src/generated/utilities_dart.dart'; |
| import 'package:analyzer/src/utilities/extensions/element.dart'; |
| import 'package:pub_semver/pub_semver.dart'; |
| |
| /// A constructor element defined in a parameterized type where the values of |
| /// the type parameters are known. |
| class ConstructorMember extends ExecutableMember |
| with |
| ConstructorElementMixin, |
| ConstructorElementMixin2 |
| implements |
| // ignore:deprecated_member_use_from_same_package,analyzer_use_new_elements |
| ConstructorElement, |
| ConstructorElement2 { |
| /// Initialize a newly created element to represent a constructor, based on |
| /// the [declaration], and applied [substitution]. |
| ConstructorMember({ |
| required ConstructorElementImpl super.declaration, |
| required super.substitution, |
| }) : super( |
| typeParameters: const <TypeParameterElementImpl>[], |
| ); |
| |
| @override |
| ConstructorElementImpl2 get baseElement => _element2; |
| |
| @override |
| ConstructorElementImpl get declaration => |
| _declaration as ConstructorElementImpl; |
| |
| @override |
| String get displayName => declaration.displayName; |
| |
| @override |
| InterfaceElementImpl2 get enclosingElement2 => _element2.enclosingElement2; |
| |
| @override |
| InterfaceElementImpl get enclosingElement3 => declaration.enclosingElement3; |
| |
| @override |
| ConstructorFragment get firstFragment => _element2.firstFragment; |
| |
| @override |
| List<ConstructorFragment> get fragments { |
| return [ |
| for (ConstructorFragment? fragment = firstFragment; |
| fragment != null; |
| fragment = fragment.nextFragment) |
| fragment, |
| ]; |
| } |
| |
| @override |
| bool get isConst => declaration.isConst; |
| |
| @override |
| bool get isConstantEvaluated => declaration.isConstantEvaluated; |
| |
| @override |
| bool get isFactory => declaration.isFactory; |
| |
| @override |
| LibraryElementImpl get library { |
| return _declaration.library!; |
| } |
| |
| @override |
| String? get lookupName => _element2.lookupName; |
| |
| @override |
| String get name => declaration.name; |
| |
| @override |
| String? get name3 => _element2.name3; |
| |
| @override |
| int? get nameEnd => declaration.nameEnd; |
| |
| @override |
| int? get periodOffset => declaration.periodOffset; |
| |
| @override |
| ConstructorElementMixin? get redirectedConstructor { |
| var element = declaration.redirectedConstructor; |
| return _redirect(element); |
| } |
| |
| @override |
| ConstructorElementMixin2? get redirectedConstructor2 { |
| return redirectedConstructor?.asElement2; |
| } |
| |
| @override |
| InterfaceTypeImpl get returnType { |
| var returnType = declaration.returnType; |
| return substitution.mapInterfaceType(returnType); |
| } |
| |
| @override |
| Source get source => _declaration.source!; |
| |
| @override |
| ConstructorElementMixin? get superConstructor { |
| var element = declaration.superConstructor; |
| return _redirect(element); |
| } |
| |
| @override |
| ConstructorElementMixin2? get superConstructor2 { |
| return superConstructor?.asElement2; |
| } |
| |
| @override |
| ConstructorElementImpl2 get _element2 => declaration.asElement2; |
| |
| @override |
| T? accept2<T>(ElementVisitor2<T> visitor) { |
| return visitor.visitConstructorElement(this); |
| } |
| |
| @override |
| void appendTo(ElementDisplayStringBuilder builder) { |
| builder.writeConstructorElement(this); |
| } |
| |
| ConstructorElementMixin? _redirect(ConstructorElementMixin? element) { |
| switch (element) { |
| case null: |
| return null; |
| case ConstructorElementImpl(): |
| return element; |
| case ConstructorMember(): |
| var memberMap = element.substitution.map; |
| var map = <TypeParameterElement2, DartType>{ |
| for (var MapEntry(:key, :value) in memberMap.entries) |
| key: substitution.substituteType(value), |
| }; |
| return ConstructorMember( |
| declaration: element.declaration, |
| substitution: Substitution.fromMap2(map), |
| ); |
| default: |
| throw UnimplementedError('(${element.runtimeType}) $element'); |
| } |
| } |
| |
| /// If the given [element]'s type is different when any type parameters |
| /// from the defining type's declaration are replaced with the actual type |
| /// arguments from the [definingType], create a constructor member |
| /// representing the given constructor. Return the member that was created, or |
| /// the original constructor if no member was created. |
| static ConstructorElementMixin from( |
| ConstructorElementImpl element, |
| InterfaceType definingType, |
| ) { |
| if (definingType.typeArguments.isEmpty) { |
| return element; |
| } |
| |
| return ConstructorMember( |
| declaration: element, |
| substitution: Substitution.fromInterfaceType(definingType), |
| ); |
| } |
| |
| /// If the given [element]'s type is different when any type parameters |
| /// from the defining type's declaration are replaced with the actual type |
| /// arguments from the [definingType], create a constructor member |
| /// representing the given constructor. Return the member that was created, or |
| /// the original constructor if no member was created. |
| static ConstructorElementMixin2 from2( |
| ConstructorElementImpl2 element, |
| InterfaceType definingType, |
| ) { |
| if (definingType.typeArguments.isEmpty) { |
| return element; |
| } |
| |
| return ConstructorMember( |
| declaration: element.asElement, |
| substitution: Substitution.fromInterfaceType(definingType), |
| ); |
| } |
| } |
| |
| /// An executable element defined in a parameterized type where the values of |
| /// the type parameters are known. |
| abstract class ExecutableMember extends Member |
| implements ExecutableElementOrMember, ExecutableElement2OrMember { |
| @override |
| final List<TypeParameterElementImpl> typeParameters; |
| |
| FunctionTypeImpl? _type; |
| |
| /// Initialize a newly created element to represent a callable element (like a |
| /// method or function or property), based on the [declaration], and applied |
| /// [substitution]. |
| /// |
| /// The [typeParameters] are fresh, and [substitution] is already applied to |
| /// their bounds. The [substitution] includes replacing [declaration] type |
| /// parameters with the provided fresh [typeParameters]. |
| ExecutableMember({ |
| required ExecutableElementImpl super.declaration, |
| required super.substitution, |
| required this.typeParameters, |
| }); |
| |
| @Deprecated('Use Element2 instead') |
| @override |
| List<Element> get children => parameters; |
| |
| @override |
| List<Element2> get children2 { |
| return [ |
| ...typeParameters2, |
| ...formalParameters, |
| ]; |
| } |
| |
| @override |
| ExecutableElementImpl get declaration => |
| _declaration as ExecutableElementImpl; |
| |
| @override |
| String get displayName => declaration.displayName; |
| |
| @override |
| Element2? get enclosingElement2 => _element2.enclosingElement2; |
| |
| @override |
| List<FormalParameterElementMixin> get formalParameters => |
| parameters.map((fragment) => fragment.asElement2).toList(); |
| |
| @override |
| List<ExecutableFragment> get fragments { |
| return [ |
| for (ExecutableFragment? fragment = firstFragment; |
| fragment != null; |
| fragment = fragment.nextFragment) |
| fragment, |
| ]; |
| } |
| |
| @override |
| bool get hasImplicitReturnType => declaration.hasImplicitReturnType; |
| |
| @override |
| bool get isAbstract => declaration.isAbstract; |
| |
| @override |
| bool get isAsynchronous => declaration.isAsynchronous; |
| |
| @override |
| bool get isAugmentation => declaration.isAugmentation; |
| |
| @override |
| bool get isExtensionTypeMember => declaration.isExtensionTypeMember; |
| |
| @override |
| bool get isExternal => declaration.isExternal; |
| |
| @override |
| bool get isGenerator => declaration.isGenerator; |
| |
| @override |
| bool get isOperator => declaration.isOperator; |
| |
| @override |
| bool get isSimplyBounded => declaration.isSimplyBounded; |
| |
| @override |
| bool get isStatic => declaration.isStatic; |
| |
| @override |
| bool get isSynchronous => declaration.isSynchronous; |
| |
| @Deprecated('Use ExecutableElement2 instead') |
| @override |
| LibraryElement get library => _declaration.library!; |
| |
| @override |
| LibraryElement2 get library2 => _element2.library2; |
| |
| @override |
| Source get librarySource => _declaration.librarySource!; |
| |
| @override |
| int get nameOffset => declaration.nameOffset; |
| |
| @override |
| Element2 get nonSynthetic2 => _element2; |
| |
| @override |
| List<ParameterElementMixin> get parameters { |
| return declaration.parameters.map<ParameterElementMixin>((element) { |
| switch (element) { |
| case FieldFormalParameterElementImpl(): |
| return FieldFormalParameterMember( |
| declaration: element, |
| substitution: substitution, |
| ); |
| case SuperFormalParameterElementImpl(): |
| return SuperFormalParameterMember( |
| declaration: element, |
| substitution: substitution, |
| ); |
| default: |
| return ParameterMember( |
| declaration: element, |
| substitution: substitution, |
| ); |
| } |
| }).toList(); |
| } |
| |
| @override |
| TypeImpl get returnType { |
| var result = declaration.returnType; |
| result = substitution.substituteType(result); |
| return result; |
| } |
| |
| @override |
| FunctionTypeImpl get type { |
| return _type ??= substitution.mapFunctionType(declaration.type); |
| } |
| |
| @override |
| List<TypeParameterElementImpl2> get typeParameters2 => |
| typeParameters.map((fragment) => fragment.asElement2).toList(); |
| |
| @override |
| ExecutableElement2 get _element2 => declaration.asElement2; |
| |
| @override |
| void appendTo(ElementDisplayStringBuilder builder) { |
| builder.writeExecutableElement(this, displayName); |
| } |
| |
| @override |
| String displayString2({ |
| bool multiline = false, |
| bool preferTypeAlias = false, |
| }) { |
| var builder = ElementDisplayStringBuilder( |
| multiline: multiline, |
| preferTypeAlias: preferTypeAlias, |
| ); |
| appendTo(builder); |
| return builder.toString(); |
| } |
| |
| @override |
| bool isAccessibleIn2(LibraryElement2 library) => |
| _element2.isAccessibleIn2(library); |
| |
| @override |
| Element2? thisOrAncestorMatching2(bool Function(Element2 p1) predicate) => |
| _element2.thisOrAncestorMatching2(predicate); |
| |
| @override |
| E? thisOrAncestorOfType2<E extends Element2>() => |
| _element2.thisOrAncestorOfType2(); |
| |
| @override |
| void visitChildren2<T>(ElementVisitor2<T> visitor) { |
| for (var child in children2) { |
| child.accept2(visitor); |
| } |
| } |
| |
| static ExecutableElement2OrMember from( |
| ExecutableElement2 element, |
| MapSubstitution substitution, |
| ) { |
| return from2(element.asElement, substitution).asElement2; |
| } |
| |
| static ExecutableElementOrMember from2( |
| ExecutableElementOrMember element, |
| MapSubstitution substitution, |
| ) { |
| if (identical(substitution, Substitution.empty)) { |
| return element; |
| } |
| |
| ExecutableElementImpl declaration; |
| var combined = substitution; |
| if (element is ExecutableMember) { |
| declaration = element.declaration; |
| |
| var map = <TypeParameterElement2, DartType>{ |
| for (var MapEntry(:key, :value) in element.substitution.map.entries) |
| key: substitution.substituteType(value), |
| }; |
| combined = Substitution.fromMap2(map); |
| } else { |
| declaration = element as ExecutableElementImpl; |
| if (!declaration.hasEnclosingTypeParameterReference) { |
| return declaration; |
| } |
| } |
| |
| switch (declaration) { |
| case ConstructorElementImpl(): |
| return ConstructorMember( |
| declaration: declaration, |
| substitution: combined, |
| ); |
| case MethodElementImpl(): |
| return MethodMember( |
| declaration: declaration, |
| substitution: combined, |
| ); |
| case PropertyAccessorElementImpl(): |
| return PropertyAccessorMember( |
| declaration: declaration, |
| substitution: combined, |
| ); |
| default: |
| throw UnimplementedError('(${declaration.runtimeType}) $element'); |
| } |
| } |
| } |
| |
| /// A parameter element defined in a parameterized type where the values of the |
| /// type parameters are known. |
| class FieldFormalParameterMember extends ParameterMember |
| implements FieldFormalParameterElementOrMember { |
| factory FieldFormalParameterMember({ |
| required FieldFormalParameterElementImpl declaration, |
| required MapSubstitution substitution, |
| }) { |
| var freshTypeParameters = _SubstitutedTypeParameters( |
| declaration.typeParameters, |
| substitution, |
| ); |
| return FieldFormalParameterMember._( |
| declaration: declaration, |
| substitution: freshTypeParameters.substitution, |
| typeParameters: freshTypeParameters.elements, |
| ); |
| } |
| |
| FieldFormalParameterMember._({ |
| required FieldFormalParameterElementImpl super.declaration, |
| required super.substitution, |
| required super.typeParameters, |
| }) : super._(); |
| |
| @override |
| FieldFormalParameterElementImpl get declaration { |
| return _declaration as FieldFormalParameterElementImpl; |
| } |
| |
| @override |
| FieldElementOrMember? get field { |
| var field = declaration.field; |
| if (field == null) { |
| return null; |
| } |
| |
| return FieldMember( |
| declaration: field, |
| substitution: substitution, |
| ); |
| } |
| |
| @override |
| bool get hasDefaultValue => declaration.hasDefaultValue; |
| |
| @override |
| bool get isCovariant => declaration.isCovariant; |
| } |
| |
| /// A field element defined in a parameterized type where the values of the type |
| /// parameters are known. |
| class FieldMember extends VariableMember |
| implements FieldElementOrMember, FieldElement2OrMember { |
| /// Initialize a newly created element to represent a field, based on the |
| /// [declaration], with applied [substitution]. |
| FieldMember({ |
| required FieldElementImpl super.declaration, |
| required super.substitution, |
| }); |
| |
| @override |
| FieldElement2 get baseElement => _element2; |
| |
| @override |
| List<Element2> get children2 => const []; |
| |
| @override |
| ConstantInitializer? get constantInitializer2 { |
| return baseElement.constantInitializer2; |
| } |
| |
| @override |
| FieldElementImpl get declaration => _declaration as FieldElementImpl; |
| |
| @override |
| String get displayName => declaration.displayName; |
| |
| @override |
| InstanceElement2 get enclosingElement2 => _element2.enclosingElement2; |
| |
| @Deprecated('Use Element2.enclosingElement2 instead or ' |
| 'Fragment.enclosingFragment instead') |
| @override |
| Element get enclosingElement3 => declaration.enclosingElement3; |
| |
| @override |
| FieldFragment get firstFragment => _element2.firstFragment; |
| |
| @override |
| List<FieldFragment> get fragments { |
| return [ |
| for (FieldFragment? fragment = firstFragment; |
| fragment != null; |
| fragment = fragment.nextFragment) |
| fragment, |
| ]; |
| } |
| |
| @override |
| PropertyAccessorElementOrMember? get getter { |
| var baseGetter = declaration.getter; |
| if (baseGetter == null) { |
| return null; |
| } |
| return PropertyAccessorMember( |
| declaration: baseGetter, |
| substitution: substitution, |
| ); |
| } |
| |
| @override |
| GetterElement2OrMember? get getter2 { |
| var baseGetter = declaration.getter; |
| if (baseGetter == null) { |
| return null; |
| } |
| return GetterMember._( |
| declaration: baseGetter, |
| substitution: substitution, |
| typeParameters: baseGetter.typeParameters, |
| ); |
| } |
| |
| @override |
| bool get hasInitializer => declaration.hasInitializer; |
| |
| @override |
| bool get isAbstract => declaration.isAbstract; |
| |
| @override |
| bool get isAugmentation => declaration.isAugmentation; |
| |
| @override |
| bool get isCovariant => declaration.isCovariant; |
| |
| @override |
| bool get isEnumConstant => declaration.isEnumConstant; |
| |
| @override |
| bool get isExternal => declaration.isExternal; |
| |
| @override |
| bool get isPromotable => declaration.isPromotable; |
| |
| @Deprecated('Use FieldElement2 instead') |
| @override |
| LibraryElement get library => _declaration.library!; |
| |
| @override |
| LibraryElement2 get library2 => _element2.library2; |
| |
| @override |
| String? get lookupName => _element2.lookupName; |
| |
| @override |
| String get name => declaration.name; |
| |
| @override |
| String? get name3 => _element2.name3; |
| |
| @override |
| Element2 get nonSynthetic2 => _element2.nonSynthetic2; |
| |
| @override |
| PropertyAccessorElementOrMember? get setter { |
| var baseSetter = declaration.setter; |
| if (baseSetter == null) { |
| return null; |
| } |
| return PropertyAccessorMember( |
| declaration: baseSetter, |
| substitution: substitution, |
| ); |
| } |
| |
| @override |
| SetterElement2OrMember? get setter2 { |
| var baseSetter = declaration.setter; |
| if (baseSetter == null) { |
| return null; |
| } |
| return SetterMember._( |
| declaration: baseSetter, |
| substitution: substitution, |
| typeParameters: baseSetter.typeParameters, |
| ); |
| } |
| |
| @override |
| Source? get source => _declaration.source; |
| |
| @override |
| FieldElement2 get _element2 => declaration.asElement2; |
| |
| @override |
| T? accept2<T>(ElementVisitor2<T> visitor) { |
| return visitor.visitFieldElement(this); |
| } |
| |
| @override |
| String displayString2( |
| {bool multiline = false, bool preferTypeAlias = false}) { |
| return _element2.displayString2( |
| multiline: multiline, preferTypeAlias: preferTypeAlias); |
| } |
| |
| @override |
| bool isAccessibleIn2(LibraryElement2 library) { |
| return _element2.isAccessibleIn2(library); |
| } |
| |
| @override |
| Element2? thisOrAncestorMatching2(bool Function(Element2 e) predicate) { |
| return _element2.thisOrAncestorMatching2(predicate); |
| } |
| |
| @override |
| E? thisOrAncestorOfType2<E extends Element2>() { |
| return _element2.thisOrAncestorOfType2<E>(); |
| } |
| |
| @override |
| void visitChildren2<T>(ElementVisitor2<T> visitor) {} |
| |
| /// If the given [element]'s type is different when any type parameters from the |
| /// defining type's declaration are replaced with the actual type arguments |
| /// from the [definingType], create a field member representing the given |
| /// field. Return the member that was created, or the base field if no member |
| /// was created. |
| static FieldElementOrMember from( |
| FieldElementImpl element, |
| InterfaceType definingType, |
| ) { |
| if (definingType.typeArguments.isEmpty) { |
| return element; |
| } |
| return FieldMember( |
| declaration: element, |
| substitution: Substitution.fromInterfaceType(definingType), |
| ); |
| } |
| |
| static FieldElementOrMember from2( |
| FieldElementImpl element, |
| MapSubstitution substitution, |
| ) { |
| if (substitution.map.isEmpty) { |
| return element; |
| } |
| return FieldMember( |
| declaration: element, |
| substitution: substitution, |
| ); |
| } |
| } |
| |
| /// A getter element defined in a parameterized type where the values of the |
| /// type parameters are known. |
| class GetterMember extends PropertyAccessorMember |
| implements GetterElement2OrMember { |
| GetterMember._({ |
| required super.declaration, |
| required super.substitution, |
| required super.typeParameters, |
| }) : super._(); |
| |
| @override |
| GetterElementImpl get baseElement => _element2; |
| |
| @override |
| SetterElement2OrMember? get correspondingSetter2 { |
| var setter = correspondingSetter; |
| if (setter is SetterMember) { |
| return setter; |
| } |
| return setter.asElement2 as SetterElementImpl?; |
| } |
| |
| @override |
| GetterFragment get firstFragment => _element2.firstFragment; |
| |
| @override |
| List<GetterFragment> get fragments { |
| return [ |
| for (GetterFragment? fragment = firstFragment; |
| fragment != null; |
| fragment = fragment.nextFragment) |
| fragment, |
| ]; |
| } |
| |
| @override |
| String? get lookupName => _element2.lookupName; |
| |
| @override |
| Element2 get nonSynthetic2 { |
| if (!isSynthetic) { |
| return this; |
| } else if (variable3 case var variable?) { |
| return variable.nonSynthetic2; |
| } |
| throw StateError('Synthetic getter has no variable'); |
| } |
| |
| @override |
| PropertyInducingElement2OrMember? get variable3 => |
| variable2.asElement2 as PropertyInducingElement2OrMember?; |
| |
| @override |
| GetterElementImpl get _element2 { |
| return declaration.asElement2 as GetterElementImpl; |
| } |
| |
| @override |
| T? accept2<T>(ElementVisitor2<T> visitor) { |
| return visitor.visitGetterElement(this); |
| } |
| |
| static GetterElement2OrMember from( |
| GetterElementImpl element, |
| InterfaceType definingType, |
| ) { |
| if (definingType.typeArguments.isEmpty) { |
| return element; |
| } |
| |
| return GetterMember._( |
| declaration: element.asElement, |
| substitution: Substitution.fromInterfaceType(definingType), |
| typeParameters: const [], |
| ); |
| } |
| } |
| |
| /// An element defined in a parameterized type where the values of the type |
| /// parameters are known. |
| abstract class Member |
| implements |
| // ignore:deprecated_member_use_from_same_package,analyzer_use_new_elements |
| Element, |
| ElementOrMember { |
| /// The element on which the parameterized element was created. |
| final ElementImpl _declaration; |
| |
| /// The substitution for type parameters referenced in the base element. |
| final MapSubstitution substitution; |
| |
| /// Initialize a newly created element to represent a member, based on the |
| /// [declaration], and applied [substitution]. |
| Member({ |
| required ElementImpl declaration, |
| required this.substitution, |
| }) : _declaration = declaration { |
| if (_declaration is Member) { |
| throw StateError('Members must be created from a declaration, but is ' |
| '(${_declaration.runtimeType}) "$_declaration".'); |
| } |
| } |
| |
| Element2 get baseElement; |
| |
| @Deprecated('Use Element2 instead') |
| @override |
| List<Element> get children => const []; |
| |
| @override |
| AnalysisContext get context => _declaration.context; |
| |
| @override |
| ElementImpl get declaration => _declaration; |
| |
| @override |
| String get displayName => _declaration.displayName; |
| |
| @override |
| String? get documentationComment => _declaration.documentationComment; |
| |
| @Deprecated('Use Element2.enclosingElement2 instead or ' |
| 'Fragment.enclosingFragment instead') |
| @override |
| Element? get enclosingElement3 => _declaration.enclosingElement3; |
| |
| @override |
| bool get hasAlwaysThrows => _declaration.hasAlwaysThrows; |
| |
| @override |
| bool get hasDeprecated => _declaration.hasDeprecated; |
| |
| @override |
| bool get hasDoNotStore => _declaration.hasDoNotStore; |
| |
| @override |
| bool get hasDoNotSubmit => _declaration.hasDoNotSubmit; |
| |
| @override |
| bool get hasFactory => _declaration.hasFactory; |
| |
| @override |
| bool get hasImmutable => _declaration.hasImmutable; |
| |
| @override |
| bool get hasInternal => _declaration.hasInternal; |
| |
| @override |
| bool get hasIsTest => _declaration.hasIsTest; |
| |
| @override |
| bool get hasIsTestGroup => _declaration.hasIsTestGroup; |
| |
| @override |
| bool get hasJS => _declaration.hasJS; |
| |
| @override |
| bool get hasLiteral => _declaration.hasLiteral; |
| |
| @override |
| bool get hasMustBeConst => _declaration.hasMustBeConst; |
| |
| @override |
| bool get hasMustBeOverridden => _declaration.hasMustBeOverridden; |
| |
| @override |
| bool get hasMustCallSuper => _declaration.hasMustCallSuper; |
| |
| @override |
| bool get hasNonVirtual => _declaration.hasNonVirtual; |
| |
| @override |
| bool get hasOptionalTypeArgs => _declaration.hasOptionalTypeArgs; |
| |
| @override |
| bool get hasOverride => _declaration.hasOverride; |
| |
| @override |
| bool get hasProtected => _declaration.hasProtected; |
| |
| @override |
| bool get hasRedeclare => _declaration.hasRedeclare; |
| |
| @override |
| bool get hasReopen => _declaration.hasReopen; |
| |
| @override |
| bool get hasRequired => _declaration.hasRequired; |
| |
| @override |
| bool get hasSealed => _declaration.hasSealed; |
| |
| @override |
| bool get hasUseResult => _declaration.hasUseResult; |
| |
| @override |
| bool get hasVisibleForOverriding => _declaration.hasVisibleForOverriding; |
| |
| @override |
| bool get hasVisibleForTemplate => _declaration.hasVisibleForTemplate; |
| |
| @override |
| bool get hasVisibleForTesting => _declaration.hasVisibleForTesting; |
| |
| @override |
| bool get hasVisibleOutsideTemplate => _declaration.hasVisibleOutsideTemplate; |
| |
| @override |
| int get id => _declaration.id; |
| |
| @override |
| bool get isPrivate => _declaration.isPrivate; |
| |
| @override |
| bool get isPublic => _declaration.isPublic; |
| |
| @override |
| bool get isSynthetic => _declaration.isSynthetic; |
| |
| @override |
| ElementKind get kind => _declaration.kind; |
| |
| @Deprecated('Use Element2 instead') |
| @override |
| LibraryElement? get library => _declaration.library; |
| |
| @override |
| Source? get librarySource => _declaration.librarySource; |
| |
| @override |
| ElementLocation get location => _declaration.location; |
| |
| @override |
| List<ElementAnnotation> get metadata => _declaration.metadata; |
| |
| MetadataImpl get metadata2 => declaration.metadata2; |
| |
| @override |
| String? get name => _declaration.name; |
| |
| @override |
| int get nameLength => _declaration.nameLength; |
| |
| @override |
| int get nameOffset => _declaration.nameOffset; |
| |
| @Deprecated('Use Element2.nonSynthetic instead') |
| @override |
| Element get nonSynthetic => _declaration.nonSynthetic; |
| |
| @override |
| AnalysisSession? get session => _declaration.session; |
| |
| @override |
| Version? get sinceSdkVersion => _declaration.sinceSdkVersion; |
| |
| Element2 get _element2; |
| |
| /// Append a textual representation of this element to the given [builder]. |
| void appendTo(ElementDisplayStringBuilder builder); |
| |
| @override |
| String getDisplayString({ |
| @Deprecated('Only non-nullable by default mode is supported') |
| bool withNullability = true, |
| bool multiline = false, |
| bool preferTypeAlias = false, |
| }) { |
| var builder = ElementDisplayStringBuilder( |
| multiline: multiline, |
| preferTypeAlias: preferTypeAlias, |
| ); |
| appendTo(builder); |
| return builder.toString(); |
| } |
| |
| @override |
| String getExtendedDisplayName(String? shortName) => |
| _declaration.getExtendedDisplayName(shortName); |
| |
| String getExtendedDisplayName2({String? shortName}) { |
| return _element2.getExtendedDisplayName2( |
| shortName: shortName, |
| ); |
| } |
| |
| @Deprecated('Use Element2 instead') |
| @override |
| bool isAccessibleIn(LibraryElement library) => |
| _declaration.isAccessibleIn(library); |
| |
| @Deprecated('Use Element2.thisOrAncestorMatching2() instead') |
| @override |
| E? thisOrAncestorMatching<E extends Element>( |
| bool Function(Element) predicate, |
| ) { |
| return declaration.thisOrAncestorMatching(predicate); |
| } |
| |
| @Deprecated('Use Element2.thisOrAncestorMatching2() instead') |
| @override |
| E? thisOrAncestorMatching3<E extends Element>( |
| bool Function(Element) predicate, |
| ) { |
| return declaration.thisOrAncestorMatching3(predicate); |
| } |
| |
| @Deprecated('Use Element2.thisOrAncestorOfType2() instead') |
| @override |
| E? thisOrAncestorOfType<E extends Element>() => |
| declaration.thisOrAncestorOfType<E>(); |
| |
| @Deprecated('Use Element2.thisOrAncestorOfType2() instead') |
| @override |
| E? thisOrAncestorOfType3<E extends Element>() => |
| declaration.thisOrAncestorOfType3<E>(); |
| |
| @override |
| String toString() { |
| return getDisplayString(); |
| } |
| } |
| |
| /// A method element defined in a parameterized type where the values of the |
| /// type parameters are known. |
| class MethodMember extends ExecutableMember |
| implements MethodElementOrMember, MethodElement2OrMember { |
| factory MethodMember({ |
| required MethodElementImpl declaration, |
| required MapSubstitution substitution, |
| }) { |
| var freshTypeParameters = _SubstitutedTypeParameters( |
| declaration.typeParameters, |
| substitution, |
| ); |
| return MethodMember._( |
| declaration: declaration, |
| substitution: freshTypeParameters.substitution, |
| typeParameters: freshTypeParameters.elements, |
| ); |
| } |
| |
| MethodMember._({ |
| required MethodElementImpl super.declaration, |
| required super.substitution, |
| required super.typeParameters, |
| }); |
| |
| @override |
| MethodElementImpl2 get baseElement => _element2; |
| |
| @override |
| MethodElementImpl get declaration => _declaration as MethodElementImpl; |
| |
| @Deprecated('Use Element2.enclosingElement2 instead or ' |
| 'Fragment.enclosingFragment instead') |
| @override |
| Element get enclosingElement3 => declaration.enclosingElement3; |
| |
| @override |
| MethodFragment get firstFragment => _element2.firstFragment; |
| |
| @override |
| List<MethodFragment> get fragments { |
| return [ |
| for (MethodFragment? fragment = firstFragment; |
| fragment != null; |
| fragment = fragment.nextFragment) |
| fragment, |
| ]; |
| } |
| |
| @override |
| LibraryElement2 get library2 => _element2.library2; |
| |
| @override |
| String? get lookupName => name3; |
| |
| @override |
| String get name => declaration.name; |
| |
| @override |
| String? get name3 => _element2.name3; |
| |
| @override |
| Source get source => _declaration.source!; |
| |
| @override |
| MethodElementImpl2 get _element2 => declaration.asElement2; |
| |
| @override |
| T? accept2<T>(ElementVisitor2<T> visitor) { |
| return visitor.visitMethodElement(this); |
| } |
| |
| /// If [definingType] has type parameters, returns [MethodMember] with |
| /// type substitutions. Otherwise returns [element] as is. |
| static MethodElement2OrMember from2( |
| MethodElementImpl2 element, |
| InterfaceType definingType, |
| ) { |
| if (definingType.typeArguments.isEmpty) { |
| return element; |
| } |
| |
| return MethodMember( |
| declaration: element.asElement, |
| substitution: Substitution.fromInterfaceType(definingType), |
| ); |
| } |
| } |
| |
| /// A parameter element defined in a parameterized type where the values of the |
| /// type parameters are known. |
| class ParameterMember extends VariableMember |
| with |
| ParameterElementMixin, |
| FormalParameterElementMixin |
| implements |
| // ignore:deprecated_member_use_from_same_package,analyzer_use_new_elements |
| ParameterElement { |
| @override |
| final List<TypeParameterElementImpl> typeParameters; |
| |
| factory ParameterMember({ |
| required ParameterElementImpl declaration, |
| required MapSubstitution substitution, |
| }) { |
| var freshTypeParameters = _SubstitutedTypeParameters( |
| declaration.typeParameters, |
| substitution, |
| ); |
| return ParameterMember._( |
| declaration: declaration, |
| substitution: freshTypeParameters.substitution, |
| typeParameters: freshTypeParameters.elements, |
| ); |
| } |
| |
| /// Initialize a newly created element to represent a parameter, based on the |
| /// [declaration], with applied [substitution]. |
| ParameterMember._({ |
| required ParameterElementImpl super.declaration, |
| required super.substitution, |
| required this.typeParameters, |
| }); |
| |
| @override |
| FormalParameterElement get baseElement => _element2; |
| |
| @Deprecated('Use Element2 instead') |
| @override |
| List<Element> get children => parameters; |
| |
| @override |
| List<Element2> get children2 { |
| return [ |
| ...typeParameters2, |
| ...formalParameters, |
| ]; |
| } |
| |
| @override |
| ConstantInitializer? get constantInitializer2 { |
| return baseElement.constantInitializer2; |
| } |
| |
| @override |
| ParameterElementImpl get declaration => _declaration as ParameterElementImpl; |
| |
| @override |
| String? get defaultValueCode => declaration.defaultValueCode; |
| |
| @override |
| FormalParameterElementImpl get element => declaration.element; |
| |
| @override |
| Element2? get enclosingElement2 => _element2.enclosingElement2; |
| |
| @Deprecated('Use Element2.enclosingElement2 instead or ' |
| 'Fragment.enclosingFragment instead') |
| @override |
| Element? get enclosingElement3 => declaration.enclosingElement3; |
| |
| @override |
| FormalParameterFragment get firstFragment => _element2.firstFragment; |
| |
| @override |
| List<FormalParameterElementImpl> get formalParameters => |
| _element2.formalParameters; |
| |
| @override |
| List<FormalParameterFragment> get fragments { |
| return [ |
| for (FormalParameterFragment? fragment = firstFragment; |
| fragment != null; |
| fragment = fragment.nextFragment) |
| fragment, |
| ]; |
| } |
| |
| @override |
| bool get hasDefaultValue => declaration.hasDefaultValue; |
| |
| @override |
| bool get isCovariant => declaration.isCovariant; |
| |
| @override |
| bool get isInitializingFormal => declaration.isInitializingFormal; |
| |
| @override |
| bool get isSuperFormal => declaration.isSuperFormal; |
| |
| @override |
| LibraryElement2? get library2 => _element2.library2; |
| |
| @override |
| String? get lookupName => _element2.lookupName; |
| |
| @override |
| String get name => declaration.name; |
| |
| @override |
| String? get name3 => _element2.name3; |
| |
| @override |
| String get nameShared => name; |
| |
| @override |
| Element2 get nonSynthetic2 => _element2; |
| |
| @deprecated |
| @override |
| ParameterKind get parameterKind { |
| return declaration.parameterKind; |
| } |
| |
| @override |
| List<ParameterElementMixin> get parameters { |
| var type = this.type; |
| if (type is FunctionTypeImpl) { |
| return type.parameters; |
| } |
| return const <ParameterElementMixin>[]; |
| } |
| |
| @override |
| Source? get source => _declaration.source; |
| |
| @override |
| List<TypeParameterElement2> get typeParameters2 => _element2.typeParameters2; |
| |
| @override |
| TypeImpl get typeShared => type; |
| |
| @override |
| FormalParameterElementImpl get _element2 => declaration.asElement2; |
| |
| @override |
| T? accept2<T>(ElementVisitor2<T> visitor) { |
| return visitor.visitFormalParameterElement(this); |
| } |
| |
| @override |
| void appendTo(ElementDisplayStringBuilder builder) { |
| builder.writeFormalParameter(this); |
| } |
| |
| @override |
| String displayString2( |
| {bool multiline = false, bool preferTypeAlias = false}) { |
| return _element2.displayString2( |
| multiline: multiline, preferTypeAlias: preferTypeAlias); |
| } |
| |
| @override |
| bool isAccessibleIn2(LibraryElement2 library) => |
| _element2.isAccessibleIn2(library); |
| |
| @override |
| Element2? thisOrAncestorMatching2(bool Function(Element2 p1) predicate) { |
| return _element2.thisOrAncestorMatching2(predicate); |
| } |
| |
| @override |
| E? thisOrAncestorOfType2<E extends Element2>() { |
| return _element2.thisOrAncestorOfType2(); |
| } |
| |
| @override |
| void visitChildren2<T>(ElementVisitor2<T> visitor) { |
| _element2.visitChildren2(visitor); |
| } |
| |
| static ParameterElementMixin from( |
| ParameterElementMixin element, MapSubstitution substitution) { |
| ParameterElementImpl declaration; |
| var combined = substitution; |
| if (element is ParameterMember) { |
| var member = element; |
| declaration = member.declaration; |
| |
| var map = <TypeParameterElement2, DartType>{ |
| for (var MapEntry(:key, :value) in member.substitution.map.entries) |
| key: substitution.substituteType(value), |
| }; |
| combined = Substitution.fromMap2(map); |
| } else { |
| declaration = element as ParameterElementImpl; |
| } |
| |
| if (combined.map.isEmpty) { |
| return element; |
| } |
| |
| return ParameterMember( |
| declaration: declaration, |
| substitution: combined, |
| ); |
| } |
| } |
| |
| /// A property accessor element defined in a parameterized type where the values |
| /// of the type parameters are known. |
| abstract class PropertyAccessorMember extends ExecutableMember |
| implements |
| PropertyAccessorElementOrMember, |
| PropertyAccessorElement2OrMember { |
| factory PropertyAccessorMember({ |
| required PropertyAccessorElementImpl declaration, |
| required MapSubstitution substitution, |
| }) { |
| var freshTypeParameters = _SubstitutedTypeParameters( |
| declaration.typeParameters, |
| substitution, |
| ); |
| if (declaration.isGetter) { |
| return GetterMember._( |
| declaration: declaration, |
| substitution: freshTypeParameters.substitution, |
| typeParameters: freshTypeParameters.elements, |
| ); |
| } else { |
| return SetterMember._( |
| declaration: declaration, |
| substitution: freshTypeParameters.substitution, |
| typeParameters: freshTypeParameters.elements, |
| ); |
| } |
| } |
| |
| PropertyAccessorMember._({ |
| required PropertyAccessorElementImpl super.declaration, |
| required super.substitution, |
| required super.typeParameters, |
| }); |
| |
| @override |
| PropertyAccessorElementOrMember? get correspondingGetter { |
| var baseGetter = declaration.correspondingGetter; |
| if (baseGetter == null) { |
| return null; |
| } |
| return PropertyAccessorMember( |
| declaration: baseGetter, |
| substitution: substitution, |
| ); |
| } |
| |
| @override |
| PropertyAccessorElementOrMember? get correspondingSetter { |
| var baseSetter = declaration.correspondingSetter; |
| if (baseSetter == null) { |
| return null; |
| } |
| return PropertyAccessorMember( |
| declaration: baseSetter, |
| substitution: substitution, |
| ); |
| } |
| |
| @override |
| PropertyAccessorElementImpl get declaration => |
| _declaration as PropertyAccessorElementImpl; |
| |
| @override |
| Element2 get enclosingElement2 { |
| return super.enclosingElement2!; |
| } |
| |
| @Deprecated('Use Element2.enclosingElement2 instead or ' |
| 'Fragment.enclosingFragment instead') |
| @override |
| Element get enclosingElement3 => declaration.enclosingElement3; |
| |
| @override |
| bool get isGetter => declaration.isGetter; |
| |
| @override |
| bool get isSetter => declaration.isSetter; |
| |
| @override |
| String get name => declaration.name; |
| |
| @override |
| String? get name3 => _element2.name3; |
| |
| @override |
| Source get source => _declaration.source!; |
| |
| @override |
| PropertyInducingElementOrMember? get variable2 { |
| var variable = declaration.variable2; |
| switch (variable) { |
| case FieldElementImpl(): |
| return FieldMember( |
| declaration: variable, |
| substitution: substitution, |
| ); |
| default: |
| return variable; |
| } |
| } |
| |
| @override |
| void appendTo(ElementDisplayStringBuilder builder) { |
| builder.writeExecutableElement( |
| this, |
| (isGetter ? 'get ' : 'set ') + displayName, |
| ); |
| } |
| |
| /// If the given [element]'s type is different when any type parameters from |
| /// the defining type's declaration are replaced with the actual type |
| /// arguments from the [definingType], create an accessor member representing |
| /// the given accessor. Return the member that was created, or the base |
| /// accessor if no member was created. |
| static PropertyAccessorElementOrMember? from( |
| PropertyAccessorElementImpl? element, |
| InterfaceType definingType, |
| ) { |
| if (element == null || definingType.typeArguments.isEmpty) { |
| return element; |
| } |
| |
| return PropertyAccessorMember( |
| declaration: element, |
| substitution: Substitution.fromInterfaceType(definingType), |
| ); |
| } |
| } |
| |
| /// A setter element defined in a parameterized type where the values of the |
| /// type parameters are known. |
| class SetterMember extends PropertyAccessorMember |
| implements SetterElement2OrMember { |
| SetterMember._({ |
| required super.declaration, |
| required super.substitution, |
| required super.typeParameters, |
| }) : super._(); |
| |
| @override |
| SetterElementImpl get baseElement => _element2; |
| |
| @override |
| GetterElement2OrMember? get correspondingGetter2 { |
| var getter = correspondingGetter; |
| if (getter is GetterMember) { |
| return getter; |
| } |
| return getter.asElement2 as GetterElementImpl?; |
| } |
| |
| @override |
| SetterFragment get firstFragment => _element2.firstFragment; |
| |
| @override |
| List<SetterFragment> get fragments { |
| return [ |
| for (SetterFragment? fragment = firstFragment; |
| fragment != null; |
| fragment = fragment.nextFragment) |
| fragment, |
| ]; |
| } |
| |
| @override |
| String? get lookupName => _element2.lookupName; |
| |
| @override |
| Element2 get nonSynthetic2 { |
| if (!isSynthetic) { |
| return this; |
| } else if (variable3 case var variable?) { |
| return variable.nonSynthetic2; |
| } |
| throw StateError('Synthetic setter has no variable'); |
| } |
| |
| @override |
| PropertyInducingElement2OrMember? get variable3 => |
| variable2.asElement2 as PropertyInducingElement2OrMember?; |
| |
| @override |
| SetterElementImpl get _element2 { |
| return declaration.asElement2 as SetterElementImpl; |
| } |
| |
| @override |
| T? accept2<T>(ElementVisitor2<T> visitor) { |
| return visitor.visitSetterElement(this); |
| } |
| |
| static SetterElement2OrMember from( |
| SetterElementImpl element, |
| InterfaceType definingType, |
| ) { |
| if (definingType.typeArguments.isEmpty) { |
| return element; |
| } |
| |
| return SetterMember._( |
| declaration: element.asElement, |
| substitution: Substitution.fromInterfaceType(definingType), |
| typeParameters: const [], |
| ); |
| } |
| } |
| |
| class SuperFormalParameterMember extends ParameterMember |
| implements SuperFormalParameterElementOrMember { |
| factory SuperFormalParameterMember({ |
| required SuperFormalParameterElementImpl declaration, |
| required MapSubstitution substitution, |
| }) { |
| var freshTypeParameters = _SubstitutedTypeParameters( |
| declaration.typeParameters, |
| substitution, |
| ); |
| return SuperFormalParameterMember._( |
| declaration: declaration, |
| substitution: freshTypeParameters.substitution, |
| typeParameters: freshTypeParameters.elements, |
| ); |
| } |
| |
| SuperFormalParameterMember._({ |
| required SuperFormalParameterElementImpl super.declaration, |
| required super.substitution, |
| required super.typeParameters, |
| }) : super._(); |
| |
| @override |
| SuperFormalParameterElementImpl get declaration { |
| return _declaration as SuperFormalParameterElementImpl; |
| } |
| |
| @override |
| bool get hasDefaultValue => declaration.hasDefaultValue; |
| |
| @override |
| bool get isCovariant => declaration.isCovariant; |
| |
| @override |
| ParameterElementMixin? get superConstructorParameter { |
| var superConstructorParameter = declaration.superConstructorParameter; |
| if (superConstructorParameter == null) { |
| return null; |
| } |
| |
| return ParameterMember.from(superConstructorParameter, substitution); |
| } |
| |
| FormalParameterElement? get superConstructorParameter2 => |
| superConstructorParameter?.asElement2; |
| } |
| |
| /// A variable element defined in a parameterized type where the values of the |
| /// type parameters are known. |
| abstract class VariableMember extends Member |
| implements VariableElementOrMember { |
| TypeImpl? _type; |
| |
| /// Initialize a newly created element to represent a variable, based on the |
| /// [declaration], with applied [substitution]. |
| VariableMember({ |
| required VariableElementImpl super.declaration, |
| required super.substitution, |
| }); |
| |
| @override |
| VariableElementImpl get declaration => _declaration as VariableElementImpl; |
| |
| @override |
| bool get hasImplicitType => declaration.hasImplicitType; |
| |
| @override |
| bool get isConst => declaration.isConst; |
| |
| @override |
| bool get isConstantEvaluated => declaration.isConstantEvaluated; |
| |
| @override |
| bool get isFinal => declaration.isFinal; |
| |
| @override |
| bool get isLate => declaration.isLate; |
| |
| @override |
| bool get isStatic => declaration.isStatic; |
| |
| @override |
| TypeImpl get type { |
| if (_type != null) return _type!; |
| |
| var result = declaration.type; |
| result = substitution.substituteType(result); |
| return _type = result; |
| } |
| |
| @override |
| void appendTo(ElementDisplayStringBuilder builder) { |
| builder.writeVariableElement(this); |
| } |
| |
| @override |
| DartObject? computeConstantValue() => declaration.computeConstantValue(); |
| } |
| |
| class _SubstitutedTypeParameters { |
| final List<TypeParameterElementImpl> elements; |
| final MapSubstitution substitution; |
| |
| factory _SubstitutedTypeParameters( |
| List<TypeParameterElementImpl> elements, |
| MapSubstitution substitution, |
| ) { |
| if (elements.isEmpty) { |
| return _SubstitutedTypeParameters._(const [], substitution); |
| } |
| |
| // Create type formals with specialized bounds. |
| // For example `<U extends T>` where T comes from an outer scope. |
| var newElements = <TypeParameterElementImpl>[]; |
| var newTypes = <TypeParameterType>[]; |
| for (int i = 0; i < elements.length; i++) { |
| var element = elements[i]; |
| var newElement = TypeParameterElementImpl.synthetic(element.name); |
| newElements.add(newElement); |
| newTypes.add( |
| newElement.instantiate( |
| nullabilitySuffix: NullabilitySuffix.none, |
| ), |
| ); |
| } |
| |
| // Update bounds to reference new TypeParameterElement(s). |
| var substitution2 = Substitution.fromPairs(elements, newTypes); |
| for (int i = 0; i < newElements.length; i++) { |
| var element = elements[i]; |
| var newElement = newElements[i]; |
| var bound = element.bound; |
| if (bound != null) { |
| var newBound = substitution2.substituteType(bound); |
| newBound = substitution.substituteType(newBound); |
| newElement.bound = newBound; |
| } |
| } |
| |
| if (substitution.map.isEmpty) { |
| return _SubstitutedTypeParameters._(newElements, substitution2); |
| } |
| |
| return _SubstitutedTypeParameters._( |
| newElements, |
| Substitution.fromMap2({ |
| ...substitution.map, |
| ...substitution2.map, |
| }), |
| ); |
| } |
| |
| _SubstitutedTypeParameters._(this.elements, this.substitution); |
| } |