fix(core): properly evaluate expressions with conditional and boolean operators
Fixes #8235 Fixes #8244 Closes #8282
This commit is contained in:
parent
1e8864c4a5
commit
1ad2a02b11
@ -264,11 +264,13 @@ export abstract class AbstractEmitterVisitor implements o.StatementVisitor, o.Ex
|
|||||||
abstract visitExternalExpr(ast: o.ExternalExpr, ctx: EmitterVisitorContext): any;
|
abstract visitExternalExpr(ast: o.ExternalExpr, ctx: EmitterVisitorContext): any;
|
||||||
|
|
||||||
visitConditionalExpr(ast: o.ConditionalExpr, ctx: EmitterVisitorContext): any {
|
visitConditionalExpr(ast: o.ConditionalExpr, ctx: EmitterVisitorContext): any {
|
||||||
|
ctx.print(`(`);
|
||||||
ast.condition.visitExpression(this, ctx);
|
ast.condition.visitExpression(this, ctx);
|
||||||
ctx.print('? ');
|
ctx.print('? ');
|
||||||
ast.trueCase.visitExpression(this, ctx);
|
ast.trueCase.visitExpression(this, ctx);
|
||||||
ctx.print(': ');
|
ctx.print(': ');
|
||||||
ast.falseCase.visitExpression(this, ctx);
|
ast.falseCase.visitExpression(this, ctx);
|
||||||
|
ctx.print(`)`);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
visitNotExpr(ast: o.NotExpr, ctx: EmitterVisitorContext): any {
|
visitNotExpr(ast: o.NotExpr, ctx: EmitterVisitorContext): any {
|
||||||
|
@ -136,7 +136,7 @@ export function main() {
|
|||||||
expect(emitStmt(o.not(someVar).toStmt())).toEqual('!someVar;');
|
expect(emitStmt(o.not(someVar).toStmt())).toEqual('!someVar;');
|
||||||
expect(
|
expect(
|
||||||
emitStmt(someVar.conditional(o.variable('trueCase'), o.variable('falseCase')).toStmt()))
|
emitStmt(someVar.conditional(o.variable('trueCase'), o.variable('falseCase')).toStmt()))
|
||||||
.toEqual('someVar? trueCase: falseCase;');
|
.toEqual('(someVar? trueCase: falseCase);');
|
||||||
|
|
||||||
expect(emitStmt(lhs.equals(rhs).toStmt())).toEqual('(lhs == rhs);');
|
expect(emitStmt(lhs.equals(rhs).toStmt())).toEqual('(lhs == rhs);');
|
||||||
expect(emitStmt(lhs.notEquals(rhs).toStmt())).toEqual('(lhs != rhs);');
|
expect(emitStmt(lhs.notEquals(rhs).toStmt())).toEqual('(lhs != rhs);');
|
||||||
|
@ -125,7 +125,7 @@ export function main() {
|
|||||||
expect(emitStmt(o.not(someVar).toStmt())).toEqual('!someVar;');
|
expect(emitStmt(o.not(someVar).toStmt())).toEqual('!someVar;');
|
||||||
expect(
|
expect(
|
||||||
emitStmt(someVar.conditional(o.variable('trueCase'), o.variable('falseCase')).toStmt()))
|
emitStmt(someVar.conditional(o.variable('trueCase'), o.variable('falseCase')).toStmt()))
|
||||||
.toEqual('someVar? trueCase: falseCase;');
|
.toEqual('(someVar? trueCase: falseCase);');
|
||||||
|
|
||||||
expect(emitStmt(lhs.equals(rhs).toStmt())).toEqual('(lhs == rhs);');
|
expect(emitStmt(lhs.equals(rhs).toStmt())).toEqual('(lhs == rhs);');
|
||||||
expect(emitStmt(lhs.notEquals(rhs).toStmt())).toEqual('(lhs != rhs);');
|
expect(emitStmt(lhs.notEquals(rhs).toStmt())).toEqual('(lhs != rhs);');
|
||||||
|
@ -126,7 +126,7 @@ export function main() {
|
|||||||
expect(emitStmt(o.not(someVar).toStmt())).toEqual('!someVar;');
|
expect(emitStmt(o.not(someVar).toStmt())).toEqual('!someVar;');
|
||||||
expect(
|
expect(
|
||||||
emitStmt(someVar.conditional(o.variable('trueCase'), o.variable('falseCase')).toStmt()))
|
emitStmt(someVar.conditional(o.variable('trueCase'), o.variable('falseCase')).toStmt()))
|
||||||
.toEqual('someVar? trueCase: falseCase;');
|
.toEqual('(someVar? trueCase: falseCase);');
|
||||||
|
|
||||||
expect(emitStmt(lhs.equals(rhs).toStmt())).toEqual('(lhs == rhs);');
|
expect(emitStmt(lhs.equals(rhs).toStmt())).toEqual('(lhs == rhs);');
|
||||||
expect(emitStmt(lhs.notEquals(rhs).toStmt())).toEqual('(lhs != rhs);');
|
expect(emitStmt(lhs.notEquals(rhs).toStmt())).toEqual('(lhs != rhs);');
|
||||||
|
@ -71,7 +71,35 @@ function declareTests(isJit: boolean) {
|
|||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('expressions', () => {
|
||||||
|
|
||||||
|
it('should evaluate conditional and boolean operators with right precedence - #8244',
|
||||||
|
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||||
|
tcb.overrideView(MyComp,
|
||||||
|
new ViewMetadata({template: `{{'red' + (true ? ' border' : '')}}`}))
|
||||||
|
.createAsync(MyComp)
|
||||||
|
.then((fixture) => {
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(fixture.nativeElement).toHaveText('red border');
|
||||||
|
async.done();
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
if (!IS_DART) {
|
||||||
|
it('should evaluate conditional and unary operators with right precedence - #8235',
|
||||||
|
inject([TestComponentBuilder, AsyncTestCompleter],
|
||||||
|
(tcb: TestComponentBuilder, async) => {
|
||||||
|
tcb.overrideView(MyComp, new ViewMetadata({template: `{{!null?.length}}`}))
|
||||||
|
.createAsync(MyComp)
|
||||||
|
.then((fixture) => {
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(fixture.nativeElement).toHaveText('true');
|
||||||
|
async.done();
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('providers', () => {
|
describe('providers', () => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user