| Index: pkg/observe/lib/src/path_observer.dart
|
| diff --git a/pkg/observe/lib/src/path_observer.dart b/pkg/observe/lib/src/path_observer.dart
|
| index 8054a3ab19d38cac680f14853aa7c197a445337a..b98aee5d36d8be61a15a9c9c13e8683fe10e3aa5 100644
|
| --- a/pkg/observe/lib/src/path_observer.dart
|
| +++ b/pkg/observe/lib/src/path_observer.dart
|
| @@ -7,12 +7,10 @@ library observe.src.path_observer;
|
| import 'dart:async';
|
| import 'dart:collection';
|
| import 'dart:math' show min;
|
| -@MirrorsUsed(metaTargets: const [Reflectable, ObservableProperty],
|
| - override: 'observe.src.path_observer')
|
| -import 'dart:mirrors';
|
| import 'package:logging/logging.dart' show Logger, Level;
|
| import 'package:observe/observe.dart';
|
| import 'package:observe/src/observable.dart' show objectType;
|
| +import 'package:smoke/smoke.dart' as smoke;
|
|
|
| /// A data-bound path starting from a view-model or model object, for example
|
| /// `foo.bar.baz`.
|
| @@ -41,7 +39,7 @@ class PathObserver extends _Observer implements Bindable {
|
| bool get _isClosed => _path == null;
|
|
|
| /// Sets the value at this path.
|
| - @reflectable void set value(Object newValue) {
|
| + void set value(Object newValue) {
|
| if (_path != null) _path.setValueFrom(_object, newValue);
|
| }
|
|
|
| @@ -148,7 +146,7 @@ class PropertyPath {
|
| String toString() {
|
| if (!isValid) return '<invalid path>';
|
| return _segments
|
| - .map((s) => s is Symbol ? MirrorSystem.getName(s) : s)
|
| + .map((s) => s is Symbol ? smoke.symbolToName(s) : s)
|
| .join('.');
|
| }
|
|
|
| @@ -229,7 +227,7 @@ bool _changeRecordMatches(record, key) {
|
| return (record as PropertyChangeRecord).name == key;
|
| }
|
| if (record is MapChangeRecord) {
|
| - if (key is Symbol) key = MirrorSystem.getName(key);
|
| + if (key is Symbol) key = smoke.symbolToName(key);
|
| return (record as MapChangeRecord).key == key;
|
| }
|
| return false;
|
| @@ -243,22 +241,21 @@ _getObjectProperty(object, property) {
|
| return object[property];
|
| }
|
| } else if (property is Symbol) {
|
| - var mirror = reflect(object);
|
| - final type = mirror.type;
|
| + final type = object.runtimeType;
|
| try {
|
| - if (_maybeHasGetter(type, property)) {
|
| - return mirror.getField(property).reflectee;
|
| + if (smoke.hasGetter(type, property) || smoke.hasNoSuchMethod(type)) {
|
| + return smoke.read(object, property);
|
| }
|
| // Support indexer if available, e.g. Maps or polymer_expressions Scope.
|
| // This is the default syntax used by polymer/nodebind and
|
| // polymer/observe-js PathObserver.
|
| - if (_hasMethod(type, const Symbol('[]'))) {
|
| - return object[MirrorSystem.getName(property)];
|
| + if (smoke.hasInstanceMethod(type, const Symbol('[]'))) {
|
| + return object[smoke.symbolToName(property)];
|
| }
|
| } on NoSuchMethodError catch (e) {
|
| // Rethrow, unless the type implements noSuchMethod, in which case we
|
| // interpret the exception as a signal that the method was not found.
|
| - if (!_hasMethod(type, #noSuchMethod)) rethrow;
|
| + if (!smoke.hasNoSuchMethod(type)) rethrow;
|
| }
|
| }
|
|
|
| @@ -277,20 +274,19 @@ bool _setObjectProperty(object, property, value) {
|
| return true;
|
| }
|
| } else if (property is Symbol) {
|
| - var mirror = reflect(object);
|
| - final type = mirror.type;
|
| + final type = object.runtimeType;
|
| try {
|
| - if (_maybeHasSetter(type, property)) {
|
| - mirror.setField(property, value);
|
| + if (smoke.hasSetter(type, property) || smoke.hasNoSuchMethod(type)) {
|
| + smoke.write(object, property, value);
|
| return true;
|
| }
|
| // Support indexer if available, e.g. Maps or polymer_expressions Scope.
|
| - if (_hasMethod(type, const Symbol('[]='))) {
|
| - object[MirrorSystem.getName(property)] = value;
|
| + if (smoke.hasInstanceMethod(type, const Symbol('[]='))) {
|
| + object[smoke.symbolToName(property)] = value;
|
| return true;
|
| }
|
| } on NoSuchMethodError catch (e) {
|
| - if (!_hasMethod(type, #noSuchMethod)) rethrow;
|
| + if (!smoke.hasNoSuchMethod(type)) rethrow;
|
| }
|
| }
|
|
|
| @@ -300,57 +296,6 @@ bool _setObjectProperty(object, property, value) {
|
| return false;
|
| }
|
|
|
| -bool _maybeHasGetter(ClassMirror type, Symbol name) {
|
| - while (type != objectType) {
|
| - final members = type.declarations;
|
| - if (members.containsKey(name)) return true;
|
| - if (members.containsKey(#noSuchMethod)) return true;
|
| - type = _safeSuperclass(type);
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -// TODO(jmesserly): workaround for:
|
| -// https://code.google.com/p/dart/issues/detail?id=10029
|
| -Symbol _setterName(Symbol getter) =>
|
| - new Symbol('${MirrorSystem.getName(getter)}=');
|
| -
|
| -bool _maybeHasSetter(ClassMirror type, Symbol name) {
|
| - var setterName = _setterName(name);
|
| - while (type != objectType) {
|
| - final members = type.declarations;
|
| - if (members[name] is VariableMirror) return true;
|
| - if (members.containsKey(setterName)) return true;
|
| - if (members.containsKey(#noSuchMethod)) return true;
|
| - type = _safeSuperclass(type);
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -/// True if the type has a method, other than on Object.
|
| -/// Doesn't consider noSuchMethod, unless [name] is `#noSuchMethod`.
|
| -bool _hasMethod(ClassMirror type, Symbol name) {
|
| - while (type != objectType) {
|
| - final member = type.declarations[name];
|
| - if (member is MethodMirror && member.isRegularMethod) return true;
|
| - type = _safeSuperclass(type);
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -ClassMirror _safeSuperclass(ClassMirror type) {
|
| - try {
|
| - return type.superclass;
|
| - } /*on UnsupportedError*/ catch (e) {
|
| - // Note: dart2js throws UnsupportedError when the type is not
|
| - // reflectable.
|
| - // TODO(jmesserly): dart2js also throws a NoSuchMethodError if the `type` is
|
| - // a bound generic, because they are not fully implemented. See
|
| - // https://code.google.com/p/dart/issues/detail?id=15573
|
| - return objectType;
|
| - }
|
| -}
|
| -
|
| // From: https://github.com/rafaelw/ChangeSummary/blob/master/change_summary.js
|
|
|
| final _pathRegExp = () {
|
| @@ -570,7 +515,7 @@ abstract class _Observer extends Bindable {
|
| return _value;
|
| }
|
|
|
| - @reflectable get value {
|
| + get value {
|
| _check(skipChanges: true);
|
| return _value;
|
| }
|
|
|