From 78cdb2d9026dd1ddb7157794c1798d0949ccbb34 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Wed, 30 Mar 2016 17:39:29 -0700 Subject: [PATCH 1/3] Adjusts emit for templates --- src/compiler/factory.ts | 68 ++++++++++++++----- src/compiler/printer.ts | 62 +++++++++-------- src/compiler/transformers/es6.ts | 17 +++-- src/compiler/visitor.ts | 4 +- ...emplateStringsWithIncompatibleTypedTags.js | 2 +- ...taggedTemplateStringsWithTagsTypedAsAny.js | 2 +- .../taggedTemplateStringsWithTypedTags.js | 2 +- .../templateStringBinaryOperations.js | 36 +++++----- .../templateStringBinaryOperationsInvalid.js | 42 ++++++------ .../reference/templateStringInArray.js | 2 +- .../templateStringInArrowFunction.js | 2 +- .../templateStringInObjectLiteral.js | 5 +- .../templateStringInObjectLiteralES6.js | 3 +- .../templateStringInPropertyName1.js | 2 +- .../templateStringInPropertyName2.js | 2 +- .../templateStringInTypeAssertion.js | 2 +- .../reference/templateStringInYieldKeyword.js | 2 +- .../templateStringWithEmbeddedComments.js | 7 +- .../templateStringWithEmbeddedCommentsES6.ts | 3 +- 19 files changed, 156 insertions(+), 109 deletions(-) diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index ab63144dfe8..4583643bc28 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -374,9 +374,9 @@ namespace ts { export function createBinary(left: Expression, operator: SyntaxKind, right: Expression, location?: TextRange) { const node = createNode(SyntaxKind.BinaryExpression, location); - node.left = parenthesizeBinaryOperand(operator, left, /*isLeftSideOfBinary*/ true); + node.left = parenthesizeBinaryOperand(operator, left, /*isLeftSideOfBinary*/ true, /*leftOperand*/ undefined); node.operatorToken = createSynthesizedNode(operator); - node.right = parenthesizeBinaryOperand(operator, right, /*isLeftSideOfBinary*/ false); + node.right = parenthesizeBinaryOperand(operator, right, /*isLeftSideOfBinary*/ false, node.left); return node; } @@ -1179,13 +1179,13 @@ namespace ts { * @param isLeftSideOfBinary A value indicating whether the operand is the left side of the * BinaryExpression. */ - export function parenthesizeBinaryOperand(binaryOperator: SyntaxKind, operand: Expression, isLeftSideOfBinary: boolean) { + export function parenthesizeBinaryOperand(binaryOperator: SyntaxKind, operand: Expression, isLeftSideOfBinary: boolean, leftOperand?: Expression) { // If the resulting expression is already parenthesized, we do not need to do any further processing. if (operand.kind === SyntaxKind.ParenthesizedExpression) { return operand; } - return binaryOperandNeedsParentheses(binaryOperator, operand, isLeftSideOfBinary) + return binaryOperandNeedsParentheses(binaryOperator, operand, isLeftSideOfBinary, leftOperand) ? createParen(operand) : operand; } @@ -1198,7 +1198,7 @@ namespace ts { * @param isLeftSideOfBinary A value indicating whether the operand is the left side of the * BinaryExpression. */ - function binaryOperandNeedsParentheses(binaryOperator: SyntaxKind, operand: Expression, isLeftSideOfBinary: boolean) { + function binaryOperandNeedsParentheses(binaryOperator: SyntaxKind, operand: Expression, isLeftSideOfBinary: boolean, leftOperand: Expression) { // If the operand has lower precedence, then it needs to be parenthesized to preserve the // intent of the expression. For example, if the operand is `a + b` and the operator is // `*`, then we need to parenthesize the operand to preserve the intended order of @@ -1240,16 +1240,30 @@ namespace ts { return binaryOperatorAssociativity === Associativity.Right; } else { - // No need to parenthesize the right operand when the binary operator and - // operand are the same and one of the following: - // x*(a*b) => x*a*b - // x|(a|b) => x|a|b - // x&(a&b) => x&a&b - // x^(a^b) => x^a^b if (isBinaryExpression(operand) - && operand.operatorToken.kind === binaryOperator - && isMathAssociativeOperator(binaryOperator)) { - return false; + && operand.operatorToken.kind === binaryOperator) { + // No need to parenthesize the right operand when the binary operator and + // operand are the same and one of the following: + // x*(a*b) => x*a*b + // x|(a|b) => x|a|b + // x&(a&b) => x&a&b + // x^(a^b) => x^a^b + if (isMathAssociativeOperator(binaryOperator)) { + return false; + } + + // No need to parenthesize the right operand when the binary operator + // is plus (+) if both the left and right operands consist solely of either + // literals of the same kind or binary plus (+) expressions for literals of + // the same kind (recursively). + // "a"+(1+2) => "a"+(1+2) + // "a"+("b"+"c") => "a"+"b"+"c" + if (binaryOperator === SyntaxKind.PlusToken) { + const leftKind = leftOperand ? getLiteralKindOfBinaryPlusOperand(leftOperand) : SyntaxKind.Unknown; + if (leftKind === getLiteralKindOfBinaryPlusOperand(operand)) { + return false; + } + } } // No need to parenthesize the right operand when the operand is right @@ -1294,14 +1308,17 @@ namespace ts { * @param expression The Expression node. */ export function parenthesizeForNew(expression: Expression): LeftHandSideExpression { - const lhs = parenthesizeForAccess(expression); - switch (lhs.kind) { + switch (expression.kind) { case SyntaxKind.CallExpression: + return createParen(expression); + case SyntaxKind.NewExpression: - return createParen(lhs); + return (expression).arguments + ? expression + : createParen(expression); } - return lhs; + return parenthesizeForAccess(expression); } /** @@ -1396,6 +1413,21 @@ namespace ts { return body; } + function getLiteralKindOfBinaryPlusOperand(node: Expression): SyntaxKind { + if (isLiteralKind(node.kind)) { + return node.kind; + } + + if (node.kind === SyntaxKind.BinaryExpression && (node).operatorToken.kind === SyntaxKind.PlusToken) { + const leftKind = getLiteralKindOfBinaryPlusOperand((node).left); + if (leftKind === getLiteralKindOfBinaryPlusOperand((node).right)) { + return leftKind; + } + } + + return SyntaxKind.Unknown; + } + function getLeftmostExpression(node: Expression): Expression { while (true) { switch (node.kind) { diff --git a/src/compiler/printer.ts b/src/compiler/printer.ts index 520ec004d79..09f797b9ba0 100644 --- a/src/compiler/printer.ts +++ b/src/compiler/printer.ts @@ -1017,6 +1017,7 @@ const _super = (function (geti, seti) { function emitTaggedTemplateExpression(node: TaggedTemplateExpression) { emitExpression(node.tag); + write(" "); emitExpression(node.template); } @@ -1751,7 +1752,7 @@ const _super = (function (geti, seti) { } function emitCaseOrDefaultClauseStatements(parentNode: Node, statements: NodeArray) { - const emitAsSingleStatement = + const emitAsSingleStatement = statements.length === 1 && ( // treat synthesized nodes as located on the same line for emit purposes @@ -2145,7 +2146,7 @@ const _super = (function (geti, seti) { writeLine(); shouldEmitInterveningComments = false; } - else if (previousSibling) { + else if (previousSibling && format & ListFormat.SpaceBetweenSiblings) { write(" "); } } @@ -2609,53 +2610,54 @@ const _super = (function (geti, seti) { // Whitespace Indented = 1 << 7, // The list should be indented. SpaceBetweenBraces = 1 << 8, // Inserts a space after the opening brace and before the closing brace. + SpaceBetweenSiblings = 1 << 9, // Inserts a space between each sibling node. // Brackets/Braces - Braces = 1 << 9, // The list is surrounded by "{" and "}". - Parenthesis = 1 << 10, // The list is surrounded by "(" and ")". - AngleBrackets = 1 << 11, // The list is surrounded by "<" and ">". - SquareBrackets = 1 << 12, // The list is surrounded by "[" and "]". + Braces = 1 << 10, // The list is surrounded by "{" and "}". + Parenthesis = 1 << 11, // The list is surrounded by "(" and ")". + AngleBrackets = 1 << 12, // The list is surrounded by "<" and ">". + SquareBrackets = 1 << 13, // The list is surrounded by "[" and "]". BracketsMask = Braces | Parenthesis | AngleBrackets | SquareBrackets, - OptionalIfUndefined = 1 << 13, // Do not emit brackets if the list is undefined. - OptionalIfEmpty = 1 << 14, // Do not emit brackets if the list is empty. + OptionalIfUndefined = 1 << 14, // Do not emit brackets if the list is undefined. + OptionalIfEmpty = 1 << 15, // Do not emit brackets if the list is empty. Optional = OptionalIfUndefined | OptionalIfEmpty, // Other - PreferNewLine = 1 << 15, // Prefer adding a LineTerminator between synthesized nodes. - NoTrailingNewLine = 1 << 16, // Do not emit a trailing NewLine for a MultiLine list. + PreferNewLine = 1 << 16, // Prefer adding a LineTerminator between synthesized nodes. + NoTrailingNewLine = 1 << 17, // Do not emit a trailing NewLine for a MultiLine list. // Precomputed Formats TypeLiteralMembers = MultiLine | Indented, - TupleTypeElements = CommaDelimited | SingleLine | Indented, - UnionTypeConstituents = BarDelimited | SingleLine, - IntersectionTypeConstituents = AmpersandDelimited | SingleLine, - ObjectBindingPatternElements = SingleLine | AllowTrailingComma | SpaceBetweenBraces | CommaDelimited, - ArrayBindingPatternElements = SingleLine | AllowTrailingComma | CommaDelimited, - ObjectLiteralExpressionProperties = PreserveLines | CommaDelimited | SpaceBetweenBraces | Indented | Braces, - ArrayLiteralExpressionElements = PreserveLines | CommaDelimited | AllowTrailingComma | Indented | SquareBrackets, - CallExpressionArguments = CommaDelimited | SingleLine | Parenthesis, - NewExpressionArguments = CommaDelimited | SingleLine | Parenthesis | OptionalIfUndefined, + TupleTypeElements = CommaDelimited | SpaceBetweenSiblings | SingleLine | Indented, + UnionTypeConstituents = BarDelimited | SpaceBetweenSiblings | SingleLine, + IntersectionTypeConstituents = AmpersandDelimited | SpaceBetweenSiblings | SingleLine, + ObjectBindingPatternElements = SingleLine | AllowTrailingComma | SpaceBetweenBraces | CommaDelimited | SpaceBetweenSiblings, + ArrayBindingPatternElements = SingleLine | AllowTrailingComma | CommaDelimited | SpaceBetweenSiblings, + ObjectLiteralExpressionProperties = PreserveLines | CommaDelimited | SpaceBetweenSiblings | SpaceBetweenBraces | Indented | Braces, + ArrayLiteralExpressionElements = PreserveLines | CommaDelimited | SpaceBetweenSiblings | AllowTrailingComma | Indented | SquareBrackets, + CallExpressionArguments = CommaDelimited | SpaceBetweenSiblings | SingleLine | Parenthesis, + NewExpressionArguments = CommaDelimited | SpaceBetweenSiblings | SingleLine | Parenthesis | OptionalIfUndefined, TemplateExpressionSpans = SingleLine, - SingleLineBlockStatements = SpaceBetweenBraces | SingleLine, + SingleLineBlockStatements = SpaceBetweenBraces | SpaceBetweenSiblings | SingleLine, MultiLineBlockStatements = Indented | MultiLine, - VariableDeclarationList = CommaDelimited | SingleLine, - SingleLineFunctionBodyStatements = SingleLine | SpaceBetweenBraces, + VariableDeclarationList = CommaDelimited | SpaceBetweenSiblings | SingleLine, + SingleLineFunctionBodyStatements = SingleLine | SpaceBetweenSiblings | SpaceBetweenBraces, MultiLineFunctionBodyStatements = MultiLine, - ClassHeritageClauses = SingleLine, + ClassHeritageClauses = SingleLine | SpaceBetweenSiblings, ClassMembers = Indented | MultiLine, InterfaceMembers = Indented | MultiLine, EnumMembers = CommaDelimited | Indented | MultiLine, CaseBlockClauses = Indented | MultiLine, - NamedImportsOrExportsElements = CommaDelimited | AllowTrailingComma | SingleLine | SpaceBetweenBraces, + NamedImportsOrExportsElements = CommaDelimited | SpaceBetweenSiblings | AllowTrailingComma | SingleLine | SpaceBetweenBraces, JsxElementChildren = SingleLine, - JsxElementAttributes = SingleLine, + JsxElementAttributes = SingleLine | SpaceBetweenSiblings, CaseOrDefaultClauseStatements = Indented | MultiLine | NoTrailingNewLine | OptionalIfEmpty, - HeritageClauseTypes = CommaDelimited | SingleLine, + HeritageClauseTypes = CommaDelimited | SpaceBetweenSiblings | SingleLine, SourceFileStatements = MultiLine | NoTrailingNewLine, Decorators = MultiLine | Optional, - TypeArguments = CommaDelimited | SingleLine | Indented | AngleBrackets | Optional, - TypeParameters = CommaDelimited | SingleLine | Indented | AngleBrackets | Optional, - Parameters = CommaDelimited | SingleLine | Indented | Parenthesis, - IndexSignatureParameters = CommaDelimited | SingleLine | Indented | SquareBrackets, + TypeArguments = CommaDelimited | SpaceBetweenSiblings | SingleLine | Indented | AngleBrackets | Optional, + TypeParameters = CommaDelimited | SpaceBetweenSiblings | SingleLine | Indented | AngleBrackets | Optional, + Parameters = CommaDelimited | SpaceBetweenSiblings | SingleLine | Indented | Parenthesis, + IndexSignatureParameters = CommaDelimited | SpaceBetweenSiblings | SingleLine | Indented | SquareBrackets, } } \ No newline at end of file diff --git a/src/compiler/transformers/es6.ts b/src/compiler/transformers/es6.ts index b1adbbc92f4..3566e3c3d81 100644 --- a/src/compiler/transformers/es6.ts +++ b/src/compiler/transformers/es6.ts @@ -2397,11 +2397,16 @@ namespace ts { } } - return inlineExpressions([ - createAssignment(temp, createArrayLiteral(cookedStrings)), - createAssignment(createPropertyAccess(temp, "raw"), createArrayLiteral(rawStrings)), - createCall(tag, templateArguments) - ]); + // NOTE: The parentheses here is entirely optional as we are now able to auto- + // parenthesize when rebuilding the tree. This should be removed in a + // future version. It is here for now to match our existing emit. + return createParen( + inlineExpressions([ + createAssignment(temp, createArrayLiteral(cookedStrings)), + createAssignment(createPropertyAccess(temp, "raw"), createArrayLiteral(rawStrings)), + createCall(tag, templateArguments) + ]) + ); } /** @@ -2426,7 +2431,7 @@ namespace ts { // ES6 Spec 11.8.6.1 - Static Semantics of TV's and TRV's // and LineTerminatorSequences are normalized to for both TV and TRV. text = text.replace(/\r\n?/g, "\n"); - text = escapeString(text); + //text = escapeString(text); return createLiteral(text, /*location*/ node); } diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index 4ad55b09bce..6c388c3f601 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -185,8 +185,8 @@ namespace ts { { name: "operand", test: isLeftHandSideExpression, parenthesize: parenthesizePostfixOperand }, ], [SyntaxKind.BinaryExpression]: [ - { name: "left", test: isExpression, parenthesize: (node: Expression, parent: BinaryExpression) => parenthesizeBinaryOperand(getOperator(parent), node, true) }, - { name: "right", test: isExpression, parenthesize: (node: Expression, parent: BinaryExpression) => parenthesizeBinaryOperand(getOperator(parent), node, false) }, + { name: "left", test: isExpression, parenthesize: (node: Expression, parent: BinaryExpression) => parenthesizeBinaryOperand(getOperator(parent), node, true, /*leftOperand*/ undefined) }, + { name: "right", test: isExpression, parenthesize: (node: Expression, parent: BinaryExpression) => parenthesizeBinaryOperand(getOperator(parent), node, false, parent.left) }, ], [SyntaxKind.ConditionalExpression]: [ { name: "condition", test: isExpression }, diff --git a/tests/baselines/reference/taggedTemplateStringsWithIncompatibleTypedTags.js b/tests/baselines/reference/taggedTemplateStringsWithIncompatibleTypedTags.js index 9d113793228..67c94fd6513 100644 --- a/tests/baselines/reference/taggedTemplateStringsWithIncompatibleTypedTags.js +++ b/tests/baselines/reference/taggedTemplateStringsWithIncompatibleTypedTags.js @@ -46,4 +46,4 @@ var f; (_l = ["abc", "def", "ghi"], _l.raw = ["abc", "def", "ghi"], (_m = ["abc", "def", "ghi"], _m.raw = ["abc", "def", "ghi"], f(_m, true, true))["member"].member(_l, 1, 2)); f.thisIsNotATag("abc"); f.thisIsNotATag("abc" + 1 + "def" + 2 + "ghi"); -var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m; +var _a, _b, _c, _d, _e, _f, _h, _g, _k, _j, _m, _l; diff --git a/tests/baselines/reference/taggedTemplateStringsWithTagsTypedAsAny.js b/tests/baselines/reference/taggedTemplateStringsWithTagsTypedAsAny.js index fd83d9d0ba0..cd3d8ba6701 100644 --- a/tests/baselines/reference/taggedTemplateStringsWithTagsTypedAsAny.js +++ b/tests/baselines/reference/taggedTemplateStringsWithTagsTypedAsAny.js @@ -39,4 +39,4 @@ var f; (_l = ["abc", "def", "ghi"], _l.raw = ["abc", "def", "ghi"], (_m = ["abc", "def", "ghi"], _m.raw = ["abc", "def", "ghi"], f(_m, 1, 2))["member"].someOtherTag(_l, 1, 2)); f.thisIsNotATag("abc"); f.thisIsNotATag("abc" + 1 + "def" + 2 + "ghi"); -var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m; +var _a, _b, _c, _d, _e, _f, _g, _h, _k, _j, _m, _l; diff --git a/tests/baselines/reference/taggedTemplateStringsWithTypedTags.js b/tests/baselines/reference/taggedTemplateStringsWithTypedTags.js index fcc2cda86dc..14b584e22e4 100644 --- a/tests/baselines/reference/taggedTemplateStringsWithTypedTags.js +++ b/tests/baselines/reference/taggedTemplateStringsWithTypedTags.js @@ -43,4 +43,4 @@ var f; (_j = ["abc", "def", "ghi"], _j.raw = ["abc", "def", "ghi"], (_k = ["abc", "def", "ghi"], _k.raw = ["abc", "def", "ghi"], f(_k, 1, 2))["member"].member(_j, 1, 2)); f.thisIsNotATag("abc"); f.thisIsNotATag("abc" + 1 + "def" + 2 + "ghi"); -var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k; +var _a, _b, _c, _d, _e, _f, _h, _g, _k, _j; diff --git a/tests/baselines/reference/templateStringBinaryOperations.js b/tests/baselines/reference/templateStringBinaryOperations.js index 691dad41f77..74093775b98 100644 --- a/tests/baselines/reference/templateStringBinaryOperations.js +++ b/tests/baselines/reference/templateStringBinaryOperations.js @@ -57,34 +57,34 @@ var a = 1 + ("" + 3); var b = 1 + ("2" + 3); var c = 1 + (3 + "4"); var d = 1 + ("2" + 3 + "4"); -var e = ("" + 3) + 5; -var f = ("2" + 3) + 5; -var g = (3 + "4") + 5; -var h = ("2" + 3 + "4") + 5; +var e = "" + 3 + 5; +var f = "2" + 3 + 5; +var g = 3 + "4" + 5; +var h = "2" + 3 + "4" + 5; var i = 1 + ("" + 3) + 5; var j = 1 + ("2" + 3) + 5; var k = 1 + (3 + "4") + 5; var l = 1 + ("2" + 3 + "4") + 5; var a2 = 1 + ("" + (3 - 4)); var b2 = 1 + ("2" + (3 - 4)); -var c2 = 1 + ((3 - 4) + "5"); +var c2 = 1 + (3 - 4 + "5"); var d2 = 1 + ("2" + (3 - 4) + "5"); -var e2 = ("" + (3 - 4)) + 6; -var f2 = ("2" + (3 - 4)) + 6; -var g2 = ((3 - 4) + "5") + 6; -var h2 = ("2" + (3 - 4) + "5") + 6; +var e2 = "" + (3 - 4) + 6; +var f2 = "2" + (3 - 4) + 6; +var g2 = 3 - 4 + "5" + 6; +var h2 = "2" + (3 - 4) + "5" + 6; var i2 = 1 + ("" + (3 - 4)) + 6; var j2 = 1 + ("2" + (3 - 4)) + 6; -var k2 = 1 + ((3 - 4) + "5") + 6; +var k2 = 1 + (3 - 4 + "5") + 6; var l2 = 1 + ("2" + (3 - 4) + "5") + 6; var a3 = 1 + ("" + 3 * 4); var b3 = 1 + ("2" + 3 * 4); var c3 = 1 + (3 * 4 + "5"); var d3 = 1 + ("2" + 3 * 4 + "5"); -var e3 = ("" + 3 * 4) + 6; -var f3 = ("2" + 3 * 4) + 6; -var g3 = (3 * 4 + "5") + 6; -var h3 = ("2" + 3 * 4 + "5") + 6; +var e3 = "" + 3 * 4 + 6; +var f3 = "2" + 3 * 4 + 6; +var g3 = 3 * 4 + "5" + 6; +var h3 = "2" + 3 * 4 + "5" + 6; var i3 = 1 + ("" + 3 * 4) + 6; var j3 = 1 + ("2" + 3 * 4) + 6; var k3 = 1 + (3 * 4 + "5") + 6; @@ -93,10 +93,10 @@ var a4 = 1 + ("" + (3 & 4)); var b4 = 1 + ("2" + (3 & 4)); var c4 = 1 + ((3 & 4) + "5"); var d4 = 1 + ("2" + (3 & 4) + "5"); -var e4 = ("" + (3 & 4)) + 6; -var f4 = ("2" + (3 & 4)) + 6; -var g4 = ((3 & 4) + "5") + 6; -var h4 = ("2" + (3 & 4) + "5") + 6; +var e4 = "" + (3 & 4) + 6; +var f4 = "2" + (3 & 4) + 6; +var g4 = (3 & 4) + "5" + 6; +var h4 = "2" + (3 & 4) + "5" + 6; var i4 = 1 + ("" + (3 & 4)) + 6; var j4 = 1 + ("2" + (3 & 4)) + 6; var k4 = 1 + ((3 & 4) + "5") + 6; diff --git a/tests/baselines/reference/templateStringBinaryOperationsInvalid.js b/tests/baselines/reference/templateStringBinaryOperationsInvalid.js index f8c0344f44b..e6c288f1b54 100644 --- a/tests/baselines/reference/templateStringBinaryOperationsInvalid.js +++ b/tests/baselines/reference/templateStringBinaryOperationsInvalid.js @@ -113,10 +113,10 @@ var a = 1 - ("" + 3); var b = 1 - ("2" + 3); var c = 1 - (3 + "4"); var d = 1 - ("2" + 3 + "4"); -var e = ("" + 3) - 5; -var f = ("2" + 3) - 5; -var g = (3 + "4") - 5; -var h = ("2" + 3 + "4") - 5; +var e = "" + 3 - 5; +var f = "2" + 3 - 5; +var g = 3 + "4" - 5; +var h = "2" + 3 + "4" - 5; var a2 = 1 * ("" + 3); var b2 = 1 * ("2" + 3); var c2 = 1 * (3 + "4"); @@ -135,35 +135,35 @@ var g3 = 3 + "4" & 5; var h3 = "2" + 3 + "4" & 5; var a4 = 1 - ("" + (3 - 4)); var b4 = 1 - ("2" + (3 - 4)); -var c4 = 1 - ((3 - 4) + "5"); +var c4 = 1 - (3 - 4 + "5"); var d4 = 1 - ("2" + (3 - 4) + "5"); -var e4 = ("" + (3 - 4)) - 6; -var f4 = ("2" + (3 - 4)) - 6; -var g4 = ((3 - 4) + "5") - 6; -var h4 = ("2" + (3 - 4) + "5") - 6; +var e4 = "" + (3 - 4) - 6; +var f4 = "2" + (3 - 4) - 6; +var g4 = 3 - 4 + "5" - 6; +var h4 = "2" + (3 - 4) + "5" - 6; var a5 = 1 - ("" + 3 * 4); var b5 = 1 - ("2" + 3 * 4); var c5 = 1 - (3 * 4 + "5"); var d5 = 1 - ("2" + 3 * 4 + "5"); -var e5 = ("" + 3 * 4) - 6; -var f5 = ("2" + 3 * 4) - 6; -var g5 = (3 * 4 + "5") - 6; -var h5 = ("2" + 3 * 4 + "5") - 6; +var e5 = "" + 3 * 4 - 6; +var f5 = "2" + 3 * 4 - 6; +var g5 = 3 * 4 + "5" - 6; +var h5 = "2" + 3 * 4 + "5" - 6; var a6 = 1 - ("" + (3 & 4)); var b6 = 1 - ("2" + (3 & 4)); var c6 = 1 - ((3 & 4) + "5"); var d6 = 1 - ("2" + (3 & 4) + "5"); -var e6 = ("" + (3 & 4)) - 6; -var f6 = ("2" + (3 & 4)) - 6; -var g6 = ((3 & 4) + "5") - 6; -var h6 = ("2" + (3 & 4) + "5") - 6; +var e6 = "" + (3 & 4) - 6; +var f6 = "2" + (3 & 4) - 6; +var g6 = (3 & 4) + "5" - 6; +var h6 = "2" + (3 & 4) + "5" - 6; var a7 = 1 * ("" + (3 - 4)); var b7 = 1 * ("2" + (3 - 4)); -var c7 = 1 * ((3 - 4) + "5"); +var c7 = 1 * (3 - 4 + "5"); var d7 = 1 * ("2" + (3 - 4) + "5"); var e7 = ("" + (3 - 4)) * 6; var f7 = ("2" + (3 - 4)) * 6; -var g7 = ((3 - 4) + "5") * 6; +var g7 = (3 - 4 + "5") * 6; var h7 = ("2" + (3 - 4) + "5") * 6; var a8 = 1 * ("" + 3 * 4); var b8 = 1 * ("2" + 3 * 4); @@ -183,11 +183,11 @@ var g9 = ((3 & 4) + "5") * 6; var h9 = ("2" + (3 & 4) + "5") * 6; var aa = 1 & "" + (3 - 4); var ba = 1 & "2" + (3 - 4); -var ca = 1 & (3 - 4) + "5"; +var ca = 1 & 3 - 4 + "5"; var da = 1 & "2" + (3 - 4) + "5"; var ea = "" + (3 - 4) & 6; var fa = "2" + (3 - 4) & 6; -var ga = (3 - 4) + "5" & 6; +var ga = 3 - 4 + "5" & 6; var ha = "2" + (3 - 4) + "5" & 6; var ab = 1 & "" + 3 * 4; var bb = 1 & "2" + 3 * 4; diff --git a/tests/baselines/reference/templateStringInArray.js b/tests/baselines/reference/templateStringInArray.js index 97d0b1a636b..7b387ae8e74 100644 --- a/tests/baselines/reference/templateStringInArray.js +++ b/tests/baselines/reference/templateStringInArray.js @@ -2,4 +2,4 @@ var x = [1, 2, `abc${ 123 }def`]; //// [templateStringInArray.js] -var x = [1, 2, ("abc" + 123 + "def")]; +var x = [1, 2, "abc" + 123 + "def"]; diff --git a/tests/baselines/reference/templateStringInArrowFunction.js b/tests/baselines/reference/templateStringInArrowFunction.js index 4c4890633e1..3e72edf031f 100644 --- a/tests/baselines/reference/templateStringInArrowFunction.js +++ b/tests/baselines/reference/templateStringInArrowFunction.js @@ -2,4 +2,4 @@ var x = x => `abc${ x }def`; //// [templateStringInArrowFunction.js] -var x = function (x) { return ("abc" + x + "def"); }; +var x = function (x) { return "abc" + x + "def"; }; diff --git a/tests/baselines/reference/templateStringInObjectLiteral.js b/tests/baselines/reference/templateStringInObjectLiteral.js index 2e4de70f57c..0381e9a95e7 100644 --- a/tests/baselines/reference/templateStringInObjectLiteral.js +++ b/tests/baselines/reference/templateStringInObjectLiteral.js @@ -5,7 +5,8 @@ var x = { } //// [templateStringInObjectLiteral.js] -var x = (_a = ["b"], _a.raw = ["b"], ({ - a: "abc" + 123 + "def" })(_a)); +var x = (_a = ["b"], _a.raw = ["b"], { + a: "abc" + 123 + "def" +}(_a)); 321; var _a; diff --git a/tests/baselines/reference/templateStringInObjectLiteralES6.js b/tests/baselines/reference/templateStringInObjectLiteralES6.js index 7de012185a9..22144e75247 100644 --- a/tests/baselines/reference/templateStringInObjectLiteralES6.js +++ b/tests/baselines/reference/templateStringInObjectLiteralES6.js @@ -6,5 +6,6 @@ var x = { //// [templateStringInObjectLiteralES6.js] var x = { - a: `abc${123}def`, } `b`; + a: `abc${123}def`, +} `b`; 321; diff --git a/tests/baselines/reference/templateStringInPropertyName1.js b/tests/baselines/reference/templateStringInPropertyName1.js index 18e35c475e3..239ba78d827 100644 --- a/tests/baselines/reference/templateStringInPropertyName1.js +++ b/tests/baselines/reference/templateStringInPropertyName1.js @@ -4,6 +4,6 @@ var x = { } //// [templateStringInPropertyName1.js] -var x = (_a = ["a"], _a.raw = ["a"], ({})(_a)); +var x = (_a = ["a"], _a.raw = ["a"], {}(_a)); 321; var _a; diff --git a/tests/baselines/reference/templateStringInPropertyName2.js b/tests/baselines/reference/templateStringInPropertyName2.js index 1a2995ca08f..8a71a6e30be 100644 --- a/tests/baselines/reference/templateStringInPropertyName2.js +++ b/tests/baselines/reference/templateStringInPropertyName2.js @@ -4,6 +4,6 @@ var x = { } //// [templateStringInPropertyName2.js] -var x = (_a = ["abc", "def", "ghi"], _a.raw = ["abc", "def", "ghi"], ({})(_a, 123, 456)); +var x = (_a = ["abc", "def", "ghi"], _a.raw = ["abc", "def", "ghi"], {}(_a, 123, 456)); 321; var _a; diff --git a/tests/baselines/reference/templateStringInTypeAssertion.js b/tests/baselines/reference/templateStringInTypeAssertion.js index 94533248b6d..723e688d94b 100644 --- a/tests/baselines/reference/templateStringInTypeAssertion.js +++ b/tests/baselines/reference/templateStringInTypeAssertion.js @@ -2,4 +2,4 @@ var x = `abc${ 123 }def`; //// [templateStringInTypeAssertion.js] -var x = ("abc" + 123 + "def"); +var x = "abc" + 123 + "def"; diff --git a/tests/baselines/reference/templateStringInYieldKeyword.js b/tests/baselines/reference/templateStringInYieldKeyword.js index 02ac42c723f..e23eaa17c9c 100644 --- a/tests/baselines/reference/templateStringInYieldKeyword.js +++ b/tests/baselines/reference/templateStringInYieldKeyword.js @@ -6,7 +6,7 @@ function* gen() { //// [templateStringInYieldKeyword.js] -function gen() { +function* gen() { // Once this is supported, the inner expression does not need to be parenthesized. var x = yield "abc" + x + "def"; } diff --git a/tests/baselines/reference/templateStringWithEmbeddedComments.js b/tests/baselines/reference/templateStringWithEmbeddedComments.js index 58a73e89ba7..730997e28fb 100644 --- a/tests/baselines/reference/templateStringWithEmbeddedComments.js +++ b/tests/baselines/reference/templateStringWithEmbeddedComments.js @@ -13,4 +13,9 @@ middle${ tail`; //// [templateStringWithEmbeddedComments.js] -"head" + 10 + "\nmiddle" + 20 + "\ntail"; +"head" + 10 + "\nmiddle" + +/* Multi- + * line + * comment + */ +20 + "\ntail"; diff --git a/tests/cases/conformance/es6/templates/templateStringWithEmbeddedCommentsES6.ts b/tests/cases/conformance/es6/templates/templateStringWithEmbeddedCommentsES6.ts index 2cb295bbfeb..974aaec5a57 100644 --- a/tests/cases/conformance/es6/templates/templateStringWithEmbeddedCommentsES6.ts +++ b/tests/cases/conformance/es6/templates/templateStringWithEmbeddedCommentsES6.ts @@ -1,4 +1,5 @@ -`head${ // single line comment +// @target: ES6 +`head${ // single line comment 10 } middle${ From fe13cdc7bdbf07a075949ee243c3c8b629e3e81f Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Wed, 30 Mar 2016 17:41:03 -0700 Subject: [PATCH 2/3] Updated a few baselines --- .../templateStringWithEmbeddedCommentsES6.js | 12 +++++++++++- .../templateStringWithEmbeddedYieldKeyword.js | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/tests/baselines/reference/templateStringWithEmbeddedCommentsES6.js b/tests/baselines/reference/templateStringWithEmbeddedCommentsES6.js index c6b3649ad2a..f5450e45b32 100644 --- a/tests/baselines/reference/templateStringWithEmbeddedCommentsES6.js +++ b/tests/baselines/reference/templateStringWithEmbeddedCommentsES6.js @@ -13,4 +13,14 @@ middle${ tail`; //// [templateStringWithEmbeddedCommentsES6.js] -"head" + 10 + "\nmiddle" + 20 + "\ntail"; +`head${ // single line comment +10} +middle${ +/* Multi- + * line + * comment + */ +20 +// closing comment +} +tail`; diff --git a/tests/baselines/reference/templateStringWithEmbeddedYieldKeyword.js b/tests/baselines/reference/templateStringWithEmbeddedYieldKeyword.js index e050441173e..8230f0ec8f1 100644 --- a/tests/baselines/reference/templateStringWithEmbeddedYieldKeyword.js +++ b/tests/baselines/reference/templateStringWithEmbeddedYieldKeyword.js @@ -6,7 +6,7 @@ function* gen { //// [templateStringWithEmbeddedYieldKeyword.js] -function gen() { +function* gen() { // Once this is supported, yield *must* be parenthesized. var x = "abc" + (yield 10) + "def"; } From 033864be820660c64dcce7a2bfc96183a45565a0 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Thu, 31 Mar 2016 10:16:05 -0700 Subject: [PATCH 3/3] PR Feedback --- src/compiler/factory.ts | 4 ++-- src/compiler/transformers/es6.ts | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 4583643bc28..7598f1f69dc 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -1248,7 +1248,7 @@ namespace ts { // x|(a|b) => x|a|b // x&(a&b) => x&a&b // x^(a^b) => x^a^b - if (isMathAssociativeOperator(binaryOperator)) { + if (operatorHasAssociativeProperty(binaryOperator)) { return false; } @@ -1286,7 +1286,7 @@ namespace ts { * * @param binaryOperator The binary operator. */ - function isMathAssociativeOperator(binaryOperator: SyntaxKind) { + function operatorHasAssociativeProperty(binaryOperator: SyntaxKind) { // The following operators are associative in JavaScript: // (a*b)*c -> a*(b*c) -> a*b*c // (a|b)|c -> a|(b|c) -> a|b|c diff --git a/src/compiler/transformers/es6.ts b/src/compiler/transformers/es6.ts index 3566e3c3d81..c008a754ebd 100644 --- a/src/compiler/transformers/es6.ts +++ b/src/compiler/transformers/es6.ts @@ -2431,7 +2431,6 @@ namespace ts { // ES6 Spec 11.8.6.1 - Static Semantics of TV's and TRV's // and LineTerminatorSequences are normalized to for both TV and TRV. text = text.replace(/\r\n?/g, "\n"); - //text = escapeString(text); return createLiteral(text, /*location*/ node); }