From cabcaaadcbd505f264dc396aad97cee427459171 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 26 Jan 2017 16:04:58 -0800 Subject: [PATCH] Property assignment is not an assignment target In a destructuring assignment, a property assignment is not an assignment target. Its initialiser is. For example: ```ts ({ source: target} = o); ``` Here, `target` is the assignment target. `source` is not. Previously, both were assignment targets. --- src/compiler/utilities.ts | 11 +++++--- ...ertyAssignmentNameIsNotAssignmentTarget.js | 17 +++++++++++++ ...ssignmentNameIsNotAssignmentTarget.symbols | 21 ++++++++++++++++ ...yAssignmentNameIsNotAssignmentTarget.types | 25 +++++++++++++++++++ ...ertyAssignmentNameIsNotAssignmentTarget.ts | 7 ++++++ 5 files changed, 78 insertions(+), 3 deletions(-) create mode 100644 tests/baselines/reference/destructuringPropertyAssignmentNameIsNotAssignmentTarget.js create mode 100644 tests/baselines/reference/destructuringPropertyAssignmentNameIsNotAssignmentTarget.symbols create mode 100644 tests/baselines/reference/destructuringPropertyAssignmentNameIsNotAssignmentTarget.types create mode 100644 tests/cases/compiler/destructuringPropertyAssignmentNameIsNotAssignmentTarget.ts diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 5c63d8bb60c34..17e9fe8e1d7a8 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1662,11 +1662,15 @@ namespace ts { node = parent; break; case SyntaxKind.ShorthandPropertyAssignment: - if ((parent).name !== node) { + if ((parent as ShorthandPropertyAssignment).name !== node) { return AssignmentKind.None; } - // Fall through + node = parent.parent; + break; case SyntaxKind.PropertyAssignment: + if ((parent as ShorthandPropertyAssignment).name === node) { + return AssignmentKind.None; + } node = parent.parent; break; default: @@ -1678,7 +1682,8 @@ namespace ts { // A node is an assignment target if it is on the left hand side of an '=' token, if it is parented by a property // assignment in an object literal that is an assignment target, or if it is parented by an array literal that is - // an assignment target. Examples include 'a = xxx', '{ p: a } = xxx', '[{ p: a}] = xxx'. + // an assignment target. Examples include 'a = xxx', '{ p: a } = xxx', '[{ a }] = xxx'. + // (Note that `p` is not a target in the above examples, only `a`.) export function isAssignmentTarget(node: Node): boolean { return getAssignmentTargetKind(node) !== AssignmentKind.None; } diff --git a/tests/baselines/reference/destructuringPropertyAssignmentNameIsNotAssignmentTarget.js b/tests/baselines/reference/destructuringPropertyAssignmentNameIsNotAssignmentTarget.js new file mode 100644 index 0000000000000..b2ba970ef51b3 --- /dev/null +++ b/tests/baselines/reference/destructuringPropertyAssignmentNameIsNotAssignmentTarget.js @@ -0,0 +1,17 @@ +//// [destructuringPropertyAssignmentNameIsNotAssignmentTarget.ts] +// test for #10668 +function qux(bar: { value: number }) { + let foo: number; + ({ value: foo } = bar); + let x = () => bar; +} + + + +//// [destructuringPropertyAssignmentNameIsNotAssignmentTarget.js] +// test for #10668 +function qux(bar) { + var foo; + (foo = bar.value); + var x = function () { return bar; }; +} diff --git a/tests/baselines/reference/destructuringPropertyAssignmentNameIsNotAssignmentTarget.symbols b/tests/baselines/reference/destructuringPropertyAssignmentNameIsNotAssignmentTarget.symbols new file mode 100644 index 0000000000000..b9ebe219f6533 --- /dev/null +++ b/tests/baselines/reference/destructuringPropertyAssignmentNameIsNotAssignmentTarget.symbols @@ -0,0 +1,21 @@ +=== tests/cases/compiler/destructuringPropertyAssignmentNameIsNotAssignmentTarget.ts === +// test for #10668 +function qux(bar: { value: number }) { +>qux : Symbol(qux, Decl(destructuringPropertyAssignmentNameIsNotAssignmentTarget.ts, 0, 0)) +>bar : Symbol(bar, Decl(destructuringPropertyAssignmentNameIsNotAssignmentTarget.ts, 1, 13)) +>value : Symbol(value, Decl(destructuringPropertyAssignmentNameIsNotAssignmentTarget.ts, 1, 19)) + + let foo: number; +>foo : Symbol(foo, Decl(destructuringPropertyAssignmentNameIsNotAssignmentTarget.ts, 2, 7)) + + ({ value: foo } = bar); +>value : Symbol(value, Decl(destructuringPropertyAssignmentNameIsNotAssignmentTarget.ts, 3, 6)) +>foo : Symbol(foo, Decl(destructuringPropertyAssignmentNameIsNotAssignmentTarget.ts, 2, 7)) +>bar : Symbol(bar, Decl(destructuringPropertyAssignmentNameIsNotAssignmentTarget.ts, 1, 13)) + + let x = () => bar; +>x : Symbol(x, Decl(destructuringPropertyAssignmentNameIsNotAssignmentTarget.ts, 4, 7)) +>bar : Symbol(bar, Decl(destructuringPropertyAssignmentNameIsNotAssignmentTarget.ts, 1, 13)) +} + + diff --git a/tests/baselines/reference/destructuringPropertyAssignmentNameIsNotAssignmentTarget.types b/tests/baselines/reference/destructuringPropertyAssignmentNameIsNotAssignmentTarget.types new file mode 100644 index 0000000000000..e0428fc959f24 --- /dev/null +++ b/tests/baselines/reference/destructuringPropertyAssignmentNameIsNotAssignmentTarget.types @@ -0,0 +1,25 @@ +=== tests/cases/compiler/destructuringPropertyAssignmentNameIsNotAssignmentTarget.ts === +// test for #10668 +function qux(bar: { value: number }) { +>qux : (bar: { value: number; }) => void +>bar : { value: number; } +>value : number + + let foo: number; +>foo : number + + ({ value: foo } = bar); +>({ value: foo } = bar) : { value: number; } +>{ value: foo } = bar : { value: number; } +>{ value: foo } : { value: number; } +>value : number +>foo : number +>bar : { value: number; } + + let x = () => bar; +>x : () => { value: number; } +>() => bar : () => { value: number; } +>bar : { value: number; } +} + + diff --git a/tests/cases/compiler/destructuringPropertyAssignmentNameIsNotAssignmentTarget.ts b/tests/cases/compiler/destructuringPropertyAssignmentNameIsNotAssignmentTarget.ts new file mode 100644 index 0000000000000..c0002f3e80a6d --- /dev/null +++ b/tests/cases/compiler/destructuringPropertyAssignmentNameIsNotAssignmentTarget.ts @@ -0,0 +1,7 @@ +// test for #10668 +function qux(bar: { value: number }) { + let foo: number; + ({ value: foo } = bar); + let x = () => bar; +} +