Make FindElement more self-consistent.

R=brianwilkerson@google.com

Change-Id: I74bc21a5e6ead36c9a631fc529497108001947ef
Reviewed-on: https://dart-review.googlesource.com/c/87269
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/test/src/dart/resolution/assignment_test.dart b/pkg/analyzer/test/src/dart/resolution/assignment_test.dart
index ba409b4..6bf04e5 100644
--- a/pkg/analyzer/test/src/dart/resolution/assignment_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/assignment_test.dart
@@ -247,7 +247,7 @@
     assertType(creation, 'B');
 
     var fRef = left.propertyName;
-    assertElement(fRef, findElement.setter('f', className: 'A'));
+    assertElement(fRef, findElement.setter('f', of: 'A'));
     assertType(fRef, 'int');
 
     var right = assignment.rightHandSide;
diff --git a/pkg/analyzer/test/src/dart/resolution/class_test.dart b/pkg/analyzer/test/src/dart/resolution/class_test.dart
index 0fecf73..5650cdb 100644
--- a/pkg/analyzer/test/src/dart/resolution/class_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/class_test.dart
@@ -141,7 +141,7 @@
     assertNoTestErrors();
     assertElement(
       findNode.simple('foo = 0;'),
-      findElement.setter('foo', className: 'A'),
+      findElement.setter('foo', of: 'A'),
     );
   }
 
diff --git a/pkg/analyzer/test/src/dart/resolution/comment_test.dart b/pkg/analyzer/test/src/dart/resolution/comment_test.dart
index 8a4d787..5371eac 100644
--- a/pkg/analyzer/test/src/dart/resolution/comment_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/comment_test.dart
@@ -61,7 +61,7 @@
     );
     assertElement(
       findNode.simple('named]'),
-      findElement.constructor('named', className: 'A'),
+      findElement.constructor('named', of: 'A'),
     );
   }
 
@@ -250,7 +250,7 @@
     await resolveTestFile();
     assertNoTestErrors();
 
-    var x = findElement.setter('x', className: 'A');
+    var x = findElement.setter('x', of: 'A');
     assertElement(findNode.simple('x] in A'), x);
     assertElement(findNode.simple('x] in B'), x);
   }
diff --git a/pkg/analyzer/test/src/dart/resolution/find_element.dart b/pkg/analyzer/test/src/dart/resolution/find_element.dart
index d408980..cbf7def 100644
--- a/pkg/analyzer/test/src/dart/resolution/find_element.dart
+++ b/pkg/analyzer/test/src/dart/resolution/find_element.dart
@@ -9,6 +9,7 @@
 
 import 'function_ast_visitor.dart';
 
+/// Helper for finding elements declared in the resolved [unit].
 class FindElement {
   final CompilationUnit unit;
 
@@ -22,18 +23,18 @@
         return class_;
       }
     }
-    fail('Not found class: $name');
+    fail('Not found: $name');
   }
 
