Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(86)

Side by Side Diff: pkg/polymer_expressions/lib/eval.dart

Issue 25967002: fix list filtering if the filter is a method (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | pkg/polymer_expressions/test/eval_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library polymer_expressions.eval; 5 library polymer_expressions.eval;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:collection'; 8 import 'dart:collection';
9 import 'dart:mirrors'; 9 import 'dart:mirrors';
10 10
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
141 } 141 }
142 142
143 /** 143 /**
144 * A mapping of names to objects. Scopes contain a set of named [variables] and 144 * A mapping of names to objects. Scopes contain a set of named [variables] and
145 * a single [model] object (which can be thought of as the "this" reference). 145 * a single [model] object (which can be thought of as the "this" reference).
146 * Names are currently looked up in [variables] first, then the [model]. 146 * Names are currently looked up in [variables] first, then the [model].
147 * 147 *
148 * Scopes can be nested by giving them a [parent]. If a name in not found in a 148 * Scopes can be nested by giving them a [parent]. If a name in not found in a
149 * Scope, it will look for it in it's parent. 149 * Scope, it will look for it in it's parent.
150 */ 150 */
151 class Scope extends Object { 151 class Scope {
Jennifer Messerly 2013/10/04 02:18:19 trivial style fix: remove "extends Object" which i
152 final Scope parent; 152 final Scope parent;
153 final Object model; 153 final Object model;
154 // TODO(justinfagnani): disallow adding/removing names 154 // TODO(justinfagnani): disallow adding/removing names
155 final ObservableMap<String, Object> _variables; 155 final ObservableMap<String, Object> _variables;
156 InstanceMirror __modelMirror; 156 InstanceMirror __modelMirror;
157 157
158 Scope({this.model, Map<String, Object> variables: const {}, this.parent}) 158 Scope({this.model, Map<String, Object> variables: const {}, this.parent})
159 : _variables = new ObservableMap.from(variables); 159 : _variables = new ObservableMap.from(variables);
160 160
161 InstanceMirror get _modelMirror { 161 InstanceMirror get _modelMirror {
162 if (__modelMirror != null) return __modelMirror; 162 if (__modelMirror != null) return __modelMirror;
163 __modelMirror = reflect(model); 163 __modelMirror = reflect(model);
164 return __modelMirror; 164 return __modelMirror;
165 } 165 }
166 166
167 Object operator[](String name) { 167 Object operator[](String name) {
168 if (name == 'this') { 168 if (name == 'this') {
169 return model; 169 return model;
170 } else if (_variables.containsKey(name)) { 170 } else if (_variables.containsKey(name)) {
171 return _convert(_variables[name]); 171 return _convert(_variables[name]);
172 } else if (model != null) { 172 } else if (model != null) {
173 var symbol = new Symbol(name); 173 var symbol = new Symbol(name);
174 var classMirror = _modelMirror.type; 174 var classMirror = _modelMirror.type;
175 var memberMirror = getMemberMirror(classMirror, symbol); 175 var memberMirror = getMemberMirror(classMirror, symbol);
justinfagnani 2013/10/04 20:46:08 We should be able to reduce the follow if/else to:
176 if (memberMirror is VariableMirror || 176 if (memberMirror is VariableMirror ||
177 (memberMirror is MethodMirror && memberMirror.isGetter)) { 177 (memberMirror is MethodMirror && memberMirror.isGetter)) {
178 return _convert(_modelMirror.getField(symbol).reflectee); 178 return _convert(_modelMirror.getField(symbol).reflectee);
179 } else if (memberMirror is MethodMirror) { 179 } else if (memberMirror is MethodMirror) {
180 return new Method(_modelMirror, symbol); 180 return new Method(_modelMirror, symbol);
181 } 181 }
182 } 182 }
183 if (parent != null) { 183 if (parent != null) {
184 return _convert(parent[name]); 184 return _convert(parent[name]);
185 } else { 185 } else {
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after
593 593
594 // TODO: make Comprehension observable and update it 594 // TODO: make Comprehension observable and update it
595 _value = new Comprehension(identifier.value, iterable); 595 _value = new Comprehension(identifier.value, iterable);
596 } 596 }
597 597
598 accept(Visitor v) => v.visitInExpression(this); 598 accept(Visitor v) => v.visitInExpression(this);
599 } 599 }
600 600
601 _toBool(v) => (v == null) ? false : v; 601 _toBool(v) => (v == null) ? false : v;
602 602
603 call(dynamic receiver, List args) { 603 /** Call a [Function] or a [Method]. */
604 Object call(Object receiver, List args) {
Jennifer Messerly 2013/10/04 02:18:19 trivial style fix: avoid "dynamic" except as type
justinfagnani 2013/10/04 20:46:08 if InstanceMirror.getField() properly closurizes,
605 var result;
604 if (receiver is Method) { 606 if (receiver is Method) {
605 return 607 result = receiver.mirror.invoke(receiver.symbol, args, null).reflectee;
606 _convert(receiver.mirror.invoke(receiver.symbol, args, null).reflectee);
607 } else { 608 } else {
608 return _convert(Function.apply(receiver, args, null)); 609 result = Function.apply(receiver, args, null);
609 } 610 }
611 return _convert(result);
610 } 612 }
611 613
612 /** 614 /**
613 * A comprehension declaration ("a in b"). [identifier] is the loop variable 615 * A comprehension declaration ("a in b"). [identifier] is the loop variable
614 * that's added to the scope during iteration. [iterable] is the set of 616 * that's added to the scope during iteration. [iterable] is the set of
615 * objects to iterate over. 617 * objects to iterate over.
616 */ 618 */
617 class Comprehension { 619 class Comprehension {
618 final String identifier; 620 final String identifier;
619 final Iterable iterable; 621 final Iterable iterable;
620 622
621 Comprehension(this.identifier, Iterable iterable) 623 Comprehension(this.identifier, Iterable iterable)
622 : iterable = (iterable != null) ? iterable : const []; 624 : iterable = (iterable != null) ? iterable : const [];
623 } 625 }
624 626
625 /** 627 /** A method on a model object in a [Scope]. */
626 * A method on a model object in a [Scope]. 628 class Method {
627 */
628 class Method { //implements _FunctionWrapper {
629 final InstanceMirror mirror; 629 final InstanceMirror mirror;
630 final Symbol symbol; 630 final Symbol symbol;
631 631
632 Method(this.mirror, this.symbol); 632 Method(this.mirror, this.symbol);
633 633
634 dynamic call(List args) => mirror.invoke(symbol, args, null).reflectee; 634 /**
635 * Support for calling single argument methods like [Filter]s.
636 * This does not work for calls that need to pass more than one argument.
637 */
638 call(arg0) => mirror.invoke(symbol, [arg0], null).reflectee;
Jennifer Messerly 2013/10/04 02:18:19 the actual bug fix. "call" is different from Funct
justinfagnani 2013/10/04 20:41:47 I think this fix could be different, because Insta
Jennifer Messerly 2013/10/04 20:44:28 Alright, I'll take a shot at removing "Method" ins
635 } 639 }
636 640
637 class EvalException implements Exception { 641 class EvalException implements Exception {
638 final String message; 642 final String message;
639 EvalException(this.message); 643 EvalException(this.message);
640 String toString() => "EvalException: $message"; 644 String toString() => "EvalException: $message";
641 } 645 }
OLDNEW
« no previous file with comments | « no previous file | pkg/polymer_expressions/test/eval_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698