feat(change_detector): add support for method calls
This commit is contained in:
@ -315,7 +315,7 @@ export class MethodCall extends AST {
|
||||
}
|
||||
|
||||
export class FunctionCall extends AST {
|
||||
@FIELD('final receiver:AST')
|
||||
@FIELD('final target:AST')
|
||||
@FIELD('final closureMap:ClosureMap')
|
||||
@FIELD('final args:List')
|
||||
constructor(target:AST, closureMap:ClosureMap, args:List) {
|
||||
|
@ -6,7 +6,9 @@ import {ClosureMap} from 'change_detection/parser/closure_map';
|
||||
var _fresh = new Object();
|
||||
|
||||
export const PROTO_RECORD_CONST = 'const';
|
||||
export const PROTO_RECORD_FUNC = 'func';
|
||||
export const PROTO_RECORD_PURE_FUNCTION = 'func';
|
||||
export const PROTO_RECORD_CLOSURE = 'closure';
|
||||
export const PROTO_RECORD_METHOD = 'method';
|
||||
export const PROTO_RECORD_PROPERTY = 'property';
|
||||
|
||||
/**
|
||||
@ -97,11 +99,20 @@ export class Record {
|
||||
this.mode = MODE_STATE_CONST;
|
||||
this.funcOrValue = protoRecord.funcOrValue;
|
||||
|
||||
} else if (protoRecord.recordType === PROTO_RECORD_FUNC) {
|
||||
this.mode = MODE_STATE_INVOKE_FUNCTION;
|
||||
} else if (protoRecord.recordType === PROTO_RECORD_PURE_FUNCTION) {
|
||||
this.mode = MODE_STATE_INVOKE_PURE_FUNCTION;
|
||||
this.funcOrValue = protoRecord.funcOrValue;
|
||||
this.args = ListWrapper.createFixedSize(protoRecord.arity);
|
||||
|
||||
} else if (protoRecord.recordType === PROTO_RECORD_METHOD) {
|
||||
this.mode = MODE_STATE_INVOKE_METHOD;
|
||||
this.funcOrValue = protoRecord.funcOrValue;
|
||||
this.args = ListWrapper.createFixedSize(protoRecord.arity);
|
||||
|
||||
} else if (protoRecord.recordType === PROTO_RECORD_CLOSURE) {
|
||||
this.mode = MODE_STATE_INVOKE_CLOSURE;
|
||||
this.args = ListWrapper.createFixedSize(protoRecord.arity);
|
||||
|
||||
} else if (protoRecord.recordType === PROTO_RECORD_PROPERTY) {
|
||||
this.mode = MODE_STATE_PROPERTY;
|
||||
this.funcOrValue = protoRecord.funcOrValue;
|
||||
@ -138,7 +149,13 @@ export class Record {
|
||||
case MODE_STATE_PROPERTY:
|
||||
return this.funcOrValue(this.context);
|
||||
|
||||
case MODE_STATE_INVOKE_FUNCTION:
|
||||
case MODE_STATE_INVOKE_METHOD:
|
||||
return this.funcOrValue(this.context, this.args);
|
||||
|
||||
case MODE_STATE_INVOKE_CLOSURE:
|
||||
return FunctionWrapper.apply(this.context, this.args);
|
||||
|
||||
case MODE_STATE_INVOKE_PURE_FUNCTION:
|
||||
return FunctionWrapper.apply(this.funcOrValue, this.args);
|
||||
|
||||
case MODE_STATE_CONST:
|
||||
@ -147,9 +164,6 @@ export class Record {
|
||||
case MODE_STATE_MARKER:
|
||||
throw new BaseException('MODE_STATE_MARKER not implemented');
|
||||
|
||||
case MODE_STATE_INVOKE_METHOD:
|
||||
throw new BaseException('MODE_STATE_INVOKE_METHOD not implemented');
|
||||
|
||||
case MODE_STATE_MAP:
|
||||
throw new BaseException('MODE_STATE_MAP not implemented');
|
||||
|
||||
@ -183,18 +197,17 @@ const MODE_STATE_MARKER = 0x0000;
|
||||
|
||||
/// _context[_protoRecord.propname] => _getter(_context)
|
||||
const MODE_STATE_PROPERTY = 0x0001;
|
||||
/// _context(_arguments)
|
||||
const MODE_STATE_INVOKE_FUNCTION = 0x0002;
|
||||
/// _getter(_context, _arguments)
|
||||
const MODE_STATE_INVOKE_PURE_FUNCTION = 0x0002;
|
||||
const MODE_STATE_INVOKE_METHOD = 0x0003;
|
||||
const MODE_STATE_INVOKE_CLOSURE = 0x0004;
|
||||
|
||||
/// _context is Map => _previousValue is MapChangeRecord
|
||||
const MODE_STATE_MAP = 0x0004;
|
||||
const MODE_STATE_MAP = 0x0005;
|
||||
/// _context is Array/List/Iterable => _previousValue = ListChangeRecord
|
||||
const MODE_STATE_LIST = 0x0005;
|
||||
const MODE_STATE_LIST = 0x0006;
|
||||
|
||||
/// _context is number/string
|
||||
const MODE_STATE_CONST = 0x0006;
|
||||
const MODE_STATE_CONST = 0x0007;
|
||||
|
||||
function isSame(a, b) {
|
||||
if (a instanceof String && b instanceof String) return a == b;
|
||||
|
@ -1,7 +1,9 @@
|
||||
import {ProtoRecord, Record, PROTO_RECORD_CONST, PROTO_RECORD_FUNC, PROTO_RECORD_PROPERTY} from './record';
|
||||
import {ProtoRecord, Record, PROTO_RECORD_CONST, PROTO_RECORD_PURE_FUNCTION,
|
||||
PROTO_RECORD_PROPERTY, PROTO_RECORD_METHOD, PROTO_RECORD_CLOSURE} from './record';
|
||||
import {FIELD, IMPLEMENTS, isBlank, isPresent, int, toBool, autoConvertAdd, BaseException} from 'facade/lang';
|
||||
import {ListWrapper} from 'facade/collection';
|
||||
import {AST, AccessMember, ImplicitReceiver, AstVisitor, LiteralPrimitive, Binary, Formatter} from './parser/ast';
|
||||
import {AST, AccessMember, ImplicitReceiver, AstVisitor, LiteralPrimitive,
|
||||
Binary, Formatter, MethodCall, FunctionCall} from './parser/ast';
|
||||
|
||||
export class ProtoWatchGroup {
|
||||
@FIELD('headRecord:ProtoRecord')
|
||||
@ -167,7 +169,7 @@ class ProtoRecordCreator {
|
||||
}
|
||||
|
||||
visitBinary(ast:Binary, dest) {
|
||||
var record = this.construct(PROTO_RECORD_FUNC, _operationToFunction(ast.operation), 2, dest);
|
||||
var record = this.construct(PROTO_RECORD_PURE_FUNCTION, _operationToFunction(ast.operation), 2, dest);
|
||||
|
||||
ast.left.visit(this, new Destination(record, 0));
|
||||
ast.right.visit(this, new Destination(record, 1));
|
||||
@ -183,13 +185,31 @@ class ProtoRecordCreator {
|
||||
|
||||
visitFormatter(ast:Formatter, dest) {
|
||||
var formatter = this.protoWatchGroup.formatters[ast.name];
|
||||
var record = this.construct(PROTO_RECORD_FUNC, formatter, ast.allArgs.length, dest);
|
||||
var record = this.construct(PROTO_RECORD_PURE_FUNCTION, formatter, ast.allArgs.length, dest);
|
||||
for (var i = 0; i < ast.allArgs.length; ++i) {
|
||||
ast.allArgs[i].visit(this, new Destination(record, i));
|
||||
}
|
||||
this.add(record);
|
||||
}
|
||||
|
||||
visitMethodCall(ast:MethodCall, dest) {
|
||||
var record = this.construct(PROTO_RECORD_METHOD, ast.fn, ast.args.length, dest);
|
||||
ast.receiver.visit(this, new Destination(record, null));
|
||||
for (var i = 0; i < ast.args.length; ++i) {
|
||||
ast.args[i].visit(this, new Destination(record, i));
|
||||
}
|
||||
this.add(record);
|
||||
}
|
||||
|
||||
visitFunctionCall(ast:FunctionCall, dest) {
|
||||
var record = this.construct(PROTO_RECORD_CLOSURE, null, ast.args.length, dest);
|
||||
ast.target.visit(this, new Destination(record, null));
|
||||
for (var i = 0; i < ast.args.length; ++i) {
|
||||
ast.args[i].visit(this, new Destination(record, i));
|
||||
}
|
||||
this.add(record);
|
||||
}
|
||||
|
||||
createRecordsFromAST(ast:AST, memento){
|
||||
ast.visit(this, memento);
|
||||
}
|
||||
|
Reference in New Issue
Block a user