parent
92f1af86d8
commit
331a051e75
@ -8,7 +8,7 @@ export class AST {
|
|||||||
|
|
||||||
assign(context, locals, value) { throw new BaseException("Not supported"); }
|
assign(context, locals, value) { throw new BaseException("Not supported"); }
|
||||||
|
|
||||||
visit(visitor): any { return null; }
|
visit(visitor: AstVisitor): any { return null; }
|
||||||
|
|
||||||
toString(): string { return "AST"; }
|
toString(): string { return "AST"; }
|
||||||
}
|
}
|
||||||
@ -16,7 +16,7 @@ export class AST {
|
|||||||
export class EmptyExpr extends AST {
|
export class EmptyExpr extends AST {
|
||||||
eval(context, locals) { return null; }
|
eval(context, locals) { return null; }
|
||||||
|
|
||||||
visit(visitor) {
|
visit(visitor: AstVisitor) {
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -24,7 +24,7 @@ export class EmptyExpr extends AST {
|
|||||||
export class ImplicitReceiver extends AST {
|
export class ImplicitReceiver extends AST {
|
||||||
eval(context, locals) { return context; }
|
eval(context, locals) { return context; }
|
||||||
|
|
||||||
visit(visitor) { return visitor.visitImplicitReceiver(this); }
|
visit(visitor: AstVisitor) { return visitor.visitImplicitReceiver(this); }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -42,7 +42,7 @@ export class Chain extends AST {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
visit(visitor) { return visitor.visitChain(this); }
|
visit(visitor: AstVisitor) { return visitor.visitChain(this); }
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Conditional extends AST {
|
export class Conditional extends AST {
|
||||||
@ -56,7 +56,7 @@ export class Conditional extends AST {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
visit(visitor) { return visitor.visitConditional(this); }
|
visit(visitor: AstVisitor) { return visitor.visitConditional(this); }
|
||||||
}
|
}
|
||||||
|
|
||||||
export class AccessMember extends AST {
|
export class AccessMember extends AST {
|
||||||
@ -88,7 +88,7 @@ export class AccessMember extends AST {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
visit(visitor) { return visitor.visitAccessMember(this); }
|
visit(visitor: AstVisitor) { return visitor.visitAccessMember(this); }
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SafeAccessMember extends AST {
|
export class SafeAccessMember extends AST {
|
||||||
@ -102,7 +102,7 @@ export class SafeAccessMember extends AST {
|
|||||||
return isBlank(evaluatedReceiver) ? null : this.getter(evaluatedReceiver);
|
return isBlank(evaluatedReceiver) ? null : this.getter(evaluatedReceiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
visit(visitor) { return visitor.visitSafeAccessMember(this); }
|
visit(visitor: AstVisitor) { return visitor.visitSafeAccessMember(this); }
|
||||||
}
|
}
|
||||||
|
|
||||||
export class KeyedAccess extends AST {
|
export class KeyedAccess extends AST {
|
||||||
@ -123,7 +123,7 @@ export class KeyedAccess extends AST {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
visit(visitor) { return visitor.visitKeyedAccess(this); }
|
visit(visitor: AstVisitor) { return visitor.visitKeyedAccess(this); }
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Pipe extends AST {
|
export class Pipe extends AST {
|
||||||
@ -132,7 +132,7 @@ export class Pipe extends AST {
|
|||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
visit(visitor) { return visitor.visitPipe(this); }
|
visit(visitor: AstVisitor) { return visitor.visitPipe(this); }
|
||||||
}
|
}
|
||||||
|
|
||||||
export class LiteralPrimitive extends AST {
|
export class LiteralPrimitive extends AST {
|
||||||
@ -140,7 +140,7 @@ export class LiteralPrimitive extends AST {
|
|||||||
|
|
||||||
eval(context, locals) { return this.value; }
|
eval(context, locals) { return this.value; }
|
||||||
|
|
||||||
visit(visitor) { return visitor.visitLiteralPrimitive(this); }
|
visit(visitor: AstVisitor) { return visitor.visitLiteralPrimitive(this); }
|
||||||
}
|
}
|
||||||
|
|
||||||
export class LiteralArray extends AST {
|
export class LiteralArray extends AST {
|
||||||
@ -150,7 +150,7 @@ export class LiteralArray extends AST {
|
|||||||
return ListWrapper.map(this.expressions, (e) => e.eval(context, locals));
|
return ListWrapper.map(this.expressions, (e) => e.eval(context, locals));
|
||||||
}
|
}
|
||||||
|
|
||||||
visit(visitor) { return visitor.visitLiteralArray(this); }
|
visit(visitor: AstVisitor) { return visitor.visitLiteralArray(this); }
|
||||||
}
|
}
|
||||||
|
|
||||||
export class LiteralMap extends AST {
|
export class LiteralMap extends AST {
|
||||||
@ -164,7 +164,7 @@ export class LiteralMap extends AST {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
visit(visitor) { return visitor.visitLiteralMap(this); }
|
visit(visitor: AstVisitor) { return visitor.visitLiteralMap(this); }
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Interpolation extends AST {
|
export class Interpolation extends AST {
|
||||||
@ -172,7 +172,7 @@ export class Interpolation extends AST {
|
|||||||
|
|
||||||
eval(context, locals) { throw new BaseException("evaluating an Interpolation is not supported"); }
|
eval(context, locals) { throw new BaseException("evaluating an Interpolation is not supported"); }
|
||||||
|
|
||||||
visit(visitor) { visitor.visitInterpolation(this); }
|
visit(visitor: AstVisitor) { visitor.visitInterpolation(this); }
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Binary extends AST {
|
export class Binary extends AST {
|
||||||
@ -223,7 +223,7 @@ export class Binary extends AST {
|
|||||||
throw 'Internal error [$operation] not handled';
|
throw 'Internal error [$operation] not handled';
|
||||||
}
|
}
|
||||||
|
|
||||||
visit(visitor) { return visitor.visitBinary(this); }
|
visit(visitor: AstVisitor) { return visitor.visitBinary(this); }
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PrefixNot extends AST {
|
export class PrefixNot extends AST {
|
||||||
@ -231,7 +231,7 @@ export class PrefixNot extends AST {
|
|||||||
|
|
||||||
eval(context, locals) { return !this.expression.eval(context, locals); }
|
eval(context, locals) { return !this.expression.eval(context, locals); }
|
||||||
|
|
||||||
visit(visitor) { return visitor.visitPrefixNot(this); }
|
visit(visitor: AstVisitor) { return visitor.visitPrefixNot(this); }
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Assignment extends AST {
|
export class Assignment extends AST {
|
||||||
@ -241,7 +241,7 @@ export class Assignment extends AST {
|
|||||||
return this.target.assign(context, locals, this.value.eval(context, locals));
|
return this.target.assign(context, locals, this.value.eval(context, locals));
|
||||||
}
|
}
|
||||||
|
|
||||||
visit(visitor) { return visitor.visitAssignment(this); }
|
visit(visitor: AstVisitor) { return visitor.visitAssignment(this); }
|
||||||
}
|
}
|
||||||
|
|
||||||
export class MethodCall extends AST {
|
export class MethodCall extends AST {
|
||||||
@ -262,7 +262,7 @@ export class MethodCall extends AST {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
visit(visitor) { return visitor.visitMethodCall(this); }
|
visit(visitor: AstVisitor) { return visitor.visitMethodCall(this); }
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SafeMethodCall extends AST {
|
export class SafeMethodCall extends AST {
|
||||||
@ -278,7 +278,7 @@ export class SafeMethodCall extends AST {
|
|||||||
return this.fn(evaluatedReceiver, evaluatedArgs);
|
return this.fn(evaluatedReceiver, evaluatedArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
visit(visitor) { return visitor.visitSafeMethodCall(this); }
|
visit(visitor: AstVisitor) { return visitor.visitSafeMethodCall(this); }
|
||||||
}
|
}
|
||||||
|
|
||||||
export class FunctionCall extends AST {
|
export class FunctionCall extends AST {
|
||||||
@ -292,7 +292,7 @@ export class FunctionCall extends AST {
|
|||||||
return FunctionWrapper.apply(obj, evalList(context, locals, this.args));
|
return FunctionWrapper.apply(obj, evalList(context, locals, this.args));
|
||||||
}
|
}
|
||||||
|
|
||||||
visit(visitor) { return visitor.visitFunctionCall(this); }
|
visit(visitor: AstVisitor) { return visitor.visitFunctionCall(this); }
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ASTWithSource extends AST {
|
export class ASTWithSource extends AST {
|
||||||
@ -304,7 +304,7 @@ export class ASTWithSource extends AST {
|
|||||||
|
|
||||||
assign(context, locals, value) { return this.ast.assign(context, locals, value); }
|
assign(context, locals, value) { return this.ast.assign(context, locals, value); }
|
||||||
|
|
||||||
visit(visitor) { return this.ast.visit(visitor); }
|
visit(visitor: AstVisitor) { return this.ast.visit(visitor); }
|
||||||
|
|
||||||
toString(): string { return `${this.source} in ${this.location}`; }
|
toString(): string { return `${this.source} in ${this.location}`; }
|
||||||
}
|
}
|
||||||
@ -314,27 +314,27 @@ export class TemplateBinding {
|
|||||||
public expression: ASTWithSource) {}
|
public expression: ASTWithSource) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// INTERFACE
|
export interface AstVisitor {
|
||||||
export class AstVisitor {
|
visitAccessMember(ast: AccessMember): any;
|
||||||
visitAccessMember(ast: AccessMember) {}
|
visitAssignment(ast: Assignment): any;
|
||||||
visitAssignment(ast: Assignment) {}
|
visitBinary(ast: Binary): any;
|
||||||
visitBinary(ast: Binary) {}
|
visitChain(ast: Chain): any;
|
||||||
visitChain(ast: Chain) {}
|
visitConditional(ast: Conditional): any;
|
||||||
visitConditional(ast: Conditional) {}
|
visitPipe(ast: Pipe): any;
|
||||||
visitPipe(ast: Pipe) {}
|
visitFunctionCall(ast: FunctionCall): any;
|
||||||
visitFunctionCall(ast: FunctionCall) {}
|
visitImplicitReceiver(ast: ImplicitReceiver): any;
|
||||||
visitImplicitReceiver(ast: ImplicitReceiver) {}
|
visitInterpolation(ast: Interpolation): any;
|
||||||
visitKeyedAccess(ast: KeyedAccess) {}
|
visitKeyedAccess(ast: KeyedAccess): any;
|
||||||
visitLiteralArray(ast: LiteralArray) {}
|
visitLiteralArray(ast: LiteralArray): any;
|
||||||
visitLiteralMap(ast: LiteralMap) {}
|
visitLiteralMap(ast: LiteralMap): any;
|
||||||
visitLiteralPrimitive(ast: LiteralPrimitive) {}
|
visitLiteralPrimitive(ast: LiteralPrimitive): any;
|
||||||
visitMethodCall(ast: MethodCall) {}
|
visitMethodCall(ast: MethodCall): any;
|
||||||
visitPrefixNot(ast: PrefixNot) {}
|
visitPrefixNot(ast: PrefixNot): any;
|
||||||
visitSafeAccessMember(ast: SafeAccessMember) {}
|
visitSafeAccessMember(ast: SafeAccessMember): any;
|
||||||
visitSafeMethodCall(ast: SafeMethodCall) {}
|
visitSafeMethodCall(ast: SafeMethodCall): any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class AstTransformer {
|
export class AstTransformer implements AstVisitor {
|
||||||
visitImplicitReceiver(ast: ImplicitReceiver) { return ast; }
|
visitImplicitReceiver(ast: ImplicitReceiver) { return ast; }
|
||||||
|
|
||||||
visitInterpolation(ast: Interpolation) {
|
visitInterpolation(ast: Interpolation) {
|
||||||
@ -393,6 +393,10 @@ export class AstTransformer {
|
|||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
visitChain(ast: Chain) { throw new BaseException('Not implemented'); }
|
||||||
|
|
||||||
|
visitAssignment(ast: Assignment) { throw new BaseException('Not implemented'); }
|
||||||
}
|
}
|
||||||
|
|
||||||
var _evalListCache = [
|
var _evalListCache = [
|
||||||
|
@ -122,7 +122,6 @@ class ProtoRecordBuilder {
|
|||||||
|
|
||||||
_appendRecords(b: BindingRecord, variableNames: List<string>) {
|
_appendRecords(b: BindingRecord, variableNames: List<string>) {
|
||||||
if (b.isDirectiveLifecycle()) {
|
if (b.isDirectiveLifecycle()) {
|
||||||
;
|
|
||||||
ListWrapper.push(
|
ListWrapper.push(
|
||||||
this.records,
|
this.records,
|
||||||
new ProtoRecord(RECORD_TYPE_DIRECTIVE_LIFECYCLE, b.lifecycleEvent, null, [], [], -1, null,
|
new ProtoRecord(RECORD_TYPE_DIRECTIVE_LIFECYCLE, b.lifecycleEvent, null, [], [], -1, null,
|
||||||
@ -133,7 +132,7 @@ class ProtoRecordBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _ConvertAstIntoProtoRecords {
|
class _ConvertAstIntoProtoRecords implements AstVisitor {
|
||||||
constructor(private _records: List<ProtoRecord>, private _bindingRecord: BindingRecord,
|
constructor(private _records: List<ProtoRecord>, private _bindingRecord: BindingRecord,
|
||||||
private _expressionAsString: string, private _variableNames: List<any>) {}
|
private _expressionAsString: string, private _variableNames: List<any>) {}
|
||||||
|
|
||||||
@ -240,6 +239,10 @@ class _ConvertAstIntoProtoRecords {
|
|||||||
[key], null, obj);
|
[key], null, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
visitAssignment(ast: Assignment) { throw new BaseException('Not supported'); }
|
||||||
|
|
||||||
|
visitChain(ast: Chain) { throw new BaseException('Not supported'); }
|
||||||
|
|
||||||
_visitAll(asts: List<any>) {
|
_visitAll(asts: List<any>) {
|
||||||
var res = ListWrapper.createFixedSize(asts.length);
|
var res = ListWrapper.createFixedSize(asts.length);
|
||||||
for (var i = 0; i < asts.length; ++i) {
|
for (var i = 0; i < asts.length; ++i) {
|
||||||
|
@ -88,6 +88,8 @@ class StringWrapper {
|
|||||||
static bool contains(String s, String substr) {
|
static bool contains(String s, String substr) {
|
||||||
return s.contains(substr);
|
return s.contains(substr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool isString(s) => s is String;
|
||||||
}
|
}
|
||||||
|
|
||||||
class StringJoiner {
|
class StringJoiner {
|
||||||
|
@ -132,6 +132,8 @@ export class StringWrapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static contains(s: string, substr: string): boolean { return s.indexOf(substr) != -1; }
|
static contains(s: string, substr: string): boolean { return s.indexOf(substr) != -1; }
|
||||||
|
|
||||||
|
static isString(s: any): boolean { return typeof s === 'string' || s instanceof String; }
|
||||||
}
|
}
|
||||||
|
|
||||||
export class StringJoiner {
|
export class StringJoiner {
|
||||||
|
180
modules/angular2/test/change_detection/parser/unparser.ts
Normal file
180
modules/angular2/test/change_detection/parser/unparser.ts
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
import {
|
||||||
|
AST,
|
||||||
|
AstVisitor,
|
||||||
|
AccessMember,
|
||||||
|
Assignment,
|
||||||
|
Binary,
|
||||||
|
Chain,
|
||||||
|
Conditional,
|
||||||
|
Pipe,
|
||||||
|
FunctionCall,
|
||||||
|
ImplicitReceiver,
|
||||||
|
Interpolation,
|
||||||
|
KeyedAccess,
|
||||||
|
LiteralArray,
|
||||||
|
LiteralMap,
|
||||||
|
LiteralPrimitive,
|
||||||
|
MethodCall,
|
||||||
|
PrefixNot,
|
||||||
|
SafeAccessMember,
|
||||||
|
SafeMethodCall
|
||||||
|
} from 'angular2/src/change_detection/parser/ast';
|
||||||
|
|
||||||
|
|
||||||
|
import {StringWrapper, RegExpWrapper} from 'angular2/src/facade/lang';
|
||||||
|
|
||||||
|
var quoteRegExp = RegExpWrapper.create('"');
|
||||||
|
|
||||||
|
export class Unparser implements AstVisitor {
|
||||||
|
private _expression: string;
|
||||||
|
|
||||||
|
unparse(ast: AST) {
|
||||||
|
this._expression = '';
|
||||||
|
this._visit(ast);
|
||||||
|
return this._expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
visitAccessMember(ast: AccessMember) {
|
||||||
|
this._visit(ast.receiver);
|
||||||
|
|
||||||
|
this._expression += ast.receiver instanceof ImplicitReceiver ? `${ast.name}` : `.${ast.name}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
visitAssignment(ast: Assignment) {
|
||||||
|
this._visit(ast.target);
|
||||||
|
this._expression += ' = ';
|
||||||
|
this._visit(ast.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
visitBinary(ast: Binary) {
|
||||||
|
this._visit(ast.left);
|
||||||
|
this._expression += ` ${ast.operation} `;
|
||||||
|
this._visit(ast.right);
|
||||||
|
}
|
||||||
|
|
||||||
|
visitChain(ast: Chain) {
|
||||||
|
ast.expressions.forEach(expression => {
|
||||||
|
this._visit(expression);
|
||||||
|
this._expression += ';'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
visitConditional(ast: Conditional) {
|
||||||
|
this._visit(ast.condition);
|
||||||
|
this._expression += ' ? ';
|
||||||
|
this._visit(ast.trueExp);
|
||||||
|
this._expression += ' : ';
|
||||||
|
this._visit(ast.falseExp);
|
||||||
|
}
|
||||||
|
|
||||||
|
visitPipe(ast: Pipe) {
|
||||||
|
this._visit(ast.exp);
|
||||||
|
this._expression += ` | ${ast.name}`;
|
||||||
|
ast.args.forEach(arg => {
|
||||||
|
this._expression += ':';
|
||||||
|
this._visit(arg);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
visitFunctionCall(ast: FunctionCall) {
|
||||||
|
this._visit(ast.target);
|
||||||
|
this._expression += '(';
|
||||||
|
var isFirst = true;
|
||||||
|
ast.args.forEach(arg => {
|
||||||
|
if (!isFirst) this._expression += ', ';
|
||||||
|
isFirst = false;
|
||||||
|
this._visit(arg);
|
||||||
|
});
|
||||||
|
this._expression += ')';
|
||||||
|
}
|
||||||
|
|
||||||
|
visitImplicitReceiver(ast: ImplicitReceiver) {}
|
||||||
|
|
||||||
|
visitInterpolation(ast: Interpolation) {
|
||||||
|
for (let i = 0; i < ast.strings.length; i++) {
|
||||||
|
this._expression += ast.strings[i];
|
||||||
|
if (i < ast.expressions.length) {
|
||||||
|
this._expression += '{{ ';
|
||||||
|
this._visit(ast.expressions[i]);
|
||||||
|
this._expression += ' }}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
visitKeyedAccess(ast: KeyedAccess) {
|
||||||
|
this._visit(ast.obj);
|
||||||
|
this._expression += '[';
|
||||||
|
this._visit(ast.key);
|
||||||
|
this._expression += ']';
|
||||||
|
}
|
||||||
|
|
||||||
|
visitLiteralArray(ast: LiteralArray) {
|
||||||
|
this._expression += '[';
|
||||||
|
var isFirst = true;
|
||||||
|
ast.expressions.forEach(expression => {
|
||||||
|
if (!isFirst) this._expression += ', ';
|
||||||
|
isFirst = false;
|
||||||
|
this._visit(expression);
|
||||||
|
});
|
||||||
|
|
||||||
|
this._expression += ']';
|
||||||
|
}
|
||||||
|
|
||||||
|
visitLiteralMap(ast: LiteralMap) {
|
||||||
|
this._expression += '{';
|
||||||
|
var isFirst = true;
|
||||||
|
for (let i = 0; i < ast.keys.length; i++) {
|
||||||
|
if (!isFirst) this._expression += ', ';
|
||||||
|
isFirst = false;
|
||||||
|
this._expression += `${ast.keys[i]}: `;
|
||||||
|
this._visit(ast.values[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._expression += '}';
|
||||||
|
}
|
||||||
|
|
||||||
|
visitLiteralPrimitive(ast: LiteralPrimitive) {
|
||||||
|
if (StringWrapper.isString(ast.value)) {
|
||||||
|
this._expression += `"${StringWrapper.replaceAll(ast.value, quoteRegExp, '\"')}"`;
|
||||||
|
} else {
|
||||||
|
this._expression += `${ast.value}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
visitMethodCall(ast: MethodCall) {
|
||||||
|
this._visit(ast.receiver);
|
||||||
|
this._expression += ast.receiver instanceof ImplicitReceiver ? `${ast.name}(` :
|
||||||
|
`.${ast.name}(`;
|
||||||
|
var isFirst = true;
|
||||||
|
ast.args.forEach(arg => {
|
||||||
|
if (!isFirst) this._expression += ', ';
|
||||||
|
isFirst = false;
|
||||||
|
this._visit(arg);
|
||||||
|
});
|
||||||
|
this._expression += ')';
|
||||||
|
}
|
||||||
|
|
||||||
|
visitPrefixNot(ast: PrefixNot) {
|
||||||
|
this._expression += '!';
|
||||||
|
this._visit(ast.expression);
|
||||||
|
}
|
||||||
|
|
||||||
|
visitSafeAccessMember(ast: SafeAccessMember) {
|
||||||
|
this._visit(ast.receiver);
|
||||||
|
this._expression += `?.${ast.name}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
visitSafeMethodCall(ast: SafeMethodCall) {
|
||||||
|
this._visit(ast.receiver);
|
||||||
|
this._expression += `?.${ast.name}(`;
|
||||||
|
var isFirst = true;
|
||||||
|
ast.args.forEach(arg => {
|
||||||
|
if (!isFirst) this._expression += ', ';
|
||||||
|
isFirst = false;
|
||||||
|
this._visit(arg);
|
||||||
|
});
|
||||||
|
this._expression += ')';
|
||||||
|
}
|
||||||
|
|
||||||
|
private _visit(ast: AST) { ast.visit(this); }
|
||||||
|
}
|
112
modules/angular2/test/change_detection/parser/unparser_spec.ts
Normal file
112
modules/angular2/test/change_detection/parser/unparser_spec.ts
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
import {ddescribe, describe, it, xit, iit, expect, beforeEach} from 'angular2/test_lib';
|
||||||
|
|
||||||
|
import {
|
||||||
|
AST,
|
||||||
|
ASTWithSource,
|
||||||
|
AccessMember,
|
||||||
|
Assignment,
|
||||||
|
Binary,
|
||||||
|
Chain,
|
||||||
|
Conditional,
|
||||||
|
Pipe,
|
||||||
|
ImplicitReceiver,
|
||||||
|
Interpolation,
|
||||||
|
KeyedAccess,
|
||||||
|
LiteralArray,
|
||||||
|
LiteralMap,
|
||||||
|
LiteralPrimitive,
|
||||||
|
MethodCall,
|
||||||
|
PrefixNot,
|
||||||
|
SafeAccessMember,
|
||||||
|
SafeMethodCall
|
||||||
|
} from 'angular2/src/change_detection/parser/ast';
|
||||||
|
|
||||||
|
import {Parser} from 'angular2/src/change_detection/parser/parser';
|
||||||
|
import {Lexer} from 'angular2/src/change_detection/parser/lexer';
|
||||||
|
import {Unparser} from './unparser';
|
||||||
|
|
||||||
|
import {reflector} from 'angular2/src/reflection/reflection';
|
||||||
|
|
||||||
|
import {isPresent, Type} from 'angular2/src/facade/lang';
|
||||||
|
|
||||||
|
export function main() {
|
||||||
|
let parser: Parser = new Parser(new Lexer(), reflector);
|
||||||
|
let unparser: Unparser = new Unparser();
|
||||||
|
|
||||||
|
function parseAction(text, location = null): ASTWithSource {
|
||||||
|
return parser.parseAction(text, location);
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseBinding(text, location = null): ASTWithSource {
|
||||||
|
return parser.parseBinding(text, location);
|
||||||
|
}
|
||||||
|
|
||||||
|
function check(expression: string, type: Type): void {
|
||||||
|
var ast = parseAction(expression).ast;
|
||||||
|
if (isPresent(type)) {
|
||||||
|
expect(ast).toBeAnInstanceOf(type);
|
||||||
|
}
|
||||||
|
expect(unparser.unparse(ast)).toEqual(expression);
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('Unparser', () => {
|
||||||
|
it('should support AccessMember', () => {
|
||||||
|
check('a', AccessMember);
|
||||||
|
check('a.b', AccessMember);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should support Assignment', () => { check('a = b', Assignment); });
|
||||||
|
|
||||||
|
it('should support Binary', () => { check('a && b', Binary); });
|
||||||
|
|
||||||
|
it('should support Chain', () => { check('a;b;', Chain); });
|
||||||
|
|
||||||
|
it('should support Conditional', () => { check('a ? b : c', Conditional); });
|
||||||
|
|
||||||
|
it('should support Pipe', () => {
|
||||||
|
var originalExp = 'a | b';
|
||||||
|
var ast = parseBinding(originalExp).ast;
|
||||||
|
expect(ast).toBeAnInstanceOf(Pipe);
|
||||||
|
expect(unparser.unparse(ast)).toEqual(originalExp);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should support KeyedAccess', () => { check('a[b]', KeyedAccess); });
|
||||||
|
|
||||||
|
it('should support LiteralArray', () => { check('[a, b]', LiteralArray); });
|
||||||
|
|
||||||
|
it('should support LiteralMap', () => { check('{a: b, c: d}', LiteralMap); });
|
||||||
|
|
||||||
|
it('should support LiteralPrimitive', () => {
|
||||||
|
check('true', LiteralPrimitive);
|
||||||
|
check('"a"', LiteralPrimitive);
|
||||||
|
check('1.234', LiteralPrimitive);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should support MethodCall', () => {
|
||||||
|
check('a(b, c)', MethodCall);
|
||||||
|
check('a.b(c, d)', MethodCall);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should support PrefixNot', () => { check('!a', PrefixNot); });
|
||||||
|
|
||||||
|
it('should support SafeAccessMember', () => { check('a?.b', SafeAccessMember); });
|
||||||
|
|
||||||
|
it('should support SafeMethodCall', () => { check('a?.b(c, d)', SafeMethodCall); });
|
||||||
|
|
||||||
|
it('should support complex expression', () => {
|
||||||
|
var originalExp = 'a + 3 * fn([c + d | e.f], {a: 3})[g].h && i';
|
||||||
|
var ast = parseBinding(originalExp).ast;
|
||||||
|
expect(unparser.unparse(ast)).toEqual(originalExp);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should support Interpolation', () => {
|
||||||
|
var ast = parser.parseInterpolation('a {{ b }}', null).ast;
|
||||||
|
expect(ast).toBeAnInstanceOf(Interpolation);
|
||||||
|
expect(unparser.unparse(ast)).toEqual('a {{ b }}');
|
||||||
|
|
||||||
|
ast = parser.parseInterpolation('a {{ b }} c', null).ast;
|
||||||
|
expect(ast).toBeAnInstanceOf(Interpolation);
|
||||||
|
expect(unparser.unparse(ast)).toEqual('a {{ b }} c');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user