From 517d6eea28fcb7ce3d0a3e1c7fa73cae4ac64123 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Fri, 10 Jan 2020 10:09:39 -0800 Subject: [PATCH] Get jsdoc host from chained assignment (#36111) * Get jsdoc host from chained assignment getSourceOfAssignment previously only checked one level of binary expression instead of following binary expressions all the way to the right. This meant that binding of `@constructor` would fail in the following example: ```js /** @constructor */ a = b = function () { } ``` * cleanup lint * use existing utility --- src/compiler/utilities.ts | 4 ++-- ...tructorTagOnNestedBinaryExpression.symbols | 14 +++++++++++++ ...nstructorTagOnNestedBinaryExpression.types | 20 +++++++++++++++++++ .../constructorTagOnNestedBinaryExpression.ts | 8 ++++++++ 4 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/constructorTagOnNestedBinaryExpression.symbols create mode 100644 tests/baselines/reference/constructorTagOnNestedBinaryExpression.types create mode 100644 tests/cases/conformance/jsdoc/constructorTagOnNestedBinaryExpression.ts diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 204c8a508fb..76394eeef53 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -2318,9 +2318,9 @@ namespace ts { function getSourceOfAssignment(node: Node): Node | undefined { return isExpressionStatement(node) && - node.expression && isBinaryExpression(node.expression) && + isBinaryExpression(node.expression) && node.expression.operatorToken.kind === SyntaxKind.EqualsToken - ? node.expression.right + ? getRightMostAssignedExpression(node.expression) : undefined; } diff --git a/tests/baselines/reference/constructorTagOnNestedBinaryExpression.symbols b/tests/baselines/reference/constructorTagOnNestedBinaryExpression.symbols new file mode 100644 index 00000000000..669354c9916 --- /dev/null +++ b/tests/baselines/reference/constructorTagOnNestedBinaryExpression.symbols @@ -0,0 +1,14 @@ +=== tests/cases/conformance/jsdoc/constructorTagOnNestedBinaryExpression.js === +// Fixes #35021 +/** @constructor */ +a = b = function c () { +>c : Symbol(c, Decl(constructorTagOnNestedBinaryExpression.js, 2, 7)) + + console.log(this) +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>this : Symbol(c, Decl(constructorTagOnNestedBinaryExpression.js, 2, 7)) + +}; + diff --git a/tests/baselines/reference/constructorTagOnNestedBinaryExpression.types b/tests/baselines/reference/constructorTagOnNestedBinaryExpression.types new file mode 100644 index 00000000000..64659df1d2b --- /dev/null +++ b/tests/baselines/reference/constructorTagOnNestedBinaryExpression.types @@ -0,0 +1,20 @@ +=== tests/cases/conformance/jsdoc/constructorTagOnNestedBinaryExpression.js === +// Fixes #35021 +/** @constructor */ +a = b = function c () { +>a = b = function c () { console.log(this)} : typeof c +>a : error +>b = function c () { console.log(this)} : typeof c +>b : error +>function c () { console.log(this)} : typeof c +>c : typeof c + + console.log(this) +>console.log(this) : void +>console.log : (message?: any, ...optionalParams: any[]) => void +>console : Console +>log : (message?: any, ...optionalParams: any[]) => void +>this : this + +}; + diff --git a/tests/cases/conformance/jsdoc/constructorTagOnNestedBinaryExpression.ts b/tests/cases/conformance/jsdoc/constructorTagOnNestedBinaryExpression.ts new file mode 100644 index 00000000000..956f302ed6f --- /dev/null +++ b/tests/cases/conformance/jsdoc/constructorTagOnNestedBinaryExpression.ts @@ -0,0 +1,8 @@ +// @allowjs: true +// @noemit: true +// @Filename: constructorTagOnNestedBinaryExpression.js +// Fixes #35021 +/** @constructor */ +a = b = function c () { + console.log(this) +};