From 125dd57a757612367bcf495ed3070bb932ae75ed Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Wed, 8 Feb 2017 13:28:23 -0800 Subject: [PATCH 1/2] Fix assigned type of assignment nested in literals Fixes #12946 --- src/compiler/checker.ts | 10 +++++- .../reference/assignmentNestedInLiterals.js | 13 +++++++ .../assignmentNestedInLiterals.symbols | 25 +++++++++++++ .../assignmentNestedInLiterals.types | 35 +++++++++++++++++++ .../compiler/assignmentNestedInLiterals.ts | 6 ++++ 5 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/assignmentNestedInLiterals.js create mode 100644 tests/baselines/reference/assignmentNestedInLiterals.symbols create mode 100644 tests/baselines/reference/assignmentNestedInLiterals.types create mode 100644 tests/cases/compiler/assignmentNestedInLiterals.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 4423b574e3..428a4e6eee 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -9469,11 +9469,19 @@ namespace ts { } function getAssignedTypeOfBinaryExpression(node: BinaryExpression): Type { - return node.parent.kind === SyntaxKind.ArrayLiteralExpression || node.parent.kind === SyntaxKind.PropertyAssignment ? + const isDestructuringDefaultAssignment = + node.parent.kind === SyntaxKind.ArrayLiteralExpression && isDestructuringAssignmentTarget(node.parent) || + node.parent.kind === SyntaxKind.PropertyAssignment && isDestructuringAssignmentTarget(node.parent.parent); + return isDestructuringDefaultAssignment ? getTypeWithDefault(getAssignedType(node), node.right) : getTypeOfExpression(node.right); } + function isDestructuringAssignmentTarget(parent: Node) { + return parent.parent.kind === SyntaxKind.BinaryExpression && (parent.parent as BinaryExpression).left === parent || + parent.parent.kind === SyntaxKind.ForOfStatement && (parent.parent as ForOfStatement).initializer === parent; + } + function getAssignedTypeOfArrayLiteralElement(node: ArrayLiteralExpression, element: Expression): Type { return getTypeOfDestructuredArrayElement(getAssignedType(node), indexOf(node.elements, element)); } diff --git a/tests/baselines/reference/assignmentNestedInLiterals.js b/tests/baselines/reference/assignmentNestedInLiterals.js new file mode 100644 index 0000000000..cd4bc6c669 --- /dev/null +++ b/tests/baselines/reference/assignmentNestedInLiterals.js @@ -0,0 +1,13 @@ +//// [assignmentNestedInLiterals.ts] +var target, x, y; +target = [x = 1, y = x]; + +var aegis, a, b; +aegis = { x: a = 1, y: b = a }; + + +//// [assignmentNestedInLiterals.js] +var target, x, y; +target = [x = 1, y = x]; +var aegis, a, b; +aegis = { x: a = 1, y: b = a }; diff --git a/tests/baselines/reference/assignmentNestedInLiterals.symbols b/tests/baselines/reference/assignmentNestedInLiterals.symbols new file mode 100644 index 0000000000..90edd9ed04 --- /dev/null +++ b/tests/baselines/reference/assignmentNestedInLiterals.symbols @@ -0,0 +1,25 @@ +=== tests/cases/compiler/assignmentNestedInLiterals.ts === +var target, x, y; +>target : Symbol(target, Decl(assignmentNestedInLiterals.ts, 0, 3)) +>x : Symbol(x, Decl(assignmentNestedInLiterals.ts, 0, 11)) +>y : Symbol(y, Decl(assignmentNestedInLiterals.ts, 0, 14)) + +target = [x = 1, y = x]; +>target : Symbol(target, Decl(assignmentNestedInLiterals.ts, 0, 3)) +>x : Symbol(x, Decl(assignmentNestedInLiterals.ts, 0, 11)) +>y : Symbol(y, Decl(assignmentNestedInLiterals.ts, 0, 14)) +>x : Symbol(x, Decl(assignmentNestedInLiterals.ts, 0, 11)) + +var aegis, a, b; +>aegis : Symbol(aegis, Decl(assignmentNestedInLiterals.ts, 3, 3)) +>a : Symbol(a, Decl(assignmentNestedInLiterals.ts, 3, 10)) +>b : Symbol(b, Decl(assignmentNestedInLiterals.ts, 3, 13)) + +aegis = { x: a = 1, y: b = a }; +>aegis : Symbol(aegis, Decl(assignmentNestedInLiterals.ts, 3, 3)) +>x : Symbol(x, Decl(assignmentNestedInLiterals.ts, 4, 9)) +>a : Symbol(a, Decl(assignmentNestedInLiterals.ts, 3, 10)) +>y : Symbol(y, Decl(assignmentNestedInLiterals.ts, 4, 19)) +>b : Symbol(b, Decl(assignmentNestedInLiterals.ts, 3, 13)) +>a : Symbol(a, Decl(assignmentNestedInLiterals.ts, 3, 10)) + diff --git a/tests/baselines/reference/assignmentNestedInLiterals.types b/tests/baselines/reference/assignmentNestedInLiterals.types new file mode 100644 index 0000000000..8c4d5aadc7 --- /dev/null +++ b/tests/baselines/reference/assignmentNestedInLiterals.types @@ -0,0 +1,35 @@ +=== tests/cases/compiler/assignmentNestedInLiterals.ts === +var target, x, y; +>target : any +>x : any +>y : any + +target = [x = 1, y = x]; +>target = [x = 1, y = x] : number[] +>target : any +>[x = 1, y = x] : number[] +>x = 1 : 1 +>x : any +>1 : 1 +>y = x : number +>y : any +>x : number + +var aegis, a, b; +>aegis : any +>a : any +>b : any + +aegis = { x: a = 1, y: b = a }; +>aegis = { x: a = 1, y: b = a } : { x: number; y: number; } +>aegis : any +>{ x: a = 1, y: b = a } : { x: number; y: number; } +>x : number +>a = 1 : 1 +>a : any +>1 : 1 +>y : number +>b = a : number +>b : any +>a : number + diff --git a/tests/cases/compiler/assignmentNestedInLiterals.ts b/tests/cases/compiler/assignmentNestedInLiterals.ts new file mode 100644 index 0000000000..5b1f52cb45 --- /dev/null +++ b/tests/cases/compiler/assignmentNestedInLiterals.ts @@ -0,0 +1,6 @@ +// @noImplicitAny: true +var target, x, y; +target = [x = 1, y = x]; + +var aegis, a, b; +aegis = { x: a = 1, y: b = a }; From a46cb033db7ad608c81e2541052cc1e3633ecadc Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Wed, 8 Feb 2017 16:14:36 -0800 Subject: [PATCH 2/2] Add for-of test case --- .../reference/assignmentNestedInLiterals.js | 8 ++++++++ .../reference/assignmentNestedInLiterals.symbols | 12 ++++++++++++ .../reference/assignmentNestedInLiterals.types | 16 ++++++++++++++++ .../cases/compiler/assignmentNestedInLiterals.ts | 4 ++++ 4 files changed, 40 insertions(+) diff --git a/tests/baselines/reference/assignmentNestedInLiterals.js b/tests/baselines/reference/assignmentNestedInLiterals.js index cd4bc6c669..8a04808256 100644 --- a/tests/baselines/reference/assignmentNestedInLiterals.js +++ b/tests/baselines/reference/assignmentNestedInLiterals.js @@ -4,6 +4,10 @@ target = [x = 1, y = x]; var aegis, a, b; aegis = { x: a = 1, y: b = a }; + +var kowloona, c, d; +for (kowloona of [c = 1, d = c]) { +} //// [assignmentNestedInLiterals.js] @@ -11,3 +15,7 @@ var target, x, y; target = [x = 1, y = x]; var aegis, a, b; aegis = { x: a = 1, y: b = a }; +var kowloona, c, d; +for (var _i = 0, _a = [c = 1, d = c]; _i < _a.length; _i++) { + kowloona = _a[_i]; +} diff --git a/tests/baselines/reference/assignmentNestedInLiterals.symbols b/tests/baselines/reference/assignmentNestedInLiterals.symbols index 90edd9ed04..761930ab9c 100644 --- a/tests/baselines/reference/assignmentNestedInLiterals.symbols +++ b/tests/baselines/reference/assignmentNestedInLiterals.symbols @@ -23,3 +23,15 @@ aegis = { x: a = 1, y: b = a }; >b : Symbol(b, Decl(assignmentNestedInLiterals.ts, 3, 13)) >a : Symbol(a, Decl(assignmentNestedInLiterals.ts, 3, 10)) +var kowloona, c, d; +>kowloona : Symbol(kowloona, Decl(assignmentNestedInLiterals.ts, 6, 3)) +>c : Symbol(c, Decl(assignmentNestedInLiterals.ts, 6, 13)) +>d : Symbol(d, Decl(assignmentNestedInLiterals.ts, 6, 16)) + +for (kowloona of [c = 1, d = c]) { +>kowloona : Symbol(kowloona, Decl(assignmentNestedInLiterals.ts, 6, 3)) +>c : Symbol(c, Decl(assignmentNestedInLiterals.ts, 6, 13)) +>d : Symbol(d, Decl(assignmentNestedInLiterals.ts, 6, 16)) +>c : Symbol(c, Decl(assignmentNestedInLiterals.ts, 6, 13)) +} + diff --git a/tests/baselines/reference/assignmentNestedInLiterals.types b/tests/baselines/reference/assignmentNestedInLiterals.types index 8c4d5aadc7..8ab73f8069 100644 --- a/tests/baselines/reference/assignmentNestedInLiterals.types +++ b/tests/baselines/reference/assignmentNestedInLiterals.types @@ -33,3 +33,19 @@ aegis = { x: a = 1, y: b = a }; >b : any >a : number +var kowloona, c, d; +>kowloona : any +>c : any +>d : any + +for (kowloona of [c = 1, d = c]) { +>kowloona : any +>[c = 1, d = c] : number[] +>c = 1 : 1 +>c : any +>1 : 1 +>d = c : number +>d : any +>c : number +} + diff --git a/tests/cases/compiler/assignmentNestedInLiterals.ts b/tests/cases/compiler/assignmentNestedInLiterals.ts index 5b1f52cb45..09d8c94488 100644 --- a/tests/cases/compiler/assignmentNestedInLiterals.ts +++ b/tests/cases/compiler/assignmentNestedInLiterals.ts @@ -4,3 +4,7 @@ target = [x = 1, y = x]; var aegis, a, b; aegis = { x: a = 1, y: b = a }; + +var kowloona, c, d; +for (kowloona of [c = 1, d = c]) { +}