feat(host): limits host properties to renames

This commit is contained in:
vsavkin
2015-06-22 08:21:03 -07:00
parent c1a494bc37
commit 92ffc465d6
8 changed files with 177 additions and 24 deletions

View File

@ -45,7 +45,8 @@ import {
SafeMethodCall,
FunctionCall,
TemplateBinding,
ASTWithSource
ASTWithSource,
AstVisitor
} from './ast';
@ -73,6 +74,12 @@ export class Parser {
return new ASTWithSource(ast, input, location);
}
parseSimpleBinding(input: string, location: string): ASTWithSource {
var tokens = this._lexer.tokenize(input);
var ast = new _ParseAST(input, location, tokens, this._reflector, false).parseSimpleBinding();
return new ASTWithSource(ast, input, location);
}
parseTemplateBindings(input: string, location: any): List<TemplateBinding> {
var tokens = this._lexer.tokenize(input);
return new _ParseAST(input, location, tokens, this._reflector, false).parseTemplateBindings();
@ -202,6 +209,14 @@ class _ParseAST {
return new Chain(exprs);
}
parseSimpleBinding(): AST {
var ast = this.parseChain();
if (!SimpleExpressionChecker.check(ast)) {
this.error(`Simple binding expression can only contain field access and constants'`);
}
return ast;
}
parsePipe() {
var result = this.parseExpression();
if (this.optionalOperator("|")) {
@ -590,3 +605,57 @@ class _ParseAST {
`Parser Error: ${message} ${location} [${this.input}] in ${this.location}`);
}
}
class SimpleExpressionChecker implements AstVisitor {
static check(ast: AST) {
var s = new SimpleExpressionChecker();
ast.visit(s);
return s.simple;
}
simple = true;
visitImplicitReceiver(ast: ImplicitReceiver) {}
visitInterpolation(ast: Interpolation) { this.simple = false; }
visitLiteralPrimitive(ast: LiteralPrimitive) {}
visitAccessMember(ast: AccessMember) {}
visitSafeAccessMember(ast: SafeAccessMember) { this.simple = false; }
visitMethodCall(ast: MethodCall) { this.simple = false; }
visitSafeMethodCall(ast: SafeMethodCall) { this.simple = false; }
visitFunctionCall(ast: FunctionCall) { this.simple = false; }
visitLiteralArray(ast: LiteralArray) { this.visitAll(ast.expressions); }
visitLiteralMap(ast: LiteralMap) { this.visitAll(ast.values); }
visitBinary(ast: Binary) { this.simple = false; }
visitPrefixNot(ast: PrefixNot) { this.simple = false; }
visitConditional(ast: Conditional) { this.simple = false; }
visitPipe(ast: BindingPipe) { this.simple = false; }
visitKeyedAccess(ast: KeyedAccess) { this.simple = false; }
visitAll(asts: List<any>) {
var res = ListWrapper.createFixedSize(asts.length);
for (var i = 0; i < asts.length; ++i) {
res[i] = asts[i].visit(this);
}
return res;
}
visitChain(ast: Chain) { this.simple = false; }
visitAssignment(ast: Assignment) { this.simple = false; }
visitIf(ast: If) { this.simple = false; }
}