diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 74ebe61b454ef..732630d7d9f5a 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -2220,7 +2220,7 @@ namespace ts { } return AssignmentDeclarationKind.ObjectDefinePropertyValue; } - if (expr.operatorToken.kind !== SyntaxKind.EqualsToken || !isAccessExpression(expr.left)) { + if (expr.operatorToken.kind !== SyntaxKind.EqualsToken || !isAccessExpression(expr.left) || isVoidZero(getRightMostAssignedExpression(expr))) { return AssignmentDeclarationKind.None; } if (isBindableStaticNameExpression(expr.left.expression, /*excludeThisKeyword*/ true) && getElementOrPropertyAccessName(expr.left) === "prototype" && isObjectLiteralExpression(getInitializerOfBinaryExpression(expr))) { @@ -2230,6 +2230,10 @@ namespace ts { return getAssignmentDeclarationPropertyAccessKind(expr.left); } + function isVoidZero(node: Node) { + return isVoidExpression(node) && isNumericLiteral(node.expression) && node.expression.text === "0"; + } + /** * Does not handle signed numeric names like `a[+0]` - handling those would require handling prefix unary expressions * throughout late binding handling as well, which is awkward (but ultimately probably doable if there is demand) diff --git a/tests/baselines/reference/assignmentToVoidZero1.js b/tests/baselines/reference/assignmentToVoidZero1.js new file mode 100644 index 0000000000000..542c1fdcf1818 --- /dev/null +++ b/tests/baselines/reference/assignmentToVoidZero1.js @@ -0,0 +1,17 @@ +//// [assignmentToVoidZero1.js] +// #38552 +exports.y = exports.x = void 0; +exports.x = 1; +exports.y = 2; + + +//// [assignmentToVoidZero1.js] +// #38552 +exports.y = exports.x = void 0; +exports.x = 1; +exports.y = 2; + + +//// [assignmentToVoidZero1.d.ts] +export var x: number; +export var y: number; diff --git a/tests/baselines/reference/assignmentToVoidZero1.symbols b/tests/baselines/reference/assignmentToVoidZero1.symbols new file mode 100644 index 0000000000000..814c82b35e21c --- /dev/null +++ b/tests/baselines/reference/assignmentToVoidZero1.symbols @@ -0,0 +1,20 @@ +=== tests/cases/conformance/salsa/assignmentToVoidZero1.js === +// #38552 +exports.y = exports.x = void 0; +>exports.y : Symbol(y, Decl(assignmentToVoidZero1.js, 2, 14)) +>exports : Symbol("tests/cases/conformance/salsa/assignmentToVoidZero1", Decl(assignmentToVoidZero1.js, 0, 0)) +>y : Symbol(y, Decl(assignmentToVoidZero1.js, 2, 14)) +>exports.x : Symbol(x, Decl(assignmentToVoidZero1.js, 1, 31)) +>exports : Symbol("tests/cases/conformance/salsa/assignmentToVoidZero1", Decl(assignmentToVoidZero1.js, 0, 0)) +>x : Symbol(x, Decl(assignmentToVoidZero1.js, 1, 31)) + +exports.x = 1; +>exports.x : Symbol(x, Decl(assignmentToVoidZero1.js, 1, 31)) +>exports : Symbol(x, Decl(assignmentToVoidZero1.js, 1, 31)) +>x : Symbol(x, Decl(assignmentToVoidZero1.js, 1, 31)) + +exports.y = 2; +>exports.y : Symbol(y, Decl(assignmentToVoidZero1.js, 2, 14)) +>exports : Symbol(y, Decl(assignmentToVoidZero1.js, 2, 14)) +>y : Symbol(y, Decl(assignmentToVoidZero1.js, 2, 14)) + diff --git a/tests/baselines/reference/assignmentToVoidZero1.types b/tests/baselines/reference/assignmentToVoidZero1.types new file mode 100644 index 0000000000000..810cdff57aa0c --- /dev/null +++ b/tests/baselines/reference/assignmentToVoidZero1.types @@ -0,0 +1,28 @@ +=== tests/cases/conformance/salsa/assignmentToVoidZero1.js === +// #38552 +exports.y = exports.x = void 0; +>exports.y = exports.x = void 0 : undefined +>exports.y : number +>exports : typeof import("tests/cases/conformance/salsa/assignmentToVoidZero1") +>y : number +>exports.x = void 0 : undefined +>exports.x : number +>exports : typeof import("tests/cases/conformance/salsa/assignmentToVoidZero1") +>x : number +>void 0 : undefined +>0 : 0 + +exports.x = 1; +>exports.x = 1 : 1 +>exports.x : number +>exports : typeof import("tests/cases/conformance/salsa/assignmentToVoidZero1") +>x : number +>1 : 1 + +exports.y = 2; +>exports.y = 2 : 2 +>exports.y : number +>exports : typeof import("tests/cases/conformance/salsa/assignmentToVoidZero1") +>y : number +>2 : 2 + diff --git a/tests/baselines/reference/assignmentToVoidZero2.errors.txt b/tests/baselines/reference/assignmentToVoidZero2.errors.txt new file mode 100644 index 0000000000000..b9da759c092cc --- /dev/null +++ b/tests/baselines/reference/assignmentToVoidZero2.errors.txt @@ -0,0 +1,36 @@ +tests/cases/conformance/salsa/assignmentToVoidZero2.js(2,9): error TS2339: Property 'k' does not exist on type 'typeof import("tests/cases/conformance/salsa/assignmentToVoidZero2")'. +tests/cases/conformance/salsa/assignmentToVoidZero2.js(5,3): error TS2339: Property 'y' does not exist on type 'typeof o'. +tests/cases/conformance/salsa/assignmentToVoidZero2.js(6,9): error TS2339: Property 'y' does not exist on type 'typeof o'. +tests/cases/conformance/salsa/assignmentToVoidZero2.js(13,9): error TS2339: Property 'q' does not exist on type 'C'. +tests/cases/conformance/salsa/importer.js(1,13): error TS2305: Module '"./assignmentToVoidZero2"' has no exported member 'k'. + + +==== tests/cases/conformance/salsa/assignmentToVoidZero2.js (4 errors) ==== + exports.j = 1; + exports.k = void 0; + ~ +!!! error TS2339: Property 'k' does not exist on type 'typeof import("tests/cases/conformance/salsa/assignmentToVoidZero2")'. + var o = {} + o.x = 1 + o.y = void 0 + ~ +!!! error TS2339: Property 'y' does not exist on type 'typeof o'. + o.x + o.y + ~ +!!! error TS2339: Property 'y' does not exist on type 'typeof o'. + + function C() { + this.p = 1 + this.q = void 0 + } + var c = new C() + c.p + c.q + ~ +!!! error TS2339: Property 'q' does not exist on type 'C'. + +==== tests/cases/conformance/salsa/importer.js (1 errors) ==== + import { j, k } from './assignmentToVoidZero2' + ~ +!!! error TS2305: Module '"./assignmentToVoidZero2"' has no exported member 'k'. + j + k + \ No newline at end of file diff --git a/tests/baselines/reference/assignmentToVoidZero2.js b/tests/baselines/reference/assignmentToVoidZero2.js new file mode 100644 index 0000000000000..c8b658474d2b8 --- /dev/null +++ b/tests/baselines/reference/assignmentToVoidZero2.js @@ -0,0 +1,46 @@ +//// [tests/cases/conformance/salsa/assignmentToVoidZero2.ts] //// + +//// [assignmentToVoidZero2.js] +exports.j = 1; +exports.k = void 0; +var o = {} +o.x = 1 +o.y = void 0 +o.x + o.y + +function C() { + this.p = 1 + this.q = void 0 +} +var c = new C() +c.p + c.q + +//// [importer.js] +import { j, k } from './assignmentToVoidZero2' +j + k + + +//// [assignmentToVoidZero2.js] +exports.j = 1; +exports.k = void 0; +var o = {}; +o.x = 1; +o.y = void 0; +o.x + o.y; +function C() { + this.p = 1; + this.q = void 0; +} +var c = new C(); +c.p + c.q; +//// [importer.js] +"use strict"; +exports.__esModule = true; +var assignmentToVoidZero2_1 = require("./assignmentToVoidZero2"); +assignmentToVoidZero2_1.j + assignmentToVoidZero2_1.k; + + +//// [assignmentToVoidZero2.d.ts] +export var j: number; +//// [importer.d.ts] +export {}; diff --git a/tests/baselines/reference/assignmentToVoidZero2.symbols b/tests/baselines/reference/assignmentToVoidZero2.symbols new file mode 100644 index 0000000000000..b5a93872fa8e3 --- /dev/null +++ b/tests/baselines/reference/assignmentToVoidZero2.symbols @@ -0,0 +1,53 @@ +=== tests/cases/conformance/salsa/assignmentToVoidZero2.js === +exports.j = 1; +>exports.j : Symbol(j, Decl(assignmentToVoidZero2.js, 0, 0)) +>exports : Symbol(j, Decl(assignmentToVoidZero2.js, 0, 0)) +>j : Symbol(j, Decl(assignmentToVoidZero2.js, 0, 0)) + +exports.k = void 0; +>exports : Symbol("tests/cases/conformance/salsa/assignmentToVoidZero2", Decl(assignmentToVoidZero2.js, 0, 0)) + +var o = {} +>o : Symbol(o, Decl(assignmentToVoidZero2.js, 2, 3), Decl(assignmentToVoidZero2.js, 2, 10)) + +o.x = 1 +>o.x : Symbol(o.x, Decl(assignmentToVoidZero2.js, 2, 10)) +>o : Symbol(o, Decl(assignmentToVoidZero2.js, 2, 3), Decl(assignmentToVoidZero2.js, 2, 10)) +>x : Symbol(o.x, Decl(assignmentToVoidZero2.js, 2, 10)) + +o.y = void 0 +>o : Symbol(o, Decl(assignmentToVoidZero2.js, 2, 3), Decl(assignmentToVoidZero2.js, 2, 10)) + +o.x + o.y +>o.x : Symbol(o.x, Decl(assignmentToVoidZero2.js, 2, 10)) +>o : Symbol(o, Decl(assignmentToVoidZero2.js, 2, 3), Decl(assignmentToVoidZero2.js, 2, 10)) +>x : Symbol(o.x, Decl(assignmentToVoidZero2.js, 2, 10)) +>o : Symbol(o, Decl(assignmentToVoidZero2.js, 2, 3), Decl(assignmentToVoidZero2.js, 2, 10)) + +function C() { +>C : Symbol(C, Decl(assignmentToVoidZero2.js, 5, 9)) + + this.p = 1 +>p : Symbol(C.p, Decl(assignmentToVoidZero2.js, 7, 14)) + + this.q = void 0 +} +var c = new C() +>c : Symbol(c, Decl(assignmentToVoidZero2.js, 11, 3)) +>C : Symbol(C, Decl(assignmentToVoidZero2.js, 5, 9)) + +c.p + c.q +>c.p : Symbol(C.p, Decl(assignmentToVoidZero2.js, 7, 14)) +>c : Symbol(c, Decl(assignmentToVoidZero2.js, 11, 3)) +>p : Symbol(C.p, Decl(assignmentToVoidZero2.js, 7, 14)) +>c : Symbol(c, Decl(assignmentToVoidZero2.js, 11, 3)) + +=== tests/cases/conformance/salsa/importer.js === +import { j, k } from './assignmentToVoidZero2' +>j : Symbol(j, Decl(importer.js, 0, 8)) +>k : Symbol(k, Decl(importer.js, 0, 11)) + +j + k +>j : Symbol(j, Decl(importer.js, 0, 8)) +>k : Symbol(k, Decl(importer.js, 0, 11)) + diff --git a/tests/baselines/reference/assignmentToVoidZero2.types b/tests/baselines/reference/assignmentToVoidZero2.types new file mode 100644 index 0000000000000..0b24811f9579d --- /dev/null +++ b/tests/baselines/reference/assignmentToVoidZero2.types @@ -0,0 +1,86 @@ +=== tests/cases/conformance/salsa/assignmentToVoidZero2.js === +exports.j = 1; +>exports.j = 1 : 1 +>exports.j : number +>exports : typeof import("tests/cases/conformance/salsa/assignmentToVoidZero2") +>j : number +>1 : 1 + +exports.k = void 0; +>exports.k = void 0 : undefined +>exports.k : any +>exports : typeof import("tests/cases/conformance/salsa/assignmentToVoidZero2") +>k : any +>void 0 : undefined +>0 : 0 + +var o = {} +>o : typeof o +>{} : {} + +o.x = 1 +>o.x = 1 : 1 +>o.x : number +>o : typeof o +>x : number +>1 : 1 + +o.y = void 0 +>o.y = void 0 : undefined +>o.y : any +>o : typeof o +>y : any +>void 0 : undefined +>0 : 0 + +o.x + o.y +>o.x + o.y : any +>o.x : number +>o : typeof o +>x : number +>o.y : any +>o : typeof o +>y : any + +function C() { +>C : typeof C + + this.p = 1 +>this.p = 1 : 1 +>this.p : any +>this : any +>p : any +>1 : 1 + + this.q = void 0 +>this.q = void 0 : undefined +>this.q : any +>this : any +>q : any +>void 0 : undefined +>0 : 0 +} +var c = new C() +>c : C +>new C() : C +>C : typeof C + +c.p + c.q +>c.p + c.q : any +>c.p : number +>c : C +>p : number +>c.q : any +>c : C +>q : any + +=== tests/cases/conformance/salsa/importer.js === +import { j, k } from './assignmentToVoidZero2' +>j : number +>k : any + +j + k +>j + k : any +>j : number +>k : any + diff --git a/tests/cases/conformance/salsa/assignmentToVoidZero1.ts b/tests/cases/conformance/salsa/assignmentToVoidZero1.ts new file mode 100644 index 0000000000000..b4911c98d2bfc --- /dev/null +++ b/tests/cases/conformance/salsa/assignmentToVoidZero1.ts @@ -0,0 +1,11 @@ +// @filename: assignmentToVoidZero1.js +// @declaration: true +// @module: commonjs +// @outdir: auss +// @checkJs: true +// @allowJs: true + +// #38552 +exports.y = exports.x = void 0; +exports.x = 1; +exports.y = 2; diff --git a/tests/cases/conformance/salsa/assignmentToVoidZero2.ts b/tests/cases/conformance/salsa/assignmentToVoidZero2.ts new file mode 100644 index 0000000000000..6820076ee5f3b --- /dev/null +++ b/tests/cases/conformance/salsa/assignmentToVoidZero2.ts @@ -0,0 +1,24 @@ +// @filename: assignmentToVoidZero2.js +// @declaration: true +// @module: commonjs +// @outdir: auss +// @checkJs: true +// @allowJs: true +// @noImplicitAny: true +exports.j = 1; +exports.k = void 0; +var o = {} +o.x = 1 +o.y = void 0 +o.x + o.y + +function C() { + this.p = 1 + this.q = void 0 +} +var c = new C() +c.p + c.q + +// @filename: importer.js +import { j, k } from './assignmentToVoidZero2' +j + k