diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 4e0d5225f58..d5ab7dd11ca 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -166,13 +166,12 @@ namespace ts { return "__export"; case SyntaxKind.ExportAssignment: return (node).isExportEquals ? "export=" : "default"; + case SyntaxKind.BinaryExpression: + // Binary expression case is for JS module 'module.exports = expr' + return "export="; case SyntaxKind.FunctionDeclaration: case SyntaxKind.ClassDeclaration: return node.flags & NodeFlags.Default ? "default" : undefined; - - case SyntaxKind.BinaryExpression: - Debug.assert(isModuleExportsAssignment(node)); - return "__jsExports"; } } @@ -936,9 +935,7 @@ namespace ts { return bindAnonymousDeclaration(node, SymbolFlags.Function, bindingName); case SyntaxKind.CallExpression: - // We're only inspecting call expressions to detect CommonJS modules, so we can skip - // this check if we've already seen the module indicator - if (isJavaScriptFile && !file.commonJsModuleIndicator) { + if (isJavaScriptFile) { bindCallExpression(node); } break; @@ -984,12 +981,13 @@ namespace ts { bindAnonymousDeclaration(file, SymbolFlags.ValueModule, `"${removeFileExtension(file.fileName) }"`); } - function bindExportAssignment(node: ExportAssignment) { + function bindExportAssignment(node: ExportAssignment|BinaryExpression) { + let boundExpression = node.kind === SyntaxKind.ExportAssignment ? (node).expression : (node).right; if (!container.symbol || !container.symbol.exports) { // Export assignment in some sort of block construct bindAnonymousDeclaration(node, SymbolFlags.Alias, getDeclarationName(node)); } - else if (node.expression.kind === SyntaxKind.Identifier) { + else if (boundExpression.kind === SyntaxKind.Identifier) { // An export default clause with an identifier exports all meanings of that identifier declareSymbol(container.symbol.exports, container.symbol, node, SymbolFlags.Alias, SymbolFlags.PropertyExcludes | SymbolFlags.AliasExcludes); } @@ -1033,11 +1031,13 @@ namespace ts { function bindModuleExportsAssignment(node: BinaryExpression) { // 'module.exports = expr' assignment setCommonJsModuleIndicator(node); - declareSymbol(file.symbol.exports, file.symbol, node, SymbolFlags.None, SymbolFlags.None); + bindExportAssignment(node); } function bindCallExpression(node: CallExpression) { - if (isRequireCall(node)) { + // We're only inspecting call expressions to detect CommonJS modules, so we can skip + // this check if we've already seen the module indicator + if (!file.commonJsModuleIndicator && isRequireCall(node)) { setCommonJsModuleIndicator(node); } } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7e15f0a3ad0..f0c81940192 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1087,20 +1087,6 @@ namespace ts { visit(resolveExternalModuleName(node, (node).moduleSpecifier)); } } - - // CommonJS 'module.exports = expr' assignments - let commonJsModuleExports = symbol.exports["__jsExports"]; - if (commonJsModuleExports) { - for (var i = 0; i < commonJsModuleExports.declarations.length; i++) { - let properties = getPropertiesOfType(checkExpression((commonJsModuleExports.declarations[i]).right)); - if (i === 0) { - result = createSymbolTable(properties); - } - else { - mergeSymbolTable(result, createSymbolTable(properties)); - } - } - } } } } @@ -2586,6 +2572,10 @@ namespace ts { if (declaration.kind === SyntaxKind.ExportAssignment) { return links.type = checkExpression((declaration).expression); } + // Handle module.exports = expr + if (declaration.kind === SyntaxKind.BinaryExpression) { + return links.type = checkExpression((declaration).right); + } // Handle exports.p = expr if (declaration.kind === SyntaxKind.PropertyAccessExpression && declaration.parent.kind === SyntaxKind.BinaryExpression) { return checkExpressionCached((declaration.parent).right); @@ -3839,9 +3829,9 @@ namespace ts { function resolveExternalModuleTypeByLiteral(name: StringLiteral) { let moduleSym = resolveExternalModuleName(name, name); if (moduleSym) { - let moduleSymSym = resolveExternalModuleSymbol(moduleSym); - if (moduleSymSym) { - return getTypeOfSymbol(moduleSymSym); + let resolvedModuleSymbol = resolveExternalModuleSymbol(moduleSym); + if (resolvedModuleSymbol) { + return getTypeOfSymbol(resolvedModuleSymbol); } } diff --git a/tests/cases/fourslash/javaScriptModules13.ts b/tests/cases/fourslash/javaScriptModules13.ts index 215f47e9ad6..8b22971009c 100644 --- a/tests/cases/fourslash/javaScriptModules13.ts +++ b/tests/cases/fourslash/javaScriptModules13.ts @@ -6,8 +6,6 @@ // @Filename: myMod.js //// if (true) { //// module.exports = { a: 10 }; -//// } else { -//// module.exports = { b: 10 }; //// } //// var invisible = true; @@ -26,4 +24,3 @@ verify.not.completionListContains('invisible'); edit.insert('x.'); verify.completionListContains('a'); -verify.completionListContains('b');