Merge branch 'master' into grammarChecks

This commit is contained in:
Cyrus Najmabadi 2014-11-20 13:07:45 -08:00
commit 6865265b45
18 changed files with 101 additions and 9 deletions

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,33 @@ 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.CallExpression:
case SyntaxKind.NewExpression:
return (<CallExpression>parent).func === template;
case SyntaxKind.ParenExpression:
return false;
case SyntaxKind.TaggedTemplateExpression:
Debug.fail("Path should be unreachable; tagged templates not supported pre-ES6.");
default:
return comparePrecedenceToBinaryPlus(parent) !== Comparison.LessThan;
}
}
/**
* Returns whether the expression has lesser, greater,
* or equal precedence to the binary '+' operator
@ -899,7 +913,6 @@ module ts {
return Comparison.GreaterThan;
}
}
}
function emitTemplateSpan(span: TemplateSpan) {

View file

@ -0,0 +1,7 @@
tests/cases/conformance/es6/templates/templateStringInCallExpression.ts(1,1): error TS2349: Cannot invoke an expression whose type lacks a call signature.
==== tests/cases/conformance/es6/templates/templateStringInCallExpression.ts (1 errors) ====
`abc${0}abc`(`hello ${0} world`, ` `, `1${2}3`);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2349: Cannot invoke an expression whose type lacks a call signature.

View file

@ -0,0 +1,5 @@
//// [templateStringInCallExpression.ts]
`abc${0}abc`(`hello ${0} world`, ` `, `1${2}3`);
//// [templateStringInCallExpression.js]
("abc" + 0 + "abc")("hello " + 0 + " world", " ", "1" + 2 + "3");

View file

@ -0,0 +1,7 @@
tests/cases/conformance/es6/templates/templateStringInCallExpressionES6.ts(1,1): error TS2349: Cannot invoke an expression whose type lacks a call signature.
==== tests/cases/conformance/es6/templates/templateStringInCallExpressionES6.ts (1 errors) ====
`abc${0}abc`(`hello ${0} world`, ` `, `1${2}3`);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2349: Cannot invoke an expression whose type lacks a call signature.

View file

@ -0,0 +1,5 @@
//// [templateStringInCallExpressionES6.ts]
`abc${0}abc`(`hello ${0} world`, ` `, `1${2}3`);
//// [templateStringInCallExpressionES6.js]
`abc${0}abc`(`hello ${0} world`, ` `, `1${2}3`);

View file

@ -0,0 +1,7 @@
tests/cases/conformance/es6/templates/templateStringInNewExpression.ts(1,1): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature.
==== tests/cases/conformance/es6/templates/templateStringInNewExpression.ts (1 errors) ====
new `abc${0}abc`(`hello ${0} world`, ` `, `1${2}3`);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature.

View file

@ -0,0 +1,5 @@
//// [templateStringInNewExpression.ts]
new `abc${0}abc`(`hello ${0} world`, ` `, `1${2}3`);
//// [templateStringInNewExpression.js]
new ("abc" + 0 + "abc")("hello " + 0 + " world", " ", "1" + 2 + "3");

View file

@ -0,0 +1,7 @@
tests/cases/conformance/es6/templates/templateStringInNewExpressionES6.ts(1,1): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature.
==== tests/cases/conformance/es6/templates/templateStringInNewExpressionES6.ts (1 errors) ====
new `abc${0}abc`(`hello ${0} world`, ` `, `1${2}3`);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature.

View file

@ -0,0 +1,5 @@
//// [templateStringInNewExpressionES6.ts]
new `abc${0}abc`(`hello ${0} world`, ` `, `1${2}3`);
//// [templateStringInNewExpressionES6.js]
new `abc${0}abc`(`hello ${0} world`, ` `, `1${2}3`);

View file

@ -0,0 +1,10 @@
tests/cases/conformance/es6/templates/templateStringInTaggedTemplate.ts(1,1): error TS1159: Tagged templates are only available when targeting ECMAScript 6 and higher.
tests/cases/conformance/es6/templates/templateStringInTaggedTemplate.ts(1,1): error TS2349: Cannot invoke an expression whose type lacks a call signature.
==== tests/cases/conformance/es6/templates/templateStringInTaggedTemplate.ts (2 errors) ====
`I AM THE ${ `${ `TAG` } ` } PORTION` `I ${ "AM" } THE TEMPLATE PORTION`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS1159: Tagged templates are only available when targeting ECMAScript 6 and higher.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2349: Cannot invoke an expression whose type lacks a call signature.

View file

@ -0,0 +1,7 @@
tests/cases/conformance/es6/templates/templateStringInTaggedTemplateES6.ts(1,1): error TS2349: Cannot invoke an expression whose type lacks a call signature.
==== tests/cases/conformance/es6/templates/templateStringInTaggedTemplateES6.ts (1 errors) ====
`I AM THE ${ `${ `TAG` } ` } PORTION` `I ${ "AM" } THE TEMPLATE PORTION`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2349: Cannot invoke an expression whose type lacks a call signature.

View file

@ -0,0 +1,5 @@
//// [templateStringInTaggedTemplateES6.ts]
`I AM THE ${ `${ `TAG` } ` } PORTION` `I ${ "AM" } THE TEMPLATE PORTION`
//// [templateStringInTaggedTemplateES6.js]
`I AM THE ${`${`TAG`} `} PORTION` `I ${"AM"} THE TEMPLATE PORTION`;

View file

@ -0,0 +1 @@
`abc${0}abc`(`hello ${0} world`, ` `, `1${2}3`);

View file

@ -0,0 +1,2 @@
// @target: ES6
`abc${0}abc`(`hello ${0} world`, ` `, `1${2}3`);

View file

@ -0,0 +1 @@
new `abc${0}abc`(`hello ${0} world`, ` `, `1${2}3`);

View file

@ -0,0 +1,2 @@
// @target: ES6
new `abc${0}abc`(`hello ${0} world`, ` `, `1${2}3`);

View file

@ -0,0 +1 @@
`I AM THE ${ `${ `TAG` } ` } PORTION` `I ${ "AM" } THE TEMPLATE PORTION`

View file

@ -0,0 +1,2 @@
// @target: ES6
`I AM THE ${ `${ `TAG` } ` } PORTION` `I ${ "AM" } THE TEMPLATE PORTION`