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