feat(parser): make method calls aware of ContextWithVariableBindings

This commit is contained in:
Victor Berchet 2015-01-19 12:58:44 +01:00
parent 8b2a5d7d17
commit 156f3d99e0
2 changed files with 30 additions and 3 deletions

View File

@ -335,8 +335,18 @@ export class MethodCall extends AST {
} }
eval(context) { eval(context) {
var obj = this.receiver.eval(context); var evaluatedContext = this.receiver.eval(context);
return this.fn(obj, evalList(context, this.args)); var evaluatedArgs = evalList(context, this.args);
while (evaluatedContext instanceof ContextWithVariableBindings) {
if (evaluatedContext.hasBinding(this.name)) {
var fn = evaluatedContext.get(this.name);
return FunctionWrapper.apply(fn, evaluatedArgs);
}
evaluatedContext = evaluatedContext.parent;
}
return this.fn(evaluatedContext, evaluatedArgs);
} }
visit(visitor, args) { visit(visitor, args) {

View File

@ -194,7 +194,7 @@ export function main() {
}); });
it("should fall back to a regular field read when ContextWithVariableBindings "+ it("should fall back to a regular field read when ContextWithVariableBindings "+
"does not have the requested field", () => { "does not have the requested field", () => {
var locals = new ContextWithVariableBindings(td(999), MapWrapper.create()); var locals = new ContextWithVariableBindings(td(999), MapWrapper.create());
expectEval("a", locals).toEqual(999); expectEval("a", locals).toEqual(999);
}); });
@ -211,6 +211,23 @@ export function main() {
it('should throw when no method', () => { it('should throw when no method', () => {
expectEvalError("blah()").toThrowError(); expectEvalError("blah()").toThrowError();
}); });
it('should evaluate a method from ContextWithVariableBindings', () => {
var context = new ContextWithVariableBindings(
td(0, 0, 'parent'),
MapWrapper.createFromPairs([['fn', () => 'child']])
);
expectEval("fn()", context).toEqual('child');
});
it('should fall back to the parent context when ContextWithVariableBindings does not ' +
'have the requested method', () => {
var context = new ContextWithVariableBindings(
td(0, 0, 'parent'),
MapWrapper.create()
);
expectEval("fn()", context).toEqual('parent');
});
}); });
describe("functional calls", () => { describe("functional calls", () => {