Index: pkg/polymer/lib/src/declaration.dart |
diff --git a/pkg/polymer/lib/src/declaration.dart b/pkg/polymer/lib/src/declaration.dart |
index 89e1d049dca7f49afb23e7b9f5e97c776b7fd1d6..bc3f424b7518e70624819aa3136b3ddf8ae9af36 100644 |
--- a/pkg/polymer/lib/src/declaration.dart |
+++ b/pkg/polymer/lib/src/declaration.dart |
@@ -47,21 +47,21 @@ class PolymerDeclaration extends HtmlElement { |
String get name => _name; |
/** |
- * Map of publish properties. Can be a [VariableMirror] or a [MethodMirror] |
- * representing a getter. If it is a getter, there will also be a setter. |
+ * Map of publish properties. Can be a field or a property getter, but if this |
+ * map contains a getter, is because it also has a corresponding setter. |
* |
- * Note: technically these are always single properties, so we could use |
- * a Symbol instead of a PropertyPath. However there are lookups between |
- * this map and [_observe] so it is easier to just track paths. |
+ * Note: technically these are always single properties, so we could use a |
+ * Symbol instead of a PropertyPath. However there are lookups between this |
+ * map and [_observe] so it is easier to just track paths. |
*/ |
- Map<PropertyPath, DeclarationMirror> _publish; |
+ Map<PropertyPath, smoke.Declaration> _publish; |
/** The names of published properties for this polymer-element. */ |
Iterable<String> get publishedProperties => |
_publish != null ? _publish.keys.map((p) => '$p') : const []; |
/** Same as [_publish] but with lower case names. */ |
- Map<String, DeclarationMirror> _publishLC; |
+ Map<String, smoke.Declaration> _publishLC; |
Map<PropertyPath, List<Symbol>> _observe; |
@@ -189,17 +189,15 @@ class PolymerDeclaration extends HtmlElement { |
_supertype = _getRegisteredType(extendee); |
if (_supertype != null) _super = _getDeclaration(extendee); |
- var cls = reflectClass(_type); |
- |
// transcribe `attributes` declarations onto own prototype's `publish` |
- publishAttributes(cls, _super); |
+ publishAttributes(_super); |
- publishProperties(_type); |
+ publishProperties(); |
- inferObservers(cls); |
+ inferObservers(); |
// desugar compound observer syntax, e.g. @ObserveProperty('a b c') |
- explodeObservers(cls); |
+ explodeObservers(); |
// Skip the rest in Dart: |
// chain various meta-data objects to inherited versions |
@@ -230,15 +228,10 @@ class PolymerDeclaration extends HtmlElement { |
// under ShadowDOMPolyfill, transforms to approximate missing CSS features |
_shimShadowDomStyling(templateContent, name, extendee); |
- var cls = reflectClass(type); |
// TODO(jmesserly): this feels unnatrual in Dart. Since we have convenient |
// lazy static initialization, can we get by without it? |
- var registered = cls.declarations[#registerCallback]; |
- if (registered != null && |
- registered is MethodMirror && |
- registered.isStatic && |
- registered.isRegularMethod) { |
- cls.invoke(#registerCallback, [this]); |
+ if (smoke.hasStaticMethod(type, #registerCallback)) { |
+ smoke.invoke(type, #registerCallback, [this]); |
} |
} |
@@ -268,7 +261,7 @@ class PolymerDeclaration extends HtmlElement { |
document.register(name, type, extendsTag: baseTag); |
} |
- void publishAttributes(ClassMirror cls, PolymerDeclaration superDecl) { |
+ void publishAttributes(PolymerDeclaration superDecl) { |
// get properties to publish |
if (superDecl != null && superDecl._publish != null) { |
// Dart note: even though we walk the type hierarchy in |
@@ -277,7 +270,7 @@ class PolymerDeclaration extends HtmlElement { |
_publish = new Map.from(superDecl._publish); |
} |
- _publish = _getPublishedProperties(cls, _publish); |
+ _publish = _getPublishedProperties(_type, _publish); |
// merge names from 'attributes' attribute |
var attrs = attributes['attributes']; |
@@ -297,14 +290,14 @@ class PolymerDeclaration extends HtmlElement { |
continue; |
} |
- var mirror = _getProperty(cls, property); |
- if (mirror == null) { |
+ var decl = smoke.getDeclaration(_type, property); |
+ if (decl == null || !decl.isProperty || decl.isFinal) { |
window.console.warn('property for attribute $attr of polymer-element ' |
'name=$name not found.'); |
continue; |
} |
if (_publish == null) _publish = {}; |
- _publish[path] = mirror; |
+ _publish[path] = decl; |
} |
} |
@@ -460,20 +453,17 @@ class PolymerDeclaration extends HtmlElement { |
* Fetch a list of all *Changed methods so we can observe the associated |
* properties. |
*/ |
- void inferObservers(ClassMirror cls) { |
- if (cls == _htmlElementType) return; |
- inferObservers(cls.superclass); |
- for (var method in cls.declarations.values) { |
- if (method is! MethodMirror || method.isStatic |
- || !method.isRegularMethod) continue; |
- |
- String name = MirrorSystem.getName(method.simpleName); |
+ void inferObservers() { |
+ var options = const smoke.QueryOptions(includeProperties: false, |
+ includeMethods: true, includeInherited: true); |
+ for (var decl in smoke.query(_type, options)) { |
+ String name = smoke.symbolToName(decl.name); |
if (name.endsWith(_OBSERVE_SUFFIX) && name != 'attributeChanged') { |
// TODO(jmesserly): now that we have a better system, should we |
// deprecate *Changed methods? |
if (_observe == null) _observe = new HashMap(); |
name = name.substring(0, name.length - 7); |
- _observe[new PropertyPath(name)] = [method.simpleName]; |
+ _observe[new PropertyPath(name)] = [decl.name]; |
} |
} |
} |
@@ -482,28 +472,22 @@ class PolymerDeclaration extends HtmlElement { |
* Fetch a list of all methods annotated with [ObserveProperty] so we can |
* observe the associated properties. |
*/ |
- void explodeObservers(ClassMirror cls) { |
- if (cls == _htmlElementType) return; |
- |
- explodeObservers(cls.superclass); |
- for (var method in cls.declarations.values) { |
- if (method is! MethodMirror || method.isStatic |
- || !method.isRegularMethod) continue; |
- |
- for (var meta in method.metadata) { |
- if (meta.reflectee is! ObserveProperty) continue; |
- |
+ void explodeObservers() { |
+ var options = const smoke.QueryOptions(includeProperties: false, |
+ includeMethods: true, includeInherited: true, |
+ withAnnotations: const [ObserveProperty]); |
+ for (var decl in smoke.query(_type, options)) { |
+ for (var meta in decl.annotations) { |
+ if (meta is! ObserveProperty) continue; |
if (_observe == null) _observe = new HashMap(); |
- |
- for (String name in meta.reflectee.names) { |
- _observe.putIfAbsent(new PropertyPath(name), () => []) |
- .add(method.simpleName); |
+ for (String name in meta.names) { |
+ _observe.putIfAbsent(new PropertyPath(name), () => []).add(decl.name); |
} |
} |
} |
} |
- void publishProperties(Type type) { |
+ void publishProperties() { |
// Dart note: _publish was already populated by publishAttributes |
if (_publish != null) _publishLC = _lowerCaseMap(_publish); |
} |
@@ -548,64 +532,18 @@ final Map _declarations = new Map<String, PolymerDeclaration>(); |
bool _isRegistered(String name) => _declarations.containsKey(name); |
PolymerDeclaration _getDeclaration(String name) => _declarations[name]; |
-final _objectType = reflectClass(Object); |
-final _htmlElementType = reflectClass(HtmlElement); |
- |
-Map _getPublishedProperties(ClassMirror cls, Map props) { |
- if (cls == _htmlElementType) return props; |
- props = _getPublishedProperties(cls.superclass, props); |
- for (var member in cls.declarations.values) { |
- if (member.isStatic || member.isPrivate) continue; |
- |
- if (member is VariableMirror && !member.isFinal |
- || member is MethodMirror && member.isGetter) { |
- |
- for (var meta in member.metadata) { |
- if (meta.reflectee is PublishedProperty) { |
- // Note: we delay the setter check until we find @published because |
- // it's a tad expensive. |
- if (member is! MethodMirror || _hasSetter(cls, member)) { |
- if (props == null) props = {}; |
- props[new PropertyPath([member.simpleName])] = member; |
- } |
- break; |
- } |
- } |
- } |
+Map<PropertyPath, smoke.Declaration> _getPublishedProperties( |
+ Type type, Map<PropertyPath, smoke.Declaration> props) { |
+ var options = const smoke.QueryOptions(includeInherited: true, |
+ withAnnotations: const [PublishedProperty]); |
+ for (var decl in smoke.query(type, options)) { |
+ if (decl.isFinal) continue; |
+ if (props == null) props = {}; |
+ props[new PropertyPath([decl.name])] = decl; |
} |
- |
return props; |
} |
-DeclarationMirror _getProperty(ClassMirror cls, Symbol property) { |
- do { |
- var mirror = cls.declarations[property]; |
- if (mirror is MethodMirror && mirror.isGetter && _hasSetter(cls, mirror) |
- || mirror is VariableMirror) { |
- return mirror; |
- } |
- cls = cls.superclass; |
- |
- // It's generally a good idea to stop at Object, since we know it doesn't |
- // have what we want. |
- // TODO(jmesserly): This is also a workaround for what appears to be a V8 |
- // bug introduced between Chrome 31 and 32. After 32 |
- // JsClassMirror.declarations on Object calls |
- // JsClassMirror.typeVariables, which tries to get the _jsConstructor's |
- // .prototype["<>"]. This ends up getting the "" property instead, maybe |
- // because "<>" doesn't exist, and gets ";" which then blows up because |
- // the code later on expects a List of ints. |
- } while (cls != _objectType); |
- return null; |
-} |
- |
-bool _hasSetter(ClassMirror cls, MethodMirror getter) { |
- var setterName = new Symbol('${MirrorSystem.getName(getter.simpleName)}='); |
- var mirror = cls.declarations[setterName]; |
- return mirror is MethodMirror && mirror.isSetter; |
-} |
- |
- |
/** Attribute prefix used for declarative event handlers. */ |
const _EVENT_PREFIX = 'on-'; |