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

Unified Diff: third_party/pkg/angular/lib/core/parser/backend.dart

Issue 124053002: Adding Angular and dependent packages for testing (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 12 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 side-by-side diff with in-line comments
Download patch
Index: third_party/pkg/angular/lib/core/parser/backend.dart
diff --git a/third_party/pkg/angular/lib/core/parser/backend.dart b/third_party/pkg/angular/lib/core/parser/backend.dart
new file mode 100644
index 0000000000000000000000000000000000000000..d5961eeccd1515d19584a850fa15ebf455488bd1
--- /dev/null
+++ b/third_party/pkg/angular/lib/core/parser/backend.dart
@@ -0,0 +1,362 @@
+part of angular.core.parser;
+
+typedef dynamic LocalsWrapper(dynamic context, dynamic locals);
+
+class BoundExpression {
+ var _context;
+ LocalsWrapper _localsWrapper;
+ Expression expression;
+
+ BoundExpression(this._context, this.expression, this._localsWrapper);
+ _localContext(locals) {
+ if (locals != null) {
+ if (_localsWrapper == null) {
+ throw new StateError("Locals $locals provided, but no LocalsWrapper strategy.");
+ }
+ return _localsWrapper(_context, locals);
+ }
+ return _context;
+ }
+
+ call([locals]) => expression.eval(_localContext(locals));
+ assign(value, [locals]) => expression.assign(_localContext(locals), value);
+}
+
+class Expression implements ParserAST {
+ final ParsedGetter eval;
+ final ParsedSetter assign;
+
+ String exp;
+ List parts;
+
+ // Expressions that represent field accesses have a couple of
+ // extra fields. We use that to generate an optimized closure
+ // for calling fields of objects without having to load the
+ // field separately.
+ Expression fieldHolder;
+ String fieldName;
+ bool get isFieldAccess => fieldHolder != null;
+
+ Expression(ParsedGetter this.eval, [ParsedSetter this.assign]);
+
+ bind(context, [localsWrapper]) => new BoundExpression(context, this, localsWrapper);
+
+ get assignable => assign != null;
+}
+
+@NgInjectableService()
+class GetterSetter {
+ static stripTrailingNulls(List l) {
+ while (l.length > 0 && l.last == null) {
+ l.removeLast();
+ }
+ return l;
+ }
+
+ static _computeUseInstanceMembers() {
+ try {
+ reflect(Object).type.instanceMembers;
+ return true;
+ } catch (e) {
+ return false;
+ }
+ }
+
+ final bool _useInstanceMembers = _computeUseInstanceMembers();
+
+ _containsKey(InstanceMirror instanceMirror, Symbol symbol) {
+ dynamic type = (instanceMirror.type as dynamic);
+ var members = _useInstanceMembers ? type.instanceMembers : type.members;
+ return members.containsKey(symbol);
+ }
+
+ _maybeInvoke(instanceMirror, symbol) {
+ if (_containsKey(instanceMirror, symbol)) {
+ MethodMirror methodMirror = instanceMirror.type.members[symbol];
+ return relaxFnArgs(([a0, a1, a2, a3, a4, a5]) {
+ var args = stripTrailingNulls([a0, a1, a2, a3, a4, a5]);
+ return instanceMirror.invoke(symbol, args).reflectee;
+ });
+ }
+ return null;
+ }
+
+ Map<String, Function> _getter_cache = {};
+
+ Function getter(String key) {
+ var value = _getter_cache[key];
+ if (value != null) return value;
+ return _getter_cache[key] = _getter(key);
+ }
+
+ Function _getter(String key) {
+ var symbol = new Symbol(key);
+ Map<ClassMirror, Function> fieldCache = {};
+ return (o) {
+ InstanceMirror instanceMirror = reflect(o);
+ ClassMirror classMirror = instanceMirror.type;
+ Function fn = fieldCache[classMirror];
+ if (fn == null) {
+ try {
+ return (fieldCache[classMirror] = (instanceMirror) => instanceMirror.getField(symbol).reflectee)(instanceMirror);
+ } on NoSuchMethodError catch (e) {
+ var value = (fieldCache[classMirror] = (instanceMirror) => _maybeInvoke(instanceMirror, symbol))(instanceMirror);
+ if (value == null) { rethrow; }
+ return value;
+ } on UnsupportedError catch (e) {
+ var value = (fieldCache[classMirror] = (instanceMirror) => _maybeInvoke(instanceMirror, symbol))(instanceMirror);
+ if (value == null) { rethrow; }
+ return value;
+ }
+ } else {
+ return fn(instanceMirror);
+ }
+ };
+ }
+
+ Function setter(String key) {
+ var symbol = new Symbol(key);
+ return (o, v) {
+ reflect(o).setField(symbol, v);
+ return v;
+ };
+ }
+}
+
+var undefined_ = const Symbol("UNDEFINED");
+
+@NgInjectableService()
+class ParserBackend {
+ GetterSetter _getterSetter;
+ FilterMap _filters;
+
+ ParserBackend(GetterSetter this._getterSetter, FilterMap this._filters);
+
+ static Expression ZERO = new Expression((_, [_x]) => 0);
+
+ getter(String path) {
+ List<String> keys = path.split('.');
+ List<Function> getters = keys.map(_getterSetter.getter).toList();
+
+ if (getters.isEmpty) {
+ return (self) => self;
+ } else {
+ return (dynamic self) {
+ if (self == null) {
+ return null;
+ }
+
+ // Cache for local closure access
+ List<String> _keys = keys;
+ List<Function> _getters = getters;
+ var _gettersLength = _getters.length;
+
+ num i = 0;
+ for (; i < _gettersLength; i++) {
+ if (self is Map) {
+ self = self[_keys[i]];
+ } else {
+ self = _getters[i](self);
+ }
+ if (self == null) {
+ return null;
+ }
+ }
+ return self;
+ };
+ }
+ }
+
+ setter(String path) {
+ List<String> keys = path.split('.');
+ List<Function> getters = keys.map(_getterSetter.getter).toList();
+ List<Function> setters = keys.map(_getterSetter.setter).toList();
+ return (dynamic self, dynamic value) {
+ num i = 0;
+ List<String> _keys = keys;
+ List<Function> _getters = getters;
+ List<Function> _setters = setters;
+ var setterLengthMinusOne = _keys.length - 1;
+
+ dynamic selfNext;
+ for (; i < setterLengthMinusOne; i++) {
+ if (self is Map) {
+ selfNext = self[_keys[i]];
+ } else {
+ selfNext = _getters[i](self);
+ }
+
+ if (selfNext == null) {
+ selfNext = {};
+ if (self is Map) {
+ self[_keys[i]] = selfNext;
+ } else {
+ _setters[i](self, selfNext);
+ }
+ }
+ self = selfNext;
+ }
+ if (self is Map) {
+ self[_keys[setterLengthMinusOne]] = value;
+ } else {
+ _setters[i](self, value);
+ }
+ return value;
+ };
+ }
+
+ List evalList(List<Expression> list, self) {
+ int length = list.length;
+ List result = new List(length);
+ for (int i = 0; i < length; i++) {
+ result[i] = list[i].eval(self);
+ }
+ return result;
+ }
+
+ _op(opKey) => OPERATORS[opKey];
+
+ Expression ternaryFn(Expression cond, Expression _true, Expression _false) =>
+ new Expression((self) => _op('?')(
+ self, cond, _true, _false));
+
+ Expression binaryFn(Expression left, String op, Expression right) =>
+ new Expression((self) => _op(op)(self, left, right));
+
+ Expression unaryFn(String op, Expression right) =>
+ new Expression((self) => _op(op)(self, right, null));
+
+ Expression assignment(Expression left, Expression right, evalError) =>
+ new Expression((self) {
+ try {
+ return left.assign(self, right.eval(self));
+ } catch (e, s) {
+ throw evalError('Caught $e', s);
+ }
+ });
+
+ Expression multipleStatements(statements) =>
+ new Expression((self) {
+ var value;
+ for ( var i = 0; i < statements.length; i++) {
+ var statement = statements[i];
+ if (statement != null)
+ value = statement.eval(self);
+ }
+ return value;
+ });
+
+ Expression functionCall(fn, fnName, argsFn, evalError) {
+ if (fn.isFieldAccess) {
+ Symbol key = new Symbol(fn.fieldName);
+ return new Expression((self) {
+ List args = evalList(argsFn, self);
+ var holder = fn.fieldHolder.eval(self);
+ InstanceMirror instanceMirror = reflect(holder);
+ return instanceMirror.invoke(key, args).reflectee;
+ });
+ } else {
+ return new Expression((self) {
+ List args = evalList(argsFn, self);
+ var userFn = safeFunctionCall(fn.eval(self), fnName, evalError);
+ return relaxFnApply(userFn, args);
+ });
+ }
+ }
+
+ Expression arrayDeclaration(elementFns) =>
+ new Expression((self){
+ var array = [];
+ for ( var i = 0; i < elementFns.length; i++) {
+ array.add(elementFns[i].eval(self));
+ }
+ return array;
+ });
+
+ Expression objectIndex(obj, indexFn, evalError) =>
+ new Expression((self) {
+ var i = indexFn.eval(self);
+ var o = obj.eval(self),
+ v, p;
+
+ v = objectIndexGetField(o, i, evalError);
+
+ return v;
+ }, (self, value) =>
+ objectIndexSetField(obj.eval(self),
+ indexFn.eval(self), value, evalError)
+ );
+
+ Expression fieldAccess(object, field) {
+ var setterFn = setter(field);
+ var getterFn = getter(field);
+ return new Expression(
+ (self) => getterFn(object.eval(self)),
+ (self, value) => setterFn(object.eval(self), value))
+ ..fieldHolder = object
+ ..fieldName = field;
+ }
+
+ Expression object(keyValues) =>
+ new Expression((self){
+ var object = {};
+ for ( var i = 0; i < keyValues.length; i++) {
+ var keyValue = keyValues[i];
+ var value = keyValue["value"].eval(self);
+ object[keyValue["key"]] = value;
+ }
+ return object;
+ });
+
+ Expression profiled(value, _perf, text) {
+ if (value is FilterExpression) return value;
+ var wrappedGetter = (s) =>
+ _perf.time('angular.parser.getter', () => value.eval(s), text);
+ var wrappedAssignFn = null;
+ if (value.assign != null) {
+ wrappedAssignFn = (s, v) =>
+ _perf.time('angular.parser.assign',
+ () => value.assign(s, v), text);
+ }
+ return new Expression(wrappedGetter, wrappedAssignFn);
+ }
+
+ Expression fromOperator(String op) =>
+ new Expression((s) => OPERATORS[op](s, null, null));
+
+ Expression getterSetter(key) =>
+ new Expression(getter(key), setter(key));
+
+ Expression value(v) =>
+ new Expression((self) => v);
+
+ zero() => ZERO;
+
+ Expression filter(String filterName,
+ Expression leftHandSide,
+ List<Expression> parameters,
+ Function evalError) {
+ var filterFn = _filters(filterName);
+ return new FilterExpression(filterFn, leftHandSide, parameters);
+ }
+}
+
+class FilterExpression extends Expression {
+ final Function filterFn;
+ final Expression leftHandSide;
+ final List<Expression> parameters;
+
+ FilterExpression(Function this.filterFn,
+ Expression this.leftHandSide,
+ List<Expression> this.parameters): super(null);
+
+ get eval => _eval;
+
+ dynamic _eval(self) {
+ var args = [leftHandSide.eval(self)];
+ for ( var i = 0; i < parameters.length; i++) {
+ args.add(parameters[i].eval(self));
+ }
+ return Function.apply(filterFn, args);
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698