From 339e1320c4a2523c8642d286421e4635605145f1 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Wed, 4 Sep 2019 10:19:18 -0700 Subject: [PATCH] Bind typedef/enum on all assignment decl kinds This fixes a crash on exports, but the code now handles all kinds returned from getAssignmentDeclarationPropertyAccessKind. --- src/compiler/binder.ts | 18 +++++++++++++++++- .../reference/enumTagOnExports.symbols | 15 +++++++++++++++ .../reference/enumTagOnExports.types | 19 +++++++++++++++++++ .../reference/enumTagOnExports2.symbols | 7 +++++++ .../reference/enumTagOnExports2.types | 9 +++++++++ .../conformance/jsdoc/enumTagOnExports.ts | 10 ++++++++++ .../conformance/jsdoc/enumTagOnExports2.ts | 7 +++++++ 7 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/enumTagOnExports.symbols create mode 100644 tests/baselines/reference/enumTagOnExports.types create mode 100644 tests/baselines/reference/enumTagOnExports2.symbols create mode 100644 tests/baselines/reference/enumTagOnExports2.types create mode 100644 tests/cases/conformance/jsdoc/enumTagOnExports.ts create mode 100644 tests/cases/conformance/jsdoc/enumTagOnExports2.ts diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 2b032f456f34a..acc9db3e629f8 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1827,7 +1827,23 @@ namespace ts { bindPotentiallyMissingNamespaces(file.symbol, declName.parent, isTopLevel, !!findAncestor(declName, d => isPropertyAccessExpression(d) && d.name.escapedText === "prototype"), /*containerIsClass*/ false); const oldContainer = container; - container = isPropertyAccessExpression(declName.parent.expression) ? declName.parent.expression.name : declName.parent.expression; + switch (getAssignmentDeclarationPropertyAccessKind(declName.parent)) { + case AssignmentDeclarationKind.ExportsProperty: + case AssignmentDeclarationKind.ModuleExports: + container = file; + break; + case AssignmentDeclarationKind.ThisProperty: + container = declName.parent.expression; + break; + case AssignmentDeclarationKind.PrototypeProperty: + container = (declName.parent.expression as PropertyAccessExpression).name; + break; + case AssignmentDeclarationKind.Property: + container = isPropertyAccessExpression(declName.parent.expression) ? declName.parent.expression.name : declName.parent.expression; + break; + case AssignmentDeclarationKind.None: + return Debug.fail("Shouldn't have detected typedef or enum on non-assignment declaration"); + } declareModuleMember(typeAlias, SymbolFlags.TypeAlias, SymbolFlags.TypeAliasExcludes); container = oldContainer; } diff --git a/tests/baselines/reference/enumTagOnExports.symbols b/tests/baselines/reference/enumTagOnExports.symbols new file mode 100644 index 0000000000000..89257c00d49e0 --- /dev/null +++ b/tests/baselines/reference/enumTagOnExports.symbols @@ -0,0 +1,15 @@ +=== tests/cases/conformance/jsdoc/enumTagOnExports.js === +/** @enum {number} */ +exports.a = {}; +>exports.a : Symbol(a, Decl(enumTagOnExports.js, 0, 0), Decl(enumTagOnExports.js, 1, 8), Decl(enumTagOnExports.js, 0, 4)) +>exports : Symbol(a, Decl(enumTagOnExports.js, 0, 0), Decl(enumTagOnExports.js, 1, 8), Decl(enumTagOnExports.js, 0, 4)) +>a : Symbol(a, Decl(enumTagOnExports.js, 0, 0), Decl(enumTagOnExports.js, 1, 8), Decl(enumTagOnExports.js, 0, 4)) + +/** @enum {string} */ +module.exports.b = {}; +>module.exports.b : Symbol(b, Decl(enumTagOnExports.js, 1, 15), Decl(enumTagOnExports.js, 4, 15), Decl(enumTagOnExports.js, 3, 4)) +>module.exports : Symbol(b, Decl(enumTagOnExports.js, 1, 15), Decl(enumTagOnExports.js, 4, 15), Decl(enumTagOnExports.js, 3, 4)) +>module : Symbol(module, Decl(enumTagOnExports.js, 1, 15)) +>exports : Symbol("tests/cases/conformance/jsdoc/enumTagOnExports", Decl(enumTagOnExports.js, 0, 0)) +>b : Symbol(b, Decl(enumTagOnExports.js, 1, 15), Decl(enumTagOnExports.js, 4, 15), Decl(enumTagOnExports.js, 3, 4)) + diff --git a/tests/baselines/reference/enumTagOnExports.types b/tests/baselines/reference/enumTagOnExports.types new file mode 100644 index 0000000000000..853e5ec090474 --- /dev/null +++ b/tests/baselines/reference/enumTagOnExports.types @@ -0,0 +1,19 @@ +=== tests/cases/conformance/jsdoc/enumTagOnExports.js === +/** @enum {number} */ +exports.a = {}; +>exports.a = {} : {} +>exports.a : typeof a +>exports : typeof import("tests/cases/conformance/jsdoc/enumTagOnExports") +>a : typeof a +>{} : {} + +/** @enum {string} */ +module.exports.b = {}; +>module.exports.b = {} : {} +>module.exports.b : typeof b +>module.exports : typeof import("tests/cases/conformance/jsdoc/enumTagOnExports") +>module : { "tests/cases/conformance/jsdoc/enumTagOnExports": typeof import("tests/cases/conformance/jsdoc/enumTagOnExports"); } +>exports : typeof import("tests/cases/conformance/jsdoc/enumTagOnExports") +>b : typeof b +>{} : {} + diff --git a/tests/baselines/reference/enumTagOnExports2.symbols b/tests/baselines/reference/enumTagOnExports2.symbols new file mode 100644 index 0000000000000..9bca24fe024a0 --- /dev/null +++ b/tests/baselines/reference/enumTagOnExports2.symbols @@ -0,0 +1,7 @@ +=== tests/cases/conformance/jsdoc/enumTagOnExports.js === +/** @enum {string} */ +module.exports = {}; +>module.exports : Symbol("tests/cases/conformance/jsdoc/enumTagOnExports", Decl(enumTagOnExports.js, 0, 0)) +>module : Symbol(module, Decl(enumTagOnExports.js, 0, 0)) +>exports : Symbol("tests/cases/conformance/jsdoc/enumTagOnExports", Decl(enumTagOnExports.js, 0, 0)) + diff --git a/tests/baselines/reference/enumTagOnExports2.types b/tests/baselines/reference/enumTagOnExports2.types new file mode 100644 index 0000000000000..9177307dde776 --- /dev/null +++ b/tests/baselines/reference/enumTagOnExports2.types @@ -0,0 +1,9 @@ +=== tests/cases/conformance/jsdoc/enumTagOnExports.js === +/** @enum {string} */ +module.exports = {}; +>module.exports = {} : typeof import("tests/cases/conformance/jsdoc/enumTagOnExports") +>module.exports : typeof import("tests/cases/conformance/jsdoc/enumTagOnExports") +>module : { "tests/cases/conformance/jsdoc/enumTagOnExports": typeof import("tests/cases/conformance/jsdoc/enumTagOnExports"); } +>exports : typeof import("tests/cases/conformance/jsdoc/enumTagOnExports") +>{} : {} + diff --git a/tests/cases/conformance/jsdoc/enumTagOnExports.ts b/tests/cases/conformance/jsdoc/enumTagOnExports.ts new file mode 100644 index 0000000000000..ce8bd0b1237d3 --- /dev/null +++ b/tests/cases/conformance/jsdoc/enumTagOnExports.ts @@ -0,0 +1,10 @@ +// @filename: enumTagOnExports.js +// @allowjs: true +// @checkjs: true +// @noemit: true + +/** @enum {number} */ +exports.a = {}; + +/** @enum {string} */ +module.exports.b = {}; diff --git a/tests/cases/conformance/jsdoc/enumTagOnExports2.ts b/tests/cases/conformance/jsdoc/enumTagOnExports2.ts new file mode 100644 index 0000000000000..3a4633138375d --- /dev/null +++ b/tests/cases/conformance/jsdoc/enumTagOnExports2.ts @@ -0,0 +1,7 @@ +// @filename: enumTagOnExports.js +// @allowjs: true +// @checkjs: true +// @noemit: true + +/** @enum {string} */ +module.exports = {};