| OLD | NEW |
| (Empty) |
| 1 library angular.core_dynamic; | |
| 2 | |
| 3 import 'dart:mirrors'; | |
| 4 import 'package:angular/core/annotation_src.dart'; | |
| 5 import 'package:angular/core/registry.dart'; | |
| 6 | |
| 7 export 'package:angular/core/registry.dart' show | |
| 8 MetadataExtractor; | |
| 9 | |
| 10 var _fieldMetadataCache = new Map<Type, Map<String, DirectiveAnnotation>>(); | |
| 11 | |
| 12 class DynamicMetadataExtractor implements MetadataExtractor { | |
| 13 final _fieldAnnotations = [ | |
| 14 reflectType(NgAttr), | |
| 15 reflectType(NgOneWay), | |
| 16 reflectType(NgOneWayOneTime), | |
| 17 reflectType(NgTwoWay), | |
| 18 reflectType(NgCallback) | |
| 19 ]; | |
| 20 | |
| 21 Iterable call(Type type) { | |
| 22 if (reflectType(type) is TypedefMirror) return []; | |
| 23 var metadata = reflectClass(type).metadata; | |
| 24 if (metadata == null) { | |
| 25 metadata = []; | |
| 26 } else { | |
| 27 metadata = metadata.map((InstanceMirror im) => map(type, im.reflectee)); | |
| 28 } | |
| 29 return metadata; | |
| 30 } | |
| 31 | |
| 32 map(Type type, obj) { | |
| 33 if (obj is Directive) { | |
| 34 return mapDirectiveAnnotation(type, obj); | |
| 35 } else { | |
| 36 return obj; | |
| 37 } | |
| 38 } | |
| 39 | |
| 40 Directive mapDirectiveAnnotation(Type type, Directive annotation) { | |
| 41 var match; | |
| 42 var fieldMetadata = fieldMetadataExtractor(type); | |
| 43 if (fieldMetadata.isNotEmpty) { | |
| 44 var newMap = annotation.map == null ? {} : new Map.from(annotation.map); | |
| 45 fieldMetadata.forEach((String fieldName, DirectiveAnnotation ann) { | |
| 46 var attrName = ann.attrName; | |
| 47 if (newMap.containsKey(attrName)) { | |
| 48 throw 'Mapping for attribute $attrName is already defined (while ' | |
| 49 'processing annottation for field $fieldName of $type)'; | |
| 50 } | |
| 51 newMap[attrName] = '${mappingSpec(ann)}$fieldName'; | |
| 52 }); | |
| 53 annotation = cloneWithNewMap(annotation, newMap); | |
| 54 } | |
| 55 return annotation; | |
| 56 } | |
| 57 | |
| 58 | |
| 59 Map<String, DirectiveAnnotation> fieldMetadataExtractor(Type type) => | |
| 60 _fieldMetadataCache.putIfAbsent(type, () => _fieldMetadataExtractor(reflec
tType(type))); | |
| 61 | |
| 62 Map<String, DirectiveAnnotation> _fieldMetadataExtractor(ClassMirror cm) { | |
| 63 var fields = <String, DirectiveAnnotation>{}; | |
| 64 if(cm.superclass != null) { | |
| 65 fields.addAll(_fieldMetadataExtractor(cm.superclass)); | |
| 66 } else { | |
| 67 fields = {}; | |
| 68 } | |
| 69 Map<Symbol, DeclarationMirror> declarations = cm.declarations; | |
| 70 declarations.forEach((symbol, dm) { | |
| 71 if(dm is VariableMirror || | |
| 72 dm is MethodMirror && (dm.isGetter || dm.isSetter)) { | |
| 73 var fieldName = MirrorSystem.getName(symbol); | |
| 74 if (dm is MethodMirror && dm.isSetter) { | |
| 75 // Remove "=" from the end of the setter. | |
| 76 fieldName = fieldName.substring(0, fieldName.length - 1); | |
| 77 } | |
| 78 dm.metadata.forEach((InstanceMirror meta) { | |
| 79 if (_fieldAnnotations.contains(meta.type)) { | |
| 80 if (fields.containsKey(fieldName)) { | |
| 81 throw 'Attribute annotation for $fieldName is defined more ' | |
| 82 'than once in ${cm.reflectedType}'; | |
| 83 } | |
| 84 fields[fieldName] = meta.reflectee as DirectiveAnnotation; | |
| 85 } | |
| 86 }); | |
| 87 } | |
| 88 }); | |
| 89 return fields; | |
| 90 } | |
| 91 } | |
| OLD | NEW |