Skip to content
This repository was archived by the owner on Feb 22, 2018. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions bin/parser_generator_for_spec.dart
Original file line number Diff line number Diff line change
Expand Up @@ -443,5 +443,65 @@ main(arguments) {
'x."foo"',
'{(:0}',
'{1234:0}',

"sub1(1)",
"sub1(3, b: 2)",
"sub2()",
"sub2(a: 3)",
"sub2(a: 3, b: 2)",
"sub2(b: 4)",

"o.sub1(1)",
"o.sub1(3, b: 2)",
"o.sub2()",
"o.sub2(a: 3)",
"o.sub2(a: 3, b: 2)",
"o.sub2(b: 4)",

"(sub1)(1)",
"(sub1)(3, b: 2)",
"(sub2)()",
"(sub2)(a: 3)",
"(sub2)(a: 3, b: 2)",
"(sub2)(b: 4)",

'foo(a: 0, a: 1)',
'foo(a: 0, b: 1, a: 2)',
'foo(0, a: 1, a: 2)',
'foo(0, a: 1, b: 2, a: 3)',

'foo(if: 0)',
'foo(a: 0, class: 0)',

'foo(a: 0)',
'foo(a: 0, b: 1)',
'foo(b: 1, a: 0)',
'foo(0)',
'foo(0, a: 0)',
'foo(0, a: 0, b: 1)',
'foo(0, b: 1, a: 0)',

'o.foo(a: 0)',
'o.foo(a: 0, b: 1)',
'o.foo(b: 1, a: 0)',
'o.foo(0)',
'o.foo(0, a: 0)',
'o.foo(0, a: 0, b: 1)',
'o.foo(0, b: 1, a: 0)',

'(foo)(a: 0)',
'(foo)(a: 0, b: 1)',
'(foo)(b: 1, a: 0)',
'(foo)(0)',
'(foo)(0, a: 0)',
'(foo)(0, a: 0, b: 1)',
'(foo)(0, b: 1, a: 0)',

'foo(a: 0, 1)',
'foo(a: 0, b: 1, 2)',
'foo(a: 0, 1, b: 2)',
'foo(a: 0, b: 1, 2, c: 3)',
'foo(0: 1)',
'foo("0": 1)',
]);
}
18 changes: 15 additions & 3 deletions example/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ packages:
analyzer:
description: analyzer
source: hosted
version: "0.11.10"
version: "0.12.2"
angular:
description:
path: ".."
Expand All @@ -15,30 +15,42 @@ packages:
description: args
source: hosted
version: "0.9.0"
barback:
description: barback
source: hosted
version: "0.11.1"
browser:
description: browser
source: hosted
version: "0.9.1"
code_transformers:
description: code_transformers
source: hosted
version: "0.0.1-dev.2"
collection:
description: collection
source: hosted
version: "0.9.1"
di:
description: di
source: hosted
version: "0.0.33"
version: "0.0.34"
html5lib:
description: html5lib
source: hosted
version: "0.9.2"
intl:
description: intl
source: hosted
version: "0.9.7"
version: "0.8.10+4"
logging:
description: logging
source: hosted
version: "0.9.1+1"
meta:
description: meta
source: hosted
version: "0.8.8"
path:
description: path
source: hosted
Expand Down
7 changes: 4 additions & 3 deletions lib/change_detection/ast.dart
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ class PureFunctionAST extends AST {
super('$name(${_argList(argsAST)})');

WatchRecord<_Handler> setupWatch(WatchGroup watchGroup) =>
watchGroup.addFunctionWatch(fn, argsAST, expression);
watchGroup.addFunctionWatch(fn, argsAST, const {}, expression);
}

/**
Expand All @@ -96,15 +96,16 @@ class MethodAST extends AST {
final AST lhsAST;
final String name;
final List<AST> argsAST;
final Map<Symbol, AST> namedArgsAST;

MethodAST(lhsAST, name, argsAST)
MethodAST(lhsAST, name, argsAST, [this.namedArgsAST = const {}])
: lhsAST = lhsAST,
name = name,
argsAST = argsAST,
super('$lhsAST.$name(${_argList(argsAST)})');

WatchRecord<_Handler> setupWatch(WatchGroup watchGroup) =>
watchGroup.addMethodWatch(lhsAST, name, argsAST, expression);
watchGroup.addMethodWatch(lhsAST, name, argsAST, namedArgsAST, expression);
}


Expand Down
73 changes: 52 additions & 21 deletions lib/change_detection/watch_group.dart
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,9 @@ class WatchGroup implements _EvalWatchList, _WatchGroupList {
* - [expression] normalized expression used for caching.
*/
_EvalWatchRecord addFunctionWatch(/* dartbug.com/16401 Function */ fn, List<AST> argsAST,
Map<Symbol, AST> namedArgsAST,
String expression) =>
_addEvalWatch(null, fn, null, argsAST, expression);
_addEvalWatch(null, fn, null, argsAST, namedArgsAST, expression);

