From 6a82ae4cbb209d6f3fdad74cdf6146747ed33449 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Mon, 7 Nov 2016 09:04:00 -0800 Subject: [PATCH] Add SpreadAssignment to visitors 1. visitNode 2. reduceNode 3. emit This fixes an emit bug for setters. --- src/compiler/emitter.ts | 9 +++++++++ src/compiler/factory.ts | 17 +++++++++++++++-- src/compiler/visitor.ts | 10 +++++++++- .../baselines/reference/objectSpreadNegative.js | 2 +- 4 files changed, 34 insertions(+), 4 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 6d4688ac004..b0413b2578e 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -732,6 +732,8 @@ const _super = (function (geti, seti) { return emitPropertyAssignment(node); case SyntaxKind.ShorthandPropertyAssignment: return emitShorthandPropertyAssignment(node); + case SyntaxKind.ShorthandPropertyAssignment: + return emitSpreadAssignment(node as SpreadAssignment); // Enum case SyntaxKind.EnumMember: @@ -2102,6 +2104,13 @@ const _super = (function (geti, seti) { } } + function emitSpreadAssignment(node: SpreadAssignment) { + if (node.expression) { + write("..."); + emitExpression(node.expression); + } + } + // // Enum // diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 536ee4cb4b4..fd2b7c1ccee 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -1399,14 +1399,27 @@ namespace ts { return node; } - export function updateShorthandPropertyAssignment(node: ShorthandPropertyAssignment, name: Identifier, objectAssignmentInitializer: Expression) { + export function createSpreadAssignment(expression: Expression, location?: TextRange) { + const node = createNode(SyntaxKind.SpreadAssignment, location); + node.expression = expression !== undefined ? parenthesizeExpressionForList(expression) : undefined; + return node; + } + + export function updateShorthandPropertyAssignment(node: ShorthandPropertyAssignment, name: Identifier, objectAssignmentInitializer: Expression) { if (node.name !== name || node.objectAssignmentInitializer !== objectAssignmentInitializer) { return updateNode(createShorthandPropertyAssignment(name, objectAssignmentInitializer, node), node); } return node; } - // Top-level nodes + export function updateSpreadAssignment(node: SpreadAssignment, expression: Expression) { + if (node.expression !== expression) { + return updateNode(createSpreadAssignment(expression, node), node); + } + return node; + } + + // Top-level nodes export function updateSourceFileNode(node: SourceFile, statements: Statement[]) { if (node.statements !== statements) { diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index 0fb0b182345..db59c309345 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -510,6 +510,10 @@ namespace ts { result = reduceNode((node).objectAssignmentInitializer, f, result); break; + case SyntaxKind.SpreadAssignment: + result = reduceNode((node as SpreadAssignment).expression, f, result); + break; + // Top-level nodes case SyntaxKind.SourceFile: result = reduceLeft((node).statements, f, result); @@ -1125,7 +1129,11 @@ namespace ts { visitNode((node).name, visitor, isIdentifier), visitNode((node).objectAssignmentInitializer, visitor, isExpression)); - // Top-level nodes + case SyntaxKind.SpreadAssignment: + return updateSpreadAssignment(node as SpreadAssignment, + visitNode((node as SpreadAssignment).expression, visitor, isExpression)); + + // Top-level nodes case SyntaxKind.SourceFile: context.startLexicalEnvironment(); return updateSourceFileNode(node, diff --git a/tests/baselines/reference/objectSpreadNegative.js b/tests/baselines/reference/objectSpreadNegative.js index 4faacd97444..6287f4559a7 100644 --- a/tests/baselines/reference/objectSpreadNegative.js +++ b/tests/baselines/reference/objectSpreadNegative.js @@ -123,7 +123,7 @@ spreadStr.charAt(1); // error, no methods either var spreadFunc = __assign({}, function () { }); spreadFunc(); // error, no call signature // write-only properties get skipped -var setterOnly = __assign({ set b(bad: number) { } }); +var setterOnly = __assign({ set b(bad) { } }); setterOnly.b = 12; // error, 'b' does not exist // methods are skipped because they aren't enumerable var C = (function () {