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

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

Issue 141703024: Refactor of PolymerExpressions. Adds "as" expressions. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Reviewable state. More readable tests. Created 6 years, 10 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
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 9
10 @MirrorsUsed(metaTargets: const [Reflectable, ObservableProperty], 10 @MirrorsUsed(metaTargets: const [Reflectable, ObservableProperty],
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 var classMirror = _modelMirror.type; 208 var classMirror = _modelMirror.type;
209 if (getMemberMirror(classMirror, symbol) != null) { 209 if (getMemberMirror(classMirror, symbol) != null) {
210 return model; 210 return model;
211 } 211 }
212 } 212 }
213 if (parent != null) { 213 if (parent != null) {
214 return parent.ownerOf(name); 214 return parent.ownerOf(name);
215 } 215 }
216 } 216 }
217 217
218 bool contains(String name) {
219 if (_variables.containsKey(name)) {
220 return true;
221 } else {
222 var symbol = new Symbol(name);
223 var classMirror = _modelMirror.type;
224 if (getMemberMirror(classMirror, symbol) != null) {
225 return true;
226 }
227 }
228 if (parent != null) {
229 return parent.contains(name);
230 }
231 return false;
232 }
233 } 218 }
234 219
235 Object _convert(v) { 220 Object _convert(v) {
236 if (v is Stream) return new StreamBinding(v); 221 if (v is Stream) return new StreamBinding(v);
237 return v; 222 return v;
238 } 223 }
239 224
240 abstract class ExpressionObserver<E extends Expression> implements Expression { 225 abstract class ExpressionObserver<E extends Expression> implements Expression {
241 final E _expr; 226 final E _expr;
242 ExpressionObserver _parent; 227 ExpressionObserver _parent;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 } 268 }
284 269
285 class Updater extends RecursiveVisitor { 270 class Updater extends RecursiveVisitor {
286 final Scope scope; 271 final Scope scope;
287 272
288 Updater(this.scope); 273 Updater(this.scope);
289 274
290 visitExpression(ExpressionObserver e) { 275 visitExpression(ExpressionObserver e) {
291 e._observe(scope); 276 e._observe(scope);
292 } 277 }
293
294 visitInExpression(InObserver c) {
295 visit(c.right);
296 visitExpression(c);
297 }
298 } 278 }
299 279
300 class ObserverBuilder extends Visitor { 280 class ObserverBuilder extends Visitor {
301 final Scope scope; 281 final Scope scope;
302 final Queue parents = new Queue(); 282 final Queue parents = new Queue();
303 283
304 ObserverBuilder(this.scope); 284 ObserverBuilder(this.scope);
305 285
306 visitEmptyExpression(EmptyExpression e) => new EmptyObserver(e); 286 visitEmptyExpression(EmptyExpression e) => new EmptyObserver(e);
307 287
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
382 var trueExpr = visit(o.trueExpr); 362 var trueExpr = visit(o.trueExpr);
383 var falseExpr = visit(o.falseExpr); 363 var falseExpr = visit(o.falseExpr);
384 var ternary = new TernaryObserver(o, condition, trueExpr, falseExpr); 364 var ternary = new TernaryObserver(o, condition, trueExpr, falseExpr);
385 condition._parent = ternary; 365 condition._parent = ternary;
386 trueExpr._parent = ternary; 366 trueExpr._parent = ternary;
387 falseExpr._parent = ternary; 367 falseExpr._parent = ternary;
388 return ternary; 368 return ternary;
389 } 369 }
390 370
391 visitInExpression(InExpression i) { 371 visitInExpression(InExpression i) {
392 // don't visit the left. It's an identifier, but we don't want to evaluate 372 throw "can't eval an in expression";
Jennifer Messerly 2014/01/31 02:48:50 throw new UnsupportedError?
justinfagnani 2014/03/12 23:21:30 Done.
393 // it, we just want to add it to the comprehension object
394 var left = visit(i.left);
395 var right = visit(i.right);
396 var inexpr = new InObserver(i, left, right);
397 right._parent = inexpr;
398 return inexpr;
399 } 373 }
374
375 visitAsExpression(AsExpression i) {
376 throw "can't eval an as expression";
377 }
378
400 } 379 }
401 380
402 class EmptyObserver extends ExpressionObserver<EmptyExpression> 381 class EmptyObserver extends ExpressionObserver<EmptyExpression>
403 implements EmptyExpression { 382 implements EmptyExpression {
404 383
405 EmptyObserver(EmptyExpression value) : super(value); 384 EmptyObserver(EmptyExpression value) : super(value);
406 385
407 _updateSelf(Scope scope) { 386 _updateSelf(Scope scope) {
408 _value = scope.model; 387 _value = scope.model;
409 // TODO(justin): listen for scope.model changes? 388 // TODO(justin): listen for scope.model changes?
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
669 _invalidate(scope); 648 _invalidate(scope);
670 } 649 }
671 }); 650 });
672 } 651 }
673 } 652 }
674 } 653 }
675 654
676 accept(Visitor v) => v.visitInvoke(this); 655 accept(Visitor v) => v.visitInvoke(this);
677 } 656 }
678 657
679 class InObserver extends ExpressionObserver<InExpression>
680 implements InExpression {
681 IdentifierObserver left;
682 ExpressionObserver right;
683
684 InObserver(Expression expr, this.left, this.right) : super(expr);
685
686 _updateSelf(Scope scope) {
687 Identifier identifier = left;
688 var iterable = right._value;
689
690 if (iterable is! Iterable && iterable != null) {
691 throw new EvalException("right side of 'in' is not an iterator");
692 }
693
694 if (iterable is ObservableList) {
695 _subscription = iterable.listChanges.listen((_) => _invalidate(scope));
696 }
697
698 // TODO: make Comprehension observable and update it
699 _value = new Comprehension(identifier.value, iterable);
700 }
701
702 accept(Visitor v) => v.visitInExpression(this);
703 }
704
705 _toBool(v) => (v == null) ? false : v; 658 _toBool(v) => (v == null) ? false : v;
706 659
707 /** Call a [Function] or a [Method]. */ 660 /** Call a [Function] or a [Method]. */
708 // TODO(jmesserly): remove this once dartbug.com/13002 is fixed. 661 // TODO(jmesserly): remove this once dartbug.com/13002 is fixed.
709 // Just inline `_convert(Function.apply(...))` to the call site. 662 // Just inline `_convert(Function.apply(...))` to the call site.
710 Object call(Object receiver, List args) { 663 Object call(Object receiver, List args) {
711 var result; 664 var result;
712 if (receiver is Method) { 665 if (receiver is Method) {
713 Method method = receiver; 666 Method method = receiver;
714 result = method.mirror.invoke(method.symbol, args, null).reflectee; 667 result = method.mirror.invoke(method.symbol, args, null).reflectee;
715 } else { 668 } else {
716 result = Function.apply(receiver, args, null); 669 result = Function.apply(receiver, args, null);
717 } 670 }
718 return _convert(result); 671 return _convert(result);
719 } 672 }
720 673
721 /**
722 * A comprehension declaration ("a in b"). [identifier] is the loop variable
723 * that's added to the scope during iteration. [iterable] is the set of
724 * objects to iterate over.
725 */
726 class Comprehension {
727 final String identifier;
728 final Iterable iterable;
729
730 Comprehension(this.identifier, Iterable iterable)
731 : iterable = (iterable != null) ? iterable : const [];
732 }
733
734 /** A method on a model object in a [Scope]. */ 674 /** A method on a model object in a [Scope]. */
735 class Method { 675 class Method {
736 final InstanceMirror mirror; 676 final InstanceMirror mirror;
737 final Symbol symbol; 677 final Symbol symbol;
738 678
739 Method(this.mirror, this.symbol); 679 Method(this.mirror, this.symbol);
740 680
741 /** 681 /**
742 * Support for calling single argument methods like [Filter]s. 682 * Support for calling single argument methods like [Filter]s.
743 * This does not work for calls that need to pass more than one argument. 683 * This does not work for calls that need to pass more than one argument.
744 */ 684 */
745 call(arg0) => mirror.invoke(symbol, [arg0], null).reflectee; 685 call(arg0) => mirror.invoke(symbol, [arg0], null).reflectee;
746 } 686 }
747 687
748 class EvalException implements Exception { 688 class EvalException implements Exception {
749 final String message; 689 final String message;
750 EvalException(this.message); 690 EvalException(this.message);
751 String toString() => "EvalException: $message"; 691 String toString() => "EvalException: $message";
752 } 692 }
OLDNEW
« no previous file with comments | « no previous file | pkg/polymer_expressions/lib/expression.dart » ('j') | pkg/polymer_expressions/lib/parser.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698