Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(81)

Unified Diff: pkg/analyzer/lib/src/dart/element/element.dart

Issue 1525663003: Move the remainder of generated/element.dart into better locations (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/analyzer/CHANGELOG.md ('k') | pkg/analyzer/lib/src/dart/element/member.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 {
« no previous file with comments | « pkg/analyzer/CHANGELOG.md ('k') | pkg/analyzer/lib/src/dart/element/member.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698