/**
* Watch a method [name]ed represented by an [expression].
Expand All @@ -198,13 +199,16 @@ class WatchGroup implements _EvalWatchList, _WatchGroupList {
* - [expression] normalized expression used for caching.
*/
_EvalWatchRecord addMethodWatch(AST lhs, String name, List<AST> argsAST,
Map<Symbol, AST> namedArgsAST,
String expression) =>
_addEvalWatch(lhs, null, name, argsAST, expression);
_addEvalWatch(lhs, null, name, argsAST, namedArgsAST, expression);



_EvalWatchRecord _addEvalWatch(AST lhsAST, /* dartbug.com/16401 Function */ fn, String name,
List<AST> argsAST, String expression) {
List<AST> argsAST,
Map<Symbol, AST> namedArgsAST,
String expression) {
_InvokeHandler invokeHandler = new _InvokeHandler(this, expression);
var evalWatchRecord = new _EvalWatchRecord(this, invokeHandler, fn, name,
argsAST.length);
Expand All @@ -218,15 +222,24 @@ class WatchGroup implements _EvalWatchList, _WatchGroupList {
}

// Convert the args from AST to WatchRecords
var i = 0;
argsAST.map((ast) =>
_cache.putIfAbsent(ast.expression, () => ast.setupWatch(this)))
.forEach((WatchRecord<_Handler> record) {
var argHandler = new _ArgHandler(this, evalWatchRecord, i++);
_ArgHandlerList._add(invokeHandler, argHandler);
record.handler.addForwardHandler(argHandler);
argHandler.acceptValue(record.currentValue);
});
Iterable<WatchRecord<_Handler>> records = argsAST.map((ast) =>
_cache.putIfAbsent(ast.expression, () => ast.setupWatch(this)));
int i = 0;
records.forEach((WatchRecord<_Handler> record) {
_ArgHandler handler = new _PositionalArgHandler(this, evalWatchRecord, i++);
_ArgHandlerList._add(invokeHandler, handler);
record.handler.addForwardHandler(handler);
handler.acceptValue(record.currentValue);
});

namedArgsAST.forEach((Symbol name, AST ast) {
WatchRecord<_Handler> record = _cache.putIfAbsent(ast.expression,
() => ast.setupWatch(this));
_ArgHandler handler = new _NamedArgHandler(this, evalWatchRecord, name);
_ArgHandlerList._add(invokeHandler, handler);
record.handler.addForwardHandler(handler);
handler.acceptValue(record.currentValue);
});

// Must be done last
_EvalWatchList._add(this, evalWatchRecord);
Expand Down Expand Up @@ -615,25 +628,42 @@ class _CollectionHandler extends _Handler {
}
}

