Fixed issue where template expression in call expressions would emit with unnecessary parentheses.

Fixes #1205.
This commit is contained in:
Daniel Rosenwasser
2014-11-19 17:04:34 -08:00
parent 8b35beaa1c
commit f51a42c6de
19 changed files with 117 additions and 24 deletions
+23 -9
View File
@@ -821,11 +821,10 @@ module ts {
Debug.assert(node.parent.kind !== SyntaxKind.TaggedTemplateExpression);
var templateNeedsParens = isExpression(node.parent)
&& node.parent.kind !== SyntaxKind.ParenExpression
&& comparePrecedenceToBinaryPlus(node.parent) !== Comparison.LessThan;
var emitOuterParens = isExpression(node.parent)
&& templateNeedsParens(node, <Expression>node.parent);
if (templateNeedsParens) {
if (emitOuterParens) {
write("(");
}
@@ -834,7 +833,7 @@ module ts {
forEach(node.templateSpans, templateSpan => {
// Check if the expression has operands and binds its operands less closely than binary '+'.
// If it does, we need to wrap the expression in parentheses. Otherwise, something like
// `abc${ 1 << 2}`
// `abc${ 1 << 2 }`
// becomes
// "abc" + 1 << 2 + ""
// which is really
@@ -855,18 +854,34 @@ module ts {
}
// Only emit if the literal is non-empty.
// The binary '+' operator is left-associative, so the first string concatenation will force
// the result up to this point to be a string. Emitting a '+ ""' has no semantic effect.
// The binary '+' operator is left-associative, so the first string concatenation
// with the head will force the result up to this point to be a string.
// Emitting a '+ ""' has no semantic effect for middles and tails.
if (templateSpan.literal.text.length !== 0) {
write(" + ")
emitLiteral(templateSpan.literal);
}
});
if (templateNeedsParens) {
if (emitOuterParens) {
write(")");
}
function templateNeedsParens(template: TemplateExpression, parent: Expression) {
switch (parent.kind) {
case SyntaxKind.TaggedTemplateExpression:
Debug.fail("Path should be unreachable; tagged templates not supported pre-ES6!");
//return (<TaggedTemplateExpression>parent).tag === template;
case SyntaxKind.CallExpression:
case SyntaxKind.NewExpression:
return (<CallExpression>parent).func === template;
case SyntaxKind.ParenExpression:
return false;
default:
return comparePrecedenceToBinaryPlus(parent) !== Comparison.LessThan;
}
}
/**
* Returns whether the expression has lesser, greater,
* or equal precedence to the binary '+' operator
@@ -899,7 +914,6 @@ module ts {
return Comparison.GreaterThan;
}
}
}
function emitTemplateSpan(span: TemplateSpan) {