| Index: pkg/analyzer/lib/src/dart/element/element.dart
|
| diff --git a/pkg/analyzer/lib/src/generated/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
|
| similarity index 54%
|
| copy from pkg/analyzer/lib/src/generated/element.dart
|
| copy to pkg/analyzer/lib/src/dart/element/element.dart
|
| index 52696341c49a199abe31da980e2abaffad07ac28..24d566ad0add79072b9afd512e186259b8ccd848 100644
|
| --- a/pkg/analyzer/lib/src/generated/element.dart
|
| +++ b/pkg/analyzer/lib/src/dart/element/element.dart
|
| @@ -2,7 +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.
|
|
|
| -library analyzer.src.generated.element;
|
| +library analyzer.src.dart.element.element;
|
|
|
| import 'dart:collection';
|
| import 'dart:math' show min;
|
| @@ -10,6 +10,7 @@ import 'dart:math' show min;
|
| import 'package:analyzer/dart/element/element.dart';
|
| import 'package:analyzer/dart/element/type.dart';
|
| import 'package:analyzer/dart/element/visitor.dart';
|
| +import 'package:analyzer/src/dart/element/type.dart';
|
| import 'package:analyzer/src/generated/ast.dart';
|
| import 'package:analyzer/src/generated/constant.dart'
|
| show DartObject, EvaluationResultImpl;
|
| @@ -25,10 +26,6 @@ import 'package:analyzer/src/generated/utilities_collection.dart';
|
| import 'package:analyzer/src/generated/utilities_dart.dart';
|
| import 'package:analyzer/src/generated/utilities_general.dart';
|
|
|
| -export 'package:analyzer/dart/element/element.dart';
|
| -export 'package:analyzer/dart/element/type.dart';
|
| -export 'package:analyzer/dart/element/visitor.dart';
|
| -
|
| /**
|
| * For AST nodes that could be in both the getter and setter contexts
|
| * ([IndexExpression]s and [SimpleIdentifier]s), the additional resolved
|
| @@ -58,78 +55,6 @@ class AuxiliaryElements {
|
| }
|
|
|
| /**
|
| - * A [Type] that represents the type 'bottom'.
|
| - */
|
| -class BottomTypeImpl extends TypeImpl {
|
| - /**
|
| - * The unique instance of this class.
|
| - */
|
| - static BottomTypeImpl _INSTANCE = new BottomTypeImpl._();
|
| -
|
| - /**
|
| - * Return the unique instance of this class.
|
| - */
|
| - static BottomTypeImpl get instance => _INSTANCE;
|
| -
|
| - /**
|
| - * Prevent the creation of instances of this class.
|
| - */
|
| - BottomTypeImpl._() : super(null, "<bottom>");
|
| -
|
| - @override
|
| - int get hashCode => 0;
|
| -
|
| - @override
|
| - bool get isBottom => true;
|
| -
|
| - @override
|
| - bool operator ==(Object object) => identical(object, this);
|
| -
|
| - @override
|
| - bool isMoreSpecificThan(DartType type,
|
| - [bool withDynamic = false, Set<Element> visitedElements]) =>
|
| - true;
|
| -
|
| - @override
|
| - bool isSubtypeOf(DartType type) => true;
|
| -
|
| - @override
|
| - bool isSupertypeOf(DartType type) => false;
|
| -
|
| - @override
|
| - TypeImpl pruned(List<FunctionTypeAliasElement> prune) => this;
|
| -
|
| - @override
|
| - BottomTypeImpl substitute2(
|
| - List<DartType> argumentTypes, List<DartType> parameterTypes,
|
| - [List<FunctionTypeAliasElement> prune]) =>
|
| - this;
|
| -}
|
| -
|
| -/**
|
| - * Type created internally if a circular reference is ever detected. Behaves
|
| - * like `dynamic`, except that when converted to a string it is displayed as
|
| - * `...`.
|
| - */
|
| -class CircularTypeImpl extends DynamicTypeImpl {
|
| - CircularTypeImpl() : super._circular();
|
| -
|
| - @override
|
| - int get hashCode => 1;
|
| -
|
| - @override
|
| - bool operator ==(Object object) => object is CircularTypeImpl;
|
| -
|
| - @override
|
| - void appendTo(StringBuffer buffer) {
|
| - buffer.write('...');
|
| - }
|
| -
|
| - @override
|
| - TypeImpl pruned(List<FunctionTypeAliasElement> prune) => this;
|
| -}
|
| -
|
| -/**
|
| * A concrete implementation of a [ClassElement].
|
| */
|
| class ClassElementImpl extends ElementImpl implements ClassElement {
|
| @@ -1451,111 +1376,6 @@ class ConstructorElementImpl extends ExecutableElementImpl
|
| }
|
|
|
| /**
|
| - * A constructor element defined in a parameterized type where the values of the
|
| - * type parameters are known.
|
| - */
|
| -class ConstructorMember extends ExecutableMember implements ConstructorElement {
|
| - /**
|
| - * Initialize a newly created element to represent a constructor, based on the
|
| - * [baseElement], defined by the [definingType]. If [type] is passed, it
|
| - * represents the full type of the member, and will take precedence over
|
| - * the [definingType].
|
| - */
|
| - ConstructorMember(ConstructorElement baseElement, InterfaceType definingType,
|
| - [FunctionType type])
|
| - : super(baseElement, definingType, type);
|
| -
|
| - @override
|
| - ConstructorElement get baseElement => super.baseElement as ConstructorElement;
|
| -
|
| - @override
|
| - InterfaceType get definingType => super.definingType as InterfaceType;
|
| -
|
| - @override
|
| - ClassElement get enclosingElement => baseElement.enclosingElement;
|
| -
|
| - @override
|
| - bool get isConst => baseElement.isConst;
|
| -
|
| - @override
|
| - bool get isDefaultConstructor => baseElement.isDefaultConstructor;
|
| -
|
| - @override
|
| - bool get isFactory => baseElement.isFactory;
|
| -
|
| - @override
|
| - int get nameEnd => baseElement.nameEnd;
|
| -
|
| - @override
|
| - int get periodOffset => baseElement.periodOffset;
|
| -
|
| - @override
|
| - ConstructorElement get redirectedConstructor =>
|
| - from(baseElement.redirectedConstructor, definingType);
|
| -
|
| - @override
|
| - accept(ElementVisitor visitor) => visitor.visitConstructorElement(this);
|
| -
|
| - @override
|
| - ConstructorDeclaration computeNode() => baseElement.computeNode();
|
| -
|
| - @override
|
| - String toString() {
|
| - ConstructorElement baseElement = this.baseElement;
|
| - List<ParameterElement> parameters = this.parameters;
|
| - FunctionType type = this.type;
|
| - StringBuffer buffer = new StringBuffer();
|
| - buffer.write(baseElement.enclosingElement.displayName);
|
| - String name = displayName;
|
| - if (name != null && !name.isEmpty) {
|
| - buffer.write(".");
|
| - buffer.write(name);
|
| - }
|
| - buffer.write("(");
|
| - int parameterCount = parameters.length;
|
| - for (int i = 0; i < parameterCount; i++) {
|
| - if (i > 0) {
|
| - buffer.write(", ");
|
| - }
|
| - buffer.write(parameters[i]);
|
| - }
|
| - buffer.write(")");
|
| - if (type != null) {
|
| - buffer.write(ElementImpl.RIGHT_ARROW);
|
| - buffer.write(type.returnType);
|
| - }
|
| - return buffer.toString();
|
| - }
|
| -
|
| - /**
|
| - * If the given [constructor]'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 ConstructorElement from(
|
| - ConstructorElement constructor, InterfaceType definingType) {
|
| - if (constructor == null || definingType.typeArguments.length == 0) {
|
| - return constructor;
|
| - }
|
| - FunctionType baseType = constructor.type;
|
| - if (baseType == null) {
|
| - // TODO(brianwilkerson) We need to understand when this can happen.
|
| - return constructor;
|
| - }
|
| - List<DartType> argumentTypes = definingType.typeArguments;
|
| - List<DartType> parameterTypes = definingType.element.type.typeArguments;
|
| - FunctionType substitutedType =
|
| - baseType.substitute2(argumentTypes, parameterTypes);
|
| - if (baseType == substitutedType) {
|
| - return constructor;
|
| - }
|
| - return new ConstructorMember(constructor, definingType, substitutedType);
|
| - }
|
| -}
|
| -
|
| -/**
|
| * A [TopLevelVariableElement] for a top-level 'const' variable that has an
|
| * initializer.
|
| */
|
| @@ -1697,77 +1517,6 @@ class DynamicElementImpl extends ElementImpl implements TypeDefiningElement {
|
| }
|
|
|
| /**
|
| - * The [Type] representing the type `dynamic`.
|
| - */
|
| -class DynamicTypeImpl extends TypeImpl {
|
| - /**
|
| - * The unique instance of this class.
|
| - */
|
| - static DynamicTypeImpl _INSTANCE = new DynamicTypeImpl._();
|
| -
|
| - /**
|
| - * Return the unique instance of this class.
|
| - */
|
| - static DynamicTypeImpl get instance => _INSTANCE;
|
| -
|
| - /**
|
| - * Prevent the creation of instances of this class.
|
| - */
|
| - DynamicTypeImpl._()
|
| - : super(new DynamicElementImpl(), Keyword.DYNAMIC.syntax) {
|
| - (element as DynamicElementImpl).type = this;
|
| - }
|
| -
|
| - /**
|
| - * Constructor used by [CircularTypeImpl].
|
| - */
|
| - DynamicTypeImpl._circular()
|
| - : super(_INSTANCE.element, Keyword.DYNAMIC.syntax);
|
| -
|
| - @override
|
| - int get hashCode => 1;
|
| -
|
| - @override
|
| - bool get isDynamic => true;
|
| -
|
| - @override
|
| - bool operator ==(Object object) => identical(object, this);
|
| -
|
| - @override
|
| - bool isMoreSpecificThan(DartType type,
|
| - [bool withDynamic = false, Set<Element> visitedElements]) {
|
| - // T is S
|
| - if (identical(this, type)) {
|
| - return true;
|
| - }
|
| - // else
|
| - return withDynamic;
|
| - }
|
| -
|
| - @override
|
| - bool isSubtypeOf(DartType type) => true;
|
| -
|
| - @override
|
| - bool isSupertypeOf(DartType type) => true;
|
| -
|
| - @override
|
| - TypeImpl pruned(List<FunctionTypeAliasElement> prune) => this;
|
| -
|
| - @override
|
| - DartType substitute2(
|
| - List<DartType> argumentTypes, List<DartType> parameterTypes,
|
| - [List<FunctionTypeAliasElement> prune]) {
|
| - int length = parameterTypes.length;
|
| - for (int i = 0; i < length; i++) {
|
| - if (parameterTypes[i] == this) {
|
| - return argumentTypes[i];
|
| - }
|
| - }
|
| - return this;
|
| - }
|
| -}
|
| -
|
| -/**
|
| * A concrete implementation of an [ElementAnnotation].
|
| */
|
| class ElementAnnotationImpl implements ElementAnnotation {
|
| @@ -2650,98 +2399,6 @@ abstract class ExecutableElementImpl extends ElementImpl
|
| }
|
|
|
| /**
|
| - * An executable element defined in a parameterized type where the values of the
|
| - * type parameters are known.
|
| - */
|
| -abstract class ExecutableMember extends Member implements ExecutableElement {
|
| - @override
|
| - final FunctionType type;
|
| -
|
| - /**
|
| - * Initialize a newly created element to represent a callable element (like a
|
| - * method or function or property), based on the [baseElement], defined by the
|
| - * [definingType]. If [type] is passed, it represents the full type of the
|
| - * member, and will take precedence over the [definingType].
|
| - */
|
| - ExecutableMember(ExecutableElement baseElement, InterfaceType definingType,
|
| - [FunctionType type])
|
| - : type = type ??
|
| - baseElement.type.substitute2(definingType.typeArguments,
|
| - TypeParameterTypeImpl.getTypes(definingType.typeParameters)),
|
| - super(baseElement, definingType);
|
| -
|
| - @override
|
| - ExecutableElement get baseElement => super.baseElement as ExecutableElement;
|
| -
|
| - @override
|
| - List<FunctionElement> get functions {
|
| - //
|
| - // Elements within this element should have type parameters substituted,
|
| - // just like this element.
|
| - //
|
| - throw new UnsupportedOperationException();
|
| -// return getBaseElement().getFunctions();
|
| - }
|
| -
|
| - @override
|
| - bool get hasImplicitReturnType => baseElement.hasImplicitReturnType;
|
| -
|
| - @override
|
| - bool get isAbstract => baseElement.isAbstract;
|
| -
|
| - @override
|
| - bool get isAsynchronous => baseElement.isAsynchronous;
|
| -
|
| - @override
|
| - bool get isExternal => baseElement.isExternal;
|
| -
|
| - @override
|
| - bool get isGenerator => baseElement.isGenerator;
|
| -
|
| - @override
|
| - bool get isOperator => baseElement.isOperator;
|
| -
|
| - @override
|
| - bool get isStatic => baseElement.isStatic;
|
| -
|
| - @override
|
| - bool get isSynchronous => baseElement.isSynchronous;
|
| -
|
| - @override
|
| - List<LabelElement> get labels => baseElement.labels;
|
| -
|
| - @override
|
| - List<LocalVariableElement> get localVariables {
|
| - //
|
| - // Elements within this element should have type parameters substituted,
|
| - // just like this element.
|
| - //
|
| - throw new UnsupportedOperationException();
|
| -// return getBaseElement().getLocalVariables();
|
| - }
|
| -
|
| - @override
|
| - List<ParameterElement> get parameters => type.parameters;
|
| -
|
| - @override
|
| - DartType get returnType => type.returnType;
|
| -
|
| - @override
|
| - List<TypeParameterElement> get typeParameters => baseElement.typeParameters;
|
| -
|
| - @override
|
| - void visitChildren(ElementVisitor visitor) {
|
| - // TODO(brianwilkerson) We need to finish implementing the accessors used
|
| - // below so that we can safely invoke them.
|
| - super.visitChildren(visitor);
|
| - safelyVisitChildren(baseElement.functions, visitor);
|
| - safelyVisitChildren(labels, visitor);
|
| - safelyVisitChildren(baseElement.localVariables, visitor);
|
| - safelyVisitChildren(parameters, visitor);
|
| - }
|
| -}
|
| -
|
| -/**
|
| * A concrete implementation of an [ExportElement].
|
| */
|
| class ExportElementImpl extends UriReferencedElementImpl
|
| @@ -2849,129 +2506,6 @@ class FieldFormalParameterElementImpl extends ParameterElementImpl
|
| }
|
|
|
| /**
|
| - * A parameter element defined in a parameterized type where the values of the
|
| - * type parameters are known.
|
| - */
|
| -class FieldFormalParameterMember extends ParameterMember
|
| - implements FieldFormalParameterElement {
|
| - /**
|
| - * Initialize a newly created element to represent a field formal parameter,
|
| - * based on the [baseElement], defined by the [definingType]. If [type]
|
| - * is passed it will be used as the substituted type for this member.
|
| - */
|
| - FieldFormalParameterMember(
|
| - FieldFormalParameterElement baseElement, ParameterizedType definingType,
|
| - [DartType type])
|
| - : super(baseElement, definingType, type);
|
| -
|
| - @override
|
| - FieldElement get field {
|
| - FieldElement field = (baseElement as FieldFormalParameterElement).field;
|
| - if (field is FieldElement) {
|
| - return FieldMember.from(
|
| - field, substituteFor(field.enclosingElement.type));
|
| - }
|
| - return field;
|
| - }
|
| -
|
| - @override
|
| - accept(ElementVisitor visitor) =>
|
| - visitor.visitFieldFormalParameterElement(this);
|
| -}
|
| -
|
| -/**
|
| - * A field element defined in a parameterized type where the values of the type
|
| - * parameters are known.
|
| - */
|
| -class FieldMember extends VariableMember implements FieldElement {
|
| - /**
|
| - * Initialize a newly created element to represent a field, based on the
|
| - * [baseElement], defined by the [definingType].
|
| - */
|
| - FieldMember(FieldElement baseElement, InterfaceType definingType)
|
| - : super(baseElement, definingType);
|
| -
|
| - @override
|
| - FieldElement get baseElement => super.baseElement as FieldElement;
|
| -
|
| - @override
|
| - ClassElement get enclosingElement => baseElement.enclosingElement;
|
| -
|
| - @override
|
| - PropertyAccessorElement get getter =>
|
| - PropertyAccessorMember.from(baseElement.getter, definingType);
|
| -
|
| - @override
|
| - bool get isEnumConstant => baseElement.isEnumConstant;
|
| -
|
| - @override
|
| - DartType get propagatedType => substituteFor(baseElement.propagatedType);
|
| -
|
| - @override
|
| - PropertyAccessorElement get setter =>
|
| - PropertyAccessorMember.from(baseElement.setter, definingType);
|
| -
|
| - @override
|
| - accept(ElementVisitor visitor) => visitor.visitFieldElement(this);
|
| -
|
| - @override
|
| - VariableDeclaration computeNode() => baseElement.computeNode();
|
| -
|
| - @override
|
| - String toString() => '$type $displayName';
|
| -
|
| - /**
|
| - * If the given [field]'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 FieldElement from(FieldElement field, ParameterizedType definingType) {
|
| - if (!_isChangedByTypeSubstitution(field, definingType)) {
|
| - return field;
|
| - }
|
| - // TODO(brianwilkerson) Consider caching the substituted type in the
|
| - // instance. It would use more memory but speed up some operations.
|
| - // We need to see how often the type is being re-computed.
|
| - return new FieldMember(field, definingType);
|
| - }
|
| -
|
| - /**
|
| - * Determine whether the given [field]'s type is changed when type parameters
|
| - * from the [definingType]'s declaration are replaced with the actual type
|
| - * arguments from the defining type.
|
| - */
|
| - static bool _isChangedByTypeSubstitution(
|
| - FieldElement field, ParameterizedType definingType) {
|
| - List<DartType> argumentTypes = definingType.typeArguments;
|
| - if (field != null && argumentTypes.length != 0) {
|
| - DartType baseType = field.type;
|
| - List<DartType> parameterTypes =
|
| - TypeParameterTypeImpl.getTypes(definingType.typeParameters);
|
| - if (baseType != null) {
|
| - DartType substitutedType =
|
| - baseType.substitute2(argumentTypes, parameterTypes);
|
| - if (baseType != substitutedType) {
|
| - return true;
|
| - }
|
| - }
|
| - // If the field has a propagated type, then we need to check whether the
|
| - // propagated type needs substitution.
|
| - DartType basePropagatedType = field.propagatedType;
|
| - if (basePropagatedType != null) {
|
| - DartType substitutedPropagatedType =
|
| - basePropagatedType.substitute2(argumentTypes, parameterTypes);
|
| - if (basePropagatedType != substitutedPropagatedType) {
|
| - return true;
|
| - }
|
| - }
|
| - }
|
| - return false;
|
| - }
|
| -}
|
| -
|
| -/**
|
| * A concrete implementation of a [FunctionElement].
|
| */
|
| class FunctionElementImpl extends ExecutableElementImpl
|
| @@ -3068,78 +2602,14 @@ class FunctionElementImpl extends ExecutableElementImpl
|
| }
|
|
|
| /**
|
| - * An element of a generic function, where the type parameters are known.
|
| + * A concrete implementation of a [FunctionTypeAliasElement].
|
| */
|
| -// TODO(jmesserly): the term "function member" is a bit weird, but it allows
|
| -// a certain consistency.
|
| -class FunctionMember extends ExecutableMember implements FunctionElement {
|
| +class FunctionTypeAliasElementImpl extends ElementImpl
|
| + implements FunctionTypeAliasElement {
|
| /**
|
| - * Initialize a newly created element to represent a function, based on the
|
| - * [baseElement], with the corresponding function [type].
|
| + * A list containing all of the parameters defined by this type alias.
|
| */
|
| - FunctionMember(FunctionElement baseElement, [DartType type])
|
| - : super(baseElement, null, type);
|
| -
|
| - @override
|
| - FunctionElement get baseElement => super.baseElement as FunctionElement;
|
| -
|
| - @override
|
| - Element get enclosingElement => baseElement.enclosingElement;
|
| -
|
| - @override
|
| - bool get isEntryPoint => baseElement.isEntryPoint;
|
| -
|
| - @override
|
| - SourceRange get visibleRange => baseElement.visibleRange;
|
| -
|
| - @override
|
| - accept(ElementVisitor visitor) => visitor.visitFunctionElement(this);
|
| -
|
| - @override
|
| - FunctionDeclaration computeNode() => baseElement.computeNode();
|
| -
|
| - @override
|
| - String toString() {
|
| - StringBuffer buffer = new StringBuffer();
|
| - buffer.write(baseElement.displayName);
|
| - (type as FunctionTypeImpl).appendTo(buffer);
|
| - return buffer.toString();
|
| - }
|
| -
|
| - /**
|
| - * If the given [method]'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 method member representing the given
|
| - * method. Return the member that was created, or the base method if no member
|
| - * was created.
|
| - */
|
| - static MethodElement from(
|
| - MethodElement method, ParameterizedType definingType) {
|
| - if (method == null || definingType.typeArguments.length == 0) {
|
| - return method;
|
| - }
|
| - FunctionType baseType = method.type;
|
| - List<DartType> argumentTypes = definingType.typeArguments;
|
| - List<DartType> parameterTypes =
|
| - TypeParameterTypeImpl.getTypes(definingType.typeParameters);
|
| - FunctionType substitutedType =
|
| - baseType.substitute2(argumentTypes, parameterTypes);
|
| - if (baseType == substitutedType) {
|
| - return method;
|
| - }
|
| - return new MethodMember(method, definingType, substitutedType);
|
| - }
|
| -}
|
| -
|
| -/**
|
| - * A concrete implementation of a [FunctionTypeAliasElement].
|
| - */
|
| -class FunctionTypeAliasElementImpl extends ElementImpl
|
| - implements FunctionTypeAliasElement {
|
| - /**
|
| - * A list containing all of the parameters defined by this type alias.
|
| - */
|
| - List<ParameterElement> _parameters = ParameterElement.EMPTY_LIST;
|
| + List<ParameterElement> _parameters = ParameterElement.EMPTY_LIST;
|
|
|
| /**
|
| * The return type defined by this type alias.
|
| @@ -3260,1900 +2730,106 @@ class FunctionTypeAliasElementImpl extends ElementImpl
|
| return typeParameter as TypeParameterElementImpl;
|
| }
|
| }
|
| - return null;
|
| - }
|
| -
|
| - @override
|
| - void visitChildren(ElementVisitor visitor) {
|
| - super.visitChildren(visitor);
|
| - safelyVisitChildren(_parameters, visitor);
|
| - safelyVisitChildren(_typeParameters, visitor);
|
| - }
|
| -}
|
| -
|
| -/**
|
| - * The type of a function, method, constructor, getter, or setter.
|
| - */
|
| -class FunctionTypeImpl extends TypeImpl implements FunctionType {
|
| - /**
|
| - * The list of [typeArguments].
|
| - */
|
| - List<DartType> _typeArguments;
|
| -
|
| - /**
|
| - * The list of [typeParameters].
|
| - */
|
| - List<TypeParameterElement> _typeParameters;
|
| -
|
| - /**
|
| - * The list of [boundTypeParameters].
|
| - */
|
| - List<TypeParameterElement> _boundTypeParameters;
|
| -
|
| - /**
|
| - * The set of typedefs which should not be expanded when exploring this type,
|
| - * to avoid creating infinite types in response to self-referential typedefs.
|
| - */
|
| - final List<FunctionTypeAliasElement> prunedTypedefs;
|
| -
|
| - /**
|
| - * Initialize a newly created function type to be declared by the given
|
| - * [element], and also initialize [typeArguments] to match the
|
| - * [typeParameters], which permits later substitution.
|
| - */
|
| - FunctionTypeImpl(ExecutableElement element,
|
| - [List<FunctionTypeAliasElement> prunedTypedefs])
|
| - : this._(element, null, prunedTypedefs, null, null, null);
|
| -
|
| - /**
|
| - * Initialize a newly created function type to be declared by the given
|
| - * [element].
|
| - */
|
| - FunctionTypeImpl.forTypedef(FunctionTypeAliasElement element,
|
| - [List<FunctionTypeAliasElement> prunedTypedefs])
|
| - : this._(element, element?.name, prunedTypedefs, null, null, null);
|
| -
|
| - /**
|
| - * Private constructor.
|
| - */
|
| - FunctionTypeImpl._(
|
| - TypeParameterizedElement element,
|
| - String name,
|
| - this.prunedTypedefs,
|
| - List<DartType> typeArguments,
|
| - List<TypeParameterElement> typeParameters,
|
| - List<TypeParameterElement> boundTypeParameters)
|
| - : super(element, name) {
|
| - _boundTypeParameters = boundTypeParameters ??
|
| - element?.typeParameters ??
|
| - TypeParameterElement.EMPTY_LIST;
|
| -
|
| - if (typeParameters == null) {
|
| - // Combine the generic type variables from all enclosing contexts, except
|
| - // for this generic function's type variables. Those variables are
|
| - // tracked in [boundTypeParameters].
|
| - typeParameters = <TypeParameterElement>[];
|
| - Element e = element?.enclosingElement;
|
| - while (e != null) {
|
| - if (e is TypeParameterizedElement) {
|
| - typeParameters.addAll((e as TypeParameterizedElement).typeParameters);
|
| - }
|
| - e = e.enclosingElement;
|
| - }
|
| - }
|
| - _typeParameters = typeParameters;
|
| -
|
| - if (typeArguments == null) {
|
| - // TODO(jmesserly): reuse TypeParameterTypeImpl.getTypes once we can
|
| - // make it generic, which will allow it to return List<DartType> instead
|
| - // of List<TypeParameterType>.
|
| - if (typeParameters.isEmpty) {
|
| - typeArguments = DartType.EMPTY_LIST;
|
| - } else {
|
| - typeArguments = new List<DartType>.from(
|
| - typeParameters.map((t) => t.type),
|
| - growable: false);
|
| - }
|
| - }
|
| - _typeArguments = typeArguments;
|
| - }
|
| -
|
| - /**
|
| - * Return the base parameter elements of this function element.
|
| - */
|
| - List<ParameterElement> get baseParameters => element.parameters;
|
| -
|
| - /**
|
| - * Return the return type defined by this function's element.
|
| - */
|
| - DartType get baseReturnType => element.returnType;
|
| -
|
| - @override
|
| - List<TypeParameterElement> get boundTypeParameters => _boundTypeParameters;
|
| -
|
| - @override
|
| - String get displayName {
|
| - String name = this.name;
|
| - if (name == null || name.length == 0) {
|
| - // Function types have an empty name when they are defined implicitly by
|
| - // either a closure or as part of a parameter declaration.
|
| - List<DartType> normalParameterTypes = this.normalParameterTypes;
|
| - List<DartType> optionalParameterTypes = this.optionalParameterTypes;
|
| - Map<String, DartType> namedParameterTypes = this.namedParameterTypes;
|
| - DartType returnType = this.returnType;
|
| - StringBuffer buffer = new StringBuffer();
|
| - buffer.write("(");
|
| - bool needsComma = false;
|
| - if (normalParameterTypes.length > 0) {
|
| - for (DartType type in normalParameterTypes) {
|
| - if (needsComma) {
|
| - buffer.write(", ");
|
| - } else {
|
| - needsComma = true;
|
| - }
|
| - buffer.write(type.displayName);
|
| - }
|
| - }
|
| - if (optionalParameterTypes.length > 0) {
|
| - if (needsComma) {
|
| - buffer.write(", ");
|
| - needsComma = false;
|
| - }
|
| - buffer.write("[");
|
| - for (DartType type in optionalParameterTypes) {
|
| - if (needsComma) {
|
| - buffer.write(", ");
|
| - } else {
|
| - needsComma = true;
|
| - }
|
| - buffer.write(type.displayName);
|
| - }
|
| - buffer.write("]");
|
| - needsComma = true;
|
| - }
|
| - if (namedParameterTypes.length > 0) {
|
| - if (needsComma) {
|
| - buffer.write(", ");
|
| - needsComma = false;
|
| - }
|
| - buffer.write("{");
|
| - namedParameterTypes.forEach((String name, DartType type) {
|
| - if (needsComma) {
|
| - buffer.write(", ");
|
| - } else {
|
| - needsComma = true;
|
| - }
|
| - buffer.write(name);
|
| - buffer.write(": ");
|
| - buffer.write(type.displayName);
|
| - });
|
| - buffer.write("}");
|
| - needsComma = true;
|
| - }
|
| - buffer.write(")");
|
| - buffer.write(ElementImpl.RIGHT_ARROW);
|
| - if (returnType == null) {
|
| - buffer.write("null");
|
| - } else {
|
| - buffer.write(returnType.displayName);
|
| - }
|
| - name = buffer.toString();
|
| - }
|
| - return name;
|
| - }
|
| -
|
| - @override
|
| - FunctionTypedElement get element => super.element;
|
| -
|
| - @override
|
| - int get hashCode {
|
| - if (element == null) {
|
| - return 0;
|
| - }
|
| - // Reference the arrays of parameters
|
| - List<DartType> normalParameterTypes = this.normalParameterTypes;
|
| - List<DartType> optionalParameterTypes = this.optionalParameterTypes;
|
| - Iterable<DartType> namedParameterTypes = this.namedParameterTypes.values;
|
| - // Generate the hashCode
|
| - int code = (returnType as TypeImpl).hashCode;
|
| - for (int i = 0; i < normalParameterTypes.length; i++) {
|
| - code = (code << 1) + (normalParameterTypes[i] as TypeImpl).hashCode;
|
| - }
|
| - for (int i = 0; i < optionalParameterTypes.length; i++) {
|
| - code = (code << 1) + (optionalParameterTypes[i] as TypeImpl).hashCode;
|
| - }
|
| - for (DartType type in namedParameterTypes) {
|
| - code = (code << 1) + (type as TypeImpl).hashCode;
|
| - }
|
| - return code;
|
| - }
|
| -
|
| - /**
|
| - * The type arguments that were used to instantiate this function type, if
|
| - * any, otherwise this will return an empty list.
|
| - *
|
| - * Given a function type `f`:
|
| - *
|
| - * f == f.originalFunction.instantiate(f.instantiatedTypeArguments)
|
| - *
|
| - * Will always hold.
|
| - */
|
| - List<DartType> get instantiatedTypeArguments {
|
| - int typeParameterCount = element.type.boundTypeParameters.length;
|
| - if (typeParameterCount == 0) {
|
| - return DartType.EMPTY_LIST;
|
| - }
|
| - // The substituted types at the end should be our bound type parameters.
|
| - int skipCount = typeArguments.length - typeParameterCount;
|
| - return new List<DartType>.from(typeArguments.skip(skipCount));
|
| - }
|
| -
|
| - @override
|
| - Map<String, DartType> get namedParameterTypes {
|
| - LinkedHashMap<String, DartType> namedParameterTypes =
|
| - new LinkedHashMap<String, DartType>();
|
| - List<ParameterElement> parameters = baseParameters;
|
| - if (parameters.length == 0) {
|
| - return namedParameterTypes;
|
| - }
|
| - List<DartType> typeParameters =
|
| - TypeParameterTypeImpl.getTypes(this.typeParameters);
|
| - for (ParameterElement parameter in parameters) {
|
| - if (parameter.parameterKind == ParameterKind.NAMED) {
|
| - DartType type = parameter.type;
|
| - if (typeArguments.length != 0 &&
|
| - typeArguments.length == typeParameters.length) {
|
| - type = (type as TypeImpl)
|
| - .substitute2(typeArguments, typeParameters, newPrune);
|
| - } else {
|
| - type = (type as TypeImpl).pruned(newPrune);
|
| - }
|
| - namedParameterTypes[parameter.name] = type;
|
| - }
|
| - }
|
| - return namedParameterTypes;
|
| - }
|
| -
|
| - /**
|
| - * Determine the new set of typedefs which should be pruned when expanding
|
| - * this function type.
|
| - */
|
| - List<FunctionTypeAliasElement> get newPrune {
|
| - Element element = this.element;
|
| - if (element is FunctionTypeAliasElement && !element.isSynthetic) {
|
| - // This typedef should be pruned, along with anything that was previously
|
| - // pruned.
|
| - if (prunedTypedefs == null) {
|
| - return <FunctionTypeAliasElement>[element];
|
| - } else {
|
| - return new List<FunctionTypeAliasElement>.from(prunedTypedefs)
|
| - ..add(element);
|
| - }
|
| - } else {
|
| - // This is not a typedef, so nothing additional needs to be pruned.
|
| - return prunedTypedefs;
|
| - }
|
| - }
|
| -
|
| - @override
|
| - List<DartType> get normalParameterTypes {
|
| - List<ParameterElement> parameters = baseParameters;
|
| - if (parameters.length == 0) {
|
| - return DartType.EMPTY_LIST;
|
| - }
|
| - List<DartType> typeParameters =
|
| - TypeParameterTypeImpl.getTypes(this.typeParameters);
|
| - List<DartType> types = new List<DartType>();
|
| - for (ParameterElement parameter in parameters) {
|
| - if (parameter.parameterKind == ParameterKind.REQUIRED) {
|
| - DartType type = parameter.type;
|
| - if (typeArguments.length != 0 &&
|
| - typeArguments.length == typeParameters.length) {
|
| - type = (type as TypeImpl)
|
| - .substitute2(typeArguments, typeParameters, newPrune);
|
| - } else {
|
| - type = (type as TypeImpl).pruned(newPrune);
|
| - }
|
| - types.add(type);
|
| - }
|
| - }
|
| - return types;
|
| - }
|
| -
|
| - @override
|
| - List<DartType> get optionalParameterTypes {
|
| - List<ParameterElement> parameters = baseParameters;
|
| - if (parameters.length == 0) {
|
| - return DartType.EMPTY_LIST;
|
| - }
|
| - List<DartType> typeParameters =
|
| - TypeParameterTypeImpl.getTypes(this.typeParameters);
|
| - List<DartType> types = new List<DartType>();
|
| - for (ParameterElement parameter in parameters) {
|
| - if (parameter.parameterKind == ParameterKind.POSITIONAL) {
|
| - DartType type = parameter.type;
|
| - if (typeArguments.length != 0 &&
|
| - typeArguments.length == typeParameters.length) {
|
| - type = (type as TypeImpl)
|
| - .substitute2(typeArguments, typeParameters, newPrune);
|
| - } else {
|
| - type = (type as TypeImpl).pruned(newPrune);
|
| - }
|
| - types.add(type);
|
| - }
|
| - }
|
| - return types;
|
| - }
|
| -
|
| - /**
|
| - * If this is an instantiation of a generic function type, this will get
|
| - * the original function from which it was instantiated.
|
| - *
|
| - * Otherwise, this will return `this`.
|
| - */
|
| - FunctionTypeImpl get originalFunction {
|
| - if (element.type.boundTypeParameters.isEmpty) {
|
| - return this;
|
| - }
|
| - return (element.type as FunctionTypeImpl).substitute2(typeArguments,
|
| - TypeParameterTypeImpl.getTypes(typeParameters), prunedTypedefs);
|
| - }
|
| -
|
| - @override
|
| - List<ParameterElement> get parameters {
|
| - List<ParameterElement> baseParameters = this.baseParameters;
|
| - // no parameters, quick return
|
| - int parameterCount = baseParameters.length;
|
| - if (parameterCount == 0) {
|
| - return baseParameters;
|
| - }
|
| - // create specialized parameters
|
| - List<ParameterElement> specializedParameters =
|
| - new List<ParameterElement>(parameterCount);
|
| - for (int i = 0; i < parameterCount; i++) {
|
| - specializedParameters[i] = ParameterMember.from(baseParameters[i], this);
|
| - }
|
| - return specializedParameters;
|
| - }
|
| -
|
| - @override
|
| - DartType get returnType {
|
| - DartType baseReturnType = this.baseReturnType;
|
| - if (baseReturnType == null) {
|
| - // TODO(brianwilkerson) This is a patch. The return type should never be
|
| - // null and we need to understand why it is and fix it.
|
| - return DynamicTypeImpl.instance;
|
| - }
|
| - // If there are no arguments to substitute, or if the arguments size doesn't
|
| - // match the parameter size, return the base return type.
|
| - if (typeArguments.length == 0 ||
|
| - typeArguments.length != typeParameters.length) {
|
| - return (baseReturnType as TypeImpl).pruned(newPrune);
|
| - }
|
| - return (baseReturnType as TypeImpl).substitute2(typeArguments,
|
| - TypeParameterTypeImpl.getTypes(typeParameters), newPrune);
|
| - }
|
| -
|
| - /**
|
| - * A list containing the actual types of the type arguments.
|
| - */
|
| - List<DartType> get typeArguments => _typeArguments;
|
| -
|
| - @override
|
| - List<TypeParameterElement> get typeParameters => _typeParameters;
|
| -
|
| - @override
|
| - bool operator ==(Object object) {
|
| - if (object is! FunctionTypeImpl) {
|
| - return false;
|
| - }
|
| - FunctionTypeImpl otherType = object as FunctionTypeImpl;
|
| - if (boundTypeParameters.length != otherType.boundTypeParameters.length) {
|
| - return false;
|
| - }
|
| - // `<T>T -> T` should be equal to `<U>U -> U`
|
| - // To test this, we instantiate both types with the same (unique) type
|
| - // variables, and see if the result is equal.
|
| - if (boundTypeParameters.isNotEmpty) {
|
| - List<DartType> instantiateTypeArgs = new List<DartType>();
|
| - List<DartType> variablesThis = new List<DartType>();
|
| - List<DartType> variablesOther = new List<DartType>();
|
| - for (int i = 0; i < boundTypeParameters.length; i++) {
|
| - TypeParameterElement pThis = boundTypeParameters[i];
|
| - TypeParameterElement pOther = otherType.boundTypeParameters[i];
|
| - TypeParameterTypeImpl pFresh = new TypeParameterTypeImpl(
|
| - new TypeParameterElementImpl(pThis.name, -1));
|
| - instantiateTypeArgs.add(pFresh);
|
| - variablesThis.add(pThis.type);
|
| - variablesOther.add(pOther.type);
|
| - // Check that the bounds are equal after equating the previous
|
| - // bound variables.
|
| - if (pThis.bound?.substitute2(instantiateTypeArgs, variablesThis) !=
|
| - pOther.bound?.substitute2(instantiateTypeArgs, variablesOther)) {
|
| - return false;
|
| - }
|
| - }
|
| - // After instantiation, they will no longer have boundTypeParameters,
|
| - // so we will continue below.
|
| - return this.instantiate(instantiateTypeArgs) ==
|
| - otherType.instantiate(instantiateTypeArgs);
|
| - }
|
| -
|
| - return returnType == otherType.returnType &&
|
| - TypeImpl.equalArrays(
|
| - normalParameterTypes, otherType.normalParameterTypes) &&
|
| - TypeImpl.equalArrays(
|
| - optionalParameterTypes, otherType.optionalParameterTypes) &&
|
| - _equals(namedParameterTypes, otherType.namedParameterTypes);
|
| - }
|
| -
|
| - @override
|
| - void appendTo(StringBuffer buffer) {
|
| - if (boundTypeParameters.isNotEmpty) {
|
| - // To print a type with type variables, first make sure we have unique
|
| - // variable names to print.
|
| - Set<TypeParameterType> freeVariables = new HashSet<TypeParameterType>();
|
| - _freeVariablesInFunctionType(this, freeVariables);
|
| -
|
| - Set<String> namesToAvoid = new HashSet<String>();
|
| - for (DartType arg in freeVariables) {
|
| - if (arg is TypeParameterType) {
|
| - namesToAvoid.add(arg.displayName);
|
| - }
|
| - }
|
| -
|
| - List<DartType> instantiateTypeArgs = new List<DartType>();
|
| - List<DartType> variables = new List<DartType>();
|
| - buffer.write("<");
|
| - for (TypeParameterElement e in boundTypeParameters) {
|
| - if (e != boundTypeParameters[0]) {
|
| - buffer.write(",");
|
| - }
|
| - String name = e.name;
|
| - int counter = 0;
|
| - while (!namesToAvoid.add(name)) {
|
| - // Unicode subscript-zero is U+2080, zero is U+0030. Other digits
|
| - // are sequential from there. Thus +0x2050 will get us the subscript.
|
| - String subscript = new String.fromCharCodes(
|
| - counter.toString().codeUnits.map((n) => n + 0x2050));
|
| -
|
| - name = e.name + subscript;
|
| - counter++;
|
| - }
|
| - TypeParameterTypeImpl t =
|
| - new TypeParameterTypeImpl(new TypeParameterElementImpl(name, -1));
|
| - t.appendTo(buffer);
|
| - instantiateTypeArgs.add(t);
|
| - variables.add(e.type);
|
| - if (e.bound != null) {
|
| - buffer.write(" extends ");
|
| - TypeImpl renamed =
|
| - e.bound.substitute2(instantiateTypeArgs, variables);
|
| - renamed.appendTo(buffer);
|
| - }
|
| - }
|
| - buffer.write(">");
|
| -
|
| - // Instantiate it and print the resulting type. After instantiation, it
|
| - // will no longer have boundTypeParameters, so we will continue below.
|
| - this.instantiate(instantiateTypeArgs).appendTo(buffer);
|
| - return;
|
| - }
|
| -
|
| - List<DartType> normalParameterTypes = this.normalParameterTypes;
|
| - List<DartType> optionalParameterTypes = this.optionalParameterTypes;
|
| - Map<String, DartType> namedParameterTypes = this.namedParameterTypes;
|
| - DartType returnType = this.returnType;
|
| - buffer.write("(");
|
| - bool needsComma = false;
|
| - if (normalParameterTypes.isNotEmpty) {
|
| - for (DartType type in normalParameterTypes) {
|
| - if (needsComma) {
|
| - buffer.write(", ");
|
| - } else {
|
| - needsComma = true;
|
| - }
|
| - (type as TypeImpl).appendTo(buffer);
|
| - }
|
| - }
|
| - if (optionalParameterTypes.isNotEmpty) {
|
| - if (needsComma) {
|
| - buffer.write(", ");
|
| - needsComma = false;
|
| - }
|
| - buffer.write("[");
|
| - for (DartType type in optionalParameterTypes) {
|
| - if (needsComma) {
|
| - buffer.write(", ");
|
| - } else {
|
| - needsComma = true;
|
| - }
|
| - (type as TypeImpl).appendTo(buffer);
|
| - }
|
| - buffer.write("]");
|
| - needsComma = true;
|
| - }
|
| - if (namedParameterTypes.isNotEmpty) {
|
| - if (needsComma) {
|
| - buffer.write(", ");
|
| - needsComma = false;
|
| - }
|
| - buffer.write("{");
|
| - namedParameterTypes.forEach((String name, DartType type) {
|
| - if (needsComma) {
|
| - buffer.write(", ");
|
| - } else {
|
| - needsComma = true;
|
| - }
|
| - buffer.write(name);
|
| - buffer.write(": ");
|
| - (type as TypeImpl).appendTo(buffer);
|
| - });
|
| - buffer.write("}");
|
| - needsComma = true;
|
| - }
|
| - buffer.write(")");
|
| - buffer.write(ElementImpl.RIGHT_ARROW);
|
| - if (returnType == null) {
|
| - buffer.write("null");
|
| - } else {
|
| - (returnType as TypeImpl).appendTo(buffer);
|
| - }
|
| - }
|
| -
|
| - @override
|
| - FunctionTypeImpl instantiate(List<DartType> argumentTypes) {
|
| - if (argumentTypes.length != boundTypeParameters.length) {
|
| - throw new IllegalArgumentException(
|
| - "argumentTypes.length (${argumentTypes.length}) != "
|
| - "boundTypeParameters.length (${boundTypeParameters.length})");
|
| - }
|
| - if (argumentTypes.isEmpty) {
|
| - return this;
|
| - }
|
| -
|
| - // Given:
|
| - // {U/T} <S> T -> S
|
| - // Where {U/T} represents the typeArguments (U) and typeParameters (T) list,
|
| - // and <S> represents the boundTypeParameters.
|
| - //
|
| - // Now instantiate([V]), and the result should be:
|
| - // {U/T, V/S} T -> S.
|
| - List<TypeParameterElement> newTypeParams = typeParameters.toList();
|
| - List<DartType> newTypeArgs = typeArguments.toList();
|
| - newTypeParams.addAll(boundTypeParameters);
|
| - newTypeArgs.addAll(argumentTypes);
|
| -
|
| - return new FunctionTypeImpl._(element, name, prunedTypedefs, newTypeArgs,
|
| - newTypeParams, TypeParameterElement.EMPTY_LIST);
|
| - }
|
| -
|
| - @override
|
| - bool isAssignableTo(DartType type) {
|
| - // A function type T may be assigned to a function type S, written T <=> S,
|
| - // iff T <: S.
|
| - return isSubtypeOf(type);
|
| - }
|
| -
|
| - @override
|
| - bool isMoreSpecificThan(DartType type,
|
| - [bool withDynamic = false, Set<Element> visitedElements]) {
|
| - // Note: visitedElements is only used for breaking recursion in the type
|
| - // hierarchy; we don't use it when recursing into the function type.
|
| -
|
| - // trivial base cases
|
| - if (type == null) {
|
| - return false;
|
| - } else if (identical(this, type) ||
|
| - type.isDynamic ||
|
| - type.isDartCoreFunction ||
|
| - type.isObject) {
|
| - return true;
|
| - } else if (type is! FunctionType) {
|
| - return false;
|
| - } else if (this == type) {
|
| - return true;
|
| - }
|
| - FunctionType t = this;
|
| - FunctionType s = type as FunctionType;
|
| - List<DartType> tTypes = t.normalParameterTypes;
|
| - List<DartType> tOpTypes = t.optionalParameterTypes;
|
| - List<DartType> sTypes = s.normalParameterTypes;
|
| - List<DartType> sOpTypes = s.optionalParameterTypes;
|
| - // If one function has positional and the other has named parameters,
|
| - // return false.
|
| - if ((sOpTypes.length > 0 && t.namedParameterTypes.length > 0) ||
|
| - (tOpTypes.length > 0 && s.namedParameterTypes.length > 0)) {
|
| - return false;
|
| - }
|
| - // named parameters case
|
| - if (t.namedParameterTypes.length > 0) {
|
| - // check that the number of required parameters are equal, and check that
|
| - // every t_i is more specific than every s_i
|
| - if (t.normalParameterTypes.length != s.normalParameterTypes.length) {
|
| - return false;
|
| - } else if (t.normalParameterTypes.length > 0) {
|
| - for (int i = 0; i < tTypes.length; i++) {
|
| - if (!(tTypes[i] as TypeImpl)
|
| - .isMoreSpecificThan(sTypes[i], withDynamic)) {
|
| - return false;
|
| - }
|
| - }
|
| - }
|
| - Map<String, DartType> namedTypesT = t.namedParameterTypes;
|
| - Map<String, DartType> namedTypesS = s.namedParameterTypes;
|
| - // if k >= m is false, return false: the passed function type has more
|
| - // named parameter types than this
|
| - if (namedTypesT.length < namedTypesS.length) {
|
| - return false;
|
| - }
|
| - // Loop through each element in S verifying that T has a matching
|
| - // parameter name and that the corresponding type is more specific then
|
| - // the type in S.
|
| - for (String keyS in namedTypesS.keys) {
|
| - DartType typeT = namedTypesT[keyS];
|
| - if (typeT == null) {
|
| - return false;
|
| - }
|
| - if (!(typeT as TypeImpl)
|
| - .isMoreSpecificThan(namedTypesS[keyS], withDynamic)) {
|
| - return false;
|
| - }
|
| - }
|
| - } else if (s.namedParameterTypes.length > 0) {
|
| - return false;
|
| - } else {
|
| - // positional parameter case
|
| - int tArgLength = tTypes.length + tOpTypes.length;
|
| - int sArgLength = sTypes.length + sOpTypes.length;
|
| - // Check that the total number of parameters in t is greater than or equal
|
| - // to the number of parameters in s and that the number of required
|
| - // parameters in s is greater than or equal to the number of required
|
| - // parameters in t.
|
| - if (tArgLength < sArgLength || sTypes.length < tTypes.length) {
|
| - return false;
|
| - }
|
| - if (tOpTypes.length == 0 && sOpTypes.length == 0) {
|
| - // No positional arguments, don't copy contents to new array
|
| - for (int i = 0; i < sTypes.length; i++) {
|
| - if (!(tTypes[i] as TypeImpl)
|
| - .isMoreSpecificThan(sTypes[i], withDynamic)) {
|
| - return false;
|
| - }
|
| - }
|
| - } else {
|
| - // Else, we do have positional parameters, copy required and positional
|
| - // parameter types into arrays to do the compare (for loop below).
|
| - List<DartType> tAllTypes = new List<DartType>(sArgLength);
|
| - for (int i = 0; i < tTypes.length; i++) {
|
| - tAllTypes[i] = tTypes[i];
|
| - }
|
| - for (int i = tTypes.length, j = 0; i < sArgLength; i++, j++) {
|
| - tAllTypes[i] = tOpTypes[j];
|
| - }
|
| - List<DartType> sAllTypes = new List<DartType>(sArgLength);
|
| - for (int i = 0; i < sTypes.length; i++) {
|
| - sAllTypes[i] = sTypes[i];
|
| - }
|
| - for (int i = sTypes.length, j = 0; i < sArgLength; i++, j++) {
|
| - sAllTypes[i] = sOpTypes[j];
|
| - }
|
| - for (int i = 0; i < sAllTypes.length; i++) {
|
| - if (!(tAllTypes[i] as TypeImpl)
|
| - .isMoreSpecificThan(sAllTypes[i], withDynamic)) {
|
| - return false;
|
| - }
|
| - }
|
| - }
|
| - }
|
| - DartType tRetType = t.returnType;
|
| - DartType sRetType = s.returnType;
|
| - return sRetType.isVoid ||
|
| - (tRetType as TypeImpl).isMoreSpecificThan(sRetType, withDynamic);
|
| - }
|
| -
|
| - @override
|
| - bool isSubtypeOf(DartType type) {
|
| - // trivial base cases
|
| - if (type == null) {
|
| - return false;
|
| - } else if (identical(this, type) ||
|
| - type.isDynamic ||
|
| - type.isDartCoreFunction ||
|
| - type.isObject) {
|
| - return true;
|
| - } else if (type is! FunctionType) {
|
| - return false;
|
| - } else if (this == type) {
|
| - return true;
|
| - }
|
| - FunctionType t = this;
|
| - FunctionType s = type as FunctionType;
|
| - List<DartType> tTypes = t.normalParameterTypes;
|
| - List<DartType> tOpTypes = t.optionalParameterTypes;
|
| - List<DartType> sTypes = s.normalParameterTypes;
|
| - List<DartType> sOpTypes = s.optionalParameterTypes;
|
| - // If one function has positional and the other has named parameters,
|
| - // return false.
|
| - if ((sOpTypes.length > 0 && t.namedParameterTypes.length > 0) ||
|
| - (tOpTypes.length > 0 && s.namedParameterTypes.length > 0)) {
|
| - return false;
|
| - }
|
| - // named parameters case
|
| - if (t.namedParameterTypes.length > 0) {
|
| - // check that the number of required parameters are equal,
|
| - // and check that every t_i is assignable to every s_i
|
| - if (t.normalParameterTypes.length != s.normalParameterTypes.length) {
|
| - return false;
|
| - } else if (t.normalParameterTypes.length > 0) {
|
| - for (int i = 0; i < tTypes.length; i++) {
|
| - if (!(tTypes[i] as TypeImpl).isAssignableTo(sTypes[i])) {
|
| - return false;
|
| - }
|
| - }
|
| - }
|
| - Map<String, DartType> namedTypesT = t.namedParameterTypes;
|
| - Map<String, DartType> namedTypesS = s.namedParameterTypes;
|
| - // if k >= m is false, return false: the passed function type has more
|
| - // named parameter types than this
|
| - if (namedTypesT.length < namedTypesS.length) {
|
| - return false;
|
| - }
|
| - // Loop through each element in S verifying that T has a matching
|
| - // parameter name and that the corresponding type is assignable to the
|
| - // type in S.
|
| - for (String keyS in namedTypesS.keys) {
|
| - DartType typeT = namedTypesT[keyS];
|
| - if (typeT == null) {
|
| - return false;
|
| - }
|
| - if (!(typeT as TypeImpl).isAssignableTo(namedTypesS[keyS])) {
|
| - return false;
|
| - }
|
| - }
|
| - } else if (s.namedParameterTypes.length > 0) {
|
| - return false;
|
| - } else {
|
| - // positional parameter case
|
| - int tArgLength = tTypes.length + tOpTypes.length;
|
| - int sArgLength = sTypes.length + sOpTypes.length;
|
| - // Check that the total number of parameters in t is greater than or
|
| - // equal to the number of parameters in s and that the number of
|
| - // required parameters in s is greater than or equal to the number of
|
| - // required parameters in t.
|
| - if (tArgLength < sArgLength || sTypes.length < tTypes.length) {
|
| - return false;
|
| - }
|
| - if (tOpTypes.length == 0 && sOpTypes.length == 0) {
|
| - // No positional arguments, don't copy contents to new array
|
| - for (int i = 0; i < sTypes.length; i++) {
|
| - if (!(tTypes[i] as TypeImpl).isAssignableTo(sTypes[i])) {
|
| - return false;
|
| - }
|
| - }
|
| - } else {
|
| - // Else, we do have positional parameters, copy required and
|
| - // positional parameter types into arrays to do the compare (for loop
|
| - // below).
|
| - List<DartType> tAllTypes = new List<DartType>(sArgLength);
|
| - for (int i = 0; i < tTypes.length; i++) {
|
| - tAllTypes[i] = tTypes[i];
|
| - }
|
| - for (int i = tTypes.length, j = 0; i < sArgLength; i++, j++) {
|
| - tAllTypes[i] = tOpTypes[j];
|
| - }
|
| - List<DartType> sAllTypes = new List<DartType>(sArgLength);
|
| - for (int i = 0; i < sTypes.length; i++) {
|
| - sAllTypes[i] = sTypes[i];
|
| - }
|
| - for (int i = sTypes.length, j = 0; i < sArgLength; i++, j++) {
|
| - sAllTypes[i] = sOpTypes[j];
|
| - }
|
| - for (int i = 0; i < sAllTypes.length; i++) {
|
| - if (!(tAllTypes[i] as TypeImpl).isAssignableTo(sAllTypes[i])) {
|
| - return false;
|
| - }
|
| - }
|
| - }
|
| - }
|
| - DartType tRetType = t.returnType;
|
| - DartType sRetType = s.returnType;
|
| - return sRetType.isVoid || (tRetType as TypeImpl).isAssignableTo(sRetType);
|
| - }
|
| -
|
| - @override
|
| - TypeImpl pruned(List<FunctionTypeAliasElement> prune) {
|
| - if (prune == null) {
|
| - return this;
|
| - } else if (prune.contains(element)) {
|
| - // Circularity found. Prune the type declaration.
|
| - return new CircularTypeImpl();
|
| - } else {
|
| - // There should never be a reason to prune a type that has already been
|
| - // pruned, since pruning is only done when expanding a function type
|
| - // alias, and function type aliases are always expanded by starting with
|
| - // base types.
|
| - assert(this.prunedTypedefs == null);
|
| - List<DartType> typeArgs = typeArguments
|
| - .map((TypeImpl t) => t.pruned(prune))
|
| - .toList(growable: false);
|
| - return new FunctionTypeImpl._(element, name, prune, typeArgs,
|
| - _typeParameters, _boundTypeParameters);
|
| - }
|
| - }
|
| -
|
| - @override
|
| - DartType substitute2(
|
| - List<DartType> argumentTypes, List<DartType> parameterTypes,
|
| - [List<FunctionTypeAliasElement> prune]) {
|
| - // Pruned types should only ever result from performing type variable
|
| - // substitution, and it doesn't make sense to substitute again after
|
| - // substituting once.
|
| - assert(this.prunedTypedefs == null);
|
| - if (argumentTypes.length != parameterTypes.length) {
|
| - throw new IllegalArgumentException(
|
| - "argumentTypes.length (${argumentTypes.length}) != parameterTypes.length (${parameterTypes.length})");
|
| - }
|
| - Element element = this.element;
|
| - if (prune != null && prune.contains(element)) {
|
| - // Circularity found. Prune the type declaration.
|
| - return new CircularTypeImpl();
|
| - }
|
| - if (argumentTypes.length == 0) {
|
| - return this.pruned(prune);
|
| - }
|
| - List<DartType> typeArgs =
|
| - TypeImpl.substitute(typeArguments, argumentTypes, parameterTypes);
|
| - return new FunctionTypeImpl._(
|
| - element, name, prune, typeArgs, _typeParameters, _boundTypeParameters);
|
| - }
|
| -
|
| - @override
|
| - FunctionTypeImpl substitute3(List<DartType> argumentTypes) =>
|
| - substitute2(argumentTypes, typeArguments);
|
| -
|
| - void _freeVariablesInFunctionType(
|
| - FunctionType type, Set<TypeParameterType> free) {
|
| - // Make some fresh variables to avoid capture.
|
| - List<DartType> typeArgs = DartType.EMPTY_LIST;
|
| - if (type.boundTypeParameters.isNotEmpty) {
|
| - typeArgs = new List<DartType>.from(type.boundTypeParameters.map((e) =>
|
| - new TypeParameterTypeImpl(new TypeParameterElementImpl(e.name, -1))));
|
| -
|
| - type = type.instantiate(typeArgs);
|
| - }
|
| -
|
| - for (ParameterElement p in type.parameters) {
|
| - _freeVariablesInType(p.type, free);
|
| - }
|
| - _freeVariablesInType(type.returnType, free);
|
| -
|
| - // Remove all of our bound variables.
|
| - free.removeAll(typeArgs);
|
| - }
|
| -
|
| - void _freeVariablesInInterfaceType(
|
| - InterfaceType type, Set<TypeParameterType> free) {
|
| - for (DartType typeArg in type.typeArguments) {
|
| - _freeVariablesInType(typeArg, free);
|
| - }
|
| - }
|
| -
|
| - void _freeVariablesInType(DartType type, Set<TypeParameterType> free) {
|
| - if (type is TypeParameterType) {
|
| - free.add(type);
|
| - } else if (type is FunctionType) {
|
| - _freeVariablesInFunctionType(type, free);
|
| - } else if (type is InterfaceType) {
|
| - _freeVariablesInInterfaceType(type, free);
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * Compute the least upper bound of types [f] and [g], both of which are
|
| - * known to be function types.
|
| - *
|
| - * In the event that f and g have different numbers of required parameters,
|
| - * `null` is returned, in which case the least upper bound is the interface
|
| - * type `Function`.
|
| - */
|
| - static FunctionType computeLeastUpperBound(FunctionType f, FunctionType g) {
|
| - // TODO(paulberry): implement this.
|
| - return null;
|
| - }
|
| -
|
| - /**
|
| - * Return `true` if all of the name/type pairs in the first map ([firstTypes])
|
| - * are equal to the corresponding name/type pairs in the second map
|
| - * ([secondTypes]). The maps are expected to iterate over their entries in the
|
| - * same order in which those entries were added to the map.
|
| - */
|
| - static bool _equals(
|
| - Map<String, DartType> firstTypes, Map<String, DartType> secondTypes) {
|
| - if (secondTypes.length != firstTypes.length) {
|
| - return false;
|
| - }
|
| - Iterator<String> firstKeys = firstTypes.keys.iterator;
|
| - Iterator<String> secondKeys = secondTypes.keys.iterator;
|
| - while (firstKeys.moveNext() && secondKeys.moveNext()) {
|
| - String firstKey = firstKeys.current;
|
| - String secondKey = secondKeys.current;
|
| - TypeImpl firstType = firstTypes[firstKey];
|
| - TypeImpl secondType = secondTypes[secondKey];
|
| - if (firstKey != secondKey || firstType != secondType) {
|
| - return false;
|
| - }
|
| - }
|
| - return true;
|
| - }
|
| -}
|
| -
|
| -/**
|
| - * A concrete implementation of a [HideElementCombinator].
|
| - */
|
| -class HideElementCombinatorImpl implements HideElementCombinator {
|
| - /**
|
| - * The names that are not to be made visible in the importing library even if
|
| - * they are defined in the imported library.
|
| - */
|
| - List<String> hiddenNames = StringUtilities.EMPTY_ARRAY;
|
| -
|
| - @override
|
| - String toString() {
|
| - StringBuffer buffer = new StringBuffer();
|
| - buffer.write("show ");
|
| - int count = hiddenNames.length;
|
| - for (int i = 0; i < count; i++) {
|
| - if (i > 0) {
|
| - buffer.write(", ");
|
| - }
|
| - buffer.write(hiddenNames[i]);
|
| - }
|
| - return buffer.toString();
|
| - }
|
| -}
|
| -
|
| -/**
|
| - * A concrete implementation of an [ImportElement].
|
| - */
|
| -class ImportElementImpl extends UriReferencedElementImpl
|
| - implements ImportElement {
|
| - /**
|
| - * The offset of the prefix of this import in the file that contains the this
|
| - * import directive, or `-1` if this import is synthetic.
|
| - */
|
| - int prefixOffset = 0;
|
| -
|
| - /**
|
| - * The library that is imported into this library by this import directive.
|
| - */
|
| - LibraryElement importedLibrary;
|
| -
|
| - /**
|
| - * The combinators that were specified as part of the import directive in the
|
| - * order in which they were specified.
|
| - */
|
| - List<NamespaceCombinator> combinators = NamespaceCombinator.EMPTY_LIST;
|
| -
|
| - /**
|
| - * The prefix that was specified as part of the import directive, or `null` if
|
| - * there was no prefix specified.
|
| - */
|
| - PrefixElement prefix;
|
| -
|
| - /**
|
| - * Initialize a newly created import element at the given [offset].
|
| - * The offset may be `-1` if the import is synthetic.
|
| - */
|
| - ImportElementImpl(int offset) : super(null, offset);
|
| -
|
| - /**
|
| - * Set whether this import is for a deferred library.
|
| - */
|
| - void set deferred(bool isDeferred) {
|
| - setModifier(Modifier.DEFERRED, isDeferred);
|
| - }
|
| -
|
| - @override
|
| - String get identifier =>
|
| - "${(importedLibrary as LibraryElementImpl).identifier}@$nameOffset";
|
| -
|
| - @override
|
| - bool get isDeferred => hasModifier(Modifier.DEFERRED);
|
| -
|
| - @override
|
| - ElementKind get kind => ElementKind.IMPORT;
|
| -
|
| - @override
|
| - accept(ElementVisitor visitor) => visitor.visitImportElement(this);
|
| -
|
| - @override
|
| - void appendTo(StringBuffer buffer) {
|
| - buffer.write("import ");
|
| - (importedLibrary as LibraryElementImpl).appendTo(buffer);
|
| - }
|
| -
|
| - @override
|
| - void visitChildren(ElementVisitor visitor) {
|
| - super.visitChildren(visitor);
|
| - safelyVisitChild(prefix, visitor);
|
| - }
|
| -}
|
| -
|
| -/**
|
| - * A concrete implementation of an [InterfaceType].
|
| - */
|
| -class InterfaceTypeImpl extends TypeImpl implements InterfaceType {
|
| - /**
|
| - * A list containing the actual types of the type arguments.
|
| - */
|
| - List<DartType> typeArguments = DartType.EMPTY_LIST;
|
| -
|
| - /**
|
| - * The set of typedefs which should not be expanded when exploring this type,
|
| - * to avoid creating infinite types in response to self-referential typedefs.
|
| - */
|
| - final List<FunctionTypeAliasElement> prunedTypedefs;
|
| -
|
| - /**
|
| - * Initialize a newly created type to be declared by the given [element].
|
| - */
|
| - InterfaceTypeImpl(ClassElement element, [this.prunedTypedefs])
|
| - : super(element, element.displayName);
|
| -
|
| - /**
|
| - * Initialize a newly created type to have the given [name]. This constructor
|
| - * should only be used in cases where there is no declaration of the type.
|
| - */
|
| - InterfaceTypeImpl.named(String name)
|
| - : prunedTypedefs = null,
|
| - super(null, name);
|
| -
|
| - /**
|
| - * Private constructor.
|
| - */
|
| - InterfaceTypeImpl._(Element element, String name, this.prunedTypedefs)
|
| - : super(element, name);
|
| -
|
| - @override
|
| - List<PropertyAccessorElement> get accessors {
|
| - List<PropertyAccessorElement> accessors = element.accessors;
|
| - List<PropertyAccessorElement> members =
|
| - new List<PropertyAccessorElement>(accessors.length);
|
| - for (int i = 0; i < accessors.length; i++) {
|
| - members[i] = PropertyAccessorMember.from(accessors[i], this);
|
| - }
|
| - return members;
|
| - }
|
| -
|
| - @override
|
| - List<ConstructorElement> get constructors {
|
| - List<ConstructorElement> constructors = element.constructors;
|
| - List<ConstructorElement> members =
|
| - new List<ConstructorElement>(constructors.length);
|
| - for (int i = 0; i < constructors.length; i++) {
|
| - members[i] = ConstructorMember.from(constructors[i], this);
|
| - }
|
| - return members;
|
| - }
|
| -
|
| - @override
|
| - String get displayName {
|
| - String name = this.name;
|
| - List<DartType> typeArguments = this.typeArguments;
|
| - bool allDynamic = true;
|
| - for (DartType type in typeArguments) {
|
| - if (type != null && !type.isDynamic) {
|
| - allDynamic = false;
|
| - break;
|
| - }
|
| - }
|
| - // If there is at least one non-dynamic type, then list them out
|
| - if (!allDynamic) {
|
| - StringBuffer buffer = new StringBuffer();
|
| - buffer.write(name);
|
| - buffer.write("<");
|
| - for (int i = 0; i < typeArguments.length; i++) {
|
| - if (i != 0) {
|
| - buffer.write(", ");
|
| - }
|
| - DartType typeArg = typeArguments[i];
|
| - buffer.write(typeArg.displayName);
|
| - }
|
| - buffer.write(">");
|
| - name = buffer.toString();
|
| - }
|
| - return name;
|
| - }
|
| -
|
| - @override
|
| - ClassElement get element => super.element as ClassElement;
|
| -
|
| - @override
|
| - int get hashCode {
|
| - ClassElement element = this.element;
|
| - if (element == null) {
|
| - return 0;
|
| - }
|
| - return element.hashCode;
|
| - }
|
| -
|
| - @override
|
| - List<InterfaceType> get interfaces {
|
| - ClassElement classElement = element;
|
| - List<InterfaceType> interfaces = classElement.interfaces;
|
| - List<TypeParameterElement> typeParameters = classElement.typeParameters;
|
| - List<DartType> parameterTypes = classElement.type.typeArguments;
|
| - if (typeParameters.length == 0) {
|
| - return interfaces;
|
| - }
|
| - int count = interfaces.length;
|
| - List<InterfaceType> typedInterfaces = new List<InterfaceType>(count);
|
| - for (int i = 0; i < count; i++) {
|
| - typedInterfaces[i] =
|
| - interfaces[i].substitute2(typeArguments, parameterTypes);
|
| - }
|
| - return typedInterfaces;
|
| - }
|
| -
|
| - @override
|
| - bool get isDartCoreFunction {
|
| - ClassElement element = this.element;
|
| - if (element == null) {
|
| - return false;
|
| - }
|
| - return element.name == "Function" && element.library.isDartCore;
|
| - }
|
| -
|
| - @override
|
| - bool get isObject => element.supertype == null;
|
| -
|
| - @override
|
| - List<MethodElement> get methods {
|
| - List<MethodElement> methods = element.methods;
|
| - List<MethodElement> members = new List<MethodElement>(methods.length);
|
| - for (int i = 0; i < methods.length; i++) {
|
| - members[i] = MethodMember.from(methods[i], this);
|
| - }
|
| - return members;
|
| - }
|
| -
|
| - @override
|
| - List<InterfaceType> get mixins {
|
| - ClassElement classElement = element;
|
| - List<InterfaceType> mixins = classElement.mixins;
|
| - List<TypeParameterElement> typeParameters = classElement.typeParameters;
|
| - List<DartType> parameterTypes = classElement.type.typeArguments;
|
| - if (typeParameters.length == 0) {
|
| - return mixins;
|
| - }
|
| - int count = mixins.length;
|
| - List<InterfaceType> typedMixins = new List<InterfaceType>(count);
|
| - for (int i = 0; i < count; i++) {
|
| - typedMixins[i] = mixins[i].substitute2(typeArguments, parameterTypes);
|
| - }
|
| - return typedMixins;
|
| - }
|
| -
|
| - @override
|
| - InterfaceType get superclass {
|
| - ClassElement classElement = element;
|
| - InterfaceType supertype = classElement.supertype;
|
| - if (supertype == null) {
|
| - return null;
|
| - }
|
| - List<DartType> typeParameters = classElement.type.typeArguments;
|
| - if (typeArguments.length == 0 ||
|
| - typeArguments.length != typeParameters.length) {
|
| - return supertype;
|
| - }
|
| - return supertype.substitute2(typeArguments, typeParameters);
|
| - }
|
| -
|
| - @override
|
| - List<TypeParameterElement> get typeParameters => element.typeParameters;
|
| -
|
| - @override
|
| - bool operator ==(Object object) {
|
| - if (identical(object, this)) {
|
| - return true;
|
| - }
|
| - if (object is! InterfaceTypeImpl) {
|
| - return false;
|
| - }
|
| - InterfaceTypeImpl otherType = object as InterfaceTypeImpl;
|
| - return (element == otherType.element) &&
|
| - TypeImpl.equalArrays(typeArguments, otherType.typeArguments);
|
| - }
|
| -
|
| - @override
|
| - void appendTo(StringBuffer buffer) {
|
| - buffer.write(name);
|
| - int argumentCount = typeArguments.length;
|
| - if (argumentCount > 0) {
|
| - buffer.write("<");
|
| - for (int i = 0; i < argumentCount; i++) {
|
| - if (i > 0) {
|
| - buffer.write(", ");
|
| - }
|
| - (typeArguments[i] as TypeImpl).appendTo(buffer);
|
| - }
|
| - buffer.write(">");
|
| - }
|
| - }
|
| -
|
| - @override
|
| - PropertyAccessorElement getGetter(String getterName) => PropertyAccessorMember
|
| - .from((element as ClassElementImpl).getGetter(getterName), this);
|
| -
|
| - @override
|
| - MethodElement getMethod(String methodName) => MethodMember.from(
|
| - (element as ClassElementImpl).getMethod(methodName), this);
|
| -
|
| - @override
|
| - PropertyAccessorElement getSetter(String setterName) => PropertyAccessorMember
|
| - .from((element as ClassElementImpl).getSetter(setterName), this);
|
| -
|
| - @override
|
| - bool isDirectSupertypeOf(InterfaceType type) {
|
| - InterfaceType i = this;
|
| - InterfaceType j = type;
|
| - ClassElement jElement = j.element;
|
| - InterfaceType supertype = jElement.supertype;
|
| - //
|
| - // If J has no direct supertype then it is Object, and Object has no direct
|
| - // supertypes.
|
| - //
|
| - if (supertype == null) {
|
| - return false;
|
| - }
|
| - //
|
| - // I is listed in the extends clause of J.
|
| - //
|
| - List<DartType> jArgs = j.typeArguments;
|
| - List<DartType> jVars = jElement.type.typeArguments;
|
| - supertype = supertype.substitute2(jArgs, jVars);
|
| - if (supertype == i) {
|
| - return true;
|
| - }
|
| - //
|
| - // I is listed in the implements clause of J.
|
| - //
|
| - for (InterfaceType interfaceType in jElement.interfaces) {
|
| - interfaceType = interfaceType.substitute2(jArgs, jVars);
|
| - if (interfaceType == i) {
|
| - return true;
|
| - }
|
| - }
|
| - //
|
| - // I is listed in the with clause of J.
|
| - //
|
| - for (InterfaceType mixinType in jElement.mixins) {
|
| - mixinType = mixinType.substitute2(jArgs, jVars);
|
| - if (mixinType == i) {
|
| - return true;
|
| - }
|
| - }
|
| - //
|
| - // J is a mixin application of the mixin of I.
|
| - //
|
| - // TODO(brianwilkerson) Determine whether this needs to be implemented or
|
| - // whether it is covered by the case above.
|
| - return false;
|
| - }
|
| -
|
| - @override
|
| - bool isMoreSpecificThan(DartType type,
|
| - [bool withDynamic = false, Set<Element> visitedElements]) {
|
| - //
|
| - // S is dynamic.
|
| - // The test to determine whether S is dynamic is done here because dynamic
|
| - // is not an instance of InterfaceType.
|
| - //
|
| - if (type.isDynamic) {
|
| - return true;
|
| - }
|
| - //
|
| - // A type T is more specific than a type S, written T << S,
|
| - // if one of the following conditions is met:
|
| - //
|
| - // Reflexivity: T is S.
|
| - //
|
| - if (this == type) {
|
| - return true;
|
| - }
|
| - if (type is InterfaceType) {
|
| - //
|
| - // T is bottom. (This case is handled by the class BottomTypeImpl.)
|
| - //
|
| - // Direct supertype: S is a direct supertype of T.
|
| - //
|
| - if (type.isDirectSupertypeOf(this)) {
|
| - return true;
|
| - }
|
| - //
|
| - // Covariance: T is of the form I<T1, ..., Tn> and S is of the form
|
| - // I<S1, ..., Sn> and Ti << Si, 1 <= i <= n.
|
| - //
|
| - ClassElement tElement = this.element;
|
| - ClassElement sElement = type.element;
|
| - if (tElement == sElement) {
|
| - List<DartType> tArguments = typeArguments;
|
| - List<DartType> sArguments = type.typeArguments;
|
| - if (tArguments.length != sArguments.length) {
|
| - return false;
|
| - }
|
| - for (int i = 0; i < tArguments.length; i++) {
|
| - if (!(tArguments[i] as TypeImpl)
|
| - .isMoreSpecificThan(sArguments[i], withDynamic)) {
|
| - return false;
|
| - }
|
| - }
|
| - return true;
|
| - }
|
| - }
|
| - //
|
| - // Transitivity: T << U and U << S.
|
| - //
|
| - // First check for infinite loops
|
| - if (element == null) {
|
| - return false;
|
| - }
|
| - if (visitedElements == null) {
|
| - visitedElements = new HashSet<ClassElement>();
|
| - } else if (visitedElements.contains(element)) {
|
| - return false;
|
| - }
|
| - visitedElements.add(element);
|
| - try {
|
| - // Iterate over all of the types U that are more specific than T because
|
| - // they are direct supertypes of T and return true if any of them are more
|
| - // specific than S.
|
| - InterfaceTypeImpl supertype = superclass;
|
| - if (supertype != null &&
|
| - supertype.isMoreSpecificThan(type, withDynamic, visitedElements)) {
|
| - return true;
|
| - }
|
| - for (InterfaceType interfaceType in interfaces) {
|
| - if ((interfaceType as InterfaceTypeImpl)
|
| - .isMoreSpecificThan(type, withDynamic, visitedElements)) {
|
| - return true;
|
| - }
|
| - }
|
| - for (InterfaceType mixinType in mixins) {
|
| - if ((mixinType as InterfaceTypeImpl)
|
| - .isMoreSpecificThan(type, withDynamic, visitedElements)) {
|
| - return true;
|
| - }
|
| - }
|
| - // If a type I includes an instance method named `call`, and the type of
|
| - // `call` is the function type F, then I is considered to be more specific
|
| - // than F.
|
| - MethodElement callMethod = getMethod('call');
|
| - if (callMethod != null && !callMethod.isStatic) {
|
| - FunctionTypeImpl callType = callMethod.type;
|
| - if (callType.isMoreSpecificThan(type, withDynamic, visitedElements)) {
|
| - return true;
|
| - }
|
| - }
|
| - return false;
|
| - } finally {
|
| - visitedElements.remove(element);
|
| - }
|
| - }
|
| -
|
| - @override
|
| - ConstructorElement lookUpConstructor(
|
| - String constructorName, LibraryElement library) {
|
| - // prepare base ConstructorElement
|
| - ConstructorElement constructorElement;
|
| - if (constructorName == null) {
|
| - constructorElement = element.unnamedConstructor;
|
| - } else {
|
| - constructorElement = element.getNamedConstructor(constructorName);
|
| - }
|
| - // not found or not accessible
|
| - if (constructorElement == null ||
|
| - !constructorElement.isAccessibleIn(library)) {
|
| - return null;
|
| - }
|
| - // return member
|
| - return ConstructorMember.from(constructorElement, this);
|
| - }
|
| -
|
| - @override
|
| - PropertyAccessorElement lookUpGetter(
|
| - String getterName, LibraryElement library) {
|
| - PropertyAccessorElement element = getGetter(getterName);
|
| - if (element != null && element.isAccessibleIn(library)) {
|
| - return element;
|
| - }
|
| - return lookUpGetterInSuperclass(getterName, library);
|
| - }
|
| -
|
| - @override
|
| - PropertyAccessorElement lookUpGetterInSuperclass(
|
| - String getterName, LibraryElement library) {
|
| - for (InterfaceType mixin in mixins.reversed) {
|
| - PropertyAccessorElement element = mixin.getGetter(getterName);
|
| - if (element != null && element.isAccessibleIn(library)) {
|
| - return element;
|
| - }
|
| - }
|
| - HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
|
| - InterfaceType supertype = superclass;
|
| - ClassElement supertypeElement =
|
| - supertype == null ? null : supertype.element;
|
| - while (supertype != null && !visitedClasses.contains(supertypeElement)) {
|
| - visitedClasses.add(supertypeElement);
|
| - PropertyAccessorElement element = supertype.getGetter(getterName);
|
| - if (element != null && element.isAccessibleIn(library)) {
|
| - return element;
|
| - }
|
| - for (InterfaceType mixin in supertype.mixins.reversed) {
|
| - element = mixin.getGetter(getterName);
|
| - if (element != null && element.isAccessibleIn(library)) {
|
| - return element;
|
| - }
|
| - }
|
| - supertype = supertype.superclass;
|
| - supertypeElement = supertype == null ? null : supertype.element;
|
| - }
|
| - return null;
|
| - }
|
| -
|
| - @override
|
| - PropertyAccessorElement lookUpInheritedGetter(String name,
|
| - {LibraryElement library, bool thisType: true}) {
|
| - PropertyAccessorElement result;
|
| - if (thisType) {
|
| - result = lookUpGetter(name, library);
|
| - } else {
|
| - result = lookUpGetterInSuperclass(name, library);
|
| - }
|
| - if (result != null) {
|
| - return result;
|
| - }
|
| - return _lookUpMemberInInterfaces(this, false, library,
|
| - new HashSet<ClassElement>(), (InterfaceType t) => t.getGetter(name));
|
| - }
|
| -
|
| - @override
|
| - ExecutableElement lookUpInheritedGetterOrMethod(String name,
|
| - {LibraryElement library}) {
|
| - ExecutableElement result =
|
| - lookUpGetter(name, library) ?? lookUpMethod(name, library);
|
| -
|
| - if (result != null) {
|
| - return result;
|
| - }
|
| - return _lookUpMemberInInterfaces(
|
| - this,
|
| - false,
|
| - library,
|
| - new HashSet<ClassElement>(),
|
| - (InterfaceType t) => t.getGetter(name) ?? t.getMethod(name));
|
| - }
|
| -
|
| - @override
|
| - MethodElement lookUpInheritedMethod(String name,
|
| - {LibraryElement library, bool thisType: true}) {
|
| - MethodElement result;
|
| - if (thisType) {
|
| - result = lookUpMethod(name, library);
|
| - } else {
|
| - result = lookUpMethodInSuperclass(name, library);
|
| - }
|
| - if (result != null) {
|
| - return result;
|
| - }
|
| - return _lookUpMemberInInterfaces(this, false, library,
|
| - new HashSet<ClassElement>(), (InterfaceType t) => t.getMethod(name));
|
| - }
|
| -
|
| - @override
|
| - PropertyAccessorElement lookUpInheritedSetter(String name,
|
| - {LibraryElement library, bool thisType: true}) {
|
| - PropertyAccessorElement result;
|
| - if (thisType) {
|
| - result = lookUpSetter(name, library);
|
| - } else {
|
| - result = lookUpSetterInSuperclass(name, library);
|
| - }
|
| - if (result != null) {
|
| - return result;
|
| - }
|
| - return _lookUpMemberInInterfaces(this, false, library,
|
| - new HashSet<ClassElement>(), (t) => t.getSetter(name));
|
| - }
|
| -
|
| - @override
|
| - MethodElement lookUpMethod(String methodName, LibraryElement library) {
|
| - MethodElement element = getMethod(methodName);
|
| - if (element != null && element.isAccessibleIn(library)) {
|
| - return element;
|
| - }
|
| - return lookUpMethodInSuperclass(methodName, library);
|
| - }
|
| -
|
| - @override
|
| - MethodElement lookUpMethodInSuperclass(
|
| - String methodName, LibraryElement library) {
|
| - for (InterfaceType mixin in mixins.reversed) {
|
| - MethodElement element = mixin.getMethod(methodName);
|
| - if (element != null && element.isAccessibleIn(library)) {
|
| - return element;
|
| - }
|
| - }
|
| - HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
|
| - InterfaceType supertype = superclass;
|
| - ClassElement supertypeElement =
|
| - supertype == null ? null : supertype.element;
|
| - while (supertype != null && !visitedClasses.contains(supertypeElement)) {
|
| - visitedClasses.add(supertypeElement);
|
| - MethodElement element = supertype.getMethod(methodName);
|
| - if (element != null && element.isAccessibleIn(library)) {
|
| - return element;
|
| - }
|
| - for (InterfaceType mixin in supertype.mixins.reversed) {
|
| - element = mixin.getMethod(methodName);
|
| - if (element != null && element.isAccessibleIn(library)) {
|
| - return element;
|
| - }
|
| - }
|
| - supertype = supertype.superclass;
|
| - supertypeElement = supertype == null ? null : supertype.element;
|
| - }
|
| - return null;
|
| - }
|
| -
|
| - @override
|
| - PropertyAccessorElement lookUpSetter(
|
| - String setterName, LibraryElement library) {
|
| - PropertyAccessorElement element = getSetter(setterName);
|
| - if (element != null && element.isAccessibleIn(library)) {
|
| - return element;
|
| - }
|
| - return lookUpSetterInSuperclass(setterName, library);
|
| - }
|
| -
|
| - @override
|
| - PropertyAccessorElement lookUpSetterInSuperclass(
|
| - String setterName, LibraryElement library) {
|
| - for (InterfaceType mixin in mixins.reversed) {
|
| - PropertyAccessorElement element = mixin.getSetter(setterName);
|
| - if (element != null && element.isAccessibleIn(library)) {
|
| - return element;
|
| - }
|
| - }
|
| - HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
|
| - InterfaceType supertype = superclass;
|
| - ClassElement supertypeElement =
|
| - supertype == null ? null : supertype.element;
|
| - while (supertype != null && !visitedClasses.contains(supertypeElement)) {
|
| - visitedClasses.add(supertypeElement);
|
| - PropertyAccessorElement element = supertype.getSetter(setterName);
|
| - if (element != null && element.isAccessibleIn(library)) {
|
| - return element;
|
| - }
|
| - for (InterfaceType mixin in supertype.mixins.reversed) {
|
| - element = mixin.getSetter(setterName);
|
| - if (element != null && element.isAccessibleIn(library)) {
|
| - return element;
|
| - }
|
| - }
|
| - supertype = supertype.superclass;
|
| - supertypeElement = supertype == null ? null : supertype.element;
|
| - }
|
| - return null;
|
| - }
|
| -
|
| - @override
|
| - InterfaceTypeImpl pruned(List<FunctionTypeAliasElement> prune) {
|
| - if (prune == null) {
|
| - return this;
|
| - } else {
|
| - // There should never be a reason to prune a type that has already been
|
| - // pruned, since pruning is only done when expanding a function type
|
| - // alias, and function type aliases are always expanded by starting with
|
| - // base types.
|
| - assert(this.prunedTypedefs == null);
|
| - InterfaceTypeImpl result = new InterfaceTypeImpl._(element, name, prune);
|
| - result.typeArguments =
|
| - typeArguments.map((TypeImpl t) => t.pruned(prune)).toList();
|
| - return result;
|
| - }
|
| + return null;
|
| }
|
|
|
| @override
|
| - InterfaceTypeImpl substitute2(
|
| - List<DartType> argumentTypes, List<DartType> parameterTypes,
|
| - [List<FunctionTypeAliasElement> prune]) {
|
| - if (argumentTypes.length != parameterTypes.length) {
|
| - throw new IllegalArgumentException(
|
| - "argumentTypes.length (${argumentTypes.length}) != parameterTypes.length (${parameterTypes.length})");
|
| - }
|
| - if (argumentTypes.length == 0 || typeArguments.length == 0) {
|
| - return this.pruned(prune);
|
| - }
|
| - List<DartType> newTypeArguments = TypeImpl.substitute(
|
| - typeArguments, argumentTypes, parameterTypes, prune);
|
| - if (JavaArrays.equals(newTypeArguments, typeArguments)) {
|
| - return this;
|
| - }
|
| - InterfaceTypeImpl newType = new InterfaceTypeImpl(element, prune);
|
| - newType.typeArguments = newTypeArguments;
|
| - return newType;
|
| + void visitChildren(ElementVisitor visitor) {
|
| + super.visitChildren(visitor);
|
| + safelyVisitChildren(_parameters, visitor);
|
| + safelyVisitChildren(_typeParameters, visitor);
|
| }
|
| +}
|
|
|
| - @override
|
| - InterfaceTypeImpl substitute4(List<DartType> argumentTypes) =>
|
| - substitute2(argumentTypes, typeArguments);
|
| -
|
| +/**
|
| + * A concrete implementation of a [HideElementCombinator].
|
| + */
|
| +class HideElementCombinatorImpl implements HideElementCombinator {
|
| /**
|
| - * Compute the least upper bound of types [i] and [j], both of which are
|
| - * known to be interface types.
|
| - *
|
| - * In the event that the algorithm fails (which might occur due to a bug in
|
| - * the analyzer), `null` is returned.
|
| - */
|
| - static InterfaceType computeLeastUpperBound(
|
| - InterfaceType i, InterfaceType j) {
|
| - // compute set of supertypes
|
| - Set<InterfaceType> si = computeSuperinterfaceSet(i);
|
| - Set<InterfaceType> sj = computeSuperinterfaceSet(j);
|
| - // union si with i and sj with j
|
| - si.add(i);
|
| - sj.add(j);
|
| - // compute intersection, reference as set 's'
|
| - List<InterfaceType> s = _intersection(si, sj);
|
| - // for each element in Set s, compute the largest inheritance path to Object
|
| - List<int> depths = new List<int>.filled(s.length, 0);
|
| - int maxDepth = 0;
|
| - for (int n = 0; n < s.length; n++) {
|
| - depths[n] = computeLongestInheritancePathToObject(s[n]);
|
| - if (depths[n] > maxDepth) {
|
| - maxDepth = depths[n];
|
| - }
|
| - }
|
| - // ensure that the currently computed maxDepth is unique,
|
| - // otherwise, decrement and test for uniqueness again
|
| - for (; maxDepth >= 0; maxDepth--) {
|
| - int indexOfLeastUpperBound = -1;
|
| - int numberOfTypesAtMaxDepth = 0;
|
| - for (int m = 0; m < depths.length; m++) {
|
| - if (depths[m] == maxDepth) {
|
| - numberOfTypesAtMaxDepth++;
|
| - indexOfLeastUpperBound = m;
|
| - }
|
| - }
|
| - if (numberOfTypesAtMaxDepth == 1) {
|
| - return s[indexOfLeastUpperBound];
|
| + * The names that are not to be made visible in the importing library even if
|
| + * they are defined in the imported library.
|
| + */
|
| + List<String> hiddenNames = StringUtilities.EMPTY_ARRAY;
|
| +
|
| + @override
|
| + String toString() {
|
| + StringBuffer buffer = new StringBuffer();
|
| + buffer.write("show ");
|
| + int count = hiddenNames.length;
|
| + for (int i = 0; i < count; i++) {
|
| + if (i > 0) {
|
| + buffer.write(", ");
|
| }
|
| + buffer.write(hiddenNames[i]);
|
| }
|
| - // Should be impossible--there should always be exactly one type with the
|
| - // maximum depth.
|
| - assert(false);
|
| - return null;
|
| + return buffer.toString();
|
| }
|
| +}
|
|
|
| +/**
|
| + * A concrete implementation of an [ImportElement].
|
| + */
|
| +class ImportElementImpl extends UriReferencedElementImpl
|
| + implements ImportElement {
|
| /**
|
| - * Return the length of the longest inheritance path from the given [type] to
|
| - * Object.
|
| - *
|
| - * See [computeLeastUpperBound].
|
| + * The offset of the prefix of this import in the file that contains the this
|
| + * import directive, or `-1` if this import is synthetic.
|
| */
|
| - static int computeLongestInheritancePathToObject(InterfaceType type) =>
|
| - _computeLongestInheritancePathToObject(
|
| - type, 0, new HashSet<ClassElement>());
|
| + int prefixOffset = 0;
|
|
|
| /**
|
| - * Returns the set of all superinterfaces of the given [type].
|
| - *
|
| - * See [computeLeastUpperBound].
|
| + * The library that is imported into this library by this import directive.
|
| */
|
| - static Set<InterfaceType> computeSuperinterfaceSet(InterfaceType type) =>
|
| - _computeSuperinterfaceSet(type, new HashSet<InterfaceType>());
|
| + LibraryElement importedLibrary;
|
|
|
| /**
|
| - * Returns a "smart" version of the "least upper bound" of the given types.
|
| - *
|
| - * If these types have the same element and differ only in terms of the type
|
| - * arguments, attempts to find a compatible set of type arguments.
|
| - *
|
| - * Otherwise, calls [DartType.getLeastUpperBound].
|
| + * The combinators that were specified as part of the import directive in the
|
| + * order in which they were specified.
|
| */
|
| - static InterfaceType getSmartLeastUpperBound(
|
| - InterfaceType first, InterfaceType second) {
|
| - // TODO(paulberry): this needs to be deprecated and replaced with a method
|
| - // in [TypeSystem], since it relies on the deprecated functionality of
|
| - // [DartType.getLeastUpperBound].
|
| - if (first.element == second.element) {
|
| - return _leastUpperBound(first, second);
|
| - }
|
| - AnalysisContext context = first.element.context;
|
| - return context.typeSystem
|
| - .getLeastUpperBound(context.typeProvider, first, second);
|
| - }
|
| + List<NamespaceCombinator> combinators = NamespaceCombinator.EMPTY_LIST;
|
|
|
| /**
|
| - * Return the length of the longest inheritance path from a subtype of the
|
| - * given [type] to Object, where the given [depth] is the length of the
|
| - * longest path from the subtype to this type. The set of [visitedTypes] is
|
| - * used to prevent infinite recursion in the case of a cyclic type structure.
|
| - *
|
| - * See [computeLongestInheritancePathToObject], and [computeLeastUpperBound].
|
| - */
|
| - static int _computeLongestInheritancePathToObject(
|
| - InterfaceType type, int depth, HashSet<ClassElement> visitedTypes) {
|
| - ClassElement classElement = type.element;
|
| - // Object case
|
| - if (classElement.supertype == null || visitedTypes.contains(classElement)) {
|
| - return depth;
|
| - }
|
| - int longestPath = 1;
|
| - try {
|
| - visitedTypes.add(classElement);
|
| - List<InterfaceType> superinterfaces = classElement.interfaces;
|
| - int pathLength;
|
| - if (superinterfaces.length > 0) {
|
| - // loop through each of the superinterfaces recursively calling this
|
| - // method and keeping track of the longest path to return
|
| - for (InterfaceType superinterface in superinterfaces) {
|
| - pathLength = _computeLongestInheritancePathToObject(
|
| - superinterface, depth + 1, visitedTypes);
|
| - if (pathLength > longestPath) {
|
| - longestPath = pathLength;
|
| - }
|
| - }
|
| - }
|
| - // finally, perform this same check on the super type
|
| - // TODO(brianwilkerson) Does this also need to add in the number of mixin
|
| - // classes?
|
| - InterfaceType supertype = classElement.supertype;
|
| - pathLength = _computeLongestInheritancePathToObject(
|
| - supertype, depth + 1, visitedTypes);
|
| - if (pathLength > longestPath) {
|
| - longestPath = pathLength;
|
| - }
|
| - } finally {
|
| - visitedTypes.remove(classElement);
|
| - }
|
| - return longestPath;
|
| - }
|
| + * The prefix that was specified as part of the import directive, or `null` if
|
| + * there was no prefix specified.
|
| + */
|
| + PrefixElement prefix;
|
|
|
| /**
|
| - * Add all of the superinterfaces of the given [type] to the given [set].
|
| - * Return the [set] as a convenience.
|
| - *
|
| - * See [computeSuperinterfaceSet], and [computeLeastUpperBound].
|
| + * Initialize a newly created import element at the given [offset].
|
| + * The offset may be `-1` if the import is synthetic.
|
| */
|
| - static Set<InterfaceType> _computeSuperinterfaceSet(
|
| - InterfaceType type, HashSet<InterfaceType> set) {
|
| - Element element = type.element;
|
| - if (element != null) {
|
| - List<InterfaceType> superinterfaces = type.interfaces;
|
| - for (InterfaceType superinterface in superinterfaces) {
|
| - if (set.add(superinterface)) {
|
| - _computeSuperinterfaceSet(superinterface, set);
|
| - }
|
| - }
|
| - InterfaceType supertype = type.superclass;
|
| - if (supertype != null) {
|
| - if (set.add(supertype)) {
|
| - _computeSuperinterfaceSet(supertype, set);
|
| - }
|
| - }
|
| - }
|
| - return set;
|
| - }
|
| + ImportElementImpl(int offset) : super(null, offset);
|
|
|
| /**
|
| - * Return the intersection of the [first] and [second] sets of types, where
|
| - * intersection is based on the equality of the types themselves.
|
| + * Set whether this import is for a deferred library.
|
| */
|
| - static List<InterfaceType> _intersection(
|
| - Set<InterfaceType> first, Set<InterfaceType> second) {
|
| - Set<InterfaceType> result = new HashSet<InterfaceType>.from(first);
|
| - result.retainAll(second);
|
| - return new List.from(result);
|
| + void set deferred(bool isDeferred) {
|
| + setModifier(Modifier.DEFERRED, isDeferred);
|
| }
|
|
|
| - /**
|
| - * Return the "least upper bound" of the given types under the assumption that
|
| - * the types have the same element and differ only in terms of the type
|
| - * arguments.
|
| - *
|
| - * The resulting type is composed by comparing the corresponding type
|
| - * arguments, keeping those that are the same, and using 'dynamic' for those
|
| - * that are different.
|
| - */
|
| - static InterfaceType _leastUpperBound(
|
| - InterfaceType firstType, InterfaceType secondType) {
|
| - ClassElement firstElement = firstType.element;
|
| - ClassElement secondElement = secondType.element;
|
| - if (firstElement != secondElement) {
|
| - throw new IllegalArgumentException('The same elements expected, but '
|
| - '$firstElement and $secondElement are given.');
|
| - }
|
| - if (firstType == secondType) {
|
| - return firstType;
|
| - }
|
| - List<DartType> firstArguments = firstType.typeArguments;
|
| - List<DartType> secondArguments = secondType.typeArguments;
|
| - int argumentCount = firstArguments.length;
|
| - if (argumentCount == 0) {
|
| - return firstType;
|
| - }
|
| - List<DartType> lubArguments = new List<DartType>(argumentCount);
|
| - for (int i = 0; i < argumentCount; i++) {
|
| - //
|
| - // Ideally we would take the least upper bound of the two argument types,
|
| - // but this can cause an infinite recursion (such as when finding the
|
| - // least upper bound of String and num).
|
| - //
|
| - if (firstArguments[i] == secondArguments[i]) {
|
| - lubArguments[i] = firstArguments[i];
|
| - }
|
| - if (lubArguments[i] == null) {
|
| - lubArguments[i] = DynamicTypeImpl.instance;
|
| - }
|
| - }
|
| - InterfaceTypeImpl lub = new InterfaceTypeImpl(firstElement);
|
| - lub.typeArguments = lubArguments;
|
| - return lub;
|
| - }
|
| -
|
| - /**
|
| - * Look up the getter with the given [name] in the interfaces
|
| - * implemented by the given [targetType], either directly or indirectly.
|
| - * Return the element representing the getter that was found, or `null` if
|
| - * there is no getter with the given name. The flag [includeTargetType] should
|
| - * be `true` if the search should include the target type. The
|
| - * [visitedInterfaces] is a set containing all of the interfaces that have
|
| - * been examined, used to prevent infinite recursion and to optimize the
|
| - * search.
|
| - */
|
| - static ExecutableElement _lookUpMemberInInterfaces(
|
| - InterfaceType targetType,
|
| - bool includeTargetType,
|
| - LibraryElement library,
|
| - HashSet<ClassElement> visitedInterfaces,
|
| - ExecutableElement getMember(InterfaceType type)) {
|
| - // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the
|
| - // specification (titled "Inheritance and Overriding" under "Interfaces")
|
| - // describes a much more complex scheme for finding the inherited member.
|
| - // We need to follow that scheme. The code below should cover the 80% case.
|
| - ClassElement targetClass = targetType.element;
|
| - if (!visitedInterfaces.add(targetClass)) {
|
| - return null;
|
| - }
|
| - if (includeTargetType) {
|
| - ExecutableElement member = getMember(targetType);
|
| - if (member != null && member.isAccessibleIn(library)) {
|
| - return member;
|
| - }
|
| - }
|
| - for (InterfaceType interfaceType in targetType.interfaces) {
|
| - ExecutableElement member = _lookUpMemberInInterfaces(
|
| - interfaceType, true, library, visitedInterfaces, getMember);
|
| - if (member != null) {
|
| - return member;
|
| - }
|
| - }
|
| - for (InterfaceType mixinType in targetType.mixins.reversed) {
|
| - ExecutableElement member = _lookUpMemberInInterfaces(
|
| - mixinType, true, library, visitedInterfaces, getMember);
|
| - if (member != null) {
|
| - return member;
|
| - }
|
| - }
|
| - InterfaceType superclass = targetType.superclass;
|
| - if (superclass == null) {
|
| - return null;
|
| - }
|
| - return _lookUpMemberInInterfaces(
|
| - superclass, true, library, visitedInterfaces, getMember);
|
| + @override
|
| + String get identifier =>
|
| + "${(importedLibrary as LibraryElementImpl).identifier}@$nameOffset";
|
| +
|
| + @override
|
| + bool get isDeferred => hasModifier(Modifier.DEFERRED);
|
| +
|
| + @override
|
| + ElementKind get kind => ElementKind.IMPORT;
|
| +
|
| + @override
|
| + accept(ElementVisitor visitor) => visitor.visitImportElement(this);
|
| +
|
| + @override
|
| + void appendTo(StringBuffer buffer) {
|
| + buffer.write("import ");
|
| + (importedLibrary as LibraryElementImpl).appendTo(buffer);
|
| + }
|
| +
|
| + @override
|
| + void visitChildren(ElementVisitor visitor) {
|
| + super.visitChildren(visitor);
|
| + safelyVisitChild(prefix, visitor);
|
| }
|
| }
|
|
|
| @@ -5857,151 +3533,6 @@ class LocalVariableElementImpl extends VariableElementImpl
|
| }
|
|
|
| /**
|
| - * An element defined in a parameterized type where the values of the type
|
| - * parameters are known.
|
| - */
|
| -abstract class Member implements Element {
|
| - /**
|
| - * The element on which the parameterized element was created.
|
| - */
|
| - final Element _baseElement;
|
| -
|
| - /**
|
| - * The type in which the element is defined.
|
| - */
|
| - final ParameterizedType _definingType;
|
| -
|
| - /**
|
| - * Initialize a newly created element to represent a member, based on the
|
| - * [baseElement], defined by the [definingType].
|
| - */
|
| - Member(this._baseElement, this._definingType);
|
| -
|
| - /**
|
| - * Return the element on which the parameterized element was created.
|
| - */
|
| - Element get baseElement => _baseElement;
|
| -
|
| - @override
|
| - AnalysisContext get context => _baseElement.context;
|
| -
|
| - /**
|
| - * Return the type in which the element is defined.
|
| - */
|
| - ParameterizedType get definingType => _definingType;
|
| -
|
| - @override
|
| - String get displayName => _baseElement.displayName;
|
| -
|
| - @override
|
| - SourceRange get docRange => _baseElement.docRange;
|
| -
|
| - int get id => _baseElement.id;
|
| -
|
| - @override
|
| - bool get isDeprecated => _baseElement.isDeprecated;
|
| -
|
| - @override
|
| - bool get isOverride => _baseElement.isOverride;
|
| -
|
| - @override
|
| - bool get isPrivate => _baseElement.isPrivate;
|
| -
|
| - @override
|
| - bool get isPublic => _baseElement.isPublic;
|
| -
|
| - @override
|
| - bool get isSynthetic => _baseElement.isSynthetic;
|
| -
|
| - @override
|
| - ElementKind get kind => _baseElement.kind;
|
| -
|
| - @override
|
| - LibraryElement get library => _baseElement.library;
|
| -
|
| - @override
|
| - ElementLocation get location => _baseElement.location;
|
| -
|
| - @override
|
| - List<ElementAnnotation> get metadata => _baseElement.metadata;
|
| -
|
| - @override
|
| - String get name => _baseElement.name;
|
| -
|
| - @override
|
| - int get nameLength => _baseElement.nameLength;
|
| -
|
| - @override
|
| - int get nameOffset => _baseElement.nameOffset;
|
| -
|
| - @override
|
| - Source get source => _baseElement.source;
|
| -
|
| - @override
|
| - CompilationUnit get unit => _baseElement.unit;
|
| -
|
| - @override
|
| - String computeDocumentationComment() =>
|
| - _baseElement.computeDocumentationComment();
|
| -
|
| - @override
|
| - AstNode computeNode() => _baseElement.computeNode();
|
| -
|
| - @override
|
| - Element getAncestor(Predicate<Element> predicate) =>
|
| - baseElement.getAncestor(predicate);
|
| -
|
| - @override
|
| - String getExtendedDisplayName(String shortName) =>
|
| - _baseElement.getExtendedDisplayName(shortName);
|
| -
|
| - @override
|
| - bool isAccessibleIn(LibraryElement library) =>
|
| - _baseElement.isAccessibleIn(library);
|
| -
|
| - /**
|
| - * If the given [child] is not `null`, use the given [visitor] to visit it.
|
| - */
|
| - void safelyVisitChild(Element child, ElementVisitor visitor) {
|
| - // TODO(brianwilkerson) Make this private
|
| - if (child != null) {
|
| - child.accept(visitor);
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * Use the given [visitor] to visit all of the [children].
|
| - */
|
| - void safelyVisitChildren(List<Element> children, ElementVisitor visitor) {
|
| - // TODO(brianwilkerson) Make this private
|
| - if (children != null) {
|
| - for (Element child in children) {
|
| - child.accept(visitor);
|
| - }
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * Return the type that results from replacing the type parameters in the
|
| - * given [type] with the type arguments associated with this member.
|
| - */
|
| - DartType substituteFor(DartType type) {
|
| - if (type == null) {
|
| - return null;
|
| - }
|
| - List<DartType> argumentTypes = _definingType.typeArguments;
|
| - List<DartType> parameterTypes =
|
| - TypeParameterTypeImpl.getTypes(_definingType.typeParameters);
|
| - return type.substitute2(argumentTypes, parameterTypes);
|
| - }
|
| -
|
| - @override
|
| - void visitChildren(ElementVisitor visitor) {
|
| - // There are no children to visit
|
| - }
|
| -}
|
| -
|
| -/**
|
| * A concrete implementation of a [MethodElement].
|
| */
|
| class MethodElementImpl extends ExecutableElementImpl implements MethodElement {
|
| @@ -6078,87 +3609,12 @@ class MethodElementImpl extends ExecutableElementImpl implements MethodElement {
|
| @override
|
| void appendTo(StringBuffer buffer) {
|
| buffer.write(displayName);
|
| - super.appendTo(buffer);
|
| - }
|
| -
|
| - @override
|
| - MethodDeclaration computeNode() =>
|
| - getNodeMatching((node) => node is MethodDeclaration);
|
| -}
|
| -
|
| -/**
|
| - * A method element defined in a parameterized type where the values of the type
|
| - * parameters are known.
|
| - */
|
| -class MethodMember extends ExecutableMember implements MethodElement {
|
| - /**
|
| - * Initialize a newly created element to represent a method, based on the
|
| - * [baseElement], defined by the [definingType]. If [type] is passed, it
|
| - * represents the full type of the member, and will take precedence over
|
| - * the [definingType].
|
| - */
|
| - MethodMember(MethodElement baseElement, InterfaceType definingType,
|
| - [DartType type])
|
| - : super(baseElement, definingType, type);
|
| -
|
| - @override
|
| - MethodElement get baseElement => super.baseElement as MethodElement;
|
| -
|
| - @override
|
| - ClassElement get enclosingElement => baseElement.enclosingElement;
|
| -
|
| - @override
|
| - accept(ElementVisitor visitor) => visitor.visitMethodElement(this);
|
| -
|
| - @override
|
| - MethodDeclaration computeNode() => baseElement.computeNode();
|
| -
|
| - @override
|
| - String toString() {
|
| - MethodElement baseElement = this.baseElement;
|
| - List<ParameterElement> parameters = this.parameters;
|
| - FunctionType type = this.type;
|
| - StringBuffer buffer = new StringBuffer();
|
| - buffer.write(baseElement.enclosingElement.displayName);
|
| - buffer.write(".");
|
| - buffer.write(baseElement.displayName);
|
| - buffer.write("(");
|
| - int parameterCount = parameters.length;
|
| - for (int i = 0; i < parameterCount; i++) {
|
| - if (i > 0) {
|
| - buffer.write(", ");
|
| - }
|
| - buffer.write(parameters[i]);
|
| - }
|
| - buffer.write(")");
|
| - if (type != null) {
|
| - buffer.write(ElementImpl.RIGHT_ARROW);
|
| - buffer.write(type.returnType);
|
| - }
|
| - return buffer.toString();
|
| - }
|
| -
|
| - /**
|
| - * If the given [method]'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 method member representing the given
|
| - * method. Return the member that was created, or the base method if no member
|
| - * was created.
|
| - */
|
| - static MethodElement from(MethodElement method, InterfaceType definingType) {
|
| - if (method == null || definingType.typeArguments.length == 0) {
|
| - return method;
|
| - }
|
| - FunctionType baseType = method.type;
|
| - List<DartType> argumentTypes = definingType.typeArguments;
|
| - List<DartType> parameterTypes = definingType.element.type.typeArguments;
|
| - FunctionType substitutedType =
|
| - baseType.substitute2(argumentTypes, parameterTypes);
|
| - if (baseType == substitutedType) {
|
| - return method;
|
| - }
|
| - return new MethodMember(method, definingType, substitutedType);
|
| + super.appendTo(buffer);
|
| }
|
| +
|
| + @override
|
| + MethodDeclaration computeNode() =>
|
| + getNodeMatching((node) => node is MethodDeclaration);
|
| }
|
|
|
| /**
|
| @@ -6602,140 +4058,6 @@ abstract class ParameterElementMixin implements ParameterElement {
|
| }
|
|
|
| /**
|
| - * A parameter element defined in a parameterized type where the values of the
|
| - * type parameters are known.
|
| - */
|
| -class ParameterMember extends VariableMember
|
| - with ParameterElementMixin
|
| - implements ParameterElement {
|
| - /**
|
| - * Initialize a newly created element to represent a parameter, based on the
|
| - * [baseElement], defined by the [definingType]. If [type] is passed it will
|
| - * represent the already substituted type.
|
| - */
|
| - ParameterMember(ParameterElement baseElement, ParameterizedType definingType,
|
| - [DartType type])
|
| - : super._(baseElement, definingType, type);
|
| -
|
| - @override
|
| - ParameterElement get baseElement => super.baseElement as ParameterElement;
|
| -
|
| - @override
|
| - String get defaultValueCode => baseElement.defaultValueCode;
|
| -
|
| - @override
|
| - Element get enclosingElement => baseElement.enclosingElement;
|
| -
|
| - @override
|
| - int get hashCode => baseElement.hashCode;
|
| -
|
| - @override
|
| - bool get isInitializingFormal => baseElement.isInitializingFormal;
|
| -
|
| - @override
|
| - ParameterKind get parameterKind => baseElement.parameterKind;
|
| -
|
| - @override
|
| - List<ParameterElement> get parameters {
|
| - DartType type = this.type;
|
| - if (type is FunctionType) {
|
| - return type.parameters;
|
| - }
|
| - return ParameterElement.EMPTY_LIST;
|
| - }
|
| -
|
| - @override
|
| - List<TypeParameterElement> get typeParameters => baseElement.typeParameters;
|
| -
|
| - @override
|
| - SourceRange get visibleRange => baseElement.visibleRange;
|
| -
|
| - // TODO(jmesserly): this equality is broken. It should consider the defining
|
| - // type as well, otherwise we're dropping the substitution.
|
| - @override
|
| - bool operator ==(Object object) =>
|
| - object is ParameterMember && baseElement == object.baseElement;
|
| -
|
| - @override
|
| - accept(ElementVisitor visitor) => visitor.visitParameterElement(this);
|
| -
|
| - @override
|
| - FormalParameter computeNode() => baseElement.computeNode();
|
| -
|
| - @override
|
| - Element getAncestor(Predicate<Element> predicate) {
|
| - Element element = baseElement.getAncestor(predicate);
|
| - ParameterizedType definingType = this.definingType;
|
| - if (definingType is InterfaceType) {
|
| - InterfaceType definingInterfaceType = definingType;
|
| - if (element is ConstructorElement) {
|
| - return ConstructorMember.from(element, definingInterfaceType);
|
| - } else if (element is MethodElement) {
|
| - return MethodMember.from(element, definingInterfaceType);
|
| - } else if (element is PropertyAccessorElement) {
|
| - return PropertyAccessorMember.from(element, definingInterfaceType);
|
| - }
|
| - }
|
| - return element;
|
| - }
|
| -
|
| - @override
|
| - String toString() {
|
| - ParameterElement baseElement = this.baseElement;
|
| - String left = "";
|
| - String right = "";
|
| - while (true) {
|
| - if (baseElement.parameterKind == ParameterKind.NAMED) {
|
| - left = "{";
|
| - right = "}";
|
| - } else if (baseElement.parameterKind == ParameterKind.POSITIONAL) {
|
| - left = "[";
|
| - right = "]";
|
| - } else if (baseElement.parameterKind == ParameterKind.REQUIRED) {}
|
| - break;
|
| - }
|
| - return '$left$type ${baseElement.displayName}$right';
|
| - }
|
| -
|
| - @override
|
| - void visitChildren(ElementVisitor visitor) {
|
| - super.visitChildren(visitor);
|
| - safelyVisitChildren(parameters, visitor);
|
| - }
|
| -
|
| - /**
|
| - * If the given [parameter]'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 parameter member representing
|
| - * the given parameter. Return the member that was created, or the base
|
| - * parameter if no member was created.
|
| - */
|
| - static ParameterElement from(
|
| - ParameterElement parameter, ParameterizedType definingType) {
|
| - if (parameter == null || definingType.typeArguments.length == 0) {
|
| - return parameter;
|
| - }
|
| - // Check if parameter type depends on defining type type arguments.
|
| - // It is possible that we did not resolve field formal parameter yet,
|
| - // so skip this check for it.
|
| - if (parameter is FieldFormalParameterElement) {
|
| - return new FieldFormalParameterMember(parameter, definingType);
|
| - } else {
|
| - DartType baseType = parameter.type;
|
| - List<DartType> argumentTypes = definingType.typeArguments;
|
| - List<DartType> parameterTypes =
|
| - TypeParameterTypeImpl.getTypes(definingType.typeParameters);
|
| - DartType substitutedType =
|
| - baseType.substitute2(argumentTypes, parameterTypes);
|
| - if (baseType == substitutedType) {
|
| - return parameter;
|
| - }
|
| - return new ParameterMember(parameter, definingType, substitutedType);
|
| - }
|
| - }
|
| -}
|
| -
|
| -/**
|
| * A concrete implementation of a [PrefixElement].
|
| */
|
| class PrefixElementImpl extends ElementImpl implements PrefixElement {
|
| @@ -6926,144 +4248,6 @@ class PropertyAccessorElementImpl extends ExecutableElementImpl
|
| }
|
|
|
| /**
|
| - * A property accessor element defined in a parameterized type where the values
|
| - * of the type parameters are known.
|
| - */
|
| -class PropertyAccessorMember extends ExecutableMember
|
| - implements PropertyAccessorElement {
|
| - /**
|
| - * Initialize a newly created element to represent a property, based on the
|
| - * [baseElement], defined by the [definingType].
|
| - */
|
| - PropertyAccessorMember(
|
| - PropertyAccessorElement baseElement, InterfaceType definingType)
|
| - : super(baseElement, definingType);
|
| -
|
| - @override
|
| - PropertyAccessorElement get baseElement =>
|
| - super.baseElement as PropertyAccessorElement;
|
| -
|
| - @override
|
| - PropertyAccessorElement get correspondingGetter =>
|
| - from(baseElement.correspondingGetter, definingType);
|
| -
|
| - @override
|
| - PropertyAccessorElement get correspondingSetter =>
|
| - from(baseElement.correspondingSetter, definingType);
|
| -
|
| - @override
|
| - InterfaceType get definingType => super.definingType as InterfaceType;
|
| -
|
| - @override
|
| - Element get enclosingElement => baseElement.enclosingElement;
|
| -
|
| - @override
|
| - bool get isGetter => baseElement.isGetter;
|
| -
|
| - @override
|
| - bool get isSetter => baseElement.isSetter;
|
| -
|
| - @override
|
| - PropertyInducingElement get variable {
|
| - PropertyInducingElement variable = baseElement.variable;
|
| - if (variable is FieldElement) {
|
| - return FieldMember.from(variable, definingType);
|
| - }
|
| - return variable;
|
| - }
|
| -
|
| - @override
|
| - accept(ElementVisitor visitor) => visitor.visitPropertyAccessorElement(this);
|
| -
|
| - @override
|
| - String toString() {
|
| - PropertyAccessorElement baseElement = this.baseElement;
|
| - List<ParameterElement> parameters = this.parameters;
|
| - FunctionType type = this.type;
|
| - StringBuffer builder = new StringBuffer();
|
| - if (isGetter) {
|
| - builder.write("get ");
|
| - } else {
|
| - builder.write("set ");
|
| - }
|
| - builder.write(baseElement.enclosingElement.displayName);
|
| - builder.write(".");
|
| - builder.write(baseElement.displayName);
|
| - builder.write("(");
|
| - int parameterCount = parameters.length;
|
| - for (int i = 0; i < parameterCount; i++) {
|
| - if (i > 0) {
|
| - builder.write(", ");
|
| - }
|
| - builder.write(parameters[i]);
|
| - }
|
| - builder.write(")");
|
| - if (type != null) {
|
| - builder.write(ElementImpl.RIGHT_ARROW);
|
| - builder.write(type.returnType);
|
| - }
|
| - return builder.toString();
|
| - }
|
| -
|
| - /**
|
| - * If the given [accessor]'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 PropertyAccessorElement from(
|
| - PropertyAccessorElement accessor, InterfaceType definingType) {
|
| - if (!_isChangedByTypeSubstitution(accessor, definingType)) {
|
| - return accessor;
|
| - }
|
| - // TODO(brianwilkerson) Consider caching the substituted type in the
|
| - // instance. It would use more memory but speed up some operations.
|
| - // We need to see how often the type is being re-computed.
|
| - return new PropertyAccessorMember(accessor, definingType);
|
| - }
|
| -
|
| - /**
|
| - * Determine whether the given property [accessor]'s type is changed when type
|
| - * parameters from the defining type's declaration are replaced with the
|
| - * actual type arguments from the [definingType].
|
| - */
|
| - static bool _isChangedByTypeSubstitution(
|
| - PropertyAccessorElement accessor, InterfaceType definingType) {
|
| - List<DartType> argumentTypes = definingType.typeArguments;
|
| - if (accessor != null && argumentTypes.length != 0) {
|
| - FunctionType baseType = accessor.type;
|
| - if (baseType == null) {
|
| - AnalysisEngine.instance.logger.logInformation(
|
| - 'Type of $accessor is null in PropertyAccessorMember._isChangedByTypeSubstitution');
|
| - return false;
|
| - }
|
| - List<DartType> parameterTypes = definingType.element.type.typeArguments;
|
| - FunctionType substitutedType =
|
| - baseType.substitute2(argumentTypes, parameterTypes);
|
| - if (baseType != substitutedType) {
|
| - return true;
|
| - }
|
| - // If this property accessor is based on a field, that field might have a
|
| - // propagated type. In which case we need to check whether the propagated
|
| - // type of the field needs substitution.
|
| - PropertyInducingElement field = accessor.variable;
|
| - if (!field.isSynthetic) {
|
| - DartType baseFieldType = field.propagatedType;
|
| - if (baseFieldType != null) {
|
| - DartType substitutedFieldType =
|
| - baseFieldType.substitute2(argumentTypes, parameterTypes);
|
| - if (baseFieldType != substitutedFieldType) {
|
| - return true;
|
| - }
|
| - }
|
| - }
|
| - }
|
| - return false;
|
| - }
|
| -}
|
| -
|
| -/**
|
| * A concrete implementation of a [PropertyInducingElement].
|
| */
|
| abstract class PropertyInducingElementImpl extends VariableElementImpl
|
| @@ -7077,289 +4261,92 @@ abstract class PropertyInducingElementImpl extends VariableElementImpl
|
| * The setter associated with this element, or `null` if the element is
|
| * effectively `final` and therefore does not have a setter associated with
|
| * it.
|
| - */
|
| - PropertyAccessorElement setter;
|
| -
|
| - /**
|
| - * The propagated type of this variable, or `null` if type propagation has not
|
| - * been performed.
|
| - */
|
| - DartType propagatedType;
|
| -
|
| - /**
|
| - * Initialize a newly created synthetic element to have the given [name] and
|
| - * [offset].
|
| - */
|
| - PropertyInducingElementImpl(String name, int offset) : super(name, offset);
|
| -
|
| - /**
|
| - * Initialize a newly created element to have the given [name].
|
| - */
|
| - PropertyInducingElementImpl.forNode(Identifier name) : super.forNode(name);
|
| -}
|
| -
|
| -/**
|
| - * A concrete implementation of a [ShowElementCombinator].
|
| - */
|
| -class ShowElementCombinatorImpl implements ShowElementCombinator {
|
| - /**
|
| - * The names that are to be made visible in the importing library if they are
|
| - * defined in the imported library.
|
| - */
|
| - List<String> shownNames = StringUtilities.EMPTY_ARRAY;
|
| -
|
| - /**
|
| - * The offset of the character immediately following the last character of
|
| - * this node.
|
| - */
|
| - int end = -1;
|
| -
|
| - /**
|
| - * The offset of the 'show' keyword of this element.
|
| - */
|
| - int offset = 0;
|
| -
|
| - @override
|
| - String toString() {
|
| - StringBuffer buffer = new StringBuffer();
|
| - buffer.write("show ");
|
| - int count = shownNames.length;
|
| - for (int i = 0; i < count; i++) {
|
| - if (i > 0) {
|
| - buffer.write(", ");
|
| - }
|
| - buffer.write(shownNames[i]);
|
| - }
|
| - return buffer.toString();
|
| - }
|
| -}
|
| -
|
| -/**
|
| - * A concrete implementation of a [TopLevelVariableElement].
|
| - */
|
| -class TopLevelVariableElementImpl extends PropertyInducingElementImpl
|
| - implements TopLevelVariableElement {
|
| - /**
|
| - * Initialize a newly created synthetic top-level variable element to have the
|
| - * given [name] and [offset].
|
| - */
|
| - TopLevelVariableElementImpl(String name, int offset) : super(name, offset);
|
| -
|
| - /**
|
| - * Initialize a newly created top-level variable element to have the given
|
| - * [name].
|
| - */
|
| - TopLevelVariableElementImpl.forNode(Identifier name) : super.forNode(name);
|
| -
|
| - @override
|
| - bool get isStatic => true;
|
| -
|
| - @override
|
| - ElementKind get kind => ElementKind.TOP_LEVEL_VARIABLE;
|
| -
|
| - @override
|
| - accept(ElementVisitor visitor) => visitor.visitTopLevelVariableElement(this);
|
| -
|
| - @override
|
| - VariableDeclaration computeNode() =>
|
| - getNodeMatching((node) => node is VariableDeclaration);
|
| -}
|
| -
|
| -/**
|
| - * The abstract class `TypeImpl` implements the behavior common to objects
|
| - * representing the declared type of elements in the element model.
|
| - */
|
| -abstract class TypeImpl implements DartType {
|
| - /**
|
| - * The element representing the declaration of this type, or `null` if the
|
| - * type has not, or cannot, be associated with an element.
|
| - */
|
| - final Element _element;
|
| -
|
| - /**
|
| - * The name of this type, or `null` if the type does not have a name.
|
| - */
|
| - final String name;
|
| -
|
| - /**
|
| - * Initialize a newly created type to be declared by the given [element] and
|
| - * to have the given [name].
|
| - */
|
| - TypeImpl(this._element, this.name);
|
| -
|
| - @override
|
| - String get displayName => name;
|
| -
|
| - @override
|
| - Element get element => _element;
|
| -
|
| - @override
|
| - bool get isBottom => false;
|
| -
|
| - @override
|
| - bool get isDartCoreFunction => false;
|
| -
|
| - @override
|
| - bool get isDynamic => false;
|
| -
|
| - @override
|
| - bool get isObject => false;
|
| -
|
| - @override
|
| - bool get isUndefined => false;
|
| -
|
| - @override
|
| - bool get isVoid => false;
|
| -
|
| - /**
|
| - * Append a textual representation of this type to the given [buffer]. The set
|
| - * of [visitedTypes] is used to prevent infinite recursion.
|
| - */
|
| - void appendTo(StringBuffer buffer) {
|
| - if (name == null) {
|
| - buffer.write("<unnamed type>");
|
| - } else {
|
| - buffer.write(name);
|
| - }
|
| - }
|
| + */
|
| + PropertyAccessorElement setter;
|
|
|
| /**
|
| - * Return `true` if this type is assignable to the given [type] (written in
|
| - * the spec as "T <=> S", where T=[this] and S=[type]).
|
| - *
|
| - * The sets [thisExpansions] and [typeExpansions], if given, are the sets of
|
| - * function type aliases that have been expanded so far in the process of
|
| - * reaching [this] and [type], respectively. These are used to avoid
|
| - * infinite regress when analyzing invalid code; since the language spec
|
| - * forbids a typedef from referring to itself directly or indirectly, we can
|
| - * use these as sets of function type aliases that don't need to be expanded.
|
| + * The propagated type of this variable, or `null` if type propagation has not
|
| + * been performed.
|
| */
|
| - @override
|
| - bool isAssignableTo(DartType type) {
|
| - // An interface type T may be assigned to a type S, written T <=> S, iff
|
| - // either T <: S or S <: T.
|
| - return isSubtypeOf(type) || (type as TypeImpl).isSubtypeOf(this);
|
| - }
|
| + DartType propagatedType;
|
|
|
| /**
|
| - * Return `true` if this type is more specific than the given [type] (written
|
| - * in the spec as "T << S", where T=[this] and S=[type]).
|
| - *
|
| - * If [withDynamic] is `true`, then "dynamic" should be considered as a
|
| - * subtype of any type (as though "dynamic" had been replaced with bottom).
|
| - *
|
| - * The set [visitedElements], if given, is the set of classes and type
|
| - * parameters that have been visited so far while examining the class
|
| - * hierarchy of [this]. This is used to avoid infinite regress when
|
| - * analyzing invalid code; since the language spec forbids loops in the class
|
| - * hierarchy, we can use this as a set of classes that don't need to be
|
| - * examined when walking the class hierarchy.
|
| + * Initialize a newly created synthetic element to have the given [name] and
|
| + * [offset].
|
| */
|
| - @override
|
| - bool isMoreSpecificThan(DartType type,
|
| - [bool withDynamic = false, Set<Element> visitedElements]);
|
| + PropertyInducingElementImpl(String name, int offset) : super(name, offset);
|
|
|
| /**
|
| - * Return `true` if this type is a subtype of the given [type] (written in
|
| - * the spec as "T <: S", where T=[this] and S=[type]).
|
| - *
|
| - * The sets [thisExpansions] and [typeExpansions], if given, are the sets of
|
| - * function type aliases that have been expanded so far in the process of
|
| - * reaching [this] and [type], respectively. These are used to avoid
|
| - * infinite regress when analyzing invalid code; since the language spec
|
| - * forbids a typedef from referring to itself directly or indirectly, we can
|
| - * use these as sets of function type aliases that don't need to be expanded.
|
| + * Initialize a newly created element to have the given [name].
|
| */
|
| - @override
|
| - bool isSubtypeOf(DartType type) {
|
| - // For non-function types, T <: S iff [_|_/dynamic]T << S.
|
| - return isMoreSpecificThan(type, true);
|
| - }
|
| + PropertyInducingElementImpl.forNode(Identifier name) : super.forNode(name);
|
| +}
|
|
|
| - @override
|
| - bool isSupertypeOf(DartType type) => type.isSubtypeOf(this);
|
| +/**
|
| + * A concrete implementation of a [ShowElementCombinator].
|
| + */
|
| +class ShowElementCombinatorImpl implements ShowElementCombinator {
|
| + /**
|
| + * The names that are to be made visible in the importing library if they are
|
| + * defined in the imported library.
|
| + */
|
| + List<String> shownNames = StringUtilities.EMPTY_ARRAY;
|
|
|
| /**
|
| - * Create a new [TypeImpl] that is identical to [this] except that when
|
| - * visiting type parameters, function parameter types, and function return
|
| - * types, function types listed in [prune] will not be expanded. This is
|
| - * used to avoid creating infinite types in the presence of circular
|
| - * typedefs.
|
| - *
|
| - * If [prune] is null, then [this] is returned unchanged.
|
| - *
|
| - * Only legal to call on a [TypeImpl] that is not already subject to pruning.
|
| + * The offset of the character immediately following the last character of
|
| + * this node.
|
| */
|
| - TypeImpl pruned(List<FunctionTypeAliasElement> prune);
|
| + int end = -1;
|
|
|
| /**
|
| - * Return the type resulting from substituting the given [argumentTypes] for
|
| - * the given [parameterTypes] in this type.
|
| - *
|
| - * In all classes derived from [TypeImpl], a new optional argument
|
| - * [prune] is added. If specified, it is a list of function typdefs
|
| - * which should not be expanded. This is used to avoid creating infinite
|
| - * types in response to self-referential typedefs.
|
| + * The offset of the 'show' keyword of this element.
|
| */
|
| - @override
|
| - DartType substitute2(
|
| - List<DartType> argumentTypes, List<DartType> parameterTypes,
|
| - [List<FunctionTypeAliasElement> prune]);
|
| + int offset = 0;
|
|
|
| @override
|
| String toString() {
|
| StringBuffer buffer = new StringBuffer();
|
| - appendTo(buffer);
|
| + buffer.write("show ");
|
| + int count = shownNames.length;
|
| + for (int i = 0; i < count; i++) {
|
| + if (i > 0) {
|
| + buffer.write(", ");
|
| + }
|
| + buffer.write(shownNames[i]);
|
| + }
|
| return buffer.toString();
|
| }
|
| +}
|
|
|
| +/**
|
| + * A concrete implementation of a [TopLevelVariableElement].
|
| + */
|
| +class TopLevelVariableElementImpl extends PropertyInducingElementImpl
|
| + implements TopLevelVariableElement {
|
| /**
|
| - * Return `true` if corresponding elements of the [first] and [second] lists
|
| - * of type arguments are all equal.
|
| + * Initialize a newly created synthetic top-level variable element to have the
|
| + * given [name] and [offset].
|
| */
|
| - static bool equalArrays(List<DartType> first, List<DartType> second) {
|
| - if (first.length != second.length) {
|
| - return false;
|
| - }
|
| - for (int i = 0; i < first.length; i++) {
|
| - if (first[i] == null) {
|
| - AnalysisEngine.instance.logger
|
| - .logInformation('Found null type argument in TypeImpl.equalArrays');
|
| - return second[i] == null;
|
| - } else if (second[i] == null) {
|
| - AnalysisEngine.instance.logger
|
| - .logInformation('Found null type argument in TypeImpl.equalArrays');
|
| - return false;
|
| - }
|
| - if (first[i] != second[i]) {
|
| - return false;
|
| - }
|
| - }
|
| - return true;
|
| - }
|
| + TopLevelVariableElementImpl(String name, int offset) : super(name, offset);
|
|
|
| /**
|
| - * Return a list containing the results of using the given [argumentTypes] and
|
| - * [parameterTypes] to perform a substitution on all of the given [types].
|
| - *
|
| - * If [prune] is specified, it is a list of function typdefs which should not
|
| - * be expanded. This is used to avoid creating infinite types in response to
|
| - * self-referential typedefs.
|
| - */
|
| - static List<DartType> substitute(List<DartType> types,
|
| - List<DartType> argumentTypes, List<DartType> parameterTypes,
|
| - [List<FunctionTypeAliasElement> prune]) {
|
| - int length = types.length;
|
| - if (length == 0) {
|
| - return types;
|
| - }
|
| - List<DartType> newTypes = new List<DartType>(length);
|
| - for (int i = 0; i < length; i++) {
|
| - newTypes[i] = (types[i] as TypeImpl)
|
| - .substitute2(argumentTypes, parameterTypes, prune);
|
| - }
|
| - return newTypes;
|
| - }
|
| + * Initialize a newly created top-level variable element to have the given
|
| + * [name].
|
| + */
|
| + TopLevelVariableElementImpl.forNode(Identifier name) : super.forNode(name);
|
| +
|
| + @override
|
| + bool get isStatic => true;
|
| +
|
| + @override
|
| + ElementKind get kind => ElementKind.TOP_LEVEL_VARIABLE;
|
| +
|
| + @override
|
| + accept(ElementVisitor visitor) => visitor.visitTopLevelVariableElement(this);
|
| +
|
| + @override
|
| + VariableDeclaration computeNode() =>
|
| + getNodeMatching((node) => node is VariableDeclaration);
|
| }
|
|
|
| /**
|
| @@ -7406,188 +4393,6 @@ class TypeParameterElementImpl extends ElementImpl
|
| }
|
|
|
| /**
|
| - * A concrete implementation of a [TypeParameterType].
|
| - */
|
| -class TypeParameterTypeImpl extends TypeImpl implements TypeParameterType {
|
| - /**
|
| - * Initialize a newly created type parameter type to be declared by the given
|
| - * [element] and to have the given name.
|
| - */
|
| - TypeParameterTypeImpl(TypeParameterElement element)
|
| - : super(element, element.name);
|
| -
|
| - @override
|
| - TypeParameterElement get element => super.element as TypeParameterElement;
|
| -
|
| - @override
|
| - int get hashCode => element.hashCode;
|
| -
|
| - @override
|
| - bool operator ==(Object object) =>
|
| - object is TypeParameterTypeImpl && (element == object.element);
|
| -
|
| - @override
|
| - bool isMoreSpecificThan(DartType s,
|
| - [bool withDynamic = false, Set<Element> visitedElements]) {
|
| - //
|
| - // A type T is more specific than a type S, written T << S,
|
| - // if one of the following conditions is met:
|
| - //
|
| - // Reflexivity: T is S.
|
| - //
|
| - if (this == s) {
|
| - return true;
|
| - }
|
| - // S is dynamic.
|
| - //
|
| - if (s.isDynamic) {
|
| - return true;
|
| - }
|
| - //
|
| - // T is a type parameter and S is the upper bound of T.
|
| - //
|
| - TypeImpl bound = element.bound;
|
| - if (s == bound) {
|
| - return true;
|
| - }
|
| - //
|
| - // T is a type parameter and S is Object.
|
| - //
|
| - if (s.isObject) {
|
| - return true;
|
| - }
|
| - // We need upper bound to continue.
|
| - if (bound == null) {
|
| - return false;
|
| - }
|
| - //
|
| - // Transitivity: T << U and U << S.
|
| - //
|
| - // First check for infinite loops
|
| - if (element == null) {
|
| - return false;
|
| - }
|
| - if (visitedElements == null) {
|
| - visitedElements = new HashSet<Element>();
|
| - } else if (visitedElements.contains(element)) {
|
| - return false;
|
| - }
|
| - visitedElements.add(element);
|
| - try {
|
| - return bound.isMoreSpecificThan(s, withDynamic, visitedElements);
|
| - } finally {
|
| - visitedElements.remove(element);
|
| - }
|
| - }
|
| -
|
| - @override
|
| - bool isSubtypeOf(DartType type) => isMoreSpecificThan(type, true);
|
| -
|
| - @override
|
| - TypeImpl pruned(List<FunctionTypeAliasElement> prune) => this;
|
| -
|
| - @override
|
| - DartType substitute2(
|
| - List<DartType> argumentTypes, List<DartType> parameterTypes,
|
| - [List<FunctionTypeAliasElement> prune]) {
|
| - int length = parameterTypes.length;
|
| - for (int i = 0; i < length; i++) {
|
| - if (parameterTypes[i] == this) {
|
| - return argumentTypes[i];
|
| - }
|
| - }
|
| - return this;
|
| - }
|
| -
|
| - /**
|
| - * Return a list containing the type parameter types defined by the given
|
| - * array of type parameter elements ([typeParameters]).
|
| - */
|
| - static List<TypeParameterType> getTypes(
|
| - List<TypeParameterElement> typeParameters) {
|
| - int count = typeParameters.length;
|
| - if (count == 0) {
|
| - return TypeParameterType.EMPTY_LIST;
|
| - }
|
| - List<TypeParameterType> types = new List<TypeParameterType>(count);
|
| - for (int i = 0; i < count; i++) {
|
| - types[i] = typeParameters[i].type;
|
| - }
|
| - return types;
|
| - }
|
| -}
|
| -
|
| -/**
|
| - * The unique instance of the class `UndefinedTypeImpl` implements the type of
|
| - * type names that couldn't be resolved.
|
| - *
|
| - * This class behaves like DynamicTypeImpl in almost every respect, to reduce
|
| - * cascading errors.
|
| - */
|
| -class UndefinedTypeImpl extends TypeImpl {
|
| - /**
|
| - * The unique instance of this class.
|
| - */
|
| - static UndefinedTypeImpl _INSTANCE = new UndefinedTypeImpl._();
|
| -
|
| - /**
|
| - * Return the unique instance of this class.
|
| - */
|
| - static UndefinedTypeImpl get instance => _INSTANCE;
|
| -
|
| - /**
|
| - * Prevent the creation of instances of this class.
|
| - */
|
| - UndefinedTypeImpl._()
|
| - : super(DynamicElementImpl.instance, Keyword.DYNAMIC.syntax);
|
| -
|
| - @override
|
| - int get hashCode => 1;
|
| -
|
| - @override
|
| - bool get isDynamic => true;
|
| -
|
| - @override
|
| - bool get isUndefined => true;
|
| -
|
| - @override
|
| - bool operator ==(Object object) => identical(object, this);
|
| -
|
| - @override
|
| - bool isMoreSpecificThan(DartType type,
|
| - [bool withDynamic = false, Set<Element> visitedElements]) {
|
| - // T is S
|
| - if (identical(this, type)) {
|
| - return true;
|
| - }
|
| - // else
|
| - return withDynamic;
|
| - }
|
| -
|
| - @override
|
| - bool isSubtypeOf(DartType type) => true;
|
| -
|
| - @override
|
| - bool isSupertypeOf(DartType type) => true;
|
| -
|
| - @override
|
| - TypeImpl pruned(List<FunctionTypeAliasElement> prune) => this;
|
| -
|
| - @override
|
| - DartType substitute2(
|
| - List<DartType> argumentTypes, List<DartType> parameterTypes,
|
| - [List<FunctionTypeAliasElement> prune]) {
|
| - int length = parameterTypes.length;
|
| - for (int i = 0; i < length; i++) {
|
| - if (parameterTypes[i] == this) {
|
| - return argumentTypes[i];
|
| - }
|
| - }
|
| - return this;
|
| - }
|
| -}
|
| -
|
| -/**
|
| * A concrete implementation of a [UriReferencedElement].
|
| */
|
| abstract class UriReferencedElementImpl extends ElementImpl
|
| @@ -7741,137 +4546,6 @@ abstract class VariableElementImpl extends ElementImpl
|
| }
|
|
|
| /**
|
| - * A variable element defined in a parameterized type where the values of the
|
| - * type parameters are known.
|
| - */
|
| -abstract class VariableMember extends Member implements VariableElement {
|
| - @override
|
| - final DartType type;
|
| -
|
| - /**
|
| - * Initialize a newly created element to represent a variable, based on the
|
| - * [baseElement], defined by the [definingType].
|
| - */
|
| - VariableMember(VariableElement baseElement, ParameterizedType definingType,
|
| - [DartType type])
|
| - : type = type ??
|
| - baseElement.type.substitute2(definingType.typeArguments,
|
| - TypeParameterTypeImpl.getTypes(definingType.typeParameters)),
|
| - super(baseElement, definingType);
|
| -
|
| - // TODO(jmesserly): this is temporary to allow the ParameterMember subclass.
|
| - // Apparently mixins don't work with optional params.
|
| - VariableMember._(VariableElement baseElement, ParameterizedType definingType,
|
| - DartType type)
|
| - : this(baseElement, definingType, type);
|
| -
|
| - @override
|
| - VariableElement get baseElement => super.baseElement as VariableElement;
|
| -
|
| - @override
|
| - DartObject get constantValue => baseElement.constantValue;
|
| -
|
| - @override
|
| - bool get hasImplicitType => baseElement.hasImplicitType;
|
| -
|
| - @override
|
| - FunctionElement get initializer {
|
| - //
|
| - // Elements within this element should have type parameters substituted,
|
| - // just like this element.
|
| - //
|
| - throw new UnsupportedOperationException();
|
| - // return getBaseElement().getInitializer();
|
| - }
|
| -
|
| - @override
|
| - bool get isConst => baseElement.isConst;
|
| -
|
| - @override
|
| - bool get isFinal => baseElement.isFinal;
|
| -
|
| - @override
|
| - bool get isPotentiallyMutatedInClosure =>
|
| - baseElement.isPotentiallyMutatedInClosure;
|
| -
|
| - @override
|
| - bool get isPotentiallyMutatedInScope =>
|
| - baseElement.isPotentiallyMutatedInScope;
|
| -
|
| - @override
|
| - bool get isStatic => baseElement.isStatic;
|
| -
|
| - @override
|
| - void visitChildren(ElementVisitor visitor) {
|
| - // TODO(brianwilkerson) We need to finish implementing the accessors used
|
| - // below so that we can safely invoke them.
|
| - super.visitChildren(visitor);
|
| - safelyVisitChild(baseElement.initializer, visitor);
|
| - }
|
| -}
|
| -
|
| -/**
|
| - * The type `void`.
|
| - */
|
| -abstract class VoidType implements DartType {
|
| - @override
|
| - VoidType substitute2(
|
| - List<DartType> argumentTypes, List<DartType> parameterTypes);
|
| -}
|
| -
|
| -/**
|
| - * A concrete implementation of a [VoidType].
|
| - */
|
| -class VoidTypeImpl extends TypeImpl implements VoidType {
|
| - /**
|
| - * The unique instance of this class.
|
| - */
|
| - static VoidTypeImpl _INSTANCE = new VoidTypeImpl();
|
| -
|
| - /**
|
| - * Return the unique instance of this class.
|
| - */
|
| - static VoidTypeImpl get instance => _INSTANCE;
|
| -
|
| - /**
|
| - * Prevent the creation of instances of this class.
|
| - */
|
| - VoidTypeImpl() : super(null, Keyword.VOID.syntax);
|
| -
|
| - @override
|
| - int get hashCode => 2;
|
| -
|
| - @override
|
| - bool get isVoid => true;
|
| -
|
| - @override
|
| - bool operator ==(Object object) => identical(object, this);
|
| -
|
| - @override
|
| - bool isMoreSpecificThan(DartType type,
|
| - [bool withDynamic = false, Set<Element> visitedElements]) =>
|
| - isSubtypeOf(type);
|
| -
|
| - @override
|
| - bool isSubtypeOf(DartType type) {
|
| - // The only subtype relations that pertain to void are therefore:
|
| - // void <: void (by reflexivity)
|
| - // bottom <: void (as bottom is a subtype of all types).
|
| - // void <: dynamic (as dynamic is a supertype of all types)
|
| - return identical(type, this) || type.isDynamic;
|
| - }
|
| -
|
| - @override
|
| - TypeImpl pruned(List<FunctionTypeAliasElement> prune) => this;
|
| -
|
| - @override
|
| - VoidTypeImpl substitute2(
|
| - List<DartType> argumentTypes, List<DartType> parameterTypes,
|
| - [List<FunctionTypeAliasElement> prune]) =>
|
| - this;
|
| -}
|
| -
|
| -/**
|
| * A visitor that visit all the elements recursively and fill the given [map].
|
| */
|
| class _BuildOffsetToElementMap extends GeneralizingElementVisitor {
|
|
|