class _ArgHandler extends _Handler {
abstract class _ArgHandler extends _Handler {
_ArgHandler _previousArgHandler, _nextArgHandler;

// TODO(misko): Why do we override parent?
final _EvalWatchRecord watchRecord;
final int index;
_ArgHandler(WatchGroup watchGrp, String expression, this.watchRecord)
: super(watchGrp, expression);

_releaseWatch() => null;
}

_ArgHandler(WatchGroup watchGrp, this.watchRecord, int index)
: index = index,
super(watchGrp, 'arg[$index]');
class _PositionalArgHandler extends _ArgHandler {
final int index;
_PositionalArgHandler(WatchGroup watchGrp, _EvalWatchRecord record, int index)
: this.index = index,
super(watchGrp, 'arg[$index]', record);

void acceptValue(object) {
watchRecord.dirtyArgs = true;
watchRecord.args[index] = object;
}
}

class _NamedArgHandler extends _ArgHandler {
final Symbol name;

_NamedArgHandler(WatchGroup watchGrp, _EvalWatchRecord record, Symbol name)
: this.name = name,
super(watchGrp, 'namedArg[$name]', record);

void acceptValue(object) {
watchRecord.dirtyArgs = true;
watchRecord.namedArgs[name] = object;
}
}

class _InvokeHandler extends _Handler implements _ArgHandlerList {
_ArgHandler _argHandlerHead, _argHandlerTail;

Expand Down Expand Up @@ -675,6 +705,7 @@ class _EvalWatchRecord implements WatchRecord<_Handler>, Record<_Handler> {
WatchGroup watchGrp;
final _Handler handler;
final List args;
final Map<Symbol, dynamic> namedArgs = new Map<Symbol, dynamic>();
final Symbol symbol;
final String name;
int mode;
Expand Down Expand Up @@ -751,7 +782,7 @@ class _EvalWatchRecord implements WatchRecord<_Handler>, Record<_Handler> {
return false;
case _MODE_FUNCTION_:
if (!dirtyArgs) return false;
value = Function.apply(fn, args);
value = Function.apply(fn, args, namedArgs);
dirtyArgs = false;
break;
case _MODE_FUNCTION_APPLY_:
Expand All @@ -761,14 +792,14 @@ class _EvalWatchRecord implements WatchRecord<_Handler>, Record<_Handler> {
break;
case _MODE_FIELD_CLOSURE_:
var closure = _instanceMirror.getField(symbol).reflectee;
value = closure == null ? null : Function.apply(closure, args);
value = closure == null ? null : Function.apply(closure, args, namedArgs);
break;
case _MODE_MAP_CLOSURE_:
var closure = object[name];
value = closure == null ? null : Function.apply(closure, args);
value = closure == null ? null : Function.apply(closure, args, namedArgs);
break;
case _MODE_METHOD_:
value = _instanceMirror.invoke(symbol, args).reflectee;
value = _instanceMirror.invoke(symbol, args, namedArgs).reflectee;
break;
default:
assert(false);
Expand Down
22 changes: 12 additions & 10 deletions lib/core/parser/dynamic_parser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import 'package:angular/core/parser/utils.dart' show EvalError;
class ClosureMap {
Getter lookupGetter(String name) => null;
Setter lookupSetter(String name) => null;
Function lookupFunction(String name, int arity) => null;
Function lookupFunction(String name, CallArguments arguments) => null;
}

@NgInjectableService()
Expand Down Expand Up @@ -128,33 +128,35 @@ class DynamicParserBackend extends ParserBackend {

Expression newCallScope(name, arguments) {
Function constructor = _computeCallConstructor(
_callScopeConstructors, name, arguments.length);
_callScopeConstructors, name, arguments);
return (constructor != null)
? constructor(name, arguments, _closures)
: new CallScope(name, arguments);
}

Expression newCallMember(object, name, arguments) {
Function constructor = _computeCallConstructor(
_callMemberConstructors, name, arguments.length);
_callMemberConstructors, name, arguments);
return (constructor != null)
? constructor(object, name, arguments, _closures)
: new CallMember(object, name, arguments);
}

Function _computeCallConstructor(Map constructors, String name, int arity) {
Function function = _closures.lookupFunction(name, arity);
return (function == null) ? null : constructors[arity];
Function _computeCallConstructor(Map constructors,
String name,
CallArguments arguments) {
Function function = _closures.lookupFunction(name, arguments);
return (function == null) ? null : constructors[arguments.arity];
}

static final Map<int, Function> _callScopeConstructors = {
0: (n, a, c) => new CallScopeFast0(n, a, c.lookupFunction(n, 0)),
1: (n, a, c) => new CallScopeFast1(n, a, c.lookupFunction(n, 1)),
0: (n, a, c) => new CallScopeFast0(n, a, c.lookupFunction),
1: (n, a, c) => new CallScopeFast1(n, a, c.lookupFunction),
};

static final Map<int, Function> _callMemberConstructors = {
0: (o, n, a, c) => new CallMemberFast0(o, n, a, c.lookupFunction(n, 0)),
1: (o, n, a, c) => new CallMemberFast1(o, n, a, c.lookupFunction(n, 1)),
0: (o, n, a, c) => new CallMemberFast0(o, n, a, c.lookupFunction),
1: (o, n, a, c) => new CallMemberFast1(o, n, a, c.lookupFunction),
};
}

Loading