Skip to content

Commit

Permalink
Merge pull request #41287 from weswigham/bind-exports-assigned-object…
Browse files Browse the repository at this point in the history
…-as-alias

Bind `module.export = {Thing}` with alias symbols
  • Loading branch information
weswigham authored Oct 28, 2020
2 parents bd27bd8 + e96ce39 commit ca8a15d
Show file tree
Hide file tree
Showing 39 changed files with 464 additions and 146 deletions.
9 changes: 9 additions & 0 deletions src/compiler/binder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2834,6 +2834,11 @@ namespace ts {
return;
}

if (isObjectLiteralExpression(assignedExpression) && every(assignedExpression.properties, isShorthandPropertyAssignment)) {
forEach(assignedExpression.properties, bindExportAssignedObjectMemberAlias);
return;
}

// 'module.exports = expr' assignment
const flags = exportAssignmentIsAlias(node)
? SymbolFlags.Alias // An export= with an EntityNameExpression or a ClassExpression exports all meanings of that identifier or class
Expand All @@ -2842,6 +2847,10 @@ namespace ts {
setValueDeclaration(symbol, node);
}

function bindExportAssignedObjectMemberAlias(node: ShorthandPropertyAssignment) {
declareSymbol(file.symbol.exports!, file.symbol, node, SymbolFlags.Alias | SymbolFlags.Assignment, SymbolFlags.None);
}

function bindThisPropertyAssignment(node: BindablePropertyAssignmentExpression | PropertyAccessExpression | LiteralLikeElementAccessExpression) {
Debug.assert(isInJSFile(node));
// private identifiers *must* be declared (even in JS files)
Expand Down
12 changes: 4 additions & 8 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6807,21 +6807,17 @@ namespace ts {
), ModifierFlags.None);
break;
}
// At present, the below case should be entirely unhit, as, generally speaking, the below case is *usually* bound
// such that the `BinaryExpression` is the declaration rather than the specific, nested binding element
// (because we don't seek to emit an alias in these forms yet). As such, the `BinaryExpression` switch case
// will be what actually handles this form. _However_, in anticipation of binding the below with proper
// alias symbols, I'm _pretty comfortable_ including the case here, even though it is not yet live.
// We don't know how to serialize this (nested?) binding element
Debug.failBadSyntaxKind(node.parent?.parent || node, "Unhandled binding element grandparent kind in declaration serialization");
break;
case SyntaxKind.ShorthandPropertyAssignment:
if (node.parent?.parent?.kind === SyntaxKind.BinaryExpression) {
// module.exports = { SomeClass }
serializeExportSpecifier(
unescapeLeadingUnderscores(symbol.escapedName),
targetName
);
break;
}
// We don't know how to serialize this (nested?) binding element
Debug.failBadSyntaxKind(node.parent?.parent || node, "Unhandled binding element grandparent kind in declaration serialization");
break;
case SyntaxKind.VariableDeclaration:
// commonjs require: const x = require('y')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"containerName": "",
"fileName": "/b.js",
"kind": "alias",
"name": "(alias) (property) f: () => void\nimport f",
"name": "(alias) function f(): void\nimport f",
"textSpan": {
"start": 8,
"length": 1
Expand All @@ -36,16 +36,8 @@
"kind": "space"
},
{
"text": "(",
"kind": "punctuation"
},
{
"text": "property",
"kind": "text"
},
{
"text": ")",
"kind": "punctuation"
"text": "function",
"kind": "keyword"
},
{
"text": " ",
Expand All @@ -55,14 +47,6 @@
"text": "f",
"kind": "aliasName"
},
{
"text": ":",
"kind": "punctuation"
},
{
"text": " ",
"kind": "space"
},
{
"text": "(",
"kind": "punctuation"
Expand All @@ -72,11 +56,7 @@
"kind": "punctuation"
},
{
"text": " ",
"kind": "space"
},
{
"text": "=>",
"text": ":",
"kind": "punctuation"
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ module.exports = { Thing }
export class Thing {
}
//// [reexport.d.ts]
export { Thing };
import Thing_1 = require("./thing");
import Thing = Thing_1.Thing;
export { Thing };
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ const Thing = require('./thing').Thing

module.exports = { Thing }
>module.exports : Symbol("tests/cases/conformance/jsdoc/declarations/reexport", Decl(reexport.js, 0, 0))
>module : Symbol(export=, Decl(reexport.js, 1, 38))
>exports : Symbol(export=, Decl(reexport.js, 1, 38))
>module : Symbol(module, Decl(reexport.js, 1, 38))
>exports : Symbol("tests/cases/conformance/jsdoc/declarations/reexport", Decl(reexport.js, 0, 0))
>Thing : Symbol(Thing, Decl(reexport.js, 2, 18))

=== tests/cases/conformance/jsdoc/declarations/thing.js ===
Expand All @@ -20,7 +20,7 @@ class Thing {}

module.exports = { Thing }
>module.exports : Symbol("tests/cases/conformance/jsdoc/declarations/thing", Decl(thing.js, 0, 0))
>module : Symbol(export=, Decl(thing.js, 1, 14))
>exports : Symbol(export=, Decl(thing.js, 1, 14))
>module : Symbol(module, Decl(thing.js, 1, 14))
>exports : Symbol("tests/cases/conformance/jsdoc/declarations/thing", Decl(thing.js, 0, 0))
>Thing : Symbol(Thing, Decl(thing.js, 2, 18))

Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@
const Thing = require('./thing').Thing
>Thing : typeof Thing
>require('./thing').Thing : typeof Thing
>require('./thing') : { Thing: typeof Thing; }
>require('./thing') : typeof import("tests/cases/conformance/jsdoc/declarations/thing")
>require : any
>'./thing' : "./thing"
>Thing : typeof Thing

module.exports = { Thing }
>module.exports = { Thing } : { Thing: typeof Thing; }
>module.exports : { Thing: typeof Thing; }
>module : { "\"tests/cases/conformance/jsdoc/declarations/reexport\"": { Thing: typeof Thing; }; }
>exports : { Thing: typeof Thing; }
>module.exports = { Thing } : typeof import("tests/cases/conformance/jsdoc/declarations/reexport")
>module.exports : typeof import("tests/cases/conformance/jsdoc/declarations/reexport")
>module : { "\"tests/cases/conformance/jsdoc/declarations/reexport\"": typeof import("tests/cases/conformance/jsdoc/declarations/reexport"); }
>exports : typeof import("tests/cases/conformance/jsdoc/declarations/reexport")
>{ Thing } : { Thing: typeof Thing; }
>Thing : typeof Thing

Expand All @@ -26,10 +26,10 @@ class Thing {}
>Thing : Thing

module.exports = { Thing }
>module.exports = { Thing } : { Thing: typeof Thing; }
>module.exports : { Thing: typeof Thing; }
>module : { "\"tests/cases/conformance/jsdoc/declarations/thing\"": { Thing: typeof Thing; }; }
>exports : { Thing: typeof Thing; }
>module.exports = { Thing } : typeof import("tests/cases/conformance/jsdoc/declarations/thing")
>module.exports : typeof import("tests/cases/conformance/jsdoc/declarations/thing")
>module : { "\"tests/cases/conformance/jsdoc/declarations/thing\"": typeof import("tests/cases/conformance/jsdoc/declarations/thing"); }
>exports : typeof import("tests/cases/conformance/jsdoc/declarations/thing")
>{ Thing } : { Thing: typeof Thing; }
>Thing : typeof Thing

Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ function b() {

module.exports = {x, b}
>module.exports : Symbol("tests/cases/conformance/jsdoc/declarations/index1", Decl(index1.js, 0, 0))
>module : Symbol(export=, Decl(index1.js, 12, 1))
>exports : Symbol(export=, Decl(index1.js, 12, 1))
>module : Symbol(module, Decl(index1.js, 12, 1))
>exports : Symbol("tests/cases/conformance/jsdoc/declarations/index1", Decl(index1.js, 0, 0))
>x : Symbol(x, Decl(index1.js, 14, 18))
>b : Symbol(b, Decl(index1.js, 14, 20))

Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ function b() {
}

module.exports = {x, b}
>module.exports = {x, b} : { x: (a: any) => string; b: () => number; }
>module.exports : { x: (a: any) => string; b: () => number; }
>module : { "\"tests/cases/conformance/jsdoc/declarations/index1\"": { x: (a: any) => string; b: () => number; }; }
>exports : { x: (a: any) => string; b: () => number; }
>module.exports = {x, b} : typeof import("tests/cases/conformance/jsdoc/declarations/index1")
>module.exports : typeof import("tests/cases/conformance/jsdoc/declarations/index1")
>module : { "\"tests/cases/conformance/jsdoc/declarations/index1\"": typeof import("tests/cases/conformance/jsdoc/declarations/index1"); }
>exports : typeof import("tests/cases/conformance/jsdoc/declarations/index1")
>{x, b} : { x: (a: any) => string; b: () => number; }
>x : (a: any) => string
>b : () => number
Expand Down
2 changes: 1 addition & 1 deletion tests/baselines/reference/jsDeclarationsExportForms.js
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,8 @@ import * as ns from "./cls";
export { ns as classContainer };
import * as ns from "./cls";
//// [cjs.d.ts]
import ns = require("./cls");
export { ns };
import ns = require("./cls");
//// [cjs2.d.ts]
export = ns;
import ns = require("./cls");
Expand Down
4 changes: 2 additions & 2 deletions tests/baselines/reference/jsDeclarationsExportForms.symbols
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ const ns = require("./cls");

module.exports = { ns };
>module.exports : Symbol("tests/cases/conformance/jsdoc/declarations/cjs", Decl(cjs.js, 0, 0))
>module : Symbol(export=, Decl(cjs.js, 0, 28))
>exports : Symbol(export=, Decl(cjs.js, 0, 28))
>module : Symbol(module, Decl(cjs.js, 0, 28))
>exports : Symbol("tests/cases/conformance/jsdoc/declarations/cjs", Decl(cjs.js, 0, 0))
>ns : Symbol(ns, Decl(cjs.js, 1, 18))

=== tests/cases/conformance/jsdoc/declarations/cjs2.js ===
Expand Down
8 changes: 4 additions & 4 deletions tests/baselines/reference/jsDeclarationsExportForms.types
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@ const ns = require("./cls");
>"./cls" : "./cls"

module.exports = { ns };
>module.exports = { ns } : { ns: typeof ns; }
>module.exports : { ns: typeof ns; }
>module : { "\"tests/cases/conformance/jsdoc/declarations/cjs\"": { ns: typeof ns; }; }
>exports : { ns: typeof ns; }
>module.exports = { ns } : typeof import("tests/cases/conformance/jsdoc/declarations/cjs")
>module.exports : typeof import("tests/cases/conformance/jsdoc/declarations/cjs")
>module : { "\"tests/cases/conformance/jsdoc/declarations/cjs\"": typeof import("tests/cases/conformance/jsdoc/declarations/cjs"); }
>exports : typeof import("tests/cases/conformance/jsdoc/declarations/cjs")
>{ ns } : { ns: typeof ns; }
>ns : typeof ns

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,5 @@ export class FancyError extends Error {
constructor(status: any);
}
//// [index.d.ts]
import errors = require("./errors");
export { errors };
import errors = require("./errors");
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
const errors = require("./errors");
>errors : Symbol(errors, Decl(index.js, 1, 5))
>require : Symbol(require)
>"./errors" : Symbol("tests/cases/conformance/jsdoc/declarations/utils/errors", Decl(errors.js, 0, 0))
>"./errors" : Symbol(errors, Decl(errors.js, 0, 0))

module.exports = {
>module.exports : Symbol("tests/cases/conformance/jsdoc/declarations/utils/index", Decl(index.js, 0, 0))
>module : Symbol(export=, Decl(index.js, 1, 35))
>exports : Symbol(export=, Decl(index.js, 1, 35))
>module : Symbol(module, Decl(index.js, 1, 35))
>exports : Symbol("tests/cases/conformance/jsdoc/declarations/utils/index", Decl(index.js, 0, 0))

errors
>errors : Symbol(errors, Decl(index.js, 3, 18))
Expand All @@ -30,8 +30,8 @@ class FancyError extends Error {

module.exports = {
>module.exports : Symbol("tests/cases/conformance/jsdoc/declarations/utils/errors", Decl(errors.js, 0, 0))
>module : Symbol(export=, Decl(errors.js, 4, 1))
>exports : Symbol(export=, Decl(errors.js, 4, 1))
>module : Symbol(module, Decl(errors.js, 4, 1))
>exports : Symbol("tests/cases/conformance/jsdoc/declarations/utils/errors", Decl(errors.js, 0, 0))

FancyError
>FancyError : Symbol(FancyError, Decl(errors.js, 6, 18))
Expand Down
24 changes: 12 additions & 12 deletions tests/baselines/reference/jsDeclarationsExportedClassAliases.types
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
=== tests/cases/conformance/jsdoc/declarations/utils/index.js ===
// issue arises here on compilation
const errors = require("./errors");
>errors : { FancyError: typeof FancyError; }
>require("./errors") : { FancyError: typeof FancyError; }
>errors : typeof errors
>require("./errors") : typeof errors
>require : any
>"./errors" : "./errors"

module.exports = {
>module.exports = { errors} : { errors: { FancyError: typeof FancyError; }; }
>module.exports : { errors: { FancyError: typeof FancyError; }; }
>module : { "\"tests/cases/conformance/jsdoc/declarations/utils/index\"": { errors: { FancyError: typeof FancyError; }; }; }
>exports : { errors: { FancyError: typeof FancyError; }; }
>{ errors} : { errors: { FancyError: typeof FancyError; }; }
>module.exports = { errors} : typeof import("tests/cases/conformance/jsdoc/declarations/utils/index")
>module.exports : typeof import("tests/cases/conformance/jsdoc/declarations/utils/index")
>module : { "\"tests/cases/conformance/jsdoc/declarations/utils/index\"": typeof import("tests/cases/conformance/jsdoc/declarations/utils/index"); }
>exports : typeof import("tests/cases/conformance/jsdoc/declarations/utils/index")
>{ errors} : { errors: typeof errors; }

errors
>errors : { FancyError: typeof FancyError; }
>errors : typeof errors

};
=== tests/cases/conformance/jsdoc/declarations/utils/errors.js ===
Expand All @@ -34,10 +34,10 @@ class FancyError extends Error {
}

module.exports = {
>module.exports = { FancyError} : { FancyError: typeof FancyError; }
>module.exports : { FancyError: typeof FancyError; }
>module : { "\"tests/cases/conformance/jsdoc/declarations/utils/errors\"": { FancyError: typeof FancyError; }; }
>exports : { FancyError: typeof FancyError; }
>module.exports = { FancyError} : typeof import("tests/cases/conformance/jsdoc/declarations/utils/errors")
>module.exports : typeof import("tests/cases/conformance/jsdoc/declarations/utils/errors")
>module : { "\"tests/cases/conformance/jsdoc/declarations/utils/errors\"": typeof import("tests/cases/conformance/jsdoc/declarations/utils/errors"); }
>exports : typeof import("tests/cases/conformance/jsdoc/declarations/utils/errors")
>{ FancyError} : { FancyError: typeof FancyError; }

FancyError
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ function testFn(input) {

module.exports = {testFn, testFnTypes};
>module.exports : Symbol("tests/cases/conformance/jsdoc/declarations/file2", Decl(file2.js, 0, 0))
>module : Symbol(export=, Decl(file2.js, 25, 1))
>exports : Symbol(export=, Decl(file2.js, 25, 1))
>module : Symbol(module, Decl(file2.js, 25, 1))
>exports : Symbol("tests/cases/conformance/jsdoc/declarations/file2", Decl(file2.js, 0, 0))
>testFn : Symbol(testFn, Decl(file2.js, 27, 18))
>testFnTypes : Symbol(testFnTypes, Decl(file2.js, 27, 25))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,10 @@ function testFn(input) {
}

module.exports = {testFn, testFnTypes};
>module.exports = {testFn, testFnTypes} : { testFn: (input: testFnTypes.input) => number; testFnTypes: { [x: string]: any; }; }
>module.exports : { testFn: (input: testFnTypes.input) => number; testFnTypes: { [x: string]: any; }; }
>module : { "\"tests/cases/conformance/jsdoc/declarations/file2\"": { testFn: (input: testFnTypes.input) => number; testFnTypes: { [x: string]: any; }; }; }
>exports : { testFn: (input: testFnTypes.input) => number; testFnTypes: { [x: string]: any; }; }
>module.exports = {testFn, testFnTypes} : typeof import("tests/cases/conformance/jsdoc/declarations/file2")
>module.exports : typeof import("tests/cases/conformance/jsdoc/declarations/file2")
>module : { "\"tests/cases/conformance/jsdoc/declarations/file2\"": typeof import("tests/cases/conformance/jsdoc/declarations/file2"); }
>exports : typeof import("tests/cases/conformance/jsdoc/declarations/file2")
>{testFn, testFnTypes} : { testFn: (input: testFnTypes.input) => number; testFnTypes: { [x: string]: any; }; }
>testFn : (input: testFnTypes.input) => number
>testFnTypes : { [x: string]: any; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ const { SomeClass, SomeClass: Another } = require('./lib');

module.exports = {
>module.exports : Symbol("tests/cases/conformance/jsdoc/declarations/main", Decl(main.js, 0, 0))
>module : Symbol(export=, Decl(main.js, 0, 59))
>exports : Symbol(export=, Decl(main.js, 0, 59))
>module : Symbol(module, Decl(main.js, 0, 59))
>exports : Symbol("tests/cases/conformance/jsdoc/declarations/main", Decl(main.js, 0, 0))

SomeClass,
>SomeClass : Symbol(SomeClass, Decl(main.js, 2, 18))
Expand Down Expand Up @@ -42,8 +42,8 @@ class SomeClass {

module.exports = {
>module.exports : Symbol("tests/cases/conformance/jsdoc/declarations/lib", Decl(lib.js, 0, 0))
>module : Symbol(export=, Decl(lib.js, 11, 1))
>exports : Symbol(export=, Decl(lib.js, 11, 1))
>module : Symbol(module, Decl(lib.js, 11, 1))
>exports : Symbol("tests/cases/conformance/jsdoc/declarations/lib", Decl(lib.js, 0, 0))

bar,
>bar : Symbol(bar, Decl(lib.js, 13, 18))
Expand Down
18 changes: 9 additions & 9 deletions tests/baselines/reference/jsDeclarationsReexportedCjsAlias.types
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ const { SomeClass, SomeClass: Another } = require('./lib');
>SomeClass : typeof SomeClass
>SomeClass : any
>Another : typeof SomeClass
>require('./lib') : { bar: (a: string) => string; SomeClass: typeof SomeClass; }
>require('./lib') : typeof import("tests/cases/conformance/jsdoc/declarations/lib")
>require : any
>'./lib' : "./lib"

module.exports = {
>module.exports = { SomeClass, Another} : { SomeClass: typeof SomeClass; Another: typeof SomeClass; }
>module.exports : { SomeClass: typeof SomeClass; Another: typeof SomeClass; }
>module : { "\"tests/cases/conformance/jsdoc/declarations/main\"": { SomeClass: typeof SomeClass; Another: typeof SomeClass; }; }
>exports : { SomeClass: typeof SomeClass; Another: typeof SomeClass; }
>module.exports = { SomeClass, Another} : typeof import("tests/cases/conformance/jsdoc/declarations/main")
>module.exports : typeof import("tests/cases/conformance/jsdoc/declarations/main")
>module : { "\"tests/cases/conformance/jsdoc/declarations/main\"": typeof import("tests/cases/conformance/jsdoc/declarations/main"); }
>exports : typeof import("tests/cases/conformance/jsdoc/declarations/main")
>{ SomeClass, Another} : { SomeClass: typeof SomeClass; Another: typeof SomeClass; }

SomeClass,
Expand Down Expand Up @@ -46,10 +46,10 @@ class SomeClass {
}

module.exports = {
>module.exports = { bar, SomeClass} : { bar: (a: string) => string; SomeClass: typeof SomeClass; }
>module.exports : { bar: (a: string) => string; SomeClass: typeof SomeClass; }
>module : { "\"tests/cases/conformance/jsdoc/declarations/lib\"": { bar: (a: string) => string; SomeClass: typeof SomeClass; }; }
>exports : { bar: (a: string) => string; SomeClass: typeof SomeClass; }
>module.exports = { bar, SomeClass} : typeof import("tests/cases/conformance/jsdoc/declarations/lib")
>module.exports : typeof import("tests/cases/conformance/jsdoc/declarations/lib")
>module : { "\"tests/cases/conformance/jsdoc/declarations/lib\"": typeof import("tests/cases/conformance/jsdoc/declarations/lib"); }
>exports : typeof import("tests/cases/conformance/jsdoc/declarations/lib")
>{ bar, SomeClass} : { bar: (a: string) => string; SomeClass: typeof SomeClass; }

bar,
Expand Down
Loading

0 comments on commit ca8a15d

Please sign in to comment.