fix(compiler): add parens around binary / ternary expressions
This fixes cases where binary / ternary operators are nested (e.g. a nested ternary operator).
This commit is contained in:

committed by
Victor Berchet

parent
a8a9660112
commit
3799f43c71
@ -310,13 +310,13 @@ class _NodeEmitterVisitor implements StatementVisitor, ExpressionVisitor {
|
|||||||
return this.record(expr, this._visitIdentifier(expr.value));
|
return this.record(expr, this._visitIdentifier(expr.value));
|
||||||
}
|
}
|
||||||
|
|
||||||
visitConditionalExpr(expr: ConditionalExpr): RecordedNode<ts.ConditionalExpression> {
|
visitConditionalExpr(expr: ConditionalExpr): RecordedNode<ts.ParenthesizedExpression> {
|
||||||
// TODO {chuckj}: Review use of ! on flaseCase. Should it be non-nullable?
|
// TODO {chuckj}: Review use of ! on falseCase. Should it be non-nullable?
|
||||||
return this.record(
|
return this.record(
|
||||||
expr,
|
expr,
|
||||||
ts.createConditional(
|
ts.createParen(ts.createConditional(
|
||||||
expr.condition.visitExpression(this, null), expr.trueCase.visitExpression(this, null),
|
expr.condition.visitExpression(this, null), expr.trueCase.visitExpression(this, null),
|
||||||
expr.falseCase !.visitExpression(this, null)));
|
expr.falseCase !.visitExpression(this, null))));
|
||||||
}
|
}
|
||||||
|
|
||||||
visitNotExpr(expr: NotExpr): RecordedNode<ts.PrefixUnaryExpression> {
|
visitNotExpr(expr: NotExpr): RecordedNode<ts.PrefixUnaryExpression> {
|
||||||
@ -345,7 +345,7 @@ class _NodeEmitterVisitor implements StatementVisitor, ExpressionVisitor {
|
|||||||
/* type */ undefined, this._visitStatements(expr.statements)));
|
/* type */ undefined, this._visitStatements(expr.statements)));
|
||||||
}
|
}
|
||||||
|
|
||||||
visitBinaryOperatorExpr(expr: BinaryOperatorExpr): RecordedNode<ts.BinaryExpression> {
|
visitBinaryOperatorExpr(expr: BinaryOperatorExpr): RecordedNode<ts.ParenthesizedExpression> {
|
||||||
let binaryOperator: ts.BinaryOperator;
|
let binaryOperator: ts.BinaryOperator;
|
||||||
switch (expr.operator) {
|
switch (expr.operator) {
|
||||||
case BinaryOperator.And:
|
case BinaryOperator.And:
|
||||||
@ -397,9 +397,9 @@ class _NodeEmitterVisitor implements StatementVisitor, ExpressionVisitor {
|
|||||||
throw new Error(`Unknown operator: ${expr.operator}`);
|
throw new Error(`Unknown operator: ${expr.operator}`);
|
||||||
}
|
}
|
||||||
return this.record(
|
return this.record(
|
||||||
expr, ts.createBinary(
|
expr, ts.createParen(ts.createBinary(
|
||||||
expr.lhs.visitExpression(this, null), binaryOperator,
|
expr.lhs.visitExpression(this, null), binaryOperator,
|
||||||
expr.rhs.visitExpression(this, null)));
|
expr.rhs.visitExpression(this, null))));
|
||||||
}
|
}
|
||||||
|
|
||||||
visitReadPropExpr(expr: ReadPropExpr): RecordedNode<ts.PropertyAccessExpression> {
|
visitReadPropExpr(expr: ReadPropExpr): RecordedNode<ts.PropertyAccessExpression> {
|
||||||
|
@ -179,7 +179,7 @@ describe('TypeScriptNodeEmitter', () => {
|
|||||||
it('should support blank literals', () => {
|
it('should support blank literals', () => {
|
||||||
expect(emitStmt(o.literal(null).toStmt())).toEqual('null;');
|
expect(emitStmt(o.literal(null).toStmt())).toEqual('null;');
|
||||||
expect(emitStmt(o.literal(undefined).toStmt())).toEqual('undefined;');
|
expect(emitStmt(o.literal(undefined).toStmt())).toEqual('undefined;');
|
||||||
expect(emitStmt(o.variable('a', null).isBlank().toStmt())).toEqual('a == null;');
|
expect(emitStmt(o.variable('a', null).isBlank().toStmt())).toEqual('(a == null);');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should support external identifiers', () => {
|
it('should support external identifiers', () => {
|
||||||
@ -195,23 +195,28 @@ describe('TypeScriptNodeEmitter', () => {
|
|||||||
expect(emitStmt(o.not(someVar).toStmt())).toEqual('!someVar;');
|
expect(emitStmt(o.not(someVar).toStmt())).toEqual('!someVar;');
|
||||||
expect(emitStmt(o.assertNotNull(someVar).toStmt())).toEqual('someVar;');
|
expect(emitStmt(o.assertNotNull(someVar).toStmt())).toEqual('someVar;');
|
||||||
expect(emitStmt(someVar.conditional(o.variable('trueCase'), o.variable('falseCase')).toStmt()))
|
expect(emitStmt(someVar.conditional(o.variable('trueCase'), o.variable('falseCase')).toStmt()))
|
||||||
.toEqual('someVar ? trueCase : falseCase;');
|
.toEqual('(someVar ? trueCase : falseCase);');
|
||||||
|
expect(emitStmt(someVar.conditional(o.variable('trueCase'), o.variable('falseCase'))
|
||||||
|
.conditional(o.variable('trueCase'), o.variable('falseCase'))
|
||||||
|
.toStmt()))
|
||||||
|
.toEqual('((someVar ? trueCase : falseCase) ? 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);');
|
||||||
expect(emitStmt(lhs.identical(rhs).toStmt())).toEqual('lhs === rhs;');
|
expect(emitStmt(lhs.identical(rhs).toStmt())).toEqual('(lhs === rhs);');
|
||||||
expect(emitStmt(lhs.notIdentical(rhs).toStmt())).toEqual('lhs !== rhs;');
|
expect(emitStmt(lhs.notIdentical(rhs).toStmt())).toEqual('(lhs !== rhs);');
|
||||||
expect(emitStmt(lhs.minus(rhs).toStmt())).toEqual('lhs - rhs;');
|
expect(emitStmt(lhs.minus(rhs).toStmt())).toEqual('(lhs - rhs);');
|
||||||
expect(emitStmt(lhs.plus(rhs).toStmt())).toEqual('lhs + rhs;');
|
expect(emitStmt(lhs.plus(rhs).toStmt())).toEqual('(lhs + rhs);');
|
||||||
expect(emitStmt(lhs.divide(rhs).toStmt())).toEqual('lhs / rhs;');
|
expect(emitStmt(lhs.divide(rhs).toStmt())).toEqual('(lhs / rhs);');
|
||||||
expect(emitStmt(lhs.multiply(rhs).toStmt())).toEqual('lhs * rhs;');
|
expect(emitStmt(lhs.multiply(rhs).toStmt())).toEqual('(lhs * rhs);');
|
||||||
expect(emitStmt(lhs.modulo(rhs).toStmt())).toEqual('lhs % rhs;');
|
expect(emitStmt(lhs.plus(rhs).multiply(rhs).toStmt())).toEqual('((lhs + rhs) * rhs);');
|
||||||
expect(emitStmt(lhs.and(rhs).toStmt())).toEqual('lhs && rhs;');
|
expect(emitStmt(lhs.modulo(rhs).toStmt())).toEqual('(lhs % rhs);');
|
||||||
expect(emitStmt(lhs.or(rhs).toStmt())).toEqual('lhs || rhs;');
|
expect(emitStmt(lhs.and(rhs).toStmt())).toEqual('(lhs && rhs);');
|
||||||
expect(emitStmt(lhs.lower(rhs).toStmt())).toEqual('lhs < rhs;');
|
expect(emitStmt(lhs.or(rhs).toStmt())).toEqual('(lhs || rhs);');
|
||||||
expect(emitStmt(lhs.lowerEquals(rhs).toStmt())).toEqual('lhs <= rhs;');
|
expect(emitStmt(lhs.lower(rhs).toStmt())).toEqual('(lhs < rhs);');
|
||||||
expect(emitStmt(lhs.bigger(rhs).toStmt())).toEqual('lhs > rhs;');
|
expect(emitStmt(lhs.lowerEquals(rhs).toStmt())).toEqual('(lhs <= rhs);');
|
||||||
expect(emitStmt(lhs.biggerEquals(rhs).toStmt())).toEqual('lhs >= rhs;');
|
expect(emitStmt(lhs.bigger(rhs).toStmt())).toEqual('(lhs > rhs);');
|
||||||
|
expect(emitStmt(lhs.biggerEquals(rhs).toStmt())).toEqual('(lhs >= rhs);');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should support function expressions', () => {
|
it('should support function expressions', () => {
|
||||||
|
Reference in New Issue
Block a user