Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 import 'dart:collection' show Queue; | |
|
jakemac
2015/02/17 23:46:45
Should probably add a library/license (ditto other
tjblasi
2015/02/18 21:18:25
None of the other files seem to have licenses righ
| |
| 2 import 'package:analyzer/src/generated/element.dart'; | |
| 3 | |
| 4 /// Provides a mechanism for checking an element for the provided | |
| 5 /// [_annotationClass] and reporting the resulting (element, annotation) pairs. | |
| 6 class AnnotationMatcher { | |
| 7 /// Queue for annotations. | |
| 8 final initQueue = new Queue<AnnotationMatch>(); | |
|
jakemac
2015/02/17 23:46:45
nit: may want to rename this
tjblasi
2015/02/18 21:18:25
Done.
| |
| 9 /// All the annotations we have seen for each element | |
| 10 final _seenAnnotations = new Map<Element, Set<ElementAnnotation>>(); | |
| 11 | |
| 12 /// The class we are searching for to populate [initQueue]. | |
| 13 final ClassElement _annotationClass; | |
| 14 | |
| 15 AnnotationMatcher(this._annotationClass); | |
| 16 | |
| 17 /// Records all [_annotationClass] annotations and the [element]s they apply t o. | |
| 18 /// Returns [true] if 1) [element] is annotated with [_annotationClass] and | |
| 19 /// 2) ([element], [_annotationClass]) has been seen previously. | |
|
jakemac
2015/02/17 23:46:45
has -> has not?
tjblasi
2015/02/18 21:18:25
Done.
| |
| 20 bool processAnnotations(ClassElement element) { | |
| 21 var found = false; | |
| 22 element.metadata.where((ElementAnnotation meta) { | |
| 23 // Only process [_annotationClass]s. | |
| 24 // TODO(tjblasi): Make this recognize non-ConstructorElement annotations. | |
| 25 return meta.element is ConstructorElement && | |
| 26 _isAnnotationMatch(meta.element.returnType); | |
| 27 }).where((ElementAnnotation meta) { | |
| 28 // Only process ([element], [meta]) combinations we haven't seen previousl y. | |
| 29 return !_seenAnnotations | |
| 30 .putIfAbsent(element, () => new Set<ElementAnnotation>()) | |
| 31 .contains(meta); | |
| 32 }).forEach((ElementAnnotation meta) { | |
| 33 _seenAnnotations[element].add(meta); | |
| 34 initQueue.addLast(new AnnotationMatch(element, meta)); | |
| 35 found = true; | |
| 36 }); | |
| 37 return found; | |
| 38 } | |
| 39 | |
| 40 /// Whether [type], its superclass, or one of its interfaces matches [_annotat ionClass]. | |
| 41 bool _isAnnotationMatch(InterfaceType type) { | |
| 42 if (type == null || type.element == null) return false; | |
| 43 if (type.element.type == _annotationClass.type) return true; | |
| 44 if (_isAnnotationMatch(type.superclass)) return true; | |
| 45 for (var interface in type.interfaces) { | |
| 46 if (_isAnnotationMatch(interface)) return true; | |
| 47 } | |
| 48 return false; | |
| 49 } | |
| 50 } | |
| 51 | |
| 52 // Element/ElementAnnotation pair. | |
| 53 class AnnotationMatch { | |
| 54 final Element element; | |
| 55 final ElementAnnotation annotation; | |
| 56 | |
| 57 AnnotationMatch(this.element, this.annotation); | |
| 58 } | |
| OLD | NEW |