-  ConstructorElement constructor(String name, {String className}) {
+  ConstructorElement constructor(String name, {String of}) {
     assert(name != '');
     ConstructorElement result;
     for (var class_ in unitElement.types) {
-      if (className == null || class_.name == className) {
+      if (of == null || class_.name == of) {
         for (var constructor in class_.constructors) {
           if (constructor.name == name) {
             if (result != null) {
-              throw new StateError('Not constructor name: $name');
+              fail('Not unique: $name');
             }
             result = constructor;
           }
@@ -43,7 +44,7 @@
     if (result != null) {
       return result;
     }
-    fail('Not found constructor: $name');
+    fail('Not found: $name');
   }
 
   ClassElement enum_(String name) {
@@ -52,49 +53,67 @@
         return enum_;
       }
     }
-    fail('Not found enum: $name');
+    fail('Not found: $name');
   }
 
   ExportElement export(String targetUri) {
-    ExportElement exportElement;
+    ExportElement result;
+
     for (var export in unitElement.library.exports) {
       var exportedUri = export.exportedLibrary.source.uri.toString();
       if (exportedUri == targetUri) {
-        if (exportElement != null) {
-          throw new StateError('Not unique $targetUri export.');
+        if (result != null) {
+          fail('Not unique: $targetUri');
         }
-        exportElement = export;
+        result = export;
       }
     }
-    if (exportElement != null) {
-      return exportElement;
+
+    if (result != null) {
+      return result;
     }
-    fail('Not found export: $targetUri');
+    fail('Not found: $targetUri');
   }
 
-  FieldElement field(String name) {
+  FieldElement field(String name, {String of}) {
+    FieldElement result;
+
+    void findIn(List<FieldElement> fields) {
+      for (var field in fields) {
+        if (field.name == name) {
+          if (result != null) {
+            fail('Not unique: $name');
+          }
+          result = field;
+        }
+      }
+    }
+
     for (var enum_ in unitElement.enums) {
-      for (var field in enum_.fields) {
-        if (field.name == name) {
-          return field;
-        }
+      if (of != null && enum_.name != of) {
+        continue;
       }
+      findIn(enum_.fields);
     }
-    for (var mixin in unitElement.mixins) {
-      for (var field in mixin.fields) {
-        if (field.name == name) {
-          return field;
-        }
-      }
-    }
+
     for (var class_ in unitElement.types) {
-      for (var field in class_.fields) {
-        if (field.name == name) {
-          return field;
-        }
+      if (of != null && class_.name != of) {
+        continue;
       }
+      findIn(class_.fields);
     }
-    fail('Not found field: $name');
+
+    for (var mixin in unitElement.mixins) {
+      if (of != null && mixin.name != of) {
+        continue;
+      }
+      findIn(mixin.fields);
+    }
+
+    if (result != null) {
+      return result;
+    }
+    fail('Not found: $name');
   }
 
   FunctionElement function(String name) {
@@ -103,7 +122,7 @@
         return function;
       }
     }
-    fail('Not found top-level function: $name');
+    fail('Not found: $name');
   }
 
   GenericTypeAliasElement genericTypeAlias(String name) {
@@ -112,45 +131,67 @@
         return element;
       }
     }
-    fail('Not found generic type alias: $name');
+    fail('Not found: $name');
   }
 
   PropertyAccessorElement getter(String name, {String of}) {
-    for (var enum_ in unitElement.enums) {
-      for (var accessor in enum_.accessors) {
+    PropertyAccessorElement result;
+
+    void findIn(List<PropertyAccessorElement> accessors) {
+      for (var accessor in accessors) {
         if (accessor.isGetter && accessor.displayName == name) {
-          return accessor;
+          if (result != null) {
+            fail('Not unique: $name');
+          }
+          result = accessor;
         }
       }
     }
+
+    for (var enum_ in unitElement.enums) {
+      if (of != null && enum_.name != of) {
+        continue;
+      }
+      findIn(enum_.accessors);
+    }
+
     for (var class_ in unitElement.types) {
       if (of != null && class_.name != of) {
         continue;
       }
-      for (var accessor in class_.accessors) {
-        if (accessor.isGetter && accessor.displayName == name) {
-          return accessor;
-        }
-      }
+      findIn(class_.accessors);
     }
-    fail('Not found class accessor: $name');
+
+    for (var mixin in unitElement.mixins) {
+      if (of != null && mixin.name != of) {
+        continue;
+      }
+      findIn(mixin.accessors);
+    }
+
+    if (result != null) {
+      return result;
+    }
+    fail('Not found: $name');
   }
 
   ImportElement import(String targetUri) {
     ImportElement importElement;
+
     for (var import in unitElement.library.imports) {
       var importedUri = import.importedLibrary.source.uri.toString();
       if (importedUri == targetUri) {
         if (importElement != null) {
-          throw new StateError('Not unique $targetUri import.');
+          fail('Not unique: $targetUri');
         }
         importElement = import;
       }
     }
+
     if (importElement != null) {
       return importElement;
     }
-    fail('Not found import: $targetUri');
+    fail('Not found: $targetUri');
   }
 
   InterfaceType interfaceType(String name) {
@@ -159,38 +200,42 @@
 
   FunctionElement localFunction(String name) {
     FunctionElement result;
+
     unit.accept(new FunctionAstVisitor(
       functionDeclarationStatement: (node) {
         var element = node.functionDeclaration.declaredElement;
         if (element is FunctionElement) {
           if (result != null) {
-            throw new StateError('Local function name $name is not unique.');
+            fail('Not unique: $name');
           }
           result = element;
         }
       },
     ));
+
     if (result == null) {
-      fail('Not found local function: $name');
+      fail('Not found: $name');
     }
     return result;
   }
 
   LocalVariableElement localVar(String name) {
     LocalVariableElement result;
+
     unit.accept(new FunctionAstVisitor(
       variableDeclaration: (node) {
         var element = node.declaredElement;
         if (element is LocalVariableElement) {
           if (result != null) {
-            throw new StateError('Local variable name $name is not unique.');
+            fail('Not unique: $name');
           }
           result = element;
         }
       },
     ));
+
     if (result == null) {
-      fail('Not found local variable: $name');
+      fail('Not found: $name');
     }
     return result;
   }
@@ -202,7 +247,7 @@
       for (var method in methods) {
         if (method.name == name) {
           if (result != null) {
-            throw new StateError('Method name $name is not unique.');
+            fail('Not unique: $name');
           }
           result = method;
         }
@@ -226,7 +271,7 @@
     if (result != null) {
       return result;
     }
-    fail('Not found class method: $name');
+    fail('Not found: $name');
   }
 
   ClassElement mixin(String name) {
@@ -235,73 +280,92 @@
         return mixin;
       }
     }
-    fail('Not found mixin: $name');
+    fail('Not found: $name');
   }
 
   ParameterElement parameter(String name) {
-    ParameterElement parameterElement;
-    void considerParameter(ParameterElement parameter) {
-      if (parameter.name == name) {
-        if (parameterElement != null) {
-          throw new StateError('Parameter name $name is not unique.');
+    ParameterElement result;
+
+    void findIn(List<ParameterElement> parameters) {
+      for (var parameter in parameters) {
+        if (parameter.name == name) {
+          if (result != null) {
+            fail('Not unique: $name');
+          }
+          result = parameter;
         }
-        parameterElement = parameter;
       }
     }
 
     for (var accessor in unitElement.accessors) {
-      accessor.parameters.forEach(considerParameter);
+      findIn(accessor.parameters);
     }
+
     for (var function in unitElement.functions) {
-      function.parameters.forEach(considerParameter);
+      findIn(function.parameters);
     }
+
     for (var function in unitElement.functionTypeAliases) {
-      function.parameters.forEach(considerParameter);
+      findIn(function.parameters);
     }
+
     for (var class_ in unitElement.types) {
       for (var constructor in class_.constructors) {
-        constructor.parameters.forEach(considerParameter);
+        findIn(constructor.parameters);
       }
       for (var method in class_.methods) {
-        method.parameters.forEach(considerParameter);
+        findIn(method.parameters);
       }
     }
-    if (parameterElement != null) {
-      return parameterElement;
+
+    if (result != null) {
+      return result;
     }
-    fail('No parameter found with name $name');
+    fail('Not found: $name');
   }
 
   PrefixElement prefix(String name) {
     for (var import_ in unitElement.library.imports) {
       var prefix = import_.prefix;
-      if (prefix != null && prefix.name == name) {
+      if (prefix?.name == name) {
         return prefix;
       }
     }
-    fail('Prefix not found: $name');
+    fail('Not found: $name');
   }
 
-  PropertyAccessorElement setter(String name, {String className}) {
+  PropertyAccessorElement setter(String name, {String of}) {
     PropertyAccessorElement result;
-    for (var class_ in unitElement.types) {
-      if (className != null && class_.name != className) {
-        continue;
-      }
-      for (var accessor in class_.accessors) {
+
+    void findIn(List<PropertyAccessorElement> accessors) {
+      for (var accessor in accessors) {
         if (accessor.isSetter && accessor.displayName == name) {
-          if (result == null) {
-            result = accessor;
-          } else {
-            throw new StateError('Class setter $name is not unique.');
+          if (result != null) {
+            fail('Not unique: $name');
           }
+          result = accessor;
         }
       }
     }
-    if (result == null) {
-      fail('Not found class setter: $name');
+
+    for (var class_ in unitElement.types) {
+      if (of != null && class_.name != of) {
+        continue;
+      }
+      findIn(class_.accessors);
     }
-    return result;
+
+    for (var mixin in unitElement.mixins) {
+      if (of != null && mixin.name != of) {
+        continue;
+      }
+      findIn(mixin.accessors);
+    }
+
+    if (result != null) {
+      return result;
+    }
+    fail('Not found: $name');
   }
 
   FunctionElement topFunction(String name) {
@@ -310,7 +374,7 @@
         return function;
       }
     }
-    fail('Not found top-level function: $name');
+    fail('Not found: $name');
   }
 
   PropertyAccessorElement topGet(String name) {
@@ -327,34 +391,42 @@
         return variable;
       }
     }
-    fail('Not found top-level variable: $name');
+    fail('Not found: $name');
   }
 
   TypeParameterElement typeParameter(String name) {
     TypeParameterElement result;
 
-    void consider(TypeParameterElement candidate) {
-      if (candidate.name == name) {
-        if (result != null) {
-          throw new StateError('Type parameter $name is not unique.');
+    void findIn(List<TypeParameterElement> typeParameters) {
+      for (var typeParameter in typeParameters) {
+        if (typeParameter.name == name) {
+          if (result != null) {
+            fail('Not unique: $name');
+          }
+          result = typeParameter;
         }
-        result = candidate;
       }
     }
 
     for (var type in unitElement.functionTypeAliases) {
-      type.typeParameters.forEach(consider);
+      findIn(type.typeParameters);
       if (type is GenericTypeAliasElement) {
-        type.function.typeParameters.forEach(consider);
+        findIn(type.function.typeParameters);
       }
     }
-    for (var type in unitElement.types) {
-      type.typeParameters.forEach(consider);
+
+    for (var class_ in unitElement.types) {
+      findIn(class_.typeParameters);
     }
+
+    for (var mixin in unitElement.mixins) {
+      findIn(mixin.typeParameters);
+    }
+
     if (result != null) {
       return result;
     }
-    fail('Not found type parameter: $name');
+    fail('Not found: $name');
   }
 
   ConstructorElement unnamedConstructor(String name) {
diff --git a/pkg/analyzer/test/src/dart/resolution/property_access_test.dart b/pkg/analyzer/test/src/dart/resolution/property_access_test.dart
index 15dfcee..c127e27 100644
--- a/pkg/analyzer/test/src/dart/resolution/property_access_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/property_access_test.dart
@@ -73,7 +73,7 @@
     var access = findNode.propertyAccess('foo = v; // ref');
     assertPropertyAccess(
       access,
-      findElement.setter('foo', className: 'A'),
+      findElement.setter('foo', of: 'A'),
       'int',
     );
     assertSuperExpression(access.target);
@@ -97,7 +97,7 @@
     var access = findNode.propertyAccess('foo = v; // ref');
     assertPropertyAccess(
       access,
-      findElement.setter('foo', className: 'A'),
+      findElement.setter('foo', of: 'A'),
       'int',
     );
     assertSuperExpression(access.target);