| Index: third_party/pkg/angular/lib/core/registry_dynamic.dart
|
| diff --git a/third_party/pkg/angular/lib/core/registry_dynamic.dart b/third_party/pkg/angular/lib/core/registry_dynamic.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..54ea6573dbbbd8230c8ba18f88d5917ae212c377
|
| --- /dev/null
|
| +++ b/third_party/pkg/angular/lib/core/registry_dynamic.dart
|
| @@ -0,0 +1,91 @@
|
| +library angular.core_dynamic;
|
| +
|
| +import 'dart:mirrors';
|
| +import 'package:angular/core/annotation_src.dart';
|
| +import 'package:angular/core/registry.dart';
|
| +
|
| +export 'package:angular/core/registry.dart' show
|
| + MetadataExtractor;
|
| +
|
| +var _fieldMetadataCache = new Map<Type, Map<String, DirectiveAnnotation>>();
|
| +
|
| +class DynamicMetadataExtractor implements MetadataExtractor {
|
| + final _fieldAnnotations = [
|
| + reflectType(NgAttr),
|
| + reflectType(NgOneWay),
|
| + reflectType(NgOneWayOneTime),
|
| + reflectType(NgTwoWay),
|
| + reflectType(NgCallback)
|
| + ];
|
| +
|
| + Iterable call(Type type) {
|
| + if (reflectType(type) is TypedefMirror) return [];
|
| + var metadata = reflectClass(type).metadata;
|
| + if (metadata == null) {
|
| + metadata = [];
|
| + } else {
|
| + metadata = metadata.map((InstanceMirror im) => map(type, im.reflectee));
|
| + }
|
| + return metadata;
|
| + }
|
| +
|
| + map(Type type, obj) {
|
| + if (obj is Directive) {
|
| + return mapDirectiveAnnotation(type, obj);
|
| + } else {
|
| + return obj;
|
| + }
|
| + }
|
| +
|
| + Directive mapDirectiveAnnotation(Type type, Directive annotation) {
|
| + var match;
|
| + var fieldMetadata = fieldMetadataExtractor(type);
|
| + if (fieldMetadata.isNotEmpty) {
|
| + var newMap = annotation.map == null ? {} : new Map.from(annotation.map);
|
| + fieldMetadata.forEach((String fieldName, DirectiveAnnotation ann) {
|
| + var attrName = ann.attrName;
|
| + if (newMap.containsKey(attrName)) {
|
| + throw 'Mapping for attribute $attrName is already defined (while '
|
| + 'processing annottation for field $fieldName of $type)';
|
| + }
|
| + newMap[attrName] = '${mappingSpec(ann)}$fieldName';
|
| + });
|
| + annotation = cloneWithNewMap(annotation, newMap);
|
| + }
|
| + return annotation;
|
| + }
|
| +
|
| +
|
| + Map<String, DirectiveAnnotation> fieldMetadataExtractor(Type type) =>
|
| + _fieldMetadataCache.putIfAbsent(type, () => _fieldMetadataExtractor(reflectType(type)));
|
| +
|
| + Map<String, DirectiveAnnotation> _fieldMetadataExtractor(ClassMirror cm) {
|
| + var fields = <String, DirectiveAnnotation>{};
|
| + if(cm.superclass != null) {
|
| + fields.addAll(_fieldMetadataExtractor(cm.superclass));
|
| + } else {
|
| + fields = {};
|
| + }
|
| + Map<Symbol, DeclarationMirror> declarations = cm.declarations;
|
| + declarations.forEach((symbol, dm) {
|
| + if(dm is VariableMirror ||
|
| + dm is MethodMirror && (dm.isGetter || dm.isSetter)) {
|
| + var fieldName = MirrorSystem.getName(symbol);
|
| + if (dm is MethodMirror && dm.isSetter) {
|
| + // Remove "=" from the end of the setter.
|
| + fieldName = fieldName.substring(0, fieldName.length - 1);
|
| + }
|
| + dm.metadata.forEach((InstanceMirror meta) {
|
| + if (_fieldAnnotations.contains(meta.type)) {
|
| + if (fields.containsKey(fieldName)) {
|
| + throw 'Attribute annotation for $fieldName is defined more '
|
| + 'than once in ${cm.reflectedType}';
|
| + }
|
| + fields[fieldName] = meta.reflectee as DirectiveAnnotation;
|
| + }
|
| + });
|
| + }
|
| + });
|
| + return fields;
|
| + }
|
| +}
|
|
|