| import 'package:analyzer/dart/ast/ast.dart'; |
| import 'package:analyzer/dart/element/element.dart'; |
| import 'package:analyzer/dart/element/type.dart'; |
| import 'package:test/test.dart'; |
| |
| import 'function_ast_visitor.dart'; |
| |
| class FindElement { |
| final CompilationUnit unit; |
| |
| FindElement(this.unit); |
| |
| CompilationUnitElement get unitElement => unit.declaredElement; |
| |
| ClassElement class_(String name) { |
| for (var class_ in unitElement.types) { |
| if (class_.name == name) { |
| return class_; |
| } |
| } |
| fail('Not found class: $name'); |
| } |
| |
| ConstructorElement constructor(String name, {String className}) { |
| assert(name != ''); |
| ConstructorElement result; |
| for (var class_ in unitElement.types) { |
| if (className == null || class_.name == className) { |
| for (var constructor in class_.constructors) { |
| if (constructor.name == name) { |
| if (result != null) { |
| throw new StateError('Not constructor name: $name'); |
| } |
| result = constructor; |
| } |
| } |
| } |
| } |
| if (result != null) { |
| return result; |
| } |
| fail('Not found constructor: $name'); |
| } |
| |
| ClassElement enum_(String name) { |
| for (var enum_ in unitElement.enums) { |
| if (enum_.name == name) { |
| return enum_; |
| } |
| } |
| fail('Not found enum: $name'); |
| } |
| |
| ExportElement export(String targetUri) { |
| ExportElement exportElement; |
| 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.'); |
| } |
| exportElement = export; |
| } |
| } |
| if (exportElement != null) { |
| return exportElement; |
| } |
| fail('Not found export: $targetUri'); |
| } |
| |
| FieldElement field(String name) { |
| for (var type in unitElement.mixins) { |
| for (var field in type.fields) { |
| if (field.name == name) { |
| return field; |
| } |
| } |
| } |
| for (var type in unitElement.types) { |
| for (var field in type.fields) { |
| if (field.name == name) { |
| return field; |
| } |
| } |
| } |
| fail('Not found class field: $name'); |
| } |
| |
| FunctionElement function(String name) { |
| for (var function in unitElement.functions) { |
| if (function.name == name) { |
| return function; |
| } |
| } |
| fail('Not found top-level function: $name'); |
| } |
| |
| PropertyAccessorElement getter(String name, {String className}) { |
| for (var class_ in unitElement.types) { |
| if (className != null && class_.name != className) { |
| continue; |
| } |
| for (var accessor in class_.accessors) { |
| if (accessor.isGetter && accessor.displayName == name) { |
| return accessor; |
| } |
| } |
| } |
| fail('Not found class accessor: $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.'); |
| } |
| importElement = import; |
| } |
| } |
| if (importElement != null) { |
| return importElement; |
| } |
| fail('Not found import: $targetUri'); |
| } |
| |
| InterfaceType interfaceType(String name) { |
| return class_(name).type; |
| } |
| |
| 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.'); |
| } |
| result = element; |
| } |
| }, |
| )); |
| if (result == null) { |
| fail('Not found local variable: $name'); |
| } |
| return result; |
| } |
| |
| MethodElement method(String name, {String of}) { |
| MethodElement result; |
| |
| void findIn(List<MethodElement> methods) { |
| for (var method in methods) { |
| if (method.name == name) { |
| if (result != null) { |
| throw new StateError('Method name $name is not unique.'); |
| } |
| result = method; |
| } |
| } |
| } |
| |
| for (var class_ in unitElement.types) { |
| if (of != null && class_.name != of) { |
| continue; |
| } |
| findIn(class_.methods); |
| } |
| |
| for (var mixin in unitElement.mixins) { |
| if (of != null && mixin.name != of) { |
| continue; |
| } |
| findIn(mixin.methods); |
| } |
| |
| if (result != null) { |
| return result; |
| } |
| fail('Not found class method: $name'); |
| } |
| |
| ClassElement mixin(String name) { |
| for (var mixin in unitElement.mixins) { |
| if (mixin.name == name) { |
| return mixin; |
| } |
| } |
| fail('Not found mixin: $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 = parameter; |
| } |
| } |
| |
| for (var accessor in unitElement.accessors) { |
| accessor.parameters.forEach(considerParameter); |
| } |
| for (var function in unitElement.functions) { |
| function.parameters.forEach(considerParameter); |
| } |
| for (var function in unitElement.functionTypeAliases) { |
| function.parameters.forEach(considerParameter); |
| } |
| for (var class_ in unitElement.types) { |
| for (var constructor in class_.constructors) { |
| constructor.parameters.forEach(considerParameter); |
| } |
| for (var method in class_.methods) { |
| method.parameters.forEach(considerParameter); |
| } |
| } |
| if (parameterElement != null) { |
| return parameterElement; |
| } |
| fail('No parameter found with name $name'); |
| } |
| |
| PrefixElement prefix(String name) { |
| for (var import_ in unitElement.library.imports) { |
| var prefix = import_.prefix; |
| if (prefix != null && prefix.name == name) { |
| return prefix; |
| } |
| } |
| fail('Prefix not found: $name'); |
| } |
| |
| PropertyAccessorElement setter(String name, {String className}) { |
| PropertyAccessorElement result; |
| for (var class_ in unitElement.types) { |
| if (className != null && class_.name != className) { |
| continue; |
| } |
| for (var accessor in class_.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 found class setter: $name'); |
| } |
| return result; |
| } |
| |
| FunctionElement topFunction(String name) { |
| for (var function in unitElement.functions) { |
| if (function.name == name) { |
| return function; |
| } |
| } |
| fail('Not found top-level function: $name'); |
| } |
| |
| PropertyAccessorElement topGet(String name) { |
| return topVar(name).getter; |
| } |
| |
| PropertyAccessorElement topSet(String name) { |
| return topVar(name).setter; |
| } |
| |
| TopLevelVariableElement topVar(String name) { |
| for (var variable in unitElement.topLevelVariables) { |
| if (variable.name == name) { |
| return variable; |
| } |
| } |
| fail('Not found top-level variable: $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.'); |
| } |
| result = candidate; |
| } |
| } |
| |
| for (var type in unitElement.functionTypeAliases) { |
| type.typeParameters.forEach(consider); |
| } |
| for (var type in unitElement.types) { |
| type.typeParameters.forEach(consider); |
| } |
| if (result != null) { |
| return result; |
| } |
| fail('Not found type parameter: $name'); |
| } |
| |
| ConstructorElement unnamedConstructor(String name) { |
| return class_(name).unnamedConstructor; |
| } |
| } |