feat(Reflection): extract reflection capabilities into a separate module

This commit is contained in:
vsavkin
2014-11-20 12:07:48 -08:00
parent 044625a098
commit 6e8175a816
46 changed files with 637 additions and 416 deletions

View File

@ -1,6 +1,5 @@
import {FIELD, autoConvertAdd, isBlank, isPresent, FunctionWrapper, BaseException} from "facade/lang";
import {List, Map, ListWrapper, MapWrapper} from "facade/collection";
import {ClosureMap} from "./closure_map";
export class AST {
eval(context) {
@ -316,11 +315,9 @@ export class MethodCall extends AST {
export class FunctionCall extends AST {
target:AST;
closureMap:ClosureMap;
args:List;
constructor(target:AST, closureMap:ClosureMap, args:List) {
constructor(target:AST, args:List) {
this.target = target;
this.closureMap = closureMap;
this.args = args;
}

View File

@ -1,22 +0,0 @@
library change_detection.parser.closure_map;
import 'dart:mirrors';
typedef SetterFn(Object obj, value);
class ClosureMap {
Function getter(String name) {
var symbol = new Symbol(name);
return (receiver) => reflect(receiver).getField(symbol).reflectee;
}
Function setter(String name) {
var symbol = new Symbol(name);
return (receiver, value) => reflect(receiver).setField(symbol, value).reflectee;
}
Function fn(String name) {
var symbol = new Symbol(name);
return (receiver, posArgs) => reflect(receiver).invoke(symbol, posArgs).reflectee;
}
}

View File

@ -1,18 +0,0 @@
export var SetterFn = Function;
export class ClosureMap {
getter(name:string) {
return new Function('o', 'return o.' + name + ';');
}
setter(name:string) {
return new Function('o', 'v', 'return o.' + name + ' = v;');
}
fn(name:string) {
var method = `o.${name}`;
return new Function('o', 'args',
`if (!${method}) throw new Error('"${name}" is undefined');` +
`return ${method}.apply(o, args);`);
}
}

View File

@ -1,8 +1,8 @@
import {FIELD, int, isBlank, BaseException, StringWrapper} from 'facade/lang';
import {FIELD, int, isBlank, isPresent, BaseException, StringWrapper} from 'facade/lang';
import {ListWrapper, List} from 'facade/collection';
import {Lexer, EOF, Token, $PERIOD, $COLON, $SEMICOLON, $LBRACKET, $RBRACKET,
$COMMA, $LBRACE, $RBRACE, $LPAREN, $RPAREN} from './lexer';
import {ClosureMap} from './closure_map';
import {reflector, Reflector} from 'reflection/reflection';
import {
AST,
ImplicitReceiver,
@ -29,41 +29,41 @@ var _implicitReceiver = new ImplicitReceiver();
export class Parser {
_lexer:Lexer;
_closureMap:ClosureMap;
constructor(lexer:Lexer, closureMap:ClosureMap){
_reflector:Reflector;
constructor(lexer:Lexer, providedReflector:Reflector = null){
this._lexer = lexer;
this._closureMap = closureMap;
this._reflector = isPresent(providedReflector) ? providedReflector : reflector;
}
parseAction(input:string):ASTWithSource {
var tokens = this._lexer.tokenize(input);
var ast = new _ParseAST(input, tokens, this._closureMap, true).parseChain();
var ast = new _ParseAST(input, tokens, this._reflector, true).parseChain();
return new ASTWithSource(ast, input);
}
parseBinding(input:string):ASTWithSource {
var tokens = this._lexer.tokenize(input);
var ast = new _ParseAST(input, tokens, this._closureMap, false).parseChain();
var ast = new _ParseAST(input, tokens, this._reflector, false).parseChain();
return new ASTWithSource(ast, input);
}
parseTemplateBindings(input:string):List<TemplateBinding> {
var tokens = this._lexer.tokenize(input);
return new _ParseAST(input, tokens, this._closureMap, false).parseTemplateBindings();
return new _ParseAST(input, tokens, this._reflector, false).parseTemplateBindings();
}
}
class _ParseAST {
input:string;
tokens:List<Token>;
closureMap:ClosureMap;
reflector:Reflector;
parseAction:boolean;
index:int;
constructor(input:string, tokens:List, closureMap:ClosureMap, parseAction:boolean) {
constructor(input:string, tokens:List, reflector:Reflector, parseAction:boolean) {
this.input = input;
this.tokens = tokens;
this.index = 0;
this.closureMap = closureMap;
this.reflector = reflector;
this.parseAction = parseAction;
}
@ -311,7 +311,7 @@ class _ParseAST {
} else if (this.optionalCharacter($LPAREN)) {
var args = this.parseCallArguments();
this.expectCharacter($RPAREN);
result = new FunctionCall(result, this.closureMap, args);
result = new FunctionCall(result, args);
} else {
return result;
@ -398,12 +398,12 @@ class _ParseAST {
if (this.optionalCharacter($LPAREN)) {
var args = this.parseCallArguments();
this.expectCharacter($RPAREN);
var fn = this.closureMap.fn(id);
var fn = this.reflector.method(id);
return new MethodCall(receiver, fn, args);
} else {
var getter = this.closureMap.getter(id);
var setter = this.closureMap.setter(id);
var getter = this.reflector.getter(id);
var setter = this.reflector.setter(id);
return new AccessMember(receiver, id, getter, setter);
}
}

View File

@ -1,7 +1,6 @@
import {ProtoRecordRange, RecordRange} from './record_range';
import {FIELD, isPresent, isBlank, int, StringWrapper, FunctionWrapper, BaseException} from 'facade/lang';
import {List, Map, ListWrapper, MapWrapper} from 'facade/collection';
import {ClosureMap} from 'change_detection/parser/closure_map';
var _fresh = new Object();

View File

@ -4,7 +4,6 @@ import {isPresent} from 'facade/lang';
import {List, ListWrapper, MapWrapper} from 'facade/collection';
import {Parser} from 'change_detection/parser/parser';
import {Lexer} from 'change_detection/parser/lexer';
import {ClosureMap} from 'change_detection/parser/closure_map';
import {
ChangeDetector,
@ -18,7 +17,7 @@ import {Record} from 'change_detection/record';
export function main() {
function ast(exp:string) {
var parser = new Parser(new Lexer(), new ClosureMap());
var parser = new Parser(new Lexer());
return parser.parseBinding(exp).ast;
}

View File

@ -1,10 +1,10 @@
import {ddescribe, describe, it, xit, iit, expect, beforeEach} from 'test_lib/test_lib';
import {BaseException, isBlank, isPresent} from 'facade/lang';
import {reflector} from 'reflection/reflection';
import {MapWrapper, ListWrapper} from 'facade/collection';
import {Parser} from 'change_detection/parser/parser';
import {Lexer} from 'change_detection/parser/lexer';
import {Formatter, LiteralPrimitive} from 'change_detection/parser/ast';
import {ClosureMap} from 'change_detection/parser/closure_map';
class TestData {
a;
@ -31,7 +31,7 @@ export function main() {
}
function createParser() {
return new Parser(new Lexer(), new ClosureMap());
return new Parser(new Lexer(), reflector);
}
function parseAction(text) {

View File

@ -4,7 +4,6 @@ import {List, ListWrapper, MapWrapper} from 'facade/collection';
import {isPresent} from 'facade/lang';
import {Parser} from 'change_detection/parser/parser';
import {Lexer} from 'change_detection/parser/lexer';
import {ClosureMap} from 'change_detection/parser/closure_map';
import {
ChangeDetector,