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

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

Issue 2469643003: Fix lookup of members (issue 27723) (Closed)
Patch Set: Created 4 years, 1 month 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 | « no previous file | pkg/analyzer/test/generated/non_error_resolver_test.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/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index d7d39a81cc47021afbefa04db855155e42f6681c..3f7545e4264468d06e9fb8914e9a3f11559b8265 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -191,45 +191,61 @@ abstract class AbstractClassElementImpl extends ElementImpl
@override
MethodElement lookUpConcreteMethod(
String methodName, LibraryElement library) =>
- _internalLookUpConcreteMethod(
- methodName, library, true, new HashSet<ClassElement>());
+ _first(_implementationsOfMethod(methodName).where(
+ (MethodElement method) =>
+ !method.isAbstract && method.isAccessibleIn(library)));
@override
PropertyAccessorElement lookUpGetter(
String getterName, LibraryElement library) =>
- _internalLookUpGetter(getterName, library, true);
+ _first(_implementationsOfGetter(getterName).where(
+ (PropertyAccessorElement getter) => getter.isAccessibleIn(library)));
@override
PropertyAccessorElement lookUpInheritedConcreteGetter(
String getterName, LibraryElement library) =>
- _internalLookUpConcreteGetter(getterName, library, false);
+ _first(_implementationsOfGetter(getterName).where(
+ (PropertyAccessorElement getter) =>
+ !getter.isAbstract &&
+ getter.isAccessibleIn(library) &&
+ getter.enclosingElement != this));
@override
MethodElement lookUpInheritedConcreteMethod(
String methodName, LibraryElement library) =>
- _internalLookUpConcreteMethod(
- methodName, library, false, new HashSet<ClassElement>());
+ _first(_implementationsOfMethod(methodName).where(
+ (MethodElement method) =>
+ !method.isAbstract &&
+ method.isAccessibleIn(library) &&
+ method.enclosingElement != this));
@override
PropertyAccessorElement lookUpInheritedConcreteSetter(
String setterName, LibraryElement library) =>
- _internalLookUpConcreteSetter(setterName, library, false);
+ _first(_implementationsOfSetter(setterName).where(
+ (PropertyAccessorElement setter) =>
+ !setter.isAbstract &&
+ setter.isAccessibleIn(library) &&
+ setter.enclosingElement != this));
@override
MethodElement lookUpInheritedMethod(
String methodName, LibraryElement library) =>
- _internalLookUpMethod(
- methodName, library, false, new HashSet<ClassElement>());
+ _first(_implementationsOfMethod(methodName).where(
+ (MethodElement method) =>
+ method.isAccessibleIn(library) &&
+ method.enclosingElement != this));
@override
MethodElement lookUpMethod(String methodName, LibraryElement library) =>
- _internalLookUpMethod(
- methodName, library, true, new HashSet<ClassElement>());
+ _first(_implementationsOfMethod(methodName)
+ .where((MethodElement method) => method.isAccessibleIn(library)));
@override
PropertyAccessorElement lookUpSetter(
String setterName, LibraryElement library) =>
- _internalLookUpSetter(setterName, library, true);
+ _first(_implementationsOfSetter(setterName).where(
+ (PropertyAccessorElement setter) => setter.isAccessibleIn(library)));
@override
void visitChildren(ElementVisitor visitor) {
@@ -238,151 +254,110 @@ abstract class AbstractClassElementImpl extends ElementImpl
safelyVisitChildren(fields, visitor);
}
- PropertyAccessorElement _internalLookUpConcreteGetter(
- String getterName, LibraryElement library, bool includeThisClass) {
- PropertyAccessorElement getter =
- _internalLookUpGetter(getterName, library, includeThisClass);
- while (getter != null && getter.isAbstract) {
- Element definingClass = getter.enclosingElement;
- if (definingClass is! ClassElement) {
- return null;
- }
- getter = getImpl(definingClass)
- ._internalLookUpGetter(getterName, library, false);
- }
- return getter;
- }
-
- MethodElement _internalLookUpConcreteMethod(
- String methodName,
- LibraryElement library,
- bool includeThisClass,
- HashSet<ClassElement> visitedClasses) {
- MethodElement method = _internalLookUpMethod(
- methodName, library, includeThisClass, visitedClasses);
- while (method != null && method.isAbstract) {
- ClassElement definingClass = method.enclosingElement;
- if (definingClass == null) {
- return null;
- }
- method = getImpl(definingClass)
- ._internalLookUpMethod(methodName, library, false, visitedClasses);
- }
- return method;
- }
-
- PropertyAccessorElement _internalLookUpConcreteSetter(
- String setterName, LibraryElement library, bool includeThisClass) {
- PropertyAccessorElement setter =
- _internalLookUpSetter(setterName, library, includeThisClass);
- while (setter != null && setter.isAbstract) {
- Element definingClass = setter.enclosingElement;
- if (definingClass is ClassElementImpl) {
- setter =
- definingClass._internalLookUpSetter(setterName, library, false);
- } else {
- return null;
- }
+ /**
+ * Return the first element from the given [iterable], or `null` if the
+ * iterable is empty.
+ */
+ Object/*=E*/ _first/*<E>*/(Iterable/*<E>*/ iterable) {
+ if (iterable.isEmpty) {
+ return null;
}
- return setter;
+ return iterable.first;
}
- PropertyAccessorElement _internalLookUpGetter(
- String getterName, LibraryElement library, bool includeThisClass) {
+ /**
+ * Return an iterable containing all of the implementations of a getter with
+ * the given [getterName] that are defined in this class any any superclass of
+ * this class (but not in interfaces).
+ *
+ * The getters that are returned are not filtered in any way. In particular,
+ * they can include getters that are not visible in some context. Clients must
+ * perform any necessary filtering.
+ *
+ * The getters are returned based on the depth of their defining class; if
+ * this class contains a definition of the getter it will occur first, if
+ * Object contains a definition of the getter it will occur last.
+ */
+ Iterable<PropertyAccessorElement> _implementationsOfGetter(
+ String getterName) sync* {
+ ClassElement classElement = this;
HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
- ClassElement currentElement = this;
- if (includeThisClass) {
- PropertyAccessorElement element = currentElement.getGetter(getterName);
- if (element != null && element.isAccessibleIn(library)) {
- return element;
- }
- }
- while (currentElement != null && visitedClasses.add(currentElement)) {
- for (InterfaceType mixin in currentElement.mixins.reversed) {
- ClassElement mixinElement = mixin.element;
- if (mixinElement != null) {
- PropertyAccessorElement element = mixinElement.getGetter(getterName);
- if (element != null && element.isAccessibleIn(library)) {
- return element;
- }
+ while (classElement != null && visitedClasses.add(classElement)) {
+ PropertyAccessorElement getter = classElement.getGetter(getterName);
+ if (getter != null) {
+ yield getter;
+ }
+ for (InterfaceType mixin in classElement.mixins.reversed) {
+ getter = mixin.element?.getGetter(getterName);
+ if (getter != null) {
+ yield getter;
}
}
- InterfaceType supertype = currentElement.supertype;
- if (supertype == null) {
- return null;
- }
- currentElement = supertype.element;
- PropertyAccessorElement element = currentElement.getGetter(getterName);
- if (element != null && element.isAccessibleIn(library)) {
- return element;
- }
+ classElement = classElement.supertype?.element;
}
- return null;
}
- MethodElement _internalLookUpMethod(String methodName, LibraryElement library,
- bool includeThisClass, HashSet<ClassElement> visitedClasses) {
- ClassElement currentElement = this;
- if (includeThisClass) {
- MethodElement element = currentElement.getMethod(methodName);
- if (element != null && element.isAccessibleIn(library)) {
- return element;
- }
- }
- while (currentElement != null && visitedClasses.add(currentElement)) {
- for (InterfaceType mixin in currentElement.mixins.reversed) {
- ClassElement mixinElement = mixin.element;
- if (mixinElement != null) {
- MethodElement element = mixinElement.getMethod(methodName);
- if (element != null && element.isAccessibleIn(library)) {
- return element;
- }
+ /**
+ * Return an iterable containing all of the implementations of a method with
+ * the given [methodName] that are defined in this class any any superclass of
+ * this class (but not in interfaces).
+ *
+ * The methods that are returned are not filtered in any way. In particular,
+ * they can include methods that are not visible in some context. Clients must
+ * perform any necessary filtering.
+ *
+ * The methods are returned based on the depth of their defining class; if
+ * this class contains a definition of the method it will occur first, if
+ * Object contains a definition of the method it will occur last.
+ */
+ Iterable<MethodElement> _implementationsOfMethod(String methodName) sync* {
+ ClassElement classElement = this;
+ HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
+ while (classElement != null && visitedClasses.add(classElement)) {
+ MethodElement method = classElement.getMethod(methodName);
+ if (method != null) {
+ yield method;
+ }
+ for (InterfaceType mixin in classElement.mixins.reversed) {
+ method = mixin.element?.getMethod(methodName);
+ if (method != null) {
+ yield method;
}
}
- InterfaceType supertype = currentElement.supertype;
- if (supertype == null) {
- return null;
- }
- currentElement = supertype.element;
- MethodElement element = currentElement.getMethod(methodName);
- if (element != null && element.isAccessibleIn(library)) {
- return element;
- }
+ classElement = classElement.supertype?.element;
}
- return null;
}
- PropertyAccessorElement _internalLookUpSetter(
- String setterName, LibraryElement library, bool includeThisClass) {
+ /**
+ * Return an iterable containing all of the implementations of a setter with
+ * the given [setterName] that are defined in this class any any superclass of
+ * this class (but not in interfaces).
+ *
+ * The setters that are returned are not filtered in any way. In particular,
+ * they can include setters that are not visible in some context. Clients must
+ * perform any necessary filtering.
+ *
+ * The setters are returned based on the depth of their defining class; if
+ * this class contains a definition of the setter it will occur first, if
+ * Object contains a definition of the setter it will occur last.
+ */
+ Iterable<PropertyAccessorElement> _implementationsOfSetter(
+ String setterName) sync* {
+ ClassElement classElement = this;
HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
- ClassElement currentElement = this;
- if (includeThisClass) {
- PropertyAccessorElement element = currentElement.getSetter(setterName);
- if (element != null && element.isAccessibleIn(library)) {
- return element;
- }
- }
- while (currentElement != null && visitedClasses.add(currentElement)) {
- for (InterfaceType mixin in currentElement.mixins.reversed) {
- ClassElement mixinElement = mixin.element;
- if (mixinElement != null) {
- PropertyAccessorElement element = mixinElement.getSetter(setterName);
- if (element != null && element.isAccessibleIn(library)) {
- return element;
- }
+ while (classElement != null && visitedClasses.add(classElement)) {
+ PropertyAccessorElement setter = classElement.getSetter(setterName);
+ if (setter != null) {
+ yield setter;
+ }
+ for (InterfaceType mixin in classElement.mixins.reversed) {
+ setter = mixin.element?.getSetter(setterName);
+ if (setter != null) {
+ yield setter;
}
}
- InterfaceType supertype = currentElement.supertype;
- if (supertype == null) {
- return null;
- }
- currentElement = supertype.element;
- PropertyAccessorElement element = currentElement.getSetter(setterName);
- if (element != null && element.isAccessibleIn(library)) {
- return element;
- }
+ classElement = classElement.supertype?.element;
}
- return null;
}
/**
« no previous file with comments | « no previous file | pkg/analyzer/test/generated/non_error_resolver_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698