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

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

Issue 103233003: New analyzer snapshot. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 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/lib/src/generated/constant.dart ('k') | pkg/analyzer/lib/src/generated/engine.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/analyzer/lib/src/generated/element.dart
diff --git a/pkg/analyzer/lib/src/generated/element.dart b/pkg/analyzer/lib/src/generated/element.dart
index ce01e2fadfae649202a3fabe0e778ffa03471d10..c024cc0d8b458be084baf6f48b9721d9c1f8f84c 100644
--- a/pkg/analyzer/lib/src/generated/element.dart
+++ b/pkg/analyzer/lib/src/generated/element.dart
@@ -182,6 +182,13 @@ abstract class ClassElement implements Element {
bool get isAbstract;
/**
+ * Return `true` if this element has an annotation of the form '@proxy'.
+ *
+ * @return `true` if this element defines a proxy
+ */
+ bool get isProxy;
+
+ /**
* Return `true` if this class is defined by a typedef construct.
*
* @return `true` if this class is defined by a typedef construct
@@ -408,6 +415,11 @@ abstract class ConstructorElement implements ClassMemberElement, ExecutableEleme
*/
abstract class Element {
/**
+ * An Unicode right arrow.
+ */
+ static final String RIGHT_ARROW = " \u2192 ";
+
+ /**
* A comparator that can be used to sort elements by their name offset. Elements with a smaller
* offset will be sorted to be before elements with a larger name offset.
*/
@@ -574,6 +586,31 @@ abstract class ElementAnnotation {
* @return the field, variable, or constructor being used as an annotation
*/
Element get element;
+
+ /**
+ * Return `true` if this annotation marks the associated element as being deprecated.
+ *
+ * @return `true` if this annotation marks the associated element as being deprecated
+ */
+ bool get isDeprecated;
+
+ /**
+ * Return `true` if this annotation marks the associated method as being expected to
+ * override an inherited method.
+ *
+ * @return `true` if this annotation marks the associated method as overriding another
+ * method
+ */
+ bool get isOverride;
+
+ /**
+ * Return `true` if this annotation marks the associated class as implementing a proxy
+ * object.
+ *
+ * @return `true` if this annotation marks the associated class as implementing a proxy
+ * object
+ */
+ bool get isProxy;
}
/**
@@ -2102,7 +2139,7 @@ class ClassElementImpl extends ElementImpl implements ClassElement {
classesToVisit.add(this);
while (!classesToVisit.isEmpty) {
ClassElement currentElement = classesToVisit.removeAt(0);
- if (javaSetAdd(visitedClasses, currentElement)) {
+ if (visitedClasses.add(currentElement)) {
for (FieldElement field in currentElement.fields) {
if (!field.isFinal && !field.isConst && !field.isStatic && !field.isSynthetic) {
return true;
@@ -2128,6 +2165,15 @@ class ClassElementImpl extends ElementImpl implements ClassElement {
bool get isAbstract => hasModifier(Modifier.ABSTRACT);
+ bool get isProxy {
+ for (ElementAnnotation annotation in metadata) {
+ if (annotation.isProxy) {
+ return true;
+ }
+ }
+ return false;
+ }
+
bool get isTypedef => hasModifier(Modifier.TYPEDEF);
bool get isValidMixin => hasModifier(Modifier.MIXIN);
@@ -2136,7 +2182,7 @@ class ClassElementImpl extends ElementImpl implements ClassElement {
Set<ClassElement> visitedClasses = new Set<ClassElement>();
ClassElement currentElement = this;
while (currentElement != null && !visitedClasses.contains(currentElement)) {
- javaSetAdd(visitedClasses, currentElement);
+ visitedClasses.add(currentElement);
PropertyAccessorElement element = currentElement.getGetter(getterName);
if (element != null && element.isAccessibleIn(library)) {
return element;
@@ -2163,7 +2209,7 @@ class ClassElementImpl extends ElementImpl implements ClassElement {
Set<ClassElement> visitedClasses = new Set<ClassElement>();
ClassElement currentElement = this;
while (currentElement != null && !visitedClasses.contains(currentElement)) {
- javaSetAdd(visitedClasses, currentElement);
+ visitedClasses.add(currentElement);
MethodElement element = currentElement.getMethod(methodName);
if (element != null && element.isAccessibleIn(library)) {
return element;
@@ -2190,7 +2236,7 @@ class ClassElementImpl extends ElementImpl implements ClassElement {
Set<ClassElement> visitedClasses = new Set<ClassElement>();
ClassElement currentElement = this;
while (currentElement != null && !visitedClasses.contains(currentElement)) {
- javaSetAdd(visitedClasses, currentElement);
+ visitedClasses.add(currentElement);
PropertyAccessorElement element = currentElement.getSetter(setterName);
if (element != null && element.isAccessibleIn(library)) {
return element;
@@ -2886,6 +2932,27 @@ class ElementAnnotationImpl implements ElementAnnotation {
static List<ElementAnnotationImpl> EMPTY_ARRAY = new List<ElementAnnotationImpl>(0);
/**
+ * The name of the class used to mark an element as being deprecated.
+ */
+ static String _DEPRECATED_CLASS_NAME = "Deprecated";
+
+ /**
+ * The name of the top-level variable used to mark an element as being deprecated.
+ */
+ static String _DEPRECATED_VARIABLE_NAME = "deprecated";
+
+ /**
+ * The name of the top-level variable used to mark a method as being expected to override an
+ * inherited method.
+ */
+ static String _OVERRIDE_VARIABLE_NAME = "override";
+
+ /**
+ * The name of the top-level variable used to mark a class as implementing a proxy object.
+ */
+ static String _PROXY_VARIABLE_NAME = "proxy";
+
+ /**
* Initialize a newly created annotation.
*
* @param element the element representing the field, variable, or constructor being used as an
@@ -2897,6 +2964,47 @@ class ElementAnnotationImpl implements ElementAnnotation {
Element get element => _element;
+ bool get isDeprecated {
+ if (_element != null) {
+ LibraryElement library = _element.library;
+ if (library != null && library.isDartCore) {
+ if (_element is ConstructorElement) {
+ ConstructorElement constructorElement = _element as ConstructorElement;
+ if (constructorElement.enclosingElement.name == _DEPRECATED_CLASS_NAME) {
+ return true;
+ }
+ } else if (_element is PropertyAccessorElement && _element.name == _DEPRECATED_VARIABLE_NAME) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ bool get isOverride {
+ if (_element != null) {
+ LibraryElement library = _element.library;
+ if (library != null && library.isDartCore) {
+ if (_element is PropertyAccessorElement && _element.name == _OVERRIDE_VARIABLE_NAME) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ bool get isProxy {
+ if (_element != null) {
+ LibraryElement library = _element.library;
+ if (library != null && library.isDartCore) {
+ if (_element is PropertyAccessorElement && _element.name == _PROXY_VARIABLE_NAME) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
String toString() => "@${_element.toString()}";
}
@@ -3037,19 +3145,8 @@ abstract class ElementImpl implements Element {
bool get isDeprecated {
for (ElementAnnotation annotation in _metadata) {
- Element element = annotation.element;
- if (element != null) {
- LibraryElement lib = element.library;
- if (lib != null && lib.isDartCore) {
- if (element is ConstructorElement) {
- ConstructorElement constructorElement = element as ConstructorElement;
- if (constructorElement.enclosingElement.name == "Deprecated") {
- return true;
- }
- } else if (element is PropertyAccessorElement && element.name == "deprecated") {
- return true;
- }
- }
+ if (annotation.isDeprecated) {
+ return true;
}
}
return false;
@@ -3578,7 +3675,7 @@ abstract class ExecutableElementImpl extends ElementImpl implements ExecutableEl
}
builder.append(")");
if (_type != null) {
- builder.append(" -> ");
+ builder.append(Element.RIGHT_ARROW);
builder.append(_type.returnType);
}
}
@@ -3819,6 +3916,45 @@ class FunctionElementImpl extends ExecutableElementImpl implements FunctionEleme
accept(ElementVisitor visitor) => visitor.visitFunctionElement(this);
+ /**
+ * Treating the set of arrays defined in [ExecutableElementImpl] as one long array, this
+ * returns the index position of the passed child in this [FunctionElement]. This gives a
+ * unique integer for each element, this is provided primarily for function elements that do not
+ * have a name (closures), which cannot use [Element#getNameOffset]. If there is no such
+ * element, `-1` is returned.
+ *
+ * @param element the element to find and return an integer for, if there is no such element,
+ * `-1` is returned
+ */
+ int getIndexPosition(Element element) {
+ List<FunctionElement> functions = this.functions;
+ List<LabelElement> labels = this.labels;
+ List<LocalVariableElement> localVariables = this.localVariables;
+ List<ParameterElement> parameters = this.parameters;
+ int count = 0;
+ for (int i = 0; i < functions.length; i++, count++) {
+ if (identical(element, functions[i])) {
+ return count;
+ }
+ }
+ for (int i = 0; i < labels.length; i++, count++) {
+ if (identical(element, labels[i])) {
+ return count;
+ }
+ }
+ for (int i = 0; i < localVariables.length; i++, count++) {
+ if (identical(element, localVariables[i])) {
+ return count;
+ }
+ }
+ for (int i = 0; i < parameters.length; i++, count++) {
+ if (identical(element, parameters[i])) {
+ return count;
+ }
+ }
+ return -1;
+ }
+
ElementKind get kind => ElementKind.FUNCTION;
SourceRange get visibleRange {
@@ -4017,7 +4153,7 @@ class FunctionTypeAliasElementImpl extends ElementImpl implements FunctionTypeAl
}
builder.append(")");
if (_type != null) {
- builder.append(" -> ");
+ builder.append(Element.RIGHT_ARROW);
builder.append(_type.returnType);
}
}
@@ -4371,7 +4507,7 @@ class LibraryElementImpl extends ElementImpl implements LibraryElement {
*/
static bool isUpToDate(LibraryElement library, int timeStamp, Set<LibraryElement> visitedLibraries) {
if (!visitedLibraries.contains(library)) {
- javaSetAdd(visitedLibraries, library);
+ visitedLibraries.add(library);
if (timeStamp < library.definingCompilationUnit.source.modificationStamp) {
return false;
}
@@ -4472,7 +4608,7 @@ class LibraryElementImpl extends ElementImpl implements LibraryElement {
for (ExportElement element in _exports) {
LibraryElement library = element.exportedLibrary;
if (library != null) {
- javaSetAdd(libraries, library);
+ libraries.add(library);
}
}
return new List.from(libraries);
@@ -4485,7 +4621,7 @@ class LibraryElementImpl extends ElementImpl implements LibraryElement {
for (ImportElement element in _imports) {
LibraryElement library = element.importedLibrary;
if (library != null) {
- javaSetAdd(libraries, library);
+ libraries.add(library);
}
}
return new List.from(libraries);
@@ -4504,7 +4640,7 @@ class LibraryElementImpl extends ElementImpl implements LibraryElement {
for (ImportElement element in _imports) {
PrefixElement prefix = element.prefix;
if (prefix != null) {
- javaSetAdd(prefixes, prefix);
+ prefixes.add(prefix);
}
}
return new List.from(prefixes);
@@ -4896,10 +5032,10 @@ class MultiplyDefinedElementImpl implements MultiplyDefinedElement {
static void add(Set<Element> elements, Element element) {
if (element is MultiplyDefinedElementImpl) {
for (Element conflictingElement in (element as MultiplyDefinedElementImpl)._conflictingElements) {
- javaSetAdd(elements, conflictingElement);
+ elements.add(conflictingElement);
}
} else {
- javaSetAdd(elements, element);
+ elements.add(element);
}
}
@@ -5806,7 +5942,7 @@ class ConstructorMember extends ExecutableMember implements ConstructorElement {
}
builder.append(")");
if (type != null) {
- builder.append(" -> ");
+ builder.append(Element.RIGHT_ARROW);
builder.append(type.returnType);
}
return builder.toString();
@@ -5873,6 +6009,24 @@ abstract class ExecutableMember extends Member implements ExecutableElement {
}
/**
+ * Instances of the class `FieldFormalParameterMember` represent 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 parameter of the given parameterized type.
+ *
+ * @param baseElement the element on which the parameterized element was created
+ * @param definingType the type in which the element is defined
+ */
+ FieldFormalParameterMember(FieldFormalParameterElement baseElement, ParameterizedType definingType) : super(baseElement, definingType);
+
+ accept(ElementVisitor visitor) => visitor.visitFieldFormalParameterElement(this);
+
+ FieldElement get field => (baseElement as FieldFormalParameterElement).field;
+}
+
+/**
* Instances of the class `FieldMember` represent a field element defined in a parameterized
* type where the values of the type parameters are known.
*/
@@ -6119,7 +6273,7 @@ class MethodMember extends ExecutableMember implements MethodElement {
}
builder.append(")");
if (type != null) {
- builder.append(" -> ");
+ builder.append(Element.RIGHT_ARROW);
builder.append(type.returnType);
}
return builder.toString();
@@ -6146,7 +6300,8 @@ class ParameterMember extends VariableMember implements ParameterElement {
if (baseParameter == null || definingType.typeArguments.length == 0) {
return baseParameter;
}
- if (baseParameter is! FieldFormalParameterElement) {
+ bool isFieldFormal = baseParameter is FieldFormalParameterElement;
+ if (!isFieldFormal) {
Type2 baseType = baseParameter.type;
List<Type2> argumentTypes = definingType.typeArguments;
List<Type2> parameterTypes = TypeParameterTypeImpl.getTypes(definingType.typeParameters);
@@ -6155,6 +6310,9 @@ class ParameterMember extends VariableMember implements ParameterElement {
return baseParameter;
}
}
+ if (isFieldFormal) {
+ return new FieldFormalParameterMember(baseParameter as FieldFormalParameterElement, definingType);
+ }
return new ParameterMember(baseParameter, definingType);
}
@@ -6324,7 +6482,7 @@ class PropertyAccessorMember extends ExecutableMember implements PropertyAccesso
}
builder.append(")");
if (type != null) {
- builder.append(" -> ");
+ builder.append(Element.RIGHT_ARROW);
builder.append(type.returnType);
}
return builder.toString();
@@ -6386,13 +6544,13 @@ class BottomTypeImpl extends TypeImpl {
bool get isBottom => true;
- bool isMoreSpecificThan3(Type2 type, bool withDynamic) => true;
-
- bool isSubtypeOf(Type2 type) => true;
-
bool isSupertypeOf(Type2 type) => false;
BottomTypeImpl substitute2(List<Type2> argumentTypes, List<Type2> parameterTypes) => this;
+
+ bool internalIsMoreSpecificThan(Type2 type, bool withDynamic, Set<TypeImpl_TypePair> visitedTypePairs) => true;
+
+ bool internalIsSubtypeOf(Type2 type, Set<TypeImpl_TypePair> visitedTypePairs) => true;
}
/**
@@ -6417,15 +6575,6 @@ class DynamicTypeImpl extends TypeImpl {
bool get isDynamic => true;
- bool isMoreSpecificThan3(Type2 type, bool withDynamic) {
- if (identical(this, type)) {
- return true;
- }
- return withDynamic;
- }
-
- bool isSubtypeOf(Type2 type) => true;
-
bool isSupertypeOf(Type2 type) => true;
Type2 substitute2(List<Type2> argumentTypes, List<Type2> parameterTypes) {
@@ -6437,6 +6586,15 @@ class DynamicTypeImpl extends TypeImpl {
}
return this;
}
+
+ bool internalIsMoreSpecificThan(Type2 type, bool withDynamic, Set<TypeImpl_TypePair> visitedTypePairs) {
+ if (identical(this, type)) {
+ return true;
+ }
+ return withDynamic;
+ }
+
+ bool internalIsSubtypeOf(Type2 type, Set<TypeImpl_TypePair> visitedTypePairs) => true;
}
/**
@@ -6557,7 +6715,8 @@ class FunctionTypeImpl extends TypeImpl implements FunctionType {
builder.append("}");
needsComma = true;
}
- builder.append(") -> ");
+ builder.append(")");
+ builder.append(Element.RIGHT_ARROW);
if (returnType == null) {
builder.append("null");
} else {
@@ -6656,9 +6815,7 @@ class FunctionTypeImpl extends TypeImpl implements FunctionType {
return element.hashCode;
}
- bool isAssignableTo(Type2 type) => this.isSubtypeOf(type);
-
- bool isMoreSpecificThan3(Type2 type, bool withDynamic) {
+ bool internalIsMoreSpecificThan(Type2 type, bool withDynamic, Set<TypeImpl_TypePair> visitedTypePairs) {
if (type == null) {
return false;
} else if (identical(this, type) || type.isDynamic || type.isDartCoreFunction || type.isObject) {
@@ -6682,7 +6839,7 @@ class FunctionTypeImpl extends TypeImpl implements FunctionType {
return false;
} else if (t.normalParameterTypes.length > 0) {
for (int i = 0; i < tTypes.length; i++) {
- if (!tTypes[i].isMoreSpecificThan3(sTypes[i], withDynamic)) {
+ if (!(tTypes[i] as TypeImpl).isMoreSpecificThan3(sTypes[i], withDynamic, visitedTypePairs)) {
return false;
}
}
@@ -6699,7 +6856,7 @@ class FunctionTypeImpl extends TypeImpl implements FunctionType {
if (typeT == null) {
return false;
}
- if (!typeT.isMoreSpecificThan3(entryS.getValue(), withDynamic)) {
+ if (!(typeT as TypeImpl).isMoreSpecificThan3(entryS.getValue(), withDynamic, visitedTypePairs)) {
return false;
}
}
@@ -6713,7 +6870,7 @@ class FunctionTypeImpl extends TypeImpl implements FunctionType {
}
if (tOpTypes.length == 0 && sOpTypes.length == 0) {
for (int i = 0; i < sTypes.length; i++) {
- if (!tTypes[i].isMoreSpecificThan3(sTypes[i], withDynamic)) {
+ if (!(tTypes[i] as TypeImpl).isMoreSpecificThan3(sTypes[i], withDynamic, visitedTypePairs)) {
return false;
}
}
@@ -6733,7 +6890,7 @@ class FunctionTypeImpl extends TypeImpl implements FunctionType {
sAllTypes[i] = sOpTypes[j];
}
for (int i = 0; i < sAllTypes.length; i++) {
- if (!tAllTypes[i].isMoreSpecificThan3(sAllTypes[i], withDynamic)) {
+ if (!(tAllTypes[i] as TypeImpl).isMoreSpecificThan3(sAllTypes[i], withDynamic, visitedTypePairs)) {
return false;
}
}
@@ -6741,94 +6898,10 @@ class FunctionTypeImpl extends TypeImpl implements FunctionType {
}
Type2 tRetType = t.returnType;
Type2 sRetType = s.returnType;
- return sRetType.isVoid || tRetType.isMoreSpecificThan3(sRetType, withDynamic);
+ return sRetType.isVoid || (tRetType as TypeImpl).isMoreSpecificThan3(sRetType, withDynamic, visitedTypePairs);
}
- bool isSubtypeOf(Type2 type) {
- 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<Type2> tTypes = t.normalParameterTypes;
- List<Type2> tOpTypes = t.optionalParameterTypes;
- List<Type2> sTypes = s.normalParameterTypes;
- List<Type2> sOpTypes = s.optionalParameterTypes;
- if ((sOpTypes.length > 0 && t.namedParameterTypes.length > 0) || (tOpTypes.length > 0 && s.namedParameterTypes.length > 0)) {
- return false;
- }
- if (t.namedParameterTypes.length > 0) {
- 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].isAssignableTo(sTypes[i])) {
- return false;
- }
- }
- }
- Map<String, Type2> namedTypesT = t.namedParameterTypes;
- Map<String, Type2> namedTypesS = s.namedParameterTypes;
- if (namedTypesT.length < namedTypesS.length) {
- return false;
- }
- JavaIterator<MapEntry<String, Type2>> iteratorS = new JavaIterator(getMapEntrySet(namedTypesS));
- while (iteratorS.hasNext) {
- MapEntry<String, Type2> entryS = iteratorS.next();
- Type2 typeT = namedTypesT[entryS.getKey()];
- if (typeT == null) {
- return false;
- }
- if (!typeT.isAssignableTo(entryS.getValue())) {
- return false;
- }
- }
- } else if (s.namedParameterTypes.length > 0) {
- return false;
- } else {
- int tArgLength = tTypes.length + tOpTypes.length;
- int sArgLength = sTypes.length + sOpTypes.length;
- if (tArgLength < sArgLength || sTypes.length < tTypes.length) {
- return false;
- }
- if (tOpTypes.length == 0 && sOpTypes.length == 0) {
- for (int i = 0; i < sTypes.length; i++) {
- if (!tTypes[i].isAssignableTo(sTypes[i])) {
- return false;
- }
- }
- } else {
- List<Type2> tAllTypes = new List<Type2>(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<Type2> sAllTypes = new List<Type2>(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].isAssignableTo(sAllTypes[i])) {
- return false;
- }
- }
- }
- }
- Type2 tRetType = t.returnType;
- Type2 sRetType = s.returnType;
- return sRetType.isVoid || tRetType.isAssignableTo(sRetType);
- }
+ bool isAssignableTo(Type2 type) => isSubtypeOf3(type, new Set<TypeImpl_TypePair>());
/**
* Set the actual types of the type arguments to the given types.
@@ -6907,7 +6980,8 @@ class FunctionTypeImpl extends TypeImpl implements FunctionType {
builder.append("}");
needsComma = true;
}
- builder.append(") -> ");
+ builder.append(")");
+ builder.append(Element.RIGHT_ARROW);
if (returnType == null) {
builder.append("null");
} else {
@@ -6927,6 +7001,92 @@ class FunctionTypeImpl extends TypeImpl implements FunctionType {
}
}
+ bool internalIsSubtypeOf(Type2 type, Set<TypeImpl_TypePair> visitedTypePairs) {
+ 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<Type2> tTypes = t.normalParameterTypes;
+ List<Type2> tOpTypes = t.optionalParameterTypes;
+ List<Type2> sTypes = s.normalParameterTypes;
+ List<Type2> sOpTypes = s.optionalParameterTypes;
+ if ((sOpTypes.length > 0 && t.namedParameterTypes.length > 0) || (tOpTypes.length > 0 && s.namedParameterTypes.length > 0)) {
+ return false;
+ }
+ if (t.namedParameterTypes.length > 0) {
+ 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).isAssignableTo2(sTypes[i], visitedTypePairs)) {
+ return false;
+ }
+ }
+ }
+ Map<String, Type2> namedTypesT = t.namedParameterTypes;
+ Map<String, Type2> namedTypesS = s.namedParameterTypes;
+ if (namedTypesT.length < namedTypesS.length) {
+ return false;
+ }
+ JavaIterator<MapEntry<String, Type2>> iteratorS = new JavaIterator(getMapEntrySet(namedTypesS));
+ while (iteratorS.hasNext) {
+ MapEntry<String, Type2> entryS = iteratorS.next();
+ Type2 typeT = namedTypesT[entryS.getKey()];
+ if (typeT == null) {
+ return false;
+ }
+ if (!(typeT as TypeImpl).isAssignableTo2(entryS.getValue(), visitedTypePairs)) {
+ return false;
+ }
+ }
+ } else if (s.namedParameterTypes.length > 0) {
+ return false;
+ } else {
+ int tArgLength = tTypes.length + tOpTypes.length;
+ int sArgLength = sTypes.length + sOpTypes.length;
+ if (tArgLength < sArgLength || sTypes.length < tTypes.length) {
+ return false;
+ }
+ if (tOpTypes.length == 0 && sOpTypes.length == 0) {
+ for (int i = 0; i < sTypes.length; i++) {
+ if (!(tTypes[i] as TypeImpl).isAssignableTo2(sTypes[i], visitedTypePairs)) {
+ return false;
+ }
+ }
+ } else {
+ List<Type2> tAllTypes = new List<Type2>(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<Type2> sAllTypes = new List<Type2>(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).isAssignableTo2(sAllTypes[i], visitedTypePairs)) {
+ return false;
+ }
+ }
+ }
+ }
+ Type2 tRetType = t.returnType;
+ Type2 sRetType = s.returnType;
+ return sRetType.isVoid || (tRetType as TypeImpl).isAssignableTo2(sRetType, visitedTypePairs);
+ }
+
/**
* Return the return type defined by this function's element.
*
@@ -6994,7 +7154,7 @@ class InterfaceTypeImpl extends TypeImpl implements InterfaceType {
}
int longestPath = 1;
try {
- javaSetAdd(visitedClasses, classElement);
+ visitedClasses.add(classElement);
List<InterfaceType> superinterfaces = classElement.interfaces;
int pathLength;
if (superinterfaces.length > 0) {
@@ -7032,13 +7192,13 @@ class InterfaceTypeImpl extends TypeImpl implements InterfaceType {
ClassElement classElement = element as ClassElement;
List<InterfaceType> superinterfaces = classElement.interfaces;
for (InterfaceType superinterface in superinterfaces) {
- if (javaSetAdd(set, superinterface)) {
+ if (set.add(superinterface)) {
computeSuperinterfaceSet2(superinterface, set);
}
}
InterfaceType supertype = classElement.supertype;
if (supertype != null) {
- if (javaSetAdd(set, supertype)) {
+ if (set.add(supertype)) {
computeSuperinterfaceSet2(supertype, set);
}
}
@@ -7066,7 +7226,7 @@ class InterfaceTypeImpl extends TypeImpl implements InterfaceType {
for (InterfaceType secondType in second) {
InterfaceType firstType = firstMap[secondType.element];
if (firstType != null) {
- javaSetAdd(result, leastUpperBound(firstType, secondType));
+ result.add(leastUpperBound(firstType, secondType));
}
}
return new List.from(result);
@@ -7205,8 +7365,8 @@ class InterfaceTypeImpl extends TypeImpl implements InterfaceType {
InterfaceType j = type as InterfaceType;
Set<InterfaceType> si = computeSuperinterfaceSet(i);
Set<InterfaceType> sj = computeSuperinterfaceSet(j);
- javaSetAdd(si, i);
- javaSetAdd(sj, j);
+ si.add(i);
+ sj.add(j);
List<InterfaceType> s = intersection(si, sj);
List<int> depths = new List<int>.filled(s.length, 0);
int maxDepth = 0;
@@ -7319,37 +7479,8 @@ class InterfaceTypeImpl extends TypeImpl implements InterfaceType {
return false;
}
- bool isMoreSpecificThan3(Type2 type, bool withDynamic) {
- if (identical(type, DynamicTypeImpl.instance)) {
- return true;
- } else if (type is! InterfaceType) {
- return false;
- }
- return isMoreSpecificThan2(type as InterfaceType, new Set<ClassElement>(), withDynamic);
- }
-
bool get isObject => element.supertype == null;
- bool isSubtypeOf(Type2 type) {
- if (identical(type, DynamicTypeImpl.instance)) {
- return true;
- } else if (type is TypeParameterType) {
- return true;
- } else if (type is FunctionType) {
- ClassElement element = this.element;
- MethodElement callMethod = element.lookUpMethod("call", element.library);
- if (callMethod != null) {
- return callMethod.type.isSubtypeOf(type);
- }
- return false;
- } else if (type is! InterfaceType) {
- return false;
- } else if (this == type) {
- return true;
- }
- return isSubtypeOf2(type as InterfaceType, new Set<ClassElement>());
- }
-
ConstructorElement lookUpConstructor(String constructorName, LibraryElement library) {
ConstructorElement constructorElement;
if (constructorName == null) {
@@ -7382,7 +7513,7 @@ class InterfaceTypeImpl extends TypeImpl implements InterfaceType {
InterfaceType supertype = superclass;
ClassElement supertypeElement = supertype == null ? null : supertype.element;
while (supertype != null && !visitedClasses.contains(supertypeElement)) {
- javaSetAdd(visitedClasses, supertypeElement);
+ visitedClasses.add(supertypeElement);
PropertyAccessorElement element = supertype.getGetter(getterName);
if (element != null && element.isAccessibleIn(library)) {
return element;
@@ -7418,7 +7549,7 @@ class InterfaceTypeImpl extends TypeImpl implements InterfaceType {
InterfaceType supertype = superclass;
ClassElement supertypeElement = supertype == null ? null : supertype.element;
while (supertype != null && !visitedClasses.contains(supertypeElement)) {
- javaSetAdd(visitedClasses, supertypeElement);
+ visitedClasses.add(supertypeElement);
MethodElement element = supertype.getMethod(methodName);
if (element != null && element.isAccessibleIn(library)) {
return element;
@@ -7454,7 +7585,7 @@ class InterfaceTypeImpl extends TypeImpl implements InterfaceType {
InterfaceType supertype = superclass;
ClassElement supertypeElement = supertype == null ? null : supertype.element;
while (supertype != null && !visitedClasses.contains(supertypeElement)) {
- javaSetAdd(visitedClasses, supertypeElement);
+ visitedClasses.add(supertypeElement);
PropertyAccessorElement element = supertype.getSetter(setterName);
if (element != null && element.isAccessibleIn(library)) {
return element;
@@ -7513,7 +7644,36 @@ class InterfaceTypeImpl extends TypeImpl implements InterfaceType {
}
}
- bool isMoreSpecificThan2(InterfaceType s, Set<ClassElement> visitedClasses, bool withDynamic) {
+ bool internalIsMoreSpecificThan(Type2 type, bool withDynamic, Set<TypeImpl_TypePair> visitedTypePairs) {
+ if (identical(type, DynamicTypeImpl.instance)) {
+ return true;
+ } else if (type is! InterfaceType) {
+ return false;
+ }
+ return isMoreSpecificThan2(type as InterfaceType, new Set<ClassElement>(), withDynamic, visitedTypePairs);
+ }
+
+ bool internalIsSubtypeOf(Type2 type, Set<TypeImpl_TypePair> visitedTypePairs) {
+ if (identical(type, DynamicTypeImpl.instance)) {
+ return true;
+ } else if (type is TypeParameterType) {
+ return true;
+ } else if (type is FunctionType) {
+ ClassElement element = this.element;
+ MethodElement callMethod = element.lookUpMethod("call", element.library);
+ if (callMethod != null) {
+ return callMethod.type.isSubtypeOf(type);
+ }
+ return false;
+ } else if (type is! InterfaceType) {
+ return false;
+ } else if (this == type) {
+ return true;
+ }
+ return isSubtypeOf2(type as InterfaceType, new Set<ClassElement>(), visitedTypePairs);
+ }
+
+ bool isMoreSpecificThan2(InterfaceType s, Set<ClassElement> visitedClasses, bool withDynamic, Set<TypeImpl_TypePair> visitedTypePairs) {
if (this == s) {
return true;
}
@@ -7529,7 +7689,7 @@ class InterfaceTypeImpl extends TypeImpl implements InterfaceType {
return false;
}
for (int i = 0; i < tArguments.length; i++) {
- if (!tArguments[i].isMoreSpecificThan3(sArguments[i], withDynamic)) {
+ if (!(tArguments[i] as TypeImpl).isMoreSpecificThan3(sArguments[i], withDynamic, visitedTypePairs)) {
return false;
}
}
@@ -7539,32 +7699,32 @@ class InterfaceTypeImpl extends TypeImpl implements InterfaceType {
if (element == null || visitedClasses.contains(element)) {
return false;
}
- javaSetAdd(visitedClasses, element);
+ visitedClasses.add(element);
InterfaceType supertype = superclass;
- if (supertype != null && (supertype as InterfaceTypeImpl).isMoreSpecificThan2(s, visitedClasses, withDynamic)) {
+ if (supertype != null && (supertype as InterfaceTypeImpl).isMoreSpecificThan2(s, visitedClasses, withDynamic, visitedTypePairs)) {
return true;
}
for (InterfaceType interfaceType in interfaces) {
- if ((interfaceType as InterfaceTypeImpl).isMoreSpecificThan2(s, visitedClasses, withDynamic)) {
+ if ((interfaceType as InterfaceTypeImpl).isMoreSpecificThan2(s, visitedClasses, withDynamic, visitedTypePairs)) {
return true;
}
}
for (InterfaceType mixinType in mixins) {
- if ((mixinType as InterfaceTypeImpl).isMoreSpecificThan2(s, visitedClasses, withDynamic)) {
+ if ((mixinType as InterfaceTypeImpl).isMoreSpecificThan2(s, visitedClasses, withDynamic, visitedTypePairs)) {
return true;
}
}
return false;
}
- bool isSubtypeOf2(InterfaceType type, Set<ClassElement> visitedClasses) {
+ bool isSubtypeOf2(InterfaceType type, Set<ClassElement> visitedClasses, Set<TypeImpl_TypePair> visitedTypePairs) {
InterfaceType typeT = this;
InterfaceType typeS = type;
ClassElement elementT = element;
if (elementT == null || visitedClasses.contains(elementT)) {
return false;
}
- javaSetAdd(visitedClasses, elementT);
+ visitedClasses.add(elementT);
if (typeT == typeS) {
return true;
} else if (elementT == typeS.element) {
@@ -7574,7 +7734,7 @@ class InterfaceTypeImpl extends TypeImpl implements InterfaceType {
return false;
}
for (int i = 0; i < typeTArgs.length; i++) {
- if (!typeTArgs[i].isSubtypeOf(typeSArgs[i])) {
+ if (!(typeTArgs[i] as TypeImpl).isSubtypeOf3(typeSArgs[i], visitedTypePairs)) {
return false;
}
}
@@ -7583,18 +7743,18 @@ class InterfaceTypeImpl extends TypeImpl implements InterfaceType {
return true;
}
InterfaceType supertype = superclass;
- if (supertype != null && (supertype as InterfaceTypeImpl).isSubtypeOf2(typeS, visitedClasses)) {
+ if (supertype != null && (supertype as InterfaceTypeImpl).isSubtypeOf2(typeS, visitedClasses, visitedTypePairs)) {
return true;
}
List<InterfaceType> interfaceTypes = interfaces;
for (InterfaceType interfaceType in interfaceTypes) {
- if ((interfaceType as InterfaceTypeImpl).isSubtypeOf2(typeS, visitedClasses)) {
+ if ((interfaceType as InterfaceTypeImpl).isSubtypeOf2(typeS, visitedClasses, visitedTypePairs)) {
return true;
}
}
List<InterfaceType> mixinTypes = mixins;
for (InterfaceType mixinType in mixinTypes) {
- if ((mixinType as InterfaceTypeImpl).isSubtypeOf2(typeS, visitedClasses)) {
+ if ((mixinType as InterfaceTypeImpl).isSubtypeOf2(typeS, visitedClasses, visitedTypePairs)) {
return true;
}
}
@@ -7665,7 +7825,22 @@ abstract class TypeImpl implements Type2 {
String get name => _name;
- bool isAssignableTo(Type2 type) => this.isSubtypeOf(type) || type.isSubtypeOf(this);
+ bool isAssignableTo(Type2 type) => isAssignableTo2(type, new Set<TypeImpl_TypePair>());
+
+ /**
+ * Return `true` if this type is assignable to the given type. A type <i>T</i> may be
+ * assigned to a type <i>S</i>, written <i>T</i> &hArr; <i>S</i>, iff either <i>T</i> <: <i>S</i>
+ * or <i>S</i> <: <i>T</i>.
+ *
+ * The given set of pairs of types (T1, T2), where each pair indicates that we invoked this method
+ * because we are in the process of answering the question of whether T1 is a subtype of T2, is
+ * used to prevent infinite loops.
+ *
+ * @param type the type being compared with this type
+ * @param visitedPairs the set of pairs of types used to prevent infinite loops
+ * @return `true` if this type is assignable to the given type
+ */
+ bool isAssignableTo2(Type2 type, Set<TypeImpl_TypePair> visitedTypePairs) => isSubtypeOf3(type, visitedTypePairs) || (type as TypeImpl).isSubtypeOf3(this, visitedTypePairs);
bool get isBottom => false;
@@ -7673,12 +7848,55 @@ abstract class TypeImpl implements Type2 {
bool get isDynamic => false;
- bool isMoreSpecificThan(Type2 type) => isMoreSpecificThan3(type, false);
+ bool isMoreSpecificThan(Type2 type) => isMoreSpecificThan3(type, false, new Set<TypeImpl_TypePair>());
- bool isMoreSpecificThan3(Type2 type, bool withDynamic) => false;
+ /**
+ * Return `true` if this type is more specific than the given type.
+ *
+ * The given set of pairs of types (T1, T2), where each pair indicates that we invoked this method
+ * because we are in the process of answering the question of whether T1 is a subtype of T2, is
+ * used to prevent infinite loops.
+ *
+ * @param type the type being compared with this type
+ * @param withDynamic `true` if "dynamic" should be considered as a subtype of any type
+ * @param visitedPairs the set of pairs of types used to prevent infinite loops
+ * @return `true` if this type is more specific than the given type
+ */
+ bool isMoreSpecificThan3(Type2 type, bool withDynamic, Set<TypeImpl_TypePair> visitedTypePairs) {
+ TypeImpl_TypePair typePair = new TypeImpl_TypePair(this, type);
+ if (!visitedTypePairs.add(typePair)) {
+ return false;
+ }
+ bool result = internalIsMoreSpecificThan(type, withDynamic, visitedTypePairs);
+ visitedTypePairs.remove(typePair);
+ return result;
+ }
bool get isObject => false;
+ bool isSubtypeOf(Type2 type) => isSubtypeOf3(type, new Set<TypeImpl_TypePair>());
+
+ /**
+ * Return `true` if this type is a subtype of the given type.
+ *
+ * The given set of pairs of types (T1, T2), where each pair indicates that we invoked this method
+ * because we are in the process of answering the question of whether T1 is a subtype of T2, is
+ * used to prevent infinite loops.
+ *
+ * @param type the type being compared with this type
+ * @param visitedPairs the set of pairs of types used to prevent infinite loops
+ * @return `true` if this type is a subtype of the given type
+ */
+ bool isSubtypeOf3(Type2 type, Set<TypeImpl_TypePair> visitedTypePairs) {
+ TypeImpl_TypePair typePair = new TypeImpl_TypePair(this, type);
+ if (!visitedTypePairs.add(typePair)) {
+ return false;
+ }
+ bool result = internalIsSubtypeOf(type, visitedTypePairs);
+ visitedTypePairs.remove(typePair);
+ return result;
+ }
+
bool isSupertypeOf(Type2 type) => type.isSubtypeOf(this);
bool get isVoid => false;
@@ -7701,6 +7919,44 @@ abstract class TypeImpl implements Type2 {
builder.append(_name);
}
}
+
+ bool internalIsMoreSpecificThan(Type2 type, bool withDynamic, Set<TypeImpl_TypePair> visitedTypePairs);
+
+ bool internalIsSubtypeOf(Type2 type, Set<TypeImpl_TypePair> visitedTypePairs);
+}
+
+class TypeImpl_TypePair {
+ Type2 _firstType;
+
+ Type2 _secondType;
+
+ TypeImpl_TypePair(Type2 firstType, Type2 secondType) {
+ this._firstType = firstType;
+ this._secondType = secondType;
+ }
+
+ bool operator ==(Object object) {
+ if (identical(object, this)) {
+ return true;
+ }
+ if (object is TypeImpl_TypePair) {
+ TypeImpl_TypePair typePair = object as TypeImpl_TypePair;
+ return _firstType == typePair._firstType && _secondType != null && _secondType == typePair._secondType;
+ }
+ return false;
+ }
+
+ int get hashCode {
+ int firstHashCode = 0;
+ if (_firstType != null) {
+ firstHashCode = _firstType.element == null ? 0 : _firstType.element.hashCode;
+ }
+ int secondHashCode = 0;
+ if (_secondType != null) {
+ secondHashCode = _secondType.element == null ? 0 : _secondType.element.hashCode;
+ }
+ return firstHashCode + secondHashCode;
+ }
}
/**
@@ -7749,7 +8005,17 @@ class TypeParameterTypeImpl extends TypeImpl implements TypeParameterType {
int get hashCode => element.hashCode;
- bool isMoreSpecificThan3(Type2 s, bool withDynamic) {
+ Type2 substitute2(List<Type2> argumentTypes, List<Type2> parameterTypes) {
+ int length = parameterTypes.length;
+ for (int i = 0; i < length; i++) {
+ if (parameterTypes[i] == this) {
+ return argumentTypes[i];
+ }
+ }
+ return this;
+ }
+
+ bool internalIsMoreSpecificThan(Type2 s, bool withDynamic, Set<TypeImpl_TypePair> visitedTypePairs) {
if (this == s) {
return true;
}
@@ -7759,22 +8025,12 @@ class TypeParameterTypeImpl extends TypeImpl implements TypeParameterType {
if (s.isDynamic) {
return true;
}
- return isMoreSpecificThan4(s, new Set<Type2>(), withDynamic);
+ return isMoreSpecificThan4(s, new Set<Type2>(), withDynamic, visitedTypePairs);
}
- bool isSubtypeOf(Type2 s) => isMoreSpecificThan3(s, true);
-
- Type2 substitute2(List<Type2> argumentTypes, List<Type2> parameterTypes) {
- int length = parameterTypes.length;
- for (int i = 0; i < length; i++) {
- if (parameterTypes[i] == this) {
- return argumentTypes[i];
- }
- }
- return this;
- }
+ bool internalIsSubtypeOf(Type2 type, Set<TypeImpl_TypePair> visitedTypePairs) => isMoreSpecificThan3(type, true, new Set<TypeImpl_TypePair>());
- bool isMoreSpecificThan4(Type2 s, Set<Type2> visitedTypes, bool withDynamic) {
+ bool isMoreSpecificThan4(Type2 s, Set<Type2> visitedTypes, bool withDynamic, Set<TypeImpl_TypePair> visitedTypePairs) {
Type2 bound = element.bound;
if (s == bound) {
return true;
@@ -7790,10 +8046,10 @@ class TypeParameterTypeImpl extends TypeImpl implements TypeParameterType {
if (visitedTypes.contains(bound)) {
return false;
}
- javaSetAdd(visitedTypes, bound);
- return boundTypeParameter.isMoreSpecificThan4(s, visitedTypes, withDynamic);
+ visitedTypes.add(bound);
+ return boundTypeParameter.isMoreSpecificThan4(s, visitedTypes, withDynamic, visitedTypePairs);
}
- return bound.isMoreSpecificThan3(s, withDynamic);
+ return (bound as TypeImpl).isMoreSpecificThan3(s, withDynamic, visitedTypePairs);
}
}
@@ -7815,13 +8071,13 @@ class VoidTypeImpl extends TypeImpl implements VoidType {
bool operator ==(Object object) => identical(object, this);
- bool isMoreSpecificThan3(Type2 type, bool withDynamic) => isSubtypeOf(type);
-
- bool isSubtypeOf(Type2 type) => identical(type, this) || identical(type, DynamicTypeImpl.instance);
-
bool get isVoid => true;
VoidTypeImpl substitute2(List<Type2> argumentTypes, List<Type2> parameterTypes) => this;
+
+ bool internalIsMoreSpecificThan(Type2 type, bool withDynamic, Set<TypeImpl_TypePair> visitedTypePairs) => isSubtypeOf(type);
+
+ bool internalIsSubtypeOf(Type2 type, Set<TypeImpl_TypePair> visitedTypePairs) => identical(type, this) || identical(type, DynamicTypeImpl.instance);
}
/**
@@ -8375,15 +8631,6 @@ abstract class Type2 {
bool isMoreSpecificThan(Type2 type);
/**
- * Return `true` if this type is more specific than the given type.
- *
- * @param type the type being compared with this type
- * @param withDynamic `true` if "dynamic" should be considered as a subtype of any type
- * @return `true` if this type is more specific than the given type
- */
- bool isMoreSpecificThan3(Type2 type, bool withDynamic);
-
- /**
* Return `true` if this type represents the type 'Object'.
*
* @return `true` if this type represents the type 'Object'
« no previous file with comments | « pkg/analyzer/lib/src/generated/constant.dart ('k') | pkg/analyzer/lib/src/generated/engine.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698