Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 import 'package:observe/observe.dart'; | 10 import 'package:observe/observe.dart'; |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 201 Object operator[](String name) { | 201 Object operator[](String name) { |
| 202 if (name == 'this') return model; | 202 if (name == 'this') return model; |
| 203 var symbol = smoke.nameToSymbol(name); | 203 var symbol = smoke.nameToSymbol(name); |
| 204 if (model == null || symbol == null) { | 204 if (model == null || symbol == null) { |
| 205 throw new EvalException("variable '$name' not found"); | 205 throw new EvalException("variable '$name' not found"); |
| 206 } | 206 } |
| 207 return _convert(smoke.read(model, symbol)); | 207 return _convert(smoke.read(model, symbol)); |
| 208 } | 208 } |
| 209 | 209 |
| 210 Object _isModelProperty(String name) => name != 'this'; | 210 Object _isModelProperty(String name) => name != 'this'; |
| 211 | |
| 212 String toString() => "[model: $model]"; | |
| 211 } | 213 } |
| 212 | 214 |
| 213 /** | 215 /** |
| 214 * A scope that holds a reference to a single variable. Polymer expressions | 216 * A scope that holds a reference to a single variable. Polymer expressions |
| 215 * introduce variables to the scope one at a time. Each time a variable is | 217 * introduce variables to the scope one at a time. Each time a variable is |
| 216 * added, a new [_LocalVariableScope] is created. | 218 * added, a new [_LocalVariableScope] is created. |
| 217 */ | 219 */ |
| 218 class _LocalVariableScope extends Scope { | 220 class _LocalVariableScope extends Scope { |
| 219 final Scope parent; | 221 final Scope parent; |
| 220 final String varName; | 222 final String varName; |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 232 Object operator[](String name) { | 234 Object operator[](String name) { |
| 233 if (varName == name) return _convert(value); | 235 if (varName == name) return _convert(value); |
| 234 if (parent != null) return parent[name]; | 236 if (parent != null) return parent[name]; |
| 235 throw new EvalException("variable '$name' not found"); | 237 throw new EvalException("variable '$name' not found"); |
| 236 } | 238 } |
| 237 | 239 |
| 238 bool _isModelProperty(String name) { | 240 bool _isModelProperty(String name) { |
| 239 if (varName == name) return false; | 241 if (varName == name) return false; |
| 240 return parent == null ? false : parent._isModelProperty(name); | 242 return parent == null ? false : parent._isModelProperty(name); |
| 241 } | 243 } |
| 244 | |
| 245 String toString() => "$parent > [local: $varName]"; | |
| 242 } | 246 } |
| 243 | 247 |
| 244 /** A scope that holds a reference to a global variables. */ | 248 /** A scope that holds a reference to a global variables. */ |
| 245 class _GlobalsScope extends Scope { | 249 class _GlobalsScope extends Scope { |
| 246 final _ModelScope parent; | 250 final _ModelScope parent; |
| 247 final Map<String, Object> variables; | 251 final Map<String, Object> variables; |
| 248 | 252 |
| 249 _GlobalsScope(this.variables, this.parent) : super._() { | 253 _GlobalsScope(this.variables, this.parent) : super._() { |
| 250 if (variables.containsKey('this')) { | 254 if (variables.containsKey('this')) { |
| 251 throw new EvalException("'this' cannot be used as a variable name."); | 255 throw new EvalException("'this' cannot be used as a variable name."); |
| 252 } | 256 } |
| 253 } | 257 } |
| 254 | 258 |
| 255 Object get model => parent != null ? parent.model : null; | 259 Object get model => parent != null ? parent.model : null; |
| 256 | 260 |
| 257 Object operator[](String name) { | 261 Object operator[](String name) { |
| 258 if (variables.containsKey(name)) return _convert(variables[name]); | 262 if (variables.containsKey(name)) return _convert(variables[name]); |
| 259 if (parent != null) return parent[name]; | 263 if (parent != null) return parent[name]; |
| 260 throw new EvalException("variable '$name' not found"); | 264 throw new EvalException("variable '$name' not found"); |
| 261 } | 265 } |
| 262 | 266 |
| 263 bool _isModelProperty(String name) { | 267 bool _isModelProperty(String name) { |
| 264 if (variables.containsKey(name)) return false; | 268 if (variables.containsKey(name)) return false; |
| 265 return parent == null ? false : parent._isModelProperty(name); | 269 return parent == null ? false : parent._isModelProperty(name); |
| 266 } | 270 } |
| 271 | |
| 272 String toString() => "$parent > [global: ${variables.keys}]"; | |
| 267 } | 273 } |
| 268 | 274 |
| 269 Object _convert(v) => v is Stream ? new StreamBinding(v) : v; | 275 Object _convert(v) => v is Stream ? new StreamBinding(v) : v; |
| 270 | 276 |
| 271 abstract class ExpressionObserver<E extends Expression> implements Expression { | 277 abstract class ExpressionObserver<E extends Expression> implements Expression { |
| 272 final E _expr; | 278 final E _expr; |
| 273 ExpressionObserver _parent; | 279 ExpressionObserver _parent; |
| 274 | 280 |
| 275 StreamSubscription _subscription; | 281 StreamSubscription _subscription; |
| 276 Object _value; | 282 Object _value; |
| (...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 723 var iterable = right._value; | 729 var iterable = right._value; |
| 724 | 730 |
| 725 if (iterable is! Iterable && iterable != null) { | 731 if (iterable is! Iterable && iterable != null) { |
| 726 throw new EvalException("right side of 'in' is not an iterator"); | 732 throw new EvalException("right side of 'in' is not an iterator"); |
| 727 } | 733 } |
| 728 | 734 |
| 729 if (iterable is ObservableList) { | 735 if (iterable is ObservableList) { |
| 730 _subscription = iterable.listChanges.listen((_) => _invalidate(scope)); | 736 _subscription = iterable.listChanges.listen((_) => _invalidate(scope)); |
| 731 } | 737 } |
| 732 | 738 |
| 733 // TODO: make Comprehension observable and update it | 739 var name = identifier.value; |
|
Jennifer Messerly
2014/05/30 22:55:10
does this TODO need to stick around?
Siggi Cherem (dart-lang)
2014/05/31 00:56:17
Yes, but there was already an equivalent TODO in _
| |
| 734 _value = new Comprehension(identifier.value, iterable); | 740 _value = iterable == null ? const [] : |
| 741 iterable.map((i) => scope.childScope(name, i)).toList(growable: false); | |
| 735 } | 742 } |
| 736 | 743 |
| 737 accept(Visitor v) => v.visitInExpression(this); | 744 accept(Visitor v) => v.visitInExpression(this); |
| 738 } | 745 } |
| 739 | 746 |
| 740 _toBool(v) => (v == null) ? false : v; | 747 _toBool(v) => (v == null) ? false : v; |
| 741 | 748 |
| 742 /** | |
| 743 * A comprehension declaration ("a in b"). [identifier] is the loop variable | |
| 744 * that's added to the scope during iteration. [iterable] is the set of | |
| 745 * objects to iterate over. | |
| 746 */ | |
| 747 class Comprehension { | |
| 748 final String identifier; | |
| 749 final Iterable iterable; | |
| 750 | |
| 751 Comprehension(this.identifier, Iterable iterable) | |
| 752 : iterable = (iterable != null) ? iterable : const []; | |
| 753 } | |
| 754 | |
| 755 class EvalException implements Exception { | 749 class EvalException implements Exception { |
| 756 final String message; | 750 final String message; |
| 757 EvalException(this.message); | 751 EvalException(this.message); |
| 758 String toString() => "EvalException: $message"; | 752 String toString() => "EvalException: $message"; |
| 759 } | 753 } |
| OLD | NEW |