Merge pull request #14172 from Microsoft/moduleExportsAlias

Fix #14171: Recognize property assignements to `module.export` aliases as exports
This commit is contained in:
Mohamed Hegazy 2017-03-07 11:13:19 -08:00 committed by GitHub
commit 89974bdaaf
6 changed files with 770 additions and 11 deletions

View File

@ -2289,7 +2289,42 @@ namespace ts {
declareSymbol(file.symbol.exports, file.symbol, <PropertyAccessExpression>node.left, SymbolFlags.Property | SymbolFlags.Export, SymbolFlags.None);
}
function isExportsOrModuleExportsOrAlias(node: Node): boolean {
return isExportsIdentifier(node) ||
isModuleExportsPropertyAccessExpression(node) ||
isNameOfExportsOrModuleExportsAliasDeclaration(node);
}
function isNameOfExportsOrModuleExportsAliasDeclaration(node: Node) {
if (node.kind === SyntaxKind.Identifier) {
const symbol = container.locals.get((<Identifier>node).text);
if (symbol && symbol.valueDeclaration && symbol.valueDeclaration.kind === SyntaxKind.VariableDeclaration) {
const declaration = symbol.valueDeclaration as VariableDeclaration;
if (declaration.initializer) {
return isExportsOrModuleExportsOrAliasOrAssignemnt(declaration.initializer);
}
}
}
return false;
}
function isExportsOrModuleExportsOrAliasOrAssignemnt(node: Node): boolean {
return isExportsOrModuleExportsOrAlias(node) ||
(isAssignmentExpression(node, /*excludeCompoundAssignements*/ true) && (isExportsOrModuleExportsOrAliasOrAssignemnt(node.left) || isExportsOrModuleExportsOrAliasOrAssignemnt(node.right)));
}
function bindModuleExportsAssignment(node: BinaryExpression) {
// A common practice in node modules is to set 'export = module.exports = {}', this ensures that 'exports'
// is still pointing to 'module.exports'.
// We do not want to consider this as 'export=' since a module can have only one of these.
// Similarlly we do not want to treat 'module.exports = exports' as an 'export='.
const assignedExpression = getRightMostAssignedExpression(node.right);
if (isEmptyObjectLiteral(assignedExpression) || isExportsOrModuleExportsOrAlias(assignedExpression)) {
// Mark it as a module in case there are no other exports in the file
setCommonJsModuleIndicator(node);
return;
}
// 'module.exports = expr' assignment
setCommonJsModuleIndicator(node);
declareSymbol(file.symbol.exports, file.symbol, node, SymbolFlags.Property | SymbolFlags.Export | SymbolFlags.ValueModule, SymbolFlags.None);
@ -2351,11 +2386,20 @@ namespace ts {
leftSideOfAssignment.parent = node;
target.parent = leftSideOfAssignment;
bindPropertyAssignment(target.text, leftSideOfAssignment, /*isPrototypeProperty*/ false);
if (isNameOfExportsOrModuleExportsAliasDeclaration(target)) {
// This can be an alias for the 'exports' or 'module.exports' names, e.g.
// var util = module.exports;
// util.property = function ...
bindExportsPropertyAssignment(node);
}
else {
bindPropertyAssignment(target.text, leftSideOfAssignment, /*isPrototypeProperty*/ false);
}
}
function bindPropertyAssignment(functionName: string, propertyAccessExpression: PropertyAccessExpression, isPrototypeProperty: boolean) {
let targetSymbol = container.locals.get(functionName);
if (targetSymbol && isDeclarationOfFunctionOrClassExpression(targetSymbol)) {
targetSymbol = (targetSymbol.valueDeclaration as VariableDeclaration).initializer.symbol;
}

View File

@ -43,7 +43,7 @@ namespace ts {
let value: Expression;
if (isDestructuringAssignment(node)) {
value = node.right;
while (isEmptyObjectLiteralOrArrayLiteral(node.left)) {
while (isEmptyArrayLiteral(node.left) || isEmptyObjectLiteral(node.left)) {
if (isDestructuringAssignment(value)) {
location = node = value;
value = node.right;

View File

@ -1425,6 +1425,21 @@ namespace ts {
return false;
}
export function getRightMostAssignedExpression(node: Node) {
while (isAssignmentExpression(node, /*excludeCompoundAssignements*/ true)) {
node = node.right;
}
return node;
}
export function isExportsIdentifier(node: Node) {
return isIdentifier(node) && node.text === "exports";
}
export function isModuleExportsPropertyAccessExpression(node: Node) {
return isPropertyAccessExpression(node) && isIdentifier(node.expression) && node.expression.text === "module" && node.name.text === "exports";
}
/// Given a BinaryExpression, returns SpecialPropertyAssignmentKind for the various kinds of property
/// assignments we treat as special in the binder
export function getSpecialPropertyAssignmentKind(expression: Node): SpecialPropertyAssignmentKind {
@ -3148,15 +3163,14 @@ namespace ts {
(node.parent.kind === SyntaxKind.PropertyAccessExpression && (<PropertyAccessExpression>node.parent).name === node);
}
export function isEmptyObjectLiteralOrArrayLiteral(expression: Node): boolean {
const kind = expression.kind;
if (kind === SyntaxKind.ObjectLiteralExpression) {
return (<ObjectLiteralExpression>expression).properties.length === 0;
}
if (kind === SyntaxKind.ArrayLiteralExpression) {
return (<ArrayLiteralExpression>expression).elements.length === 0;
}
return false;
export function isEmptyObjectLiteral(expression: Node): boolean {
return expression.kind === SyntaxKind.ObjectLiteralExpression &&
(<ObjectLiteralExpression>expression).properties.length === 0;
}
export function isEmptyArrayLiteral(expression: Node): boolean {
return expression.kind === SyntaxKind.ArrayLiteralExpression &&
(<ArrayLiteralExpression>expression).elements.length === 0;
}
export function getLocalSymbolForExportDefault(symbol: Symbol) {

View File

@ -0,0 +1,227 @@
=== tests/cases/conformance/salsa/a.ts ===
import b = require("./b.js");
>b : Symbol(b, Decl(a.ts, 0, 0))
b.func1;
>b.func1 : Symbol(b.func1, Decl(b.js, 0, 27))
>b : Symbol(b, Decl(a.ts, 0, 0))
>func1 : Symbol(b.func1, Decl(b.js, 0, 27))
b.func2;
>b.func2 : Symbol(b.func2, Decl(b.js, 1, 37))
>b : Symbol(b, Decl(a.ts, 0, 0))
>func2 : Symbol(b.func2, Decl(b.js, 1, 37))
b.func3;
>b.func3 : Symbol(b.func3, Decl(b.js, 4, 40))
>b : Symbol(b, Decl(a.ts, 0, 0))
>func3 : Symbol(b.func3, Decl(b.js, 4, 40))
b.func4;
>b.func4 : Symbol(b.func4, Decl(b.js, 5, 43))
>b : Symbol(b, Decl(a.ts, 0, 0))
>func4 : Symbol(b.func4, Decl(b.js, 5, 43))
b.func5;
>b.func5 : Symbol(b.func5, Decl(b.js, 8, 57))
>b : Symbol(b, Decl(a.ts, 0, 0))
>func5 : Symbol(b.func5, Decl(b.js, 8, 57))
b.func6;
>b.func6 : Symbol(b.func6, Decl(b.js, 11, 57))
>b : Symbol(b, Decl(a.ts, 0, 0))
>func6 : Symbol(b.func6, Decl(b.js, 11, 57))
b.func7;
>b.func7 : Symbol(b.func7, Decl(b.js, 15, 60))
>b : Symbol(b, Decl(a.ts, 0, 0))
>func7 : Symbol(b.func7, Decl(b.js, 15, 60))
b.func8;
>b.func8 : Symbol(b.func8, Decl(b.js, 18, 67))
>b : Symbol(b, Decl(a.ts, 0, 0))
>func8 : Symbol(b.func8, Decl(b.js, 18, 67))
b.func9;
>b.func9 : Symbol(b.func9, Decl(b.js, 21, 62))
>b : Symbol(b, Decl(a.ts, 0, 0))
>func9 : Symbol(b.func9, Decl(b.js, 21, 62))
b.func10;
>b.func10 : Symbol(b.func10, Decl(b.js, 24, 62))
>b : Symbol(b, Decl(a.ts, 0, 0))
>func10 : Symbol(b.func10, Decl(b.js, 24, 62))
b.func11;
>b.func11 : Symbol(b.func11, Decl(b.js, 27, 50), Decl(b.js, 31, 50))
>b : Symbol(b, Decl(a.ts, 0, 0))
>func11 : Symbol(b.func11, Decl(b.js, 27, 50), Decl(b.js, 31, 50))
b.func12;
>b.func12 : Symbol(b.func12, Decl(b.js, 28, 33), Decl(b.js, 32, 33))
>b : Symbol(b, Decl(a.ts, 0, 0))
>func12 : Symbol(b.func12, Decl(b.js, 28, 33), Decl(b.js, 32, 33))
b.func13;
>b.func13 : Symbol(b.func13, Decl(b.js, 35, 30))
>b : Symbol(b, Decl(a.ts, 0, 0))
>func13 : Symbol(b.func13, Decl(b.js, 35, 30))
b.func14;
>b.func14 : Symbol(b.func14, Decl(b.js, 36, 33))
>b : Symbol(b, Decl(a.ts, 0, 0))
>func14 : Symbol(b.func14, Decl(b.js, 36, 33))
b.func15;
>b.func15 : Symbol(b.func15, Decl(b.js, 39, 30))
>b : Symbol(b, Decl(a.ts, 0, 0))
>func15 : Symbol(b.func15, Decl(b.js, 39, 30))
b.func16;
>b.func16 : Symbol(b.func16, Decl(b.js, 40, 33))
>b : Symbol(b, Decl(a.ts, 0, 0))
>func16 : Symbol(b.func16, Decl(b.js, 40, 33))
b.func17;
>b.func17 : Symbol(b.func17, Decl(b.js, 43, 30))
>b : Symbol(b, Decl(a.ts, 0, 0))
>func17 : Symbol(b.func17, Decl(b.js, 43, 30))
b.func18;
>b.func18 : Symbol(b.func18, Decl(b.js, 44, 33))
>b : Symbol(b, Decl(a.ts, 0, 0))
>func18 : Symbol(b.func18, Decl(b.js, 44, 33))
b.func19;
>b.func19 : Symbol(b.func19, Decl(b.js, 47, 20))
>b : Symbol(b, Decl(a.ts, 0, 0))
>func19 : Symbol(b.func19, Decl(b.js, 47, 20))
b.func20;
>b.func20 : Symbol(b.func20, Decl(b.js, 48, 33))
>b : Symbol(b, Decl(a.ts, 0, 0))
>func20 : Symbol(b.func20, Decl(b.js, 48, 33))
=== tests/cases/conformance/salsa/b.js ===
var exportsAlias = exports;
>exportsAlias : Symbol(exportsAlias, Decl(b.js, 0, 3))
exportsAlias.func1 = function () { };
>exportsAlias : Symbol(exportsAlias, Decl(b.js, 0, 3))
exports.func2 = function () { };
>exports : Symbol(func2, Decl(b.js, 1, 37))
>func2 : Symbol(func2, Decl(b.js, 1, 37))
var moduleExportsAlias = module.exports;
>moduleExportsAlias : Symbol(moduleExportsAlias, Decl(b.js, 4, 3))
moduleExportsAlias.func3 = function () { };
>moduleExportsAlias : Symbol(moduleExportsAlias, Decl(b.js, 4, 3))
module.exports.func4 = function () { };
>module.exports : Symbol(func4, Decl(b.js, 5, 43))
>func4 : Symbol(func4, Decl(b.js, 5, 43))
var multipleDeclarationAlias1 = exports = module.exports;
>multipleDeclarationAlias1 : Symbol(multipleDeclarationAlias1, Decl(b.js, 8, 3))
multipleDeclarationAlias1.func5 = function () { };
>multipleDeclarationAlias1 : Symbol(multipleDeclarationAlias1, Decl(b.js, 8, 3))
var multipleDeclarationAlias2 = module.exports = exports;
>multipleDeclarationAlias2 : Symbol(multipleDeclarationAlias2, Decl(b.js, 11, 3))
multipleDeclarationAlias2.func6 = function () { };
>multipleDeclarationAlias2 : Symbol(multipleDeclarationAlias2, Decl(b.js, 11, 3))
var someOtherVariable;
>someOtherVariable : Symbol(someOtherVariable, Decl(b.js, 14, 3))
var multipleDeclarationAlias3 = someOtherVariable = exports;
>multipleDeclarationAlias3 : Symbol(multipleDeclarationAlias3, Decl(b.js, 15, 3))
>someOtherVariable : Symbol(someOtherVariable, Decl(b.js, 14, 3))
multipleDeclarationAlias3.func7 = function () { };
>multipleDeclarationAlias3 : Symbol(multipleDeclarationAlias3, Decl(b.js, 15, 3))
var multipleDeclarationAlias4 = someOtherVariable = module.exports;
>multipleDeclarationAlias4 : Symbol(multipleDeclarationAlias4, Decl(b.js, 18, 3))
>someOtherVariable : Symbol(someOtherVariable, Decl(b.js, 14, 3))
multipleDeclarationAlias4.func8 = function () { };
>multipleDeclarationAlias4 : Symbol(multipleDeclarationAlias4, Decl(b.js, 18, 3))
var multipleDeclarationAlias5 = module.exports = exports = {};
>multipleDeclarationAlias5 : Symbol(multipleDeclarationAlias5, Decl(b.js, 21, 3))
multipleDeclarationAlias5.func9 = function () { };
>multipleDeclarationAlias5 : Symbol(multipleDeclarationAlias5, Decl(b.js, 21, 3))
var multipleDeclarationAlias6 = exports = module.exports = {};
>multipleDeclarationAlias6 : Symbol(multipleDeclarationAlias6, Decl(b.js, 24, 3))
multipleDeclarationAlias6.func10 = function () { };
>multipleDeclarationAlias6 : Symbol(multipleDeclarationAlias6, Decl(b.js, 24, 3))
exports = module.exports = someOtherVariable = {};
>someOtherVariable : Symbol(someOtherVariable, Decl(b.js, 14, 3))
exports.func11 = function () { };
>exports : Symbol(func11, Decl(b.js, 27, 50), Decl(b.js, 31, 50))
>func11 : Symbol(func11, Decl(b.js, 27, 50), Decl(b.js, 31, 50))
module.exports.func12 = function () { };
>module.exports : Symbol(func12, Decl(b.js, 28, 33), Decl(b.js, 32, 33))
>func12 : Symbol(func12, Decl(b.js, 28, 33), Decl(b.js, 32, 33))
exports = module.exports = someOtherVariable = {};
>someOtherVariable : Symbol(someOtherVariable, Decl(b.js, 14, 3))
exports.func11 = function () { };
>exports : Symbol(func11, Decl(b.js, 27, 50), Decl(b.js, 31, 50))
>func11 : Symbol(func11, Decl(b.js, 27, 50), Decl(b.js, 31, 50))
module.exports.func12 = function () { };
>module.exports : Symbol(func12, Decl(b.js, 28, 33), Decl(b.js, 32, 33))
>func12 : Symbol(func12, Decl(b.js, 28, 33), Decl(b.js, 32, 33))
exports = module.exports = {};
exports.func13 = function () { };
>exports : Symbol(func13, Decl(b.js, 35, 30))
>func13 : Symbol(func13, Decl(b.js, 35, 30))
module.exports.func14 = function () { };
>module.exports : Symbol(func14, Decl(b.js, 36, 33))
>func14 : Symbol(func14, Decl(b.js, 36, 33))
exports = module.exports = {};
exports.func15 = function () { };
>exports : Symbol(func15, Decl(b.js, 39, 30))
>func15 : Symbol(func15, Decl(b.js, 39, 30))
module.exports.func16 = function () { };
>module.exports : Symbol(func16, Decl(b.js, 40, 33))
>func16 : Symbol(func16, Decl(b.js, 40, 33))
module.exports = exports = {};
exports.func17 = function () { };
>exports : Symbol(func17, Decl(b.js, 43, 30))
>func17 : Symbol(func17, Decl(b.js, 43, 30))
module.exports.func18 = function () { };
>module.exports : Symbol(func18, Decl(b.js, 44, 33))
>func18 : Symbol(func18, Decl(b.js, 44, 33))
module.exports = {};
exports.func19 = function () { };
>exports : Symbol(func19, Decl(b.js, 47, 20))
>func19 : Symbol(func19, Decl(b.js, 47, 20))
module.exports.func20 = function () { };
>module.exports : Symbol(func20, Decl(b.js, 48, 33))
>func20 : Symbol(func20, Decl(b.js, 48, 33))

View File

@ -0,0 +1,395 @@
=== tests/cases/conformance/salsa/a.ts ===
import b = require("./b.js");
>b : typeof b
b.func1;
>b.func1 : () => void
>b : typeof b
>func1 : () => void
b.func2;
>b.func2 : () => void
>b : typeof b
>func2 : () => void
b.func3;
>b.func3 : () => void
>b : typeof b
>func3 : () => void
b.func4;
>b.func4 : () => void
>b : typeof b
>func4 : () => void
b.func5;
>b.func5 : () => void
>b : typeof b
>func5 : () => void
b.func6;
>b.func6 : () => void
>b : typeof b
>func6 : () => void
b.func7;
>b.func7 : () => void
>b : typeof b
>func7 : () => void
b.func8;
>b.func8 : () => void
>b : typeof b
>func8 : () => void
b.func9;
>b.func9 : () => void
>b : typeof b
>func9 : () => void
b.func10;
>b.func10 : () => void
>b : typeof b
>func10 : () => void
b.func11;
>b.func11 : () => void
>b : typeof b
>func11 : () => void
b.func12;
>b.func12 : () => void
>b : typeof b
>func12 : () => void
b.func13;
>b.func13 : () => void
>b : typeof b
>func13 : () => void
b.func14;
>b.func14 : () => void
>b : typeof b
>func14 : () => void
b.func15;
>b.func15 : () => void
>b : typeof b
>func15 : () => void
b.func16;
>b.func16 : () => void
>b : typeof b
>func16 : () => void
b.func17;
>b.func17 : () => void
>b : typeof b
>func17 : () => void
b.func18;
>b.func18 : () => void
>b : typeof b
>func18 : () => void
b.func19;
>b.func19 : () => void
>b : typeof b
>func19 : () => void
b.func20;
>b.func20 : () => void
>b : typeof b
>func20 : () => void
=== tests/cases/conformance/salsa/b.js ===
var exportsAlias = exports;
>exportsAlias : any
>exports : any
exportsAlias.func1 = function () { };
>exportsAlias.func1 = function () { } : () => void
>exportsAlias.func1 : any
>exportsAlias : any
>func1 : any
>function () { } : () => void
exports.func2 = function () { };
>exports.func2 = function () { } : () => void
>exports.func2 : any
>exports : any
>func2 : any
>function () { } : () => void
var moduleExportsAlias = module.exports;
>moduleExportsAlias : any
>module.exports : any
>module : any
>exports : any
moduleExportsAlias.func3 = function () { };
>moduleExportsAlias.func3 = function () { } : () => void
>moduleExportsAlias.func3 : any
>moduleExportsAlias : any
>func3 : any
>function () { } : () => void
module.exports.func4 = function () { };
>module.exports.func4 = function () { } : () => void
>module.exports.func4 : any
>module.exports : any
>module : any
>exports : any
>func4 : any
>function () { } : () => void
var multipleDeclarationAlias1 = exports = module.exports;
>multipleDeclarationAlias1 : any
>exports = module.exports : any
>exports : any
>module.exports : any
>module : any
>exports : any
multipleDeclarationAlias1.func5 = function () { };
>multipleDeclarationAlias1.func5 = function () { } : () => void
>multipleDeclarationAlias1.func5 : any
>multipleDeclarationAlias1 : any
>func5 : any
>function () { } : () => void
var multipleDeclarationAlias2 = module.exports = exports;
>multipleDeclarationAlias2 : any
>module.exports = exports : any
>module.exports : any
>module : any
>exports : any
>exports : any
multipleDeclarationAlias2.func6 = function () { };
>multipleDeclarationAlias2.func6 = function () { } : () => void
>multipleDeclarationAlias2.func6 : any
>multipleDeclarationAlias2 : any
>func6 : any
>function () { } : () => void
var someOtherVariable;
>someOtherVariable : any
var multipleDeclarationAlias3 = someOtherVariable = exports;
>multipleDeclarationAlias3 : any
>someOtherVariable = exports : any
>someOtherVariable : any
>exports : any
multipleDeclarationAlias3.func7 = function () { };
>multipleDeclarationAlias3.func7 = function () { } : () => void
>multipleDeclarationAlias3.func7 : any
>multipleDeclarationAlias3 : any
>func7 : any
>function () { } : () => void
var multipleDeclarationAlias4 = someOtherVariable = module.exports;
>multipleDeclarationAlias4 : any
>someOtherVariable = module.exports : any
>someOtherVariable : any
>module.exports : any
>module : any
>exports : any
multipleDeclarationAlias4.func8 = function () { };
>multipleDeclarationAlias4.func8 = function () { } : () => void
>multipleDeclarationAlias4.func8 : any
>multipleDeclarationAlias4 : any
>func8 : any
>function () { } : () => void
var multipleDeclarationAlias5 = module.exports = exports = {};
>multipleDeclarationAlias5 : {}
>module.exports = exports = {} : {}
>module.exports : any
>module : any
>exports : any
>exports = {} : {}
>exports : any
>{} : {}
multipleDeclarationAlias5.func9 = function () { };
>multipleDeclarationAlias5.func9 = function () { } : () => void
>multipleDeclarationAlias5.func9 : any
>multipleDeclarationAlias5 : {}
>func9 : any
>function () { } : () => void
var multipleDeclarationAlias6 = exports = module.exports = {};
>multipleDeclarationAlias6 : {}
>exports = module.exports = {} : {}
>exports : any
>module.exports = {} : {}
>module.exports : any
>module : any
>exports : any
>{} : {}
multipleDeclarationAlias6.func10 = function () { };
>multipleDeclarationAlias6.func10 = function () { } : () => void
>multipleDeclarationAlias6.func10 : any
>multipleDeclarationAlias6 : {}
>func10 : any
>function () { } : () => void
exports = module.exports = someOtherVariable = {};
>exports = module.exports = someOtherVariable = {} : {}
>exports : any
>module.exports = someOtherVariable = {} : {}
>module.exports : any
>module : any
>exports : any
>someOtherVariable = {} : {}
>someOtherVariable : any
>{} : {}
exports.func11 = function () { };
>exports.func11 = function () { } : () => void
>exports.func11 : any
>exports : any
>func11 : any
>function () { } : () => void
module.exports.func12 = function () { };
>module.exports.func12 = function () { } : () => void
>module.exports.func12 : any
>module.exports : any
>module : any
>exports : any
>func12 : any
>function () { } : () => void
exports = module.exports = someOtherVariable = {};
>exports = module.exports = someOtherVariable = {} : {}
>exports : any
>module.exports = someOtherVariable = {} : {}
>module.exports : any
>module : any
>exports : any
>someOtherVariable = {} : {}
>someOtherVariable : any
>{} : {}
exports.func11 = function () { };
>exports.func11 = function () { } : () => void
>exports.func11 : any
>exports : any
>func11 : any
>function () { } : () => void
module.exports.func12 = function () { };
>module.exports.func12 = function () { } : () => void
>module.exports.func12 : any
>module.exports : any
>module : any
>exports : any
>func12 : any
>function () { } : () => void
exports = module.exports = {};
>exports = module.exports = {} : {}
>exports : any
>module.exports = {} : {}
>module.exports : any
>module : any
>exports : any
>{} : {}
exports.func13 = function () { };
>exports.func13 = function () { } : () => void
>exports.func13 : any
>exports : any
>func13 : any
>function () { } : () => void
module.exports.func14 = function () { };
>module.exports.func14 = function () { } : () => void
>module.exports.func14 : any
>module.exports : any
>module : any
>exports : any
>func14 : any
>function () { } : () => void
exports = module.exports = {};
>exports = module.exports = {} : {}
>exports : any
>module.exports = {} : {}
>module.exports : any
>module : any
>exports : any
>{} : {}
exports.func15 = function () { };
>exports.func15 = function () { } : () => void
>exports.func15 : any
>exports : any
>func15 : any
>function () { } : () => void
module.exports.func16 = function () { };
>module.exports.func16 = function () { } : () => void
>module.exports.func16 : any
>module.exports : any
>module : any
>exports : any
>func16 : any
>function () { } : () => void
module.exports = exports = {};
>module.exports = exports = {} : {}
>module.exports : any
>module : any
>exports : any
>exports = {} : {}
>exports : any
>{} : {}
exports.func17 = function () { };
>exports.func17 = function () { } : () => void
>exports.func17 : any
>exports : any
>func17 : any
>function () { } : () => void
module.exports.func18 = function () { };
>module.exports.func18 = function () { } : () => void
>module.exports.func18 : any
>module.exports : any
>module : any
>exports : any
>func18 : any
>function () { } : () => void
module.exports = {};
>module.exports = {} : {}
>module.exports : any
>module : any
>exports : any
>{} : {}
exports.func19 = function () { };
>exports.func19 = function () { } : () => void
>exports.func19 : any
>exports : any
>func19 : any
>function () { } : () => void
module.exports.func20 = function () { };
>module.exports.func20 = function () { } : () => void
>module.exports.func20 : any
>module.exports : any
>module : any
>exports : any
>func20 : any
>function () { } : () => void

View File

@ -0,0 +1,79 @@
// @allowJS: true
// @noEmit: true
// @filename: a.ts
import b = require("./b.js");
b.func1;
b.func2;
b.func3;
b.func4;
b.func5;
b.func6;
b.func7;
b.func8;
b.func9;
b.func10;
b.func11;
b.func12;
b.func13;
b.func14;
b.func15;
b.func16;
b.func17;
b.func18;
b.func19;
b.func20;
// @filename: b.js
var exportsAlias = exports;
exportsAlias.func1 = function () { };
exports.func2 = function () { };
var moduleExportsAlias = module.exports;
moduleExportsAlias.func3 = function () { };
module.exports.func4 = function () { };
var multipleDeclarationAlias1 = exports = module.exports;
multipleDeclarationAlias1.func5 = function () { };
var multipleDeclarationAlias2 = module.exports = exports;
multipleDeclarationAlias2.func6 = function () { };
var someOtherVariable;
var multipleDeclarationAlias3 = someOtherVariable = exports;
multipleDeclarationAlias3.func7 = function () { };
var multipleDeclarationAlias4 = someOtherVariable = module.exports;
multipleDeclarationAlias4.func8 = function () { };
var multipleDeclarationAlias5 = module.exports = exports = {};
multipleDeclarationAlias5.func9 = function () { };
var multipleDeclarationAlias6 = exports = module.exports = {};
multipleDeclarationAlias6.func10 = function () { };
exports = module.exports = someOtherVariable = {};
exports.func11 = function () { };
module.exports.func12 = function () { };
exports = module.exports = someOtherVariable = {};
exports.func11 = function () { };
module.exports.func12 = function () { };
exports = module.exports = {};
exports.func13 = function () { };
module.exports.func14 = function () { };
exports = module.exports = {};
exports.func15 = function () { };
module.exports.func16 = function () { };
module.exports = exports = {};
exports.func17 = function () { };
module.exports.func18 = function () { };
module.exports = {};
exports.func19 = function () { };
module.exports.func20 = function () { };