From 4f9ccd0e5f447fd2022307f5c722686b978f4973 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Wed, 8 Jul 2020 17:00:48 -0700 Subject: [PATCH 01/30] First attempt at aliases for require --- src/compiler/binder.ts | 8 +++++- src/compiler/checker.ts | 56 +++++++++++++++++++-------------------- src/compiler/types.ts | 1 + src/compiler/utilities.ts | 11 +++++++- 4 files changed, 46 insertions(+), 30 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index b9126ca464ce3..a8c5218de58d6 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -543,6 +543,7 @@ namespace ts { function declareModuleMember(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags): Symbol { const hasExportModifier = getCombinedModifierFlags(node) & ModifierFlags.Export; if (symbolFlags & SymbolFlags.Alias) { + // TODO: handle non-destructuring const x=require here (after altering flags from bindVariableDeclaration) if (node.kind === SyntaxKind.ExportSpecifier || (node.kind === SyntaxKind.ImportEqualsDeclaration && hasExportModifier)) { return declareSymbol(container.symbol.exports!, container.symbol, node, symbolFlags, symbolExcludes); } @@ -3183,7 +3184,12 @@ namespace ts { if (!isBindingPattern(node.name)) { if (isBlockOrCatchScoped(node)) { - bindBlockScopedDeclaration(node, SymbolFlags.BlockScopedVariable, SymbolFlags.BlockScopedVariableExcludes); + if (isRequireVariableDeclaration(node, /*requireStringLiteralLikeArgument*/ true)) { + declareSymbolAndAddToSymbolTable(node, SymbolFlags.Alias, SymbolFlags.AliasExcludes); + } + else { + bindBlockScopedDeclaration(node, SymbolFlags.BlockScopedVariable, SymbolFlags.BlockScopedVariableExcludes); + } } else if (isParameterDeclaration(node)) { // It is safe to walk up parent chain to find whether the node is a destructuring parameter declaration diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6214de3540729..776ee0d114751 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1912,11 +1912,8 @@ namespace ts { if (lastLocation && ( lastLocation === (location as BindingElement).initializer || lastLocation === (location as BindingElement).name && isBindingPattern(lastLocation))) { - const root = getRootDeclaration(location); - if (root.kind === SyntaxKind.Parameter) { - if (!associatedDeclarationForContainingInitializerOrBindingName) { - associatedDeclarationForContainingInitializerOrBindingName = location as BindingElement; - } + if (isParameterDeclaration(location as BindingElement) && !associatedDeclarationForContainingInitializerOrBindingName) { + associatedDeclarationForContainingInitializerOrBindingName = location as BindingElement; } } break; @@ -2380,7 +2377,8 @@ namespace ts { && node.parent.operatorToken.kind === SyntaxKind.EqualsToken && isAliasableOrJsExpression(node.parent.right) || node.kind === SyntaxKind.ShorthandPropertyAssignment || - node.kind === SyntaxKind.PropertyAssignment && isAliasableOrJsExpression((node as PropertyAssignment).initializer); + node.kind === SyntaxKind.PropertyAssignment && isAliasableOrJsExpression((node as PropertyAssignment).initializer) || + isRequireVariableDeclaration(node, /*requireStringLiteralLikeArgument*/ true); } function isAliasableOrJsExpression(e: Expression) { @@ -2578,9 +2576,9 @@ namespace ts { return result; } - function getExportOfModule(symbol: Symbol, specifier: ImportOrExportSpecifier, dontResolveAlias: boolean): Symbol | undefined { + function getExportOfModule(symbol: Symbol, specifier: ImportOrExportSpecifier | BindingElement, dontResolveAlias: boolean): Symbol | undefined { if (symbol.flags & SymbolFlags.Module) { - const name = (specifier.propertyName ?? specifier.name).escapedText; + const name = ((specifier.propertyName ?? specifier.name) as Identifier).escapedText; const exportSymbol = getExportsOfSymbol(symbol).get(name); const resolved = resolveSymbol(exportSymbol, dontResolveAlias); markSymbolOfAliasDeclarationIfTypeOnly(specifier, exportSymbol, resolved, /*overwriteEmpty*/ false); @@ -2597,11 +2595,13 @@ namespace ts { } } - function getExternalModuleMember(node: ImportDeclaration | ExportDeclaration, specifier: ImportOrExportSpecifier, dontResolveAlias = false): Symbol | undefined { - const moduleSymbol = resolveExternalModuleName(node, node.moduleSpecifier!)!; // TODO: GH#18217 + function getExternalModuleMember(node: ImportDeclaration | ExportDeclaration | VariableDeclaration, specifier: ImportOrExportSpecifier | BindingElement, dontResolveAlias = false): Symbol | undefined { + const moduleSpecifier = isVariableDeclaration(node) ? (getFirstPropertyAccessExpression(node.initializer!) as CallExpression).arguments[0] : node.moduleSpecifier!; + const moduleSymbol = resolveExternalModuleName(node, moduleSpecifier)!; // TODO: GH#18217 const name = specifier.propertyName || specifier.name; + Debug.assert(isIdentifier(name)); // :eyes: const suppressInteropError = name.escapedText === InternalSymbolName.Default && !!(compilerOptions.allowSyntheticDefaultImports || compilerOptions.esModuleInterop); - const targetSymbol = resolveESModuleSymbol(moduleSymbol, node.moduleSpecifier!, dontResolveAlias, suppressInteropError); + const targetSymbol = resolveESModuleSymbol(moduleSymbol, moduleSpecifier, dontResolveAlias, suppressInteropError); if (targetSymbol) { if (name.escapedText) { if (isShorthandAmbientModuleSymbol(moduleSymbol)) { @@ -2662,7 +2662,7 @@ namespace ts { } } - function reportNonExportedMember(node: ImportDeclaration | ExportDeclaration, name: Identifier, declarationName: string, moduleSymbol: Symbol, moduleName: string): void { + function reportNonExportedMember(node: ImportDeclaration | ExportDeclaration | VariableDeclaration, name: Identifier, declarationName: string, moduleSymbol: Symbol, moduleName: string): void { const localSymbol = moduleSymbol.valueDeclaration.locals?.get(name.escapedText); const exports = moduleSymbol.exports; if (localSymbol) { @@ -2686,7 +2686,7 @@ namespace ts { } } - function reportInvalidImportEqualsExportMember(node: ImportDeclaration | ExportDeclaration, name: Identifier, declarationName: string, moduleName: string) { + function reportInvalidImportEqualsExportMember(node: ImportDeclaration | ExportDeclaration | VariableDeclaration, name: Identifier, declarationName: string, moduleName: string) { if (moduleKind >= ModuleKind.ES2015) { const message = compilerOptions.esModuleInterop ? Diagnostics._0_can_only_be_imported_by_using_a_default_import : Diagnostics._0_can_only_be_imported_by_turning_on_the_esModuleInterop_flag_and_using_a_default_import; @@ -2706,8 +2706,8 @@ namespace ts { } } - function getTargetOfImportSpecifier(node: ImportSpecifier, dontResolveAlias: boolean): Symbol | undefined { - const resolved = getExternalModuleMember(node.parent.parent.parent, node, dontResolveAlias); + function getTargetOfImportSpecifier(node: ImportSpecifier | BindingElement, dontResolveAlias: boolean): Symbol | undefined { + const resolved = getExternalModuleMember(isBindingElement(node) ? getRootDeclaration(node) as VariableDeclaration : node.parent.parent.parent, node, dontResolveAlias); markSymbolOfAliasDeclarationIfTypeOnly(node, /*immediateTarget*/ undefined, resolved, /*overwriteEmpty*/ false); return resolved; } @@ -2766,13 +2766,14 @@ namespace ts { case SyntaxKind.ImportEqualsDeclaration: return getTargetOfImportEqualsDeclaration(node, dontRecursivelyResolve); case SyntaxKind.ImportClause: - return getTargetOfImportClause(node, dontRecursivelyResolve); + return getTargetOfImportClause(node as ImportClause, dontRecursivelyResolve); case SyntaxKind.NamespaceImport: return getTargetOfNamespaceImport(node, dontRecursivelyResolve); case SyntaxKind.NamespaceExport: return getTargetOfNamespaceExport(node, dontRecursivelyResolve); case SyntaxKind.ImportSpecifier: - return getTargetOfImportSpecifier(node, dontRecursivelyResolve); + case SyntaxKind.BindingElement: + return getTargetOfImportSpecifier(node as ImportSpecifier | BindingElement, dontRecursivelyResolve); case SyntaxKind.ExportSpecifier: return getTargetOfExportSpecifier(node, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace, dontRecursivelyResolve); case SyntaxKind.ExportAssignment: @@ -2786,6 +2787,8 @@ namespace ts { return getTargetOfPropertyAssignment(node as PropertyAssignment, dontRecursivelyResolve); case SyntaxKind.PropertyAccessExpression: return getTargetOfPropertyAccessExpression(node as PropertyAccessExpression, dontRecursivelyResolve); + case SyntaxKind.VariableDeclaration: + return Debug.fail('second time around'); //getTargetOfRequireClause(node as VariableDeclaration, dontRecursivelyResolve); default: return Debug.fail(); } @@ -12014,16 +12017,7 @@ namespace ts { const valueType = getTypeOfSymbol(symbol); let typeType = valueType; if (symbol.valueDeclaration) { - const decl = getRootDeclaration(symbol.valueDeclaration); - let isRequireAlias = false; - if (isVariableDeclaration(decl) && decl.initializer) { - let expr = decl.initializer; - // skip past entity names, eg `require("x").a.b.c` - while (isPropertyAccessExpression(expr)) { - expr = expr.expression; - } - isRequireAlias = isCallExpression(expr) && isRequireCall(expr, /*requireStringLiteralLikeArgument*/ true) && !!valueType.symbol; - } + const isRequireAlias = isRequireVariableDeclaration(symbol.valueDeclaration, /*requireStringLiteralLikeArgument*/ true); const isImportTypeWithQualifier = node.kind === SyntaxKind.ImportType && (node as ImportTypeNode).qualifier; // valueType might not have a symbol, eg, {import('./b').STRING_LITERAL} if (valueType.symbol && (isRequireAlias || isImportTypeWithQualifier)) { @@ -32734,7 +32728,7 @@ namespace ts { forEach(node.name.elements, checkSourceElement); } // For a parameter declaration with an initializer, error and exit if the containing function doesn't have a body - if (node.initializer && getRootDeclaration(node).kind === SyntaxKind.Parameter && nodeIsMissing((getContainingFunction(node) as FunctionLikeDeclaration).body)) { + if (node.initializer && isParameterDeclaration(node) && nodeIsMissing((getContainingFunction(node) as FunctionLikeDeclaration).body)) { error(node, Diagnostics.A_parameter_initializer_is_only_allowed_in_a_function_or_constructor_implementation); return; } @@ -32766,6 +32760,12 @@ namespace ts { } return; } + // For a require binding element, validate the alias and exit + // TODO: Probably should mark the symbol so I don't have to keep rescanning this + if (isBindingElement(node) && isRequireVariableDeclaration(node, /*requireStringLiteralLikeArgument*/ true)) { + checkAliasSymbol(node); + return; + } const symbol = getSymbolOfNode(node); const type = convertAutoToAny(getTypeOfSymbol(symbol)); if (node === symbol.valueDeclaration) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 2472b302545cc..9587df51f7896 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3002,6 +3002,7 @@ namespace ts { readonly name: Identifier; // Declared name } + // TODO: Probably should now include BindingElement export type ImportOrExportSpecifier = | ImportSpecifier | ExportSpecifier diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 732630d7d9f5a..791799b4cbda5 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1927,11 +1927,13 @@ namespace ts { /** * Returns true if the node is a VariableDeclaration initialized to a require call (see `isRequireCall`). * This function does not test if the node is in a JavaScript file or not. + * TODO: But probably should???! */ export function isRequireVariableDeclaration(node: Node, requireStringLiteralLikeArgument: true): node is RequireVariableDeclaration; export function isRequireVariableDeclaration(node: Node, requireStringLiteralLikeArgument: boolean): node is VariableDeclaration; export function isRequireVariableDeclaration(node: Node, requireStringLiteralLikeArgument: boolean): node is VariableDeclaration { - return isVariableDeclaration(node) && !!node.initializer && isRequireCall(node.initializer, requireStringLiteralLikeArgument); + node = getRootDeclaration(node); + return isVariableDeclaration(node) && !!node.initializer && isRequireCall(getFirstPropertyAccessExpression(node.initializer), requireStringLiteralLikeArgument); } export function isRequireVariableDeclarationStatement(node: Node, requireStringLiteralLikeArgument = true): node is VariableStatement { @@ -4741,6 +4743,13 @@ namespace ts { } } + export function getFirstPropertyAccessExpression(expr: Expression): Expression { + while (isPropertyAccessExpression(expr)) { + expr = expr.expression; + } + return expr; + } + export function isDottedName(node: Expression): boolean { return node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.ThisKeyword || node.kind === SyntaxKind.SuperKeyword || node.kind === SyntaxKind.PropertyAccessExpression && isDottedName((node).expression) || From 277d52ad2d738ec75495006d3c77e67db17e6c55 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Thu, 9 Jul 2020 15:46:32 -0700 Subject: [PATCH 02/30] test+initial support for const x=require --- src/compiler/checker.ts | 17 +++---- .../requireAssertsFromTypescript.symbols | 45 ++++++++++++++++++ .../requireAssertsFromTypescript.types | 47 +++++++++++++++++++ .../salsa/requireAssertsFromTypescript.ts | 16 +++++++ 4 files changed, 117 insertions(+), 8 deletions(-) create mode 100644 tests/baselines/reference/requireAssertsFromTypescript.symbols create mode 100644 tests/baselines/reference/requireAssertsFromTypescript.types create mode 100644 tests/cases/conformance/salsa/requireAssertsFromTypescript.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a8aff585f9355..be04b956177a8 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2385,9 +2385,11 @@ namespace ts { return isAliasableExpression(e) || isFunctionExpression(e) && isJSConstructor(e); } - function getTargetOfImportEqualsDeclaration(node: ImportEqualsDeclaration, dontResolveAlias: boolean): Symbol | undefined { - if (node.moduleReference.kind === SyntaxKind.ExternalModuleReference) { - const immediate = resolveExternalModuleName(node, getExternalModuleImportEqualsDeclarationExpression(node)); + function getTargetOfImportEqualsDeclaration(node: ImportEqualsDeclaration | VariableDeclaration, dontResolveAlias: boolean): Symbol | undefined { + if (isVariableDeclaration(node) || node.moduleReference.kind === SyntaxKind.ExternalModuleReference) { + const immediate = resolveExternalModuleName(node, isVariableDeclaration(node) + ? (getFirstPropertyAccessExpression(node.initializer!) as CallExpression).arguments[0] + : getExternalModuleImportEqualsDeclarationExpression(node)); const resolved = resolveExternalModuleSymbol(immediate); markSymbolOfAliasDeclarationIfTypeOnly(node, immediate, resolved, /*overwriteEmpty*/ false); return resolved; @@ -2764,7 +2766,8 @@ namespace ts { function getTargetOfAliasDeclaration(node: Declaration, dontRecursivelyResolve = false): Symbol | undefined { switch (node.kind) { case SyntaxKind.ImportEqualsDeclaration: - return getTargetOfImportEqualsDeclaration(node, dontRecursivelyResolve); + case SyntaxKind.VariableDeclaration: + return getTargetOfImportEqualsDeclaration(node as ImportEqualsDeclaration | VariableDeclaration, dontRecursivelyResolve); case SyntaxKind.ImportClause: return getTargetOfImportClause(node as ImportClause, dontRecursivelyResolve); case SyntaxKind.NamespaceImport: @@ -2787,8 +2790,6 @@ namespace ts { return getTargetOfPropertyAssignment(node as PropertyAssignment, dontRecursivelyResolve); case SyntaxKind.PropertyAccessExpression: return getTargetOfPropertyAccessExpression(node as PropertyAccessExpression, dontRecursivelyResolve); - case SyntaxKind.VariableDeclaration: - return Debug.fail('second time around'); //getTargetOfRequireClause(node as VariableDeclaration, dontRecursivelyResolve); default: return Debug.fail(); } @@ -32763,7 +32764,7 @@ namespace ts { } // For a require binding element, validate the alias and exit // TODO: Probably should mark the symbol so I don't have to keep rescanning this - if (isBindingElement(node) && isRequireVariableDeclaration(node, /*requireStringLiteralLikeArgument*/ true)) { + if (/*isBindingElement(node) && */isRequireVariableDeclaration(node, /*requireStringLiteralLikeArgument*/ true)) { checkAliasSymbol(node); return; } @@ -35213,7 +35214,7 @@ namespace ts { return true; } - function checkAliasSymbol(node: ImportEqualsDeclaration | ImportClause | NamespaceImport | ImportSpecifier | ExportSpecifier | NamespaceExport) { + function checkAliasSymbol(node: ImportEqualsDeclaration | VariableDeclaration | ImportClause | NamespaceImport | ImportSpecifier | ExportSpecifier | NamespaceExport) { let symbol = getSymbolOfNode(node); const target = resolveAlias(symbol); diff --git a/tests/baselines/reference/requireAssertsFromTypescript.symbols b/tests/baselines/reference/requireAssertsFromTypescript.symbols new file mode 100644 index 0000000000000..0d39960aff7c5 --- /dev/null +++ b/tests/baselines/reference/requireAssertsFromTypescript.symbols @@ -0,0 +1,45 @@ +=== tests/cases/conformance/salsa/38379.js === +const { art } = require('./ex') +>art : Symbol(art, Decl(38379.js, 0, 7)) +>require : Symbol(require) +>'./ex' : Symbol("tests/cases/conformance/salsa/ex", Decl(ex.d.ts, 0, 0)) + +const artoo = require('./ex2') +>artoo : Symbol(artoo, Decl(38379.js, 1, 5)) +>require : Symbol(require) +>'./ex2' : Symbol("tests/cases/conformance/salsa/ex2", Decl(ex2.d.ts, 0, 0)) + +let x = 1 +>x : Symbol(x, Decl(38379.js, 2, 3)) + +art(x) +>art : Symbol(art, Decl(38379.js, 0, 7)) +>x : Symbol(x, Decl(38379.js, 2, 3)) + +let y = 1 +>y : Symbol(y, Decl(38379.js, 4, 3)) + +artoo(y) +>artoo : Symbol(artoo, Decl(38379.js, 1, 5)) +>y : Symbol(y, Decl(38379.js, 4, 3)) + +=== tests/cases/conformance/salsa/ex.d.ts === +// based on assert in @types/node +export function art(value: any, message?: string | Error): asserts value; +>art : Symbol(art, Decl(ex.d.ts, 0, 0)) +>value : Symbol(value, Decl(ex.d.ts, 1, 20)) +>message : Symbol(message, Decl(ex.d.ts, 1, 31)) +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>value : Symbol(value, Decl(ex.d.ts, 1, 20)) + +=== tests/cases/conformance/salsa/ex2.d.ts === +declare function art(value: any, message?: string | Error): asserts value; +>art : Symbol(art, Decl(ex2.d.ts, 0, 0)) +>value : Symbol(value, Decl(ex2.d.ts, 0, 21)) +>message : Symbol(message, Decl(ex2.d.ts, 0, 32)) +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>value : Symbol(value, Decl(ex2.d.ts, 0, 21)) + +export = art; +>art : Symbol(art, Decl(ex2.d.ts, 0, 0)) + diff --git a/tests/baselines/reference/requireAssertsFromTypescript.types b/tests/baselines/reference/requireAssertsFromTypescript.types new file mode 100644 index 0000000000000..d146adfdc4fd6 --- /dev/null +++ b/tests/baselines/reference/requireAssertsFromTypescript.types @@ -0,0 +1,47 @@ +=== tests/cases/conformance/salsa/38379.js === +const { art } = require('./ex') +>art : (value: any, message?: string | Error) => asserts value +>require('./ex') : typeof import("tests/cases/conformance/salsa/ex") +>require : any +>'./ex' : "./ex" + +const artoo = require('./ex2') +>artoo : (value: any, message?: string | Error) => asserts value +>require('./ex2') : (value: any, message?: string | Error) => asserts value +>require : any +>'./ex2' : "./ex2" + +let x = 1 +>x : number +>1 : 1 + +art(x) +>art(x) : void +>art : (value: any, message?: string | Error) => asserts value +>x : number + +let y = 1 +>y : number +>1 : 1 + +artoo(y) +>artoo(y) : void +>artoo : (value: any, message?: string | Error) => asserts value +>y : number + +=== tests/cases/conformance/salsa/ex.d.ts === +// based on assert in @types/node +export function art(value: any, message?: string | Error): asserts value; +>art : (value: any, message?: string | Error) => asserts value +>value : any +>message : string | Error + +=== tests/cases/conformance/salsa/ex2.d.ts === +declare function art(value: any, message?: string | Error): asserts value; +>art : (value: any, message?: string | Error) => asserts value +>value : any +>message : string | Error + +export = art; +>art : (value: any, message?: string | Error) => asserts value + diff --git a/tests/cases/conformance/salsa/requireAssertsFromTypescript.ts b/tests/cases/conformance/salsa/requireAssertsFromTypescript.ts new file mode 100644 index 0000000000000..ccdd8353ba80b --- /dev/null +++ b/tests/cases/conformance/salsa/requireAssertsFromTypescript.ts @@ -0,0 +1,16 @@ +// @noEmit: true +// @allowJs: true +// @checkJs: true +// @Filename: ex.d.ts +// based on assert in @types/node +export function art(value: any, message?: string | Error): asserts value; +// @Filename: ex2.d.ts +declare function art(value: any, message?: string | Error): asserts value; +export = art; +// @Filename: 38379.js +const { art } = require('./ex') +const artoo = require('./ex2') +let x = 1 +art(x) +let y = 1 +artoo(y) From bcdc2e4a97263b1aedafc4f325bb7003f8065095 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Thu, 9 Jul 2020 16:05:47 -0700 Subject: [PATCH 03/30] 1st round of baseline improvements --- .../reference/constructorFunctions2.types | 8 ++++---- ...ateBoundAssignmentDeclarationSupport1.symbols | 6 +++--- .../lateBoundAssignmentDeclarationSupport1.types | 10 +++++----- ...ateBoundAssignmentDeclarationSupport2.symbols | 6 +++--- .../lateBoundAssignmentDeclarationSupport2.types | 10 +++++----- ...ateBoundAssignmentDeclarationSupport3.symbols | 6 +++--- .../lateBoundAssignmentDeclarationSupport3.types | 10 +++++----- ...ateBoundAssignmentDeclarationSupport4.symbols | 10 +++++----- .../lateBoundAssignmentDeclarationSupport4.types | 8 ++++---- ...ateBoundAssignmentDeclarationSupport5.symbols | 10 +++++----- .../lateBoundAssignmentDeclarationSupport5.types | 8 ++++---- ...ateBoundAssignmentDeclarationSupport6.symbols | 10 +++++----- .../lateBoundAssignmentDeclarationSupport6.types | 8 ++++---- ...ateBoundAssignmentDeclarationSupport7.symbols | 14 +++++++------- .../lateBoundAssignmentDeclarationSupport7.types | 10 +++++----- .../reference/moduleExportAlias2.symbols | 4 ++-- .../baselines/reference/moduleExportAlias2.types | 12 ++++++------ .../reference/typeFromParamTagForFunction.types | 16 ++++++++-------- .../reference/typeFromPropertyAssignment19.types | 6 +++--- .../typeFromPropertyAssignment37.symbols | 10 +++++----- .../reference/typeFromPropertyAssignment37.types | 8 ++++---- 21 files changed, 95 insertions(+), 95 deletions(-) diff --git a/tests/baselines/reference/constructorFunctions2.types b/tests/baselines/reference/constructorFunctions2.types index 0f5933e04f4be..8b1f3711770aa 100644 --- a/tests/baselines/reference/constructorFunctions2.types +++ b/tests/baselines/reference/constructorFunctions2.types @@ -9,16 +9,16 @@ declare var module: any, exports: any; === tests/cases/conformance/salsa/index.js === const A = require("./other"); ->A : typeof import("tests/cases/conformance/salsa/other") ->require("./other") : typeof import("tests/cases/conformance/salsa/other") +>A : typeof A +>require("./other") : typeof A >require : (id: string) => any >"./other" : "./other" const a = new A().id; >a : number >new A().id : number ->new A() : import("tests/cases/conformance/salsa/other") ->A : typeof import("tests/cases/conformance/salsa/other") +>new A() : A +>A : typeof A >id : number const B = function() { this.id = 1; } diff --git a/tests/baselines/reference/lateBoundAssignmentDeclarationSupport1.symbols b/tests/baselines/reference/lateBoundAssignmentDeclarationSupport1.symbols index ee7bd17cb08df..c290fc349bb09 100644 --- a/tests/baselines/reference/lateBoundAssignmentDeclarationSupport1.symbols +++ b/tests/baselines/reference/lateBoundAssignmentDeclarationSupport1.symbols @@ -2,7 +2,7 @@ const x = require("./lateBoundAssignmentDeclarationSupport1.js"); >x : Symbol(x, Decl(usage.js, 0, 5)) >require : Symbol(require) ->"./lateBoundAssignmentDeclarationSupport1.js" : Symbol("tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport1", Decl(lateBoundAssignmentDeclarationSupport1.js, 0, 0)) +>"./lateBoundAssignmentDeclarationSupport1.js" : Symbol(x, Decl(lateBoundAssignmentDeclarationSupport1.js, 0, 0)) const y = x["my-fake-sym"]; >y : Symbol(y, Decl(usage.js, 1, 5)) @@ -11,9 +11,9 @@ const y = x["my-fake-sym"]; const z = x[x.S]; >z : Symbol(z, Decl(usage.js, 2, 5)) >x : Symbol(x, Decl(usage.js, 0, 5)) ->x.S : Symbol(S, Decl(lateBoundAssignmentDeclarationSupport1.js, 5, 21)) +>x.S : Symbol(x.S, Decl(lateBoundAssignmentDeclarationSupport1.js, 5, 21)) >x : Symbol(x, Decl(usage.js, 0, 5)) ->S : Symbol(S, Decl(lateBoundAssignmentDeclarationSupport1.js, 5, 21)) +>S : Symbol(x.S, Decl(lateBoundAssignmentDeclarationSupport1.js, 5, 21)) === tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport1.js === // currently unsupported diff --git a/tests/baselines/reference/lateBoundAssignmentDeclarationSupport1.types b/tests/baselines/reference/lateBoundAssignmentDeclarationSupport1.types index e81eca01ae515..8b31cce2543f7 100644 --- a/tests/baselines/reference/lateBoundAssignmentDeclarationSupport1.types +++ b/tests/baselines/reference/lateBoundAssignmentDeclarationSupport1.types @@ -1,22 +1,22 @@ === tests/cases/conformance/salsa/usage.js === const x = require("./lateBoundAssignmentDeclarationSupport1.js"); ->x : typeof import("tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport1") ->require("./lateBoundAssignmentDeclarationSupport1.js") : typeof import("tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport1") +>x : typeof x +>require("./lateBoundAssignmentDeclarationSupport1.js") : typeof x >require : any >"./lateBoundAssignmentDeclarationSupport1.js" : "./lateBoundAssignmentDeclarationSupport1.js" const y = x["my-fake-sym"]; >y : any >x["my-fake-sym"] : any ->x : typeof import("tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport1") +>x : typeof x >"my-fake-sym" : "my-fake-sym" const z = x[x.S]; >z : any >x[x.S] : any ->x : typeof import("tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport1") +>x : typeof x >x.S : unique symbol ->x : typeof import("tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport1") +>x : typeof x >S : unique symbol === tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport1.js === diff --git a/tests/baselines/reference/lateBoundAssignmentDeclarationSupport2.symbols b/tests/baselines/reference/lateBoundAssignmentDeclarationSupport2.symbols index 54b247eb10822..5c252fe3db692 100644 --- a/tests/baselines/reference/lateBoundAssignmentDeclarationSupport2.symbols +++ b/tests/baselines/reference/lateBoundAssignmentDeclarationSupport2.symbols @@ -2,7 +2,7 @@ const x = require("./lateBoundAssignmentDeclarationSupport2.js"); >x : Symbol(x, Decl(usage.js, 0, 5)) >require : Symbol(require) ->"./lateBoundAssignmentDeclarationSupport2.js" : Symbol("tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport2", Decl(lateBoundAssignmentDeclarationSupport2.js, 0, 0)) +>"./lateBoundAssignmentDeclarationSupport2.js" : Symbol(x, Decl(lateBoundAssignmentDeclarationSupport2.js, 0, 0)) const y = x["my-fake-sym"]; >y : Symbol(y, Decl(usage.js, 1, 5)) @@ -11,9 +11,9 @@ const y = x["my-fake-sym"]; const z = x[x.S]; >z : Symbol(z, Decl(usage.js, 2, 5)) >x : Symbol(x, Decl(usage.js, 0, 5)) ->x.S : Symbol(S, Decl(lateBoundAssignmentDeclarationSupport2.js, 5, 28)) +>x.S : Symbol(x.S, Decl(lateBoundAssignmentDeclarationSupport2.js, 5, 28)) >x : Symbol(x, Decl(usage.js, 0, 5)) ->S : Symbol(S, Decl(lateBoundAssignmentDeclarationSupport2.js, 5, 28)) +>S : Symbol(x.S, Decl(lateBoundAssignmentDeclarationSupport2.js, 5, 28)) === tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport2.js === // currently unsupported diff --git a/tests/baselines/reference/lateBoundAssignmentDeclarationSupport2.types b/tests/baselines/reference/lateBoundAssignmentDeclarationSupport2.types index 1c0090329d92c..818a0ab212ed8 100644 --- a/tests/baselines/reference/lateBoundAssignmentDeclarationSupport2.types +++ b/tests/baselines/reference/lateBoundAssignmentDeclarationSupport2.types @@ -1,22 +1,22 @@ === tests/cases/conformance/salsa/usage.js === const x = require("./lateBoundAssignmentDeclarationSupport2.js"); ->x : typeof import("tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport2") ->require("./lateBoundAssignmentDeclarationSupport2.js") : typeof import("tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport2") +>x : typeof x +>require("./lateBoundAssignmentDeclarationSupport2.js") : typeof x >require : any >"./lateBoundAssignmentDeclarationSupport2.js" : "./lateBoundAssignmentDeclarationSupport2.js" const y = x["my-fake-sym"]; >y : any >x["my-fake-sym"] : any ->x : typeof import("tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport2") +>x : typeof x >"my-fake-sym" : "my-fake-sym" const z = x[x.S]; >z : any >x[x.S] : any ->x : typeof import("tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport2") +>x : typeof x >x.S : unique symbol ->x : typeof import("tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport2") +>x : typeof x >S : unique symbol === tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport2.js === diff --git a/tests/baselines/reference/lateBoundAssignmentDeclarationSupport3.symbols b/tests/baselines/reference/lateBoundAssignmentDeclarationSupport3.symbols index 412faa1164a22..3a9c558d36042 100644 --- a/tests/baselines/reference/lateBoundAssignmentDeclarationSupport3.symbols +++ b/tests/baselines/reference/lateBoundAssignmentDeclarationSupport3.symbols @@ -2,7 +2,7 @@ const x = require("./lateBoundAssignmentDeclarationSupport3.js"); >x : Symbol(x, Decl(usage.js, 0, 5)) >require : Symbol(require) ->"./lateBoundAssignmentDeclarationSupport3.js" : Symbol("tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport3", Decl(lateBoundAssignmentDeclarationSupport3.js, 0, 0)) +>"./lateBoundAssignmentDeclarationSupport3.js" : Symbol(x, Decl(lateBoundAssignmentDeclarationSupport3.js, 0, 0)) const y = x["my-fake-sym"]; >y : Symbol(y, Decl(usage.js, 1, 5)) @@ -11,9 +11,9 @@ const y = x["my-fake-sym"]; const z = x[x.S]; >z : Symbol(z, Decl(usage.js, 2, 5)) >x : Symbol(x, Decl(usage.js, 0, 5)) ->x.S : Symbol(S, Decl(lateBoundAssignmentDeclarationSupport3.js, 5, 61)) +>x.S : Symbol(x.S, Decl(lateBoundAssignmentDeclarationSupport3.js, 5, 61)) >x : Symbol(x, Decl(usage.js, 0, 5)) ->S : Symbol(S, Decl(lateBoundAssignmentDeclarationSupport3.js, 5, 61)) +>S : Symbol(x.S, Decl(lateBoundAssignmentDeclarationSupport3.js, 5, 61)) === tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport3.js === // currently unsupported diff --git a/tests/baselines/reference/lateBoundAssignmentDeclarationSupport3.types b/tests/baselines/reference/lateBoundAssignmentDeclarationSupport3.types index 5811c9a4c33c5..511f2e6153e9f 100644 --- a/tests/baselines/reference/lateBoundAssignmentDeclarationSupport3.types +++ b/tests/baselines/reference/lateBoundAssignmentDeclarationSupport3.types @@ -1,22 +1,22 @@ === tests/cases/conformance/salsa/usage.js === const x = require("./lateBoundAssignmentDeclarationSupport3.js"); ->x : typeof import("tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport3") ->require("./lateBoundAssignmentDeclarationSupport3.js") : typeof import("tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport3") +>x : typeof x +>require("./lateBoundAssignmentDeclarationSupport3.js") : typeof x >require : any >"./lateBoundAssignmentDeclarationSupport3.js" : "./lateBoundAssignmentDeclarationSupport3.js" const y = x["my-fake-sym"]; >y : any >x["my-fake-sym"] : any ->x : typeof import("tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport3") +>x : typeof x >"my-fake-sym" : "my-fake-sym" const z = x[x.S]; >z : any >x[x.S] : any ->x : typeof import("tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport3") +>x : typeof x >x.S : unique symbol ->x : typeof import("tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport3") +>x : typeof x >S : unique symbol === tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport3.js === diff --git a/tests/baselines/reference/lateBoundAssignmentDeclarationSupport4.symbols b/tests/baselines/reference/lateBoundAssignmentDeclarationSupport4.symbols index a6c3f2cacfbc1..fd52892f5a509 100644 --- a/tests/baselines/reference/lateBoundAssignmentDeclarationSupport4.symbols +++ b/tests/baselines/reference/lateBoundAssignmentDeclarationSupport4.symbols @@ -2,13 +2,13 @@ const x = require("./lateBoundAssignmentDeclarationSupport4.js"); >x : Symbol(x, Decl(usage.js, 0, 5)) >require : Symbol(require) ->"./lateBoundAssignmentDeclarationSupport4.js" : Symbol("tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport4", Decl(lateBoundAssignmentDeclarationSupport4.js, 0, 0)) +>"./lateBoundAssignmentDeclarationSupport4.js" : Symbol(x, Decl(lateBoundAssignmentDeclarationSupport4.js, 0, 0)) const inst = new x.F(); >inst : Symbol(inst, Decl(usage.js, 1, 5)) ->x.F : Symbol(F, Decl(lateBoundAssignmentDeclarationSupport4.js, 10, 22)) +>x.F : Symbol(x.F, Decl(lateBoundAssignmentDeclarationSupport4.js, 10, 22)) >x : Symbol(x, Decl(usage.js, 0, 5)) ->F : Symbol(F, Decl(lateBoundAssignmentDeclarationSupport4.js, 10, 22)) +>F : Symbol(x.F, Decl(lateBoundAssignmentDeclarationSupport4.js, 10, 22)) const y = inst["my-fake-sym"]; >y : Symbol(y, Decl(usage.js, 2, 5)) @@ -17,9 +17,9 @@ const y = inst["my-fake-sym"]; const z = inst[x.S]; >z : Symbol(z, Decl(usage.js, 3, 5)) >inst : Symbol(inst, Decl(usage.js, 1, 5)) ->x.S : Symbol(S, Decl(lateBoundAssignmentDeclarationSupport4.js, 11, 21)) +>x.S : Symbol(x.S, Decl(lateBoundAssignmentDeclarationSupport4.js, 11, 21)) >x : Symbol(x, Decl(usage.js, 0, 5)) ->S : Symbol(S, Decl(lateBoundAssignmentDeclarationSupport4.js, 11, 21)) +>S : Symbol(x.S, Decl(lateBoundAssignmentDeclarationSupport4.js, 11, 21)) === tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport4.js === // currently unsupported diff --git a/tests/baselines/reference/lateBoundAssignmentDeclarationSupport4.types b/tests/baselines/reference/lateBoundAssignmentDeclarationSupport4.types index 5d5d8bd4bef41..0c8199d0fcbab 100644 --- a/tests/baselines/reference/lateBoundAssignmentDeclarationSupport4.types +++ b/tests/baselines/reference/lateBoundAssignmentDeclarationSupport4.types @@ -1,7 +1,7 @@ === tests/cases/conformance/salsa/usage.js === const x = require("./lateBoundAssignmentDeclarationSupport4.js"); ->x : typeof import("tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport4") ->require("./lateBoundAssignmentDeclarationSupport4.js") : typeof import("tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport4") +>x : typeof x +>require("./lateBoundAssignmentDeclarationSupport4.js") : typeof x >require : any >"./lateBoundAssignmentDeclarationSupport4.js" : "./lateBoundAssignmentDeclarationSupport4.js" @@ -9,7 +9,7 @@ const inst = new x.F(); >inst : F >new x.F() : F >x.F : typeof F ->x : typeof import("tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport4") +>x : typeof x >F : typeof F const y = inst["my-fake-sym"]; @@ -23,7 +23,7 @@ const z = inst[x.S]; >inst[x.S] : any >inst : F >x.S : unique symbol ->x : typeof import("tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport4") +>x : typeof x >S : unique symbol === tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport4.js === diff --git a/tests/baselines/reference/lateBoundAssignmentDeclarationSupport5.symbols b/tests/baselines/reference/lateBoundAssignmentDeclarationSupport5.symbols index 3d4cde8385d6b..90a1f464648ca 100644 --- a/tests/baselines/reference/lateBoundAssignmentDeclarationSupport5.symbols +++ b/tests/baselines/reference/lateBoundAssignmentDeclarationSupport5.symbols @@ -2,13 +2,13 @@ const x = require("./lateBoundAssignmentDeclarationSupport5.js"); >x : Symbol(x, Decl(usage.js, 0, 5)) >require : Symbol(require) ->"./lateBoundAssignmentDeclarationSupport5.js" : Symbol("tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport5", Decl(lateBoundAssignmentDeclarationSupport5.js, 0, 0)) +>"./lateBoundAssignmentDeclarationSupport5.js" : Symbol(x, Decl(lateBoundAssignmentDeclarationSupport5.js, 0, 0)) const inst = new x.F(); >inst : Symbol(inst, Decl(usage.js, 1, 5)) ->x.F : Symbol(F, Decl(lateBoundAssignmentDeclarationSupport5.js, 12, 22)) +>x.F : Symbol(x.F, Decl(lateBoundAssignmentDeclarationSupport5.js, 12, 22)) >x : Symbol(x, Decl(usage.js, 0, 5)) ->F : Symbol(F, Decl(lateBoundAssignmentDeclarationSupport5.js, 12, 22)) +>F : Symbol(x.F, Decl(lateBoundAssignmentDeclarationSupport5.js, 12, 22)) const y = inst["my-fake-sym"]; >y : Symbol(y, Decl(usage.js, 2, 5)) @@ -17,9 +17,9 @@ const y = inst["my-fake-sym"]; const z = inst[x.S]; >z : Symbol(z, Decl(usage.js, 3, 5)) >inst : Symbol(inst, Decl(usage.js, 1, 5)) ->x.S : Symbol(S, Decl(lateBoundAssignmentDeclarationSupport5.js, 13, 21)) +>x.S : Symbol(x.S, Decl(lateBoundAssignmentDeclarationSupport5.js, 13, 21)) >x : Symbol(x, Decl(usage.js, 0, 5)) ->S : Symbol(S, Decl(lateBoundAssignmentDeclarationSupport5.js, 13, 21)) +>S : Symbol(x.S, Decl(lateBoundAssignmentDeclarationSupport5.js, 13, 21)) === tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport5.js === // currently unsupported diff --git a/tests/baselines/reference/lateBoundAssignmentDeclarationSupport5.types b/tests/baselines/reference/lateBoundAssignmentDeclarationSupport5.types index 5c73c112a78a1..d5b65354374ca 100644 --- a/tests/baselines/reference/lateBoundAssignmentDeclarationSupport5.types +++ b/tests/baselines/reference/lateBoundAssignmentDeclarationSupport5.types @@ -1,7 +1,7 @@ === tests/cases/conformance/salsa/usage.js === const x = require("./lateBoundAssignmentDeclarationSupport5.js"); ->x : typeof import("tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport5") ->require("./lateBoundAssignmentDeclarationSupport5.js") : typeof import("tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport5") +>x : typeof x +>require("./lateBoundAssignmentDeclarationSupport5.js") : typeof x >require : any >"./lateBoundAssignmentDeclarationSupport5.js" : "./lateBoundAssignmentDeclarationSupport5.js" @@ -9,7 +9,7 @@ const inst = new x.F(); >inst : F >new x.F() : F >x.F : typeof F ->x : typeof import("tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport5") +>x : typeof x >F : typeof F const y = inst["my-fake-sym"]; @@ -23,7 +23,7 @@ const z = inst[x.S]; >inst[x.S] : any >inst : F >x.S : unique symbol ->x : typeof import("tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport5") +>x : typeof x >S : unique symbol === tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport5.js === diff --git a/tests/baselines/reference/lateBoundAssignmentDeclarationSupport6.symbols b/tests/baselines/reference/lateBoundAssignmentDeclarationSupport6.symbols index a77cac27638bf..f4feb41d11d40 100644 --- a/tests/baselines/reference/lateBoundAssignmentDeclarationSupport6.symbols +++ b/tests/baselines/reference/lateBoundAssignmentDeclarationSupport6.symbols @@ -2,13 +2,13 @@ const x = require("./lateBoundAssignmentDeclarationSupport6.js"); >x : Symbol(x, Decl(usage.js, 0, 5)) >require : Symbol(require) ->"./lateBoundAssignmentDeclarationSupport6.js" : Symbol("tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport6", Decl(lateBoundAssignmentDeclarationSupport6.js, 0, 0)) +>"./lateBoundAssignmentDeclarationSupport6.js" : Symbol(x, Decl(lateBoundAssignmentDeclarationSupport6.js, 0, 0)) const inst = new x.F(); >inst : Symbol(inst, Decl(usage.js, 1, 5)) ->x.F : Symbol(F, Decl(lateBoundAssignmentDeclarationSupport6.js, 11, 22)) +>x.F : Symbol(x.F, Decl(lateBoundAssignmentDeclarationSupport6.js, 11, 22)) >x : Symbol(x, Decl(usage.js, 0, 5)) ->F : Symbol(F, Decl(lateBoundAssignmentDeclarationSupport6.js, 11, 22)) +>F : Symbol(x.F, Decl(lateBoundAssignmentDeclarationSupport6.js, 11, 22)) const y = inst["my-fake-sym"]; >y : Symbol(y, Decl(usage.js, 2, 5)) @@ -17,9 +17,9 @@ const y = inst["my-fake-sym"]; const z = inst[x.S]; >z : Symbol(z, Decl(usage.js, 3, 5)) >inst : Symbol(inst, Decl(usage.js, 1, 5)) ->x.S : Symbol(S, Decl(lateBoundAssignmentDeclarationSupport6.js, 12, 21)) +>x.S : Symbol(x.S, Decl(lateBoundAssignmentDeclarationSupport6.js, 12, 21)) >x : Symbol(x, Decl(usage.js, 0, 5)) ->S : Symbol(S, Decl(lateBoundAssignmentDeclarationSupport6.js, 12, 21)) +>S : Symbol(x.S, Decl(lateBoundAssignmentDeclarationSupport6.js, 12, 21)) === tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport6.js === // currently unsupported diff --git a/tests/baselines/reference/lateBoundAssignmentDeclarationSupport6.types b/tests/baselines/reference/lateBoundAssignmentDeclarationSupport6.types index 4aa5319115454..54d6ca94a9e1b 100644 --- a/tests/baselines/reference/lateBoundAssignmentDeclarationSupport6.types +++ b/tests/baselines/reference/lateBoundAssignmentDeclarationSupport6.types @@ -1,7 +1,7 @@ === tests/cases/conformance/salsa/usage.js === const x = require("./lateBoundAssignmentDeclarationSupport6.js"); ->x : typeof import("tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport6") ->require("./lateBoundAssignmentDeclarationSupport6.js") : typeof import("tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport6") +>x : typeof x +>require("./lateBoundAssignmentDeclarationSupport6.js") : typeof x >require : any >"./lateBoundAssignmentDeclarationSupport6.js" : "./lateBoundAssignmentDeclarationSupport6.js" @@ -9,7 +9,7 @@ const inst = new x.F(); >inst : F >new x.F() : F >x.F : typeof F ->x : typeof import("tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport6") +>x : typeof x >F : typeof F const y = inst["my-fake-sym"]; @@ -23,7 +23,7 @@ const z = inst[x.S]; >inst[x.S] : any >inst : F >x.S : unique symbol ->x : typeof import("tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport6") +>x : typeof x >S : unique symbol === tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport6.js === diff --git a/tests/baselines/reference/lateBoundAssignmentDeclarationSupport7.symbols b/tests/baselines/reference/lateBoundAssignmentDeclarationSupport7.symbols index e0014532ecbec..434f00ed278fe 100644 --- a/tests/baselines/reference/lateBoundAssignmentDeclarationSupport7.symbols +++ b/tests/baselines/reference/lateBoundAssignmentDeclarationSupport7.symbols @@ -2,23 +2,23 @@ const x = require("./lateBoundAssignmentDeclarationSupport7.js"); >x : Symbol(x, Decl(usage.js, 0, 5)) >require : Symbol(require) ->"./lateBoundAssignmentDeclarationSupport7.js" : Symbol("tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport7", Decl(lateBoundAssignmentDeclarationSupport7.js, 0, 0)) +>"./lateBoundAssignmentDeclarationSupport7.js" : Symbol(x, Decl(lateBoundAssignmentDeclarationSupport7.js, 0, 0)) const y = x.F["my-fake-sym"]; >y : Symbol(y, Decl(usage.js, 1, 5)) ->x.F : Symbol(F, Decl(lateBoundAssignmentDeclarationSupport7.js, 6, 15)) +>x.F : Symbol(x.F, Decl(lateBoundAssignmentDeclarationSupport7.js, 6, 15)) >x : Symbol(x, Decl(usage.js, 0, 5)) ->F : Symbol(F, Decl(lateBoundAssignmentDeclarationSupport7.js, 6, 15)) +>F : Symbol(x.F, Decl(lateBoundAssignmentDeclarationSupport7.js, 6, 15)) >"my-fake-sym" : Symbol(F.F[_str], Decl(lateBoundAssignmentDeclarationSupport7.js, 5, 15)) const z = x.F[x.S]; >z : Symbol(z, Decl(usage.js, 2, 5)) ->x.F : Symbol(F, Decl(lateBoundAssignmentDeclarationSupport7.js, 6, 15)) +>x.F : Symbol(x.F, Decl(lateBoundAssignmentDeclarationSupport7.js, 6, 15)) >x : Symbol(x, Decl(usage.js, 0, 5)) ->F : Symbol(F, Decl(lateBoundAssignmentDeclarationSupport7.js, 6, 15)) ->x.S : Symbol(S, Decl(lateBoundAssignmentDeclarationSupport7.js, 7, 21)) +>F : Symbol(x.F, Decl(lateBoundAssignmentDeclarationSupport7.js, 6, 15)) +>x.S : Symbol(x.S, Decl(lateBoundAssignmentDeclarationSupport7.js, 7, 21)) >x : Symbol(x, Decl(usage.js, 0, 5)) ->S : Symbol(S, Decl(lateBoundAssignmentDeclarationSupport7.js, 7, 21)) +>S : Symbol(x.S, Decl(lateBoundAssignmentDeclarationSupport7.js, 7, 21)) === tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport7.js === const _sym = Symbol(); diff --git a/tests/baselines/reference/lateBoundAssignmentDeclarationSupport7.types b/tests/baselines/reference/lateBoundAssignmentDeclarationSupport7.types index 84c3829369131..d0d472cb20ad4 100644 --- a/tests/baselines/reference/lateBoundAssignmentDeclarationSupport7.types +++ b/tests/baselines/reference/lateBoundAssignmentDeclarationSupport7.types @@ -1,7 +1,7 @@ === tests/cases/conformance/salsa/usage.js === const x = require("./lateBoundAssignmentDeclarationSupport7.js"); ->x : typeof import("tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport7") ->require("./lateBoundAssignmentDeclarationSupport7.js") : typeof import("tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport7") +>x : typeof x +>require("./lateBoundAssignmentDeclarationSupport7.js") : typeof x >require : any >"./lateBoundAssignmentDeclarationSupport7.js" : "./lateBoundAssignmentDeclarationSupport7.js" @@ -9,7 +9,7 @@ const y = x.F["my-fake-sym"]; >y : string >x.F["my-fake-sym"] : string >x.F : typeof F ->x : typeof import("tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport7") +>x : typeof x >F : typeof F >"my-fake-sym" : "my-fake-sym" @@ -17,10 +17,10 @@ const z = x.F[x.S]; >z : string >x.F[x.S] : string >x.F : typeof F ->x : typeof import("tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport7") +>x : typeof x >F : typeof F >x.S : unique symbol ->x : typeof import("tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport7") +>x : typeof x >S : unique symbol === tests/cases/conformance/salsa/lateBoundAssignmentDeclarationSupport7.js === diff --git a/tests/baselines/reference/moduleExportAlias2.symbols b/tests/baselines/reference/moduleExportAlias2.symbols index 3571a6760e191..2e33643aa9018 100644 --- a/tests/baselines/reference/moduleExportAlias2.symbols +++ b/tests/baselines/reference/moduleExportAlias2.symbols @@ -7,9 +7,9 @@ const C = require("./semver") var two = C.f(1) >two : Symbol(two, Decl(index.js, 2, 3)) ->C.f : Symbol(f, Decl(semver.js, 1, 28)) +>C.f : Symbol(C.f, Decl(semver.js, 1, 28)) >C : Symbol(C, Decl(index.js, 1, 5)) ->f : Symbol(f, Decl(semver.js, 1, 28)) +>f : Symbol(C.f, Decl(semver.js, 1, 28)) var c = new C >c : Symbol(c, Decl(index.js, 3, 3)) diff --git a/tests/baselines/reference/moduleExportAlias2.types b/tests/baselines/reference/moduleExportAlias2.types index 6552d86075414..6f8ba54ad61da 100644 --- a/tests/baselines/reference/moduleExportAlias2.types +++ b/tests/baselines/reference/moduleExportAlias2.types @@ -1,8 +1,8 @@ === tests/cases/conformance/salsa/index.js === /// const C = require("./semver") ->C : typeof import("tests/cases/conformance/salsa/semver") ->require("./semver") : typeof import("tests/cases/conformance/salsa/semver") +>C : typeof C +>require("./semver") : typeof C >require : (name: string) => any >"./semver" : "./semver" @@ -10,14 +10,14 @@ var two = C.f(1) >two : any >C.f(1) : any >C.f : (n: any) => any ->C : typeof import("tests/cases/conformance/salsa/semver") +>C : typeof C >f : (n: any) => any >1 : 1 var c = new C ->c : import("tests/cases/conformance/salsa/semver") ->new C : import("tests/cases/conformance/salsa/semver") ->C : typeof import("tests/cases/conformance/salsa/semver") +>c : C +>new C : C +>C : typeof C === tests/cases/conformance/salsa/node.d.ts === declare function require(name: string): any; diff --git a/tests/baselines/reference/typeFromParamTagForFunction.types b/tests/baselines/reference/typeFromParamTagForFunction.types index 73daa299cf1be..f36bca8748c20 100644 --- a/tests/baselines/reference/typeFromParamTagForFunction.types +++ b/tests/baselines/reference/typeFromParamTagForFunction.types @@ -86,17 +86,17 @@ export function C() { === tests/cases/conformance/salsa/c.js === const { C } = require("./c-ext"); ->C : typeof import("tests/cases/conformance/salsa/c-ext").C +>C : typeof C >require("./c-ext") : typeof import("tests/cases/conformance/salsa/c-ext") >require : (id: string) => any >"./c-ext" : "./c-ext" /** @param {C} p */ function c(p) { p.x; } ->c : (p: import("tests/cases/conformance/salsa/c-ext").C) => void ->p : import("tests/cases/conformance/salsa/c-ext").C +>c : (p: C) => void +>p : C >p.x : number ->p : import("tests/cases/conformance/salsa/c-ext").C +>p : C >x : number === tests/cases/conformance/salsa/d-ext.js === @@ -144,17 +144,17 @@ export class E { === tests/cases/conformance/salsa/e.js === const { E } = require("./e-ext"); ->E : typeof import("tests/cases/conformance/salsa/e-ext").E +>E : typeof E >require("./e-ext") : typeof import("tests/cases/conformance/salsa/e-ext") >require : (id: string) => any >"./e-ext" : "./e-ext" /** @param {E} p */ function e(p) { p.x; } ->e : (p: import("tests/cases/conformance/salsa/e-ext").E) => void ->p : import("tests/cases/conformance/salsa/e-ext").E +>e : (p: E) => void +>p : E >p.x : number ->p : import("tests/cases/conformance/salsa/e-ext").E +>p : E >x : number === tests/cases/conformance/salsa/f.js === diff --git a/tests/baselines/reference/typeFromPropertyAssignment19.types b/tests/baselines/reference/typeFromPropertyAssignment19.types index d09029fb94954..a82897616e32b 100644 --- a/tests/baselines/reference/typeFromPropertyAssignment19.types +++ b/tests/baselines/reference/typeFromPropertyAssignment19.types @@ -1,8 +1,8 @@ === tests/cases/conformance/salsa/index.js === /// const C = require("./semver") ->C : typeof import("tests/cases/conformance/salsa/semver") ->require("./semver") : typeof import("tests/cases/conformance/salsa/semver") +>C : typeof C +>require("./semver") : typeof C >require : any >"./semver" : "./semver" @@ -10,7 +10,7 @@ var two = C.f(1) >two : any >C.f(1) : any >C.f : (n: any) => any ->C : typeof import("tests/cases/conformance/salsa/semver") +>C : typeof C >f : (n: any) => any >1 : 1 diff --git a/tests/baselines/reference/typeFromPropertyAssignment37.symbols b/tests/baselines/reference/typeFromPropertyAssignment37.symbols index 4d2af775b000a..909ded56c27c7 100644 --- a/tests/baselines/reference/typeFromPropertyAssignment37.symbols +++ b/tests/baselines/reference/typeFromPropertyAssignment37.symbols @@ -2,20 +2,20 @@ const util = require('./mod') >util : Symbol(util, Decl(use.js, 0, 5)) >require : Symbol(require) ->'./mod' : Symbol("tests/cases/conformance/salsa/mod", Decl(mod.js, 0, 0)) +>'./mod' : Symbol(util, Decl(mod.js, 0, 0)) function n() { >n : Symbol(n, Decl(use.js, 0, 29)) util.existy // no error ->util.existy : Symbol(existy, Decl(mod.js, 1, 14)) +>util.existy : Symbol(util.existy, Decl(mod.js, 1, 14)) >util : Symbol(util, Decl(use.js, 0, 5)) ->existy : Symbol(existy, Decl(mod.js, 1, 14)) +>existy : Symbol(util.existy, Decl(mod.js, 1, 14)) } util.existy // no error ->util.existy : Symbol(existy, Decl(mod.js, 1, 14)) +>util.existy : Symbol(util.existy, Decl(mod.js, 1, 14)) >util : Symbol(util, Decl(use.js, 0, 5)) ->existy : Symbol(existy, Decl(mod.js, 1, 14)) +>existy : Symbol(util.existy, Decl(mod.js, 1, 14)) === tests/cases/conformance/salsa/mod.js === const util = exports = module.exports = {} diff --git a/tests/baselines/reference/typeFromPropertyAssignment37.types b/tests/baselines/reference/typeFromPropertyAssignment37.types index 5a6ed5d845469..2813969da827e 100644 --- a/tests/baselines/reference/typeFromPropertyAssignment37.types +++ b/tests/baselines/reference/typeFromPropertyAssignment37.types @@ -1,7 +1,7 @@ === tests/cases/conformance/salsa/use.js === const util = require('./mod') ->util : typeof import("tests/cases/conformance/salsa/mod") ->require('./mod') : typeof import("tests/cases/conformance/salsa/mod") +>util : typeof util +>require('./mod') : typeof util >require : any >'./mod' : "./mod" @@ -10,12 +10,12 @@ function n() { util.existy // no error >util.existy : () => void ->util : typeof import("tests/cases/conformance/salsa/mod") +>util : typeof util >existy : () => void } util.existy // no error >util.existy : () => void ->util : typeof import("tests/cases/conformance/salsa/mod") +>util : typeof util >existy : () => void === tests/cases/conformance/salsa/mod.js === From 20aa6ed7eb4a60371acb5daf61b36e80d4c73b70 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Thu, 9 Jul 2020 16:16:43 -0700 Subject: [PATCH 04/30] 2nd round of baseline updates --- src/compiler/binder.ts | 8 +++++- .../chainedPrototypeAssignment.symbols | 10 +++---- .../chainedPrototypeAssignment.types | 8 +++--- .../reference/moduleExportAlias4.symbols | 8 +++--- .../reference/moduleExportAlias4.types | 22 ++++++++-------- .../reference/moduleExportAssignment.symbols | 4 +-- ...ExportWithExportPropertyAssignment.symbols | 4 +-- ...xportWithExportPropertyAssignment3.symbols | 4 +-- ...xportWithExportPropertyAssignment4.symbols | 16 ++++++------ ...eExportWithExportPropertyAssignment4.types | 12 ++++----- .../typeFromPropertyAssignment17.symbols | 12 ++++----- .../typeFromPropertyAssignment17.types | 10 +++---- .../varRequireFromJavascript.symbols | 14 +++++----- .../reference/varRequireFromJavascript.types | 22 ++++++++-------- .../varRequireFromTypescript.symbols | 14 +++++----- .../reference/varRequireFromTypescript.types | 26 +++++++++---------- 16 files changed, 100 insertions(+), 94 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index a8c5218de58d6..f5705632ae361 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -3184,6 +3184,7 @@ namespace ts { if (!isBindingPattern(node.name)) { if (isBlockOrCatchScoped(node)) { + // TODO: This can probably come first, and be mutex with the succeeding 3 branches if (isRequireVariableDeclaration(node, /*requireStringLiteralLikeArgument*/ true)) { declareSymbolAndAddToSymbolTable(node, SymbolFlags.Alias, SymbolFlags.AliasExcludes); } @@ -3204,7 +3205,12 @@ namespace ts { declareSymbolAndAddToSymbolTable(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.ParameterExcludes); } else { - declareSymbolAndAddToSymbolTable(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.FunctionScopedVariableExcludes); + if (isRequireVariableDeclaration(node, /*requireStringLiteralLikeArgument*/ true)) { + declareSymbolAndAddToSymbolTable(node, SymbolFlags.Alias, SymbolFlags.AliasExcludes); + } + else { + declareSymbolAndAddToSymbolTable(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.FunctionScopedVariableExcludes); + } } } } diff --git a/tests/baselines/reference/chainedPrototypeAssignment.symbols b/tests/baselines/reference/chainedPrototypeAssignment.symbols index 64211c83d0206..bd31b70bc87f1 100644 --- a/tests/baselines/reference/chainedPrototypeAssignment.symbols +++ b/tests/baselines/reference/chainedPrototypeAssignment.symbols @@ -3,19 +3,19 @@ var mod = require('./mod'); >mod : Symbol(mod, Decl(use.js, 1, 3)) >require : Symbol(require, Decl(types.d.ts, 0, 0)) ->'./mod' : Symbol("tests/cases/conformance/salsa/mod", Decl(mod.js, 0, 0)) +>'./mod' : Symbol(mod, Decl(mod.js, 0, 0)) var a = new mod.A() >a : Symbol(a, Decl(use.js, 2, 3)) ->mod.A : Symbol(A, Decl(mod.js, 6, 1)) +>mod.A : Symbol(mod.A, Decl(mod.js, 6, 1)) >mod : Symbol(mod, Decl(use.js, 1, 3)) ->A : Symbol(A, Decl(mod.js, 6, 1)) +>A : Symbol(mod.A, Decl(mod.js, 6, 1)) var b = new mod.B() >b : Symbol(b, Decl(use.js, 3, 3)) ->mod.B : Symbol(B, Decl(mod.js, 7, 13)) +>mod.B : Symbol(mod.B, Decl(mod.js, 7, 13)) >mod : Symbol(mod, Decl(use.js, 1, 3)) ->B : Symbol(B, Decl(mod.js, 7, 13)) +>B : Symbol(mod.B, Decl(mod.js, 7, 13)) a.m('nope') >a.m : Symbol(m, Decl(mod.js, 9, 29)) diff --git a/tests/baselines/reference/chainedPrototypeAssignment.types b/tests/baselines/reference/chainedPrototypeAssignment.types index d3754807da6ae..ccd81fa038096 100644 --- a/tests/baselines/reference/chainedPrototypeAssignment.types +++ b/tests/baselines/reference/chainedPrototypeAssignment.types @@ -1,8 +1,8 @@ === tests/cases/conformance/salsa/use.js === /// var mod = require('./mod'); ->mod : typeof import("tests/cases/conformance/salsa/mod") ->require('./mod') : typeof import("tests/cases/conformance/salsa/mod") +>mod : typeof mod +>require('./mod') : typeof mod >require : (name: string) => any >'./mod' : "./mod" @@ -10,14 +10,14 @@ var a = new mod.A() >a : A >new mod.A() : A >mod.A : typeof A ->mod : typeof import("tests/cases/conformance/salsa/mod") +>mod : typeof mod >A : typeof A var b = new mod.B() >b : B >new mod.B() : B >mod.B : typeof B ->mod : typeof import("tests/cases/conformance/salsa/mod") +>mod : typeof mod >B : typeof B a.m('nope') diff --git a/tests/baselines/reference/moduleExportAlias4.symbols b/tests/baselines/reference/moduleExportAlias4.symbols index fd149513b7bb0..2d27298ac9038 100644 --- a/tests/baselines/reference/moduleExportAlias4.symbols +++ b/tests/baselines/reference/moduleExportAlias4.symbols @@ -9,13 +9,13 @@ module.exports = class C {} >module.exports : Symbol("tests/cases/conformance/salsa/bug24024", Decl(bug24024.js, 0, 0)) >module : Symbol(export=, Decl(bug24024.js, 1, 31)) >exports : Symbol(export=, Decl(bug24024.js, 1, 31)) ->C : Symbol(C, Decl(bug24024.js, 2, 16)) +>C : Symbol(wat, Decl(bug24024.js, 2, 16)) module.exports.D = class D { } ->module.exports.D : Symbol(D, Decl(bug24024.js, 2, 27)) ->module.exports : Symbol(D, Decl(bug24024.js, 2, 27)) +>module.exports.D : Symbol(wat.D, Decl(bug24024.js, 2, 27)) +>module.exports : Symbol(wat.D, Decl(bug24024.js, 2, 27)) >module : Symbol(module, Decl(bug24024.js, 1, 31)) >exports : Symbol("tests/cases/conformance/salsa/bug24024", Decl(bug24024.js, 0, 0)) ->D : Symbol(D, Decl(bug24024.js, 2, 27)) +>D : Symbol(wat.D, Decl(bug24024.js, 2, 27)) >D : Symbol(D, Decl(bug24024.js, 3, 18)) diff --git a/tests/baselines/reference/moduleExportAlias4.types b/tests/baselines/reference/moduleExportAlias4.types index 5bf29c9331e4c..173c7c714a284 100644 --- a/tests/baselines/reference/moduleExportAlias4.types +++ b/tests/baselines/reference/moduleExportAlias4.types @@ -1,25 +1,25 @@ === tests/cases/conformance/salsa/bug24024.js === // #24024 var wat = require('./bug24024') ->wat : typeof import("tests/cases/conformance/salsa/bug24024") ->require('./bug24024') : typeof import("tests/cases/conformance/salsa/bug24024") +>wat : typeof wat +>require('./bug24024') : typeof wat >require : any >'./bug24024' : "./bug24024" module.exports = class C {} ->module.exports = class C {} : typeof import("tests/cases/conformance/salsa/bug24024") ->module.exports : typeof import("tests/cases/conformance/salsa/bug24024") ->module : { "\"tests/cases/conformance/salsa/bug24024\"": typeof import("tests/cases/conformance/salsa/bug24024"); } ->exports : typeof import("tests/cases/conformance/salsa/bug24024") ->class C {} : typeof import("tests/cases/conformance/salsa/bug24024") ->C : typeof import("tests/cases/conformance/salsa/bug24024") +>module.exports = class C {} : typeof wat +>module.exports : typeof wat +>module : { "\"tests/cases/conformance/salsa/bug24024\"": typeof wat; } +>exports : typeof wat +>class C {} : typeof wat +>C : typeof wat module.exports.D = class D { } >module.exports.D = class D { } : typeof D >module.exports.D : typeof D ->module.exports : typeof import("tests/cases/conformance/salsa/bug24024") ->module : { "\"tests/cases/conformance/salsa/bug24024\"": typeof import("tests/cases/conformance/salsa/bug24024"); } ->exports : typeof import("tests/cases/conformance/salsa/bug24024") +>module.exports : typeof wat +>module : { "\"tests/cases/conformance/salsa/bug24024\"": typeof wat; } +>exports : typeof wat >D : typeof D >class D { } : typeof D >D : typeof D diff --git a/tests/baselines/reference/moduleExportAssignment.symbols b/tests/baselines/reference/moduleExportAssignment.symbols index be741bdb9880a..e89dabfd946ef 100644 --- a/tests/baselines/reference/moduleExportAssignment.symbols +++ b/tests/baselines/reference/moduleExportAssignment.symbols @@ -5,9 +5,9 @@ var npmlog = require('./npmlog') >'./npmlog' : Symbol("tests/cases/conformance/salsa/npmlog", Decl(npmlog.js, 0, 0)) npmlog.x ->npmlog.x : Symbol(x, Decl(npmlog.js, 7, 23)) +>npmlog.x : Symbol(npmlog.x, Decl(npmlog.js, 7, 23)) >npmlog : Symbol(npmlog, Decl(use.js, 0, 3)) ->x : Symbol(x, Decl(npmlog.js, 7, 23)) +>x : Symbol(npmlog.x, Decl(npmlog.js, 7, 23)) npmlog.on >npmlog.on : Symbol(EE.on, Decl(npmlog.js, 0, 10)) diff --git a/tests/baselines/reference/moduleExportWithExportPropertyAssignment.symbols b/tests/baselines/reference/moduleExportWithExportPropertyAssignment.symbols index 19725dbd2a519..c65205747a60f 100644 --- a/tests/baselines/reference/moduleExportWithExportPropertyAssignment.symbols +++ b/tests/baselines/reference/moduleExportWithExportPropertyAssignment.symbols @@ -9,9 +9,9 @@ mod1() >mod1 : Symbol(mod1, Decl(a.js, 1, 3)) mod1.f() // error, not enough arguments ->mod1.f : Symbol(f, Decl(mod1.js, 1, 32)) +>mod1.f : Symbol(mod1.f, Decl(mod1.js, 1, 32)) >mod1 : Symbol(mod1, Decl(a.js, 1, 3)) ->f : Symbol(f, Decl(mod1.js, 1, 32)) +>f : Symbol(mod1.f, Decl(mod1.js, 1, 32)) === tests/cases/conformance/salsa/requires.d.ts === declare var module: { exports: any }; diff --git a/tests/baselines/reference/moduleExportWithExportPropertyAssignment3.symbols b/tests/baselines/reference/moduleExportWithExportPropertyAssignment3.symbols index 1c4aa535f6164..6006339a0b418 100644 --- a/tests/baselines/reference/moduleExportWithExportPropertyAssignment3.symbols +++ b/tests/baselines/reference/moduleExportWithExportPropertyAssignment3.symbols @@ -24,9 +24,9 @@ mod1.bothAfter.toFixed() // error, 'toFixed' not on 'string | number' mod1.justProperty.length >mod1.justProperty.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) ->mod1.justProperty : Symbol(justProperty, Decl(mod1.js, 7, 35)) +>mod1.justProperty : Symbol(mod1.justProperty, Decl(mod1.js, 7, 35)) >mod1 : Symbol(mod1, Decl(a.js, 1, 3)) ->justProperty : Symbol(justProperty, Decl(mod1.js, 7, 35)) +>justProperty : Symbol(mod1.justProperty, Decl(mod1.js, 7, 35)) >length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) === tests/cases/conformance/salsa/requires.d.ts === diff --git a/tests/baselines/reference/moduleExportWithExportPropertyAssignment4.symbols b/tests/baselines/reference/moduleExportWithExportPropertyAssignment4.symbols index 82277b0540a63..5f7dbc398dc2d 100644 --- a/tests/baselines/reference/moduleExportWithExportPropertyAssignment4.symbols +++ b/tests/baselines/reference/moduleExportWithExportPropertyAssignment4.symbols @@ -7,26 +7,26 @@ var mod1 = require('./mod1') mod1.justExport.toFixed() >mod1.justExport.toFixed : Symbol(Number.toFixed, Decl(lib.es5.d.ts, --, --)) ->mod1.justExport : Symbol(A.justExport, Decl(mod1.js, 1, 36)) +>mod1.justExport : Symbol(mod1.justExport, Decl(mod1.js, 1, 36)) >mod1 : Symbol(mod1, Decl(a.js, 1, 3)) ->justExport : Symbol(A.justExport, Decl(mod1.js, 1, 36)) +>justExport : Symbol(mod1.justExport, Decl(mod1.js, 1, 36)) >toFixed : Symbol(Number.toFixed, Decl(lib.es5.d.ts, --, --)) mod1.bothBefore.toFixed() // error ->mod1.bothBefore : Symbol(A.bothBefore, Decl(mod1.js, 2, 16), Decl(mod1.js, 0, 0)) +>mod1.bothBefore : Symbol(mod1.bothBefore, Decl(mod1.js, 2, 16), Decl(mod1.js, 0, 0)) >mod1 : Symbol(mod1, Decl(a.js, 1, 3)) ->bothBefore : Symbol(A.bothBefore, Decl(mod1.js, 2, 16), Decl(mod1.js, 0, 0)) +>bothBefore : Symbol(mod1.bothBefore, Decl(mod1.js, 2, 16), Decl(mod1.js, 0, 0)) mod1.bothAfter.toFixed() ->mod1.bothAfter : Symbol(A.bothAfter, Decl(mod1.js, 3, 16), Decl(mod1.js, 8, 1)) +>mod1.bothAfter : Symbol(mod1.bothAfter, Decl(mod1.js, 3, 16), Decl(mod1.js, 8, 1)) >mod1 : Symbol(mod1, Decl(a.js, 1, 3)) ->bothAfter : Symbol(A.bothAfter, Decl(mod1.js, 3, 16), Decl(mod1.js, 8, 1)) +>bothAfter : Symbol(mod1.bothAfter, Decl(mod1.js, 3, 16), Decl(mod1.js, 8, 1)) mod1.justProperty.length >mod1.justProperty.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) ->mod1.justProperty : Symbol(justProperty, Decl(mod1.js, 9, 35)) +>mod1.justProperty : Symbol(mod1.justProperty, Decl(mod1.js, 9, 35)) >mod1 : Symbol(mod1, Decl(a.js, 1, 3)) ->justProperty : Symbol(justProperty, Decl(mod1.js, 9, 35)) +>justProperty : Symbol(mod1.justProperty, Decl(mod1.js, 9, 35)) >length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) === tests/cases/conformance/salsa/requires.d.ts === diff --git a/tests/baselines/reference/moduleExportWithExportPropertyAssignment4.types b/tests/baselines/reference/moduleExportWithExportPropertyAssignment4.types index 0ddaff1d58a90..d74a430cc15e0 100644 --- a/tests/baselines/reference/moduleExportWithExportPropertyAssignment4.types +++ b/tests/baselines/reference/moduleExportWithExportPropertyAssignment4.types @@ -1,8 +1,8 @@ === tests/cases/conformance/salsa/a.js === /// var mod1 = require('./mod1') ->mod1 : typeof import("tests/cases/conformance/salsa/mod1") ->require('./mod1') : typeof import("tests/cases/conformance/salsa/mod1") +>mod1 : typeof mod1 +>require('./mod1') : typeof mod1 >require : (name: string) => any >'./mod1' : "./mod1" @@ -10,7 +10,7 @@ mod1.justExport.toFixed() >mod1.justExport.toFixed() : string >mod1.justExport.toFixed : (fractionDigits?: number) => string >mod1.justExport : number ->mod1 : typeof import("tests/cases/conformance/salsa/mod1") +>mod1 : typeof mod1 >justExport : number >toFixed : (fractionDigits?: number) => string @@ -18,7 +18,7 @@ mod1.bothBefore.toFixed() // error >mod1.bothBefore.toFixed() : any >mod1.bothBefore.toFixed : any >mod1.bothBefore : string | number ->mod1 : typeof import("tests/cases/conformance/salsa/mod1") +>mod1 : typeof mod1 >bothBefore : string | number >toFixed : any @@ -26,14 +26,14 @@ mod1.bothAfter.toFixed() >mod1.bothAfter.toFixed() : any >mod1.bothAfter.toFixed : any >mod1.bothAfter : string | number ->mod1 : typeof import("tests/cases/conformance/salsa/mod1") +>mod1 : typeof mod1 >bothAfter : string | number >toFixed : any mod1.justProperty.length >mod1.justProperty.length : number >mod1.justProperty : string ->mod1 : typeof import("tests/cases/conformance/salsa/mod1") +>mod1 : typeof mod1 >justProperty : string >length : number diff --git a/tests/baselines/reference/typeFromPropertyAssignment17.symbols b/tests/baselines/reference/typeFromPropertyAssignment17.symbols index 5d6f98f309b63..b6121ee2507cc 100644 --- a/tests/baselines/reference/typeFromPropertyAssignment17.symbols +++ b/tests/baselines/reference/typeFromPropertyAssignment17.symbols @@ -7,16 +7,16 @@ var mini = require('./minimatch') mini.M.defaults() >mini.M.defaults : Symbol(M.defaults, Decl(minimatch.js, 8, 1)) ->mini.M : Symbol(minimatch.M, Decl(minimatch.js, 1, 26)) +>mini.M : Symbol(mini.M, Decl(minimatch.js, 1, 26)) >mini : Symbol(mini, Decl(use.js, 1, 3)) ->M : Symbol(minimatch.M, Decl(minimatch.js, 1, 26)) +>M : Symbol(mini.M, Decl(minimatch.js, 1, 26)) >defaults : Symbol(M.defaults, Decl(minimatch.js, 8, 1)) var m = new mini.M() >m : Symbol(m, Decl(use.js, 3, 3)) ->mini.M : Symbol(minimatch.M, Decl(minimatch.js, 1, 26)) +>mini.M : Symbol(mini.M, Decl(minimatch.js, 1, 26)) >mini : Symbol(mini, Decl(use.js, 1, 3)) ->M : Symbol(minimatch.M, Decl(minimatch.js, 1, 26)) +>M : Symbol(mini.M, Decl(minimatch.js, 1, 26)) m.m() >m.m : Symbol(M.m, Decl(minimatch.js, 11, 1)) @@ -24,9 +24,9 @@ m.m() >m : Symbol(M.m, Decl(minimatch.js, 11, 1)) mini.filter() ->mini.filter : Symbol(minimatch.filter, Decl(minimatch.js, 2, 15)) +>mini.filter : Symbol(mini.filter, Decl(minimatch.js, 2, 15)) >mini : Symbol(mini, Decl(use.js, 1, 3)) ->filter : Symbol(minimatch.filter, Decl(minimatch.js, 2, 15)) +>filter : Symbol(mini.filter, Decl(minimatch.js, 2, 15)) === tests/cases/conformance/salsa/types.d.ts === declare var require: any; diff --git a/tests/baselines/reference/typeFromPropertyAssignment17.types b/tests/baselines/reference/typeFromPropertyAssignment17.types index 9ed784c6a204b..86f6b6346f166 100644 --- a/tests/baselines/reference/typeFromPropertyAssignment17.types +++ b/tests/baselines/reference/typeFromPropertyAssignment17.types @@ -1,8 +1,8 @@ === tests/cases/conformance/salsa/use.js === /// var mini = require('./minimatch') ->mini : typeof import("tests/cases/conformance/salsa/minimatch") ->require('./minimatch') : typeof import("tests/cases/conformance/salsa/minimatch") +>mini : typeof mini +>require('./minimatch') : typeof mini >require : any >'./minimatch' : "./minimatch" @@ -10,7 +10,7 @@ mini.M.defaults() >mini.M.defaults() : any >mini.M.defaults : (def: any) => any >mini.M : typeof M ->mini : typeof import("tests/cases/conformance/salsa/minimatch") +>mini : typeof mini >M : typeof M >defaults : (def: any) => any @@ -18,7 +18,7 @@ var m = new mini.M() >m : M >new mini.M() : M >mini.M : typeof M ->mini : typeof import("tests/cases/conformance/salsa/minimatch") +>mini : typeof mini >M : typeof M m.m() @@ -30,7 +30,7 @@ m.m() mini.filter() >mini.filter() : void >mini.filter : () => void ->mini : typeof import("tests/cases/conformance/salsa/minimatch") +>mini : typeof mini >filter : () => void === tests/cases/conformance/salsa/types.d.ts === diff --git a/tests/baselines/reference/varRequireFromJavascript.symbols b/tests/baselines/reference/varRequireFromJavascript.symbols index 03a2a2516dee2..0ea20514a8c7e 100644 --- a/tests/baselines/reference/varRequireFromJavascript.symbols +++ b/tests/baselines/reference/varRequireFromJavascript.symbols @@ -2,19 +2,19 @@ var ex = require('./ex') >ex : Symbol(ex, Decl(use.js, 0, 3)) >require : Symbol(require) ->'./ex' : Symbol("tests/cases/conformance/salsa/ex", Decl(ex.js, 0, 0)) +>'./ex' : Symbol(ex, Decl(ex.js, 0, 0)) // values work var crunch = new ex.Crunch(1); >crunch : Symbol(crunch, Decl(use.js, 3, 3)) ->ex.Crunch : Symbol(Crunch, Decl(ex.js, 0, 0)) +>ex.Crunch : Symbol(ex.Crunch, Decl(ex.js, 0, 0)) >ex : Symbol(ex, Decl(use.js, 0, 3)) ->Crunch : Symbol(Crunch, Decl(ex.js, 0, 0)) +>Crunch : Symbol(ex.Crunch, Decl(ex.js, 0, 0)) crunch.n ->crunch.n : Symbol(Crunch.n, Decl(ex.js, 2, 20)) +>crunch.n : Symbol(ex.Crunch.n, Decl(ex.js, 2, 20)) >crunch : Symbol(crunch, Decl(use.js, 3, 3)) ->n : Symbol(Crunch.n, Decl(ex.js, 2, 20)) +>n : Symbol(ex.Crunch.n, Decl(ex.js, 2, 20)) // types work @@ -26,9 +26,9 @@ function f(wrap) { >wrap : Symbol(wrap, Decl(use.js, 11, 11)) wrap.n ->wrap.n : Symbol(Crunch.n, Decl(ex.js, 2, 20)) +>wrap.n : Symbol(ex.Crunch.n, Decl(ex.js, 2, 20)) >wrap : Symbol(wrap, Decl(use.js, 11, 11)) ->n : Symbol(Crunch.n, Decl(ex.js, 2, 20)) +>n : Symbol(ex.Crunch.n, Decl(ex.js, 2, 20)) } === tests/cases/conformance/salsa/ex.js === diff --git a/tests/baselines/reference/varRequireFromJavascript.types b/tests/baselines/reference/varRequireFromJavascript.types index 84fef5df25936..f304eb6a1a106 100644 --- a/tests/baselines/reference/varRequireFromJavascript.types +++ b/tests/baselines/reference/varRequireFromJavascript.types @@ -1,22 +1,22 @@ === tests/cases/conformance/salsa/use.js === var ex = require('./ex') ->ex : typeof import("tests/cases/conformance/salsa/ex") ->require('./ex') : typeof import("tests/cases/conformance/salsa/ex") +>ex : typeof ex +>require('./ex') : typeof ex >require : any >'./ex' : "./ex" // values work var crunch = new ex.Crunch(1); ->crunch : import("tests/cases/conformance/salsa/ex").Crunch ->new ex.Crunch(1) : import("tests/cases/conformance/salsa/ex").Crunch ->ex.Crunch : typeof import("tests/cases/conformance/salsa/ex").Crunch ->ex : typeof import("tests/cases/conformance/salsa/ex") ->Crunch : typeof import("tests/cases/conformance/salsa/ex").Crunch +>crunch : ex.Crunch +>new ex.Crunch(1) : ex.Crunch +>ex.Crunch : typeof ex.Crunch +>ex : typeof ex +>Crunch : typeof ex.Crunch >1 : 1 crunch.n >crunch.n : number ->crunch : import("tests/cases/conformance/salsa/ex").Crunch +>crunch : ex.Crunch >n : number @@ -25,12 +25,12 @@ crunch.n * @param {ex.Crunch} wrap */ function f(wrap) { ->f : (wrap: import("tests/cases/conformance/salsa/ex").Crunch) => void ->wrap : import("tests/cases/conformance/salsa/ex").Crunch +>f : (wrap: ex.Crunch) => void +>wrap : ex.Crunch wrap.n >wrap.n : number ->wrap : import("tests/cases/conformance/salsa/ex").Crunch +>wrap : ex.Crunch >n : number } diff --git a/tests/baselines/reference/varRequireFromTypescript.symbols b/tests/baselines/reference/varRequireFromTypescript.symbols index 70c918aba056c..9ed299b1d7b26 100644 --- a/tests/baselines/reference/varRequireFromTypescript.symbols +++ b/tests/baselines/reference/varRequireFromTypescript.symbols @@ -2,19 +2,19 @@ var ex = require('./ex') >ex : Symbol(ex, Decl(use.js, 0, 3)) >require : Symbol(require) ->'./ex' : Symbol("tests/cases/conformance/salsa/ex", Decl(ex.d.ts, 0, 0)) +>'./ex' : Symbol(ex, Decl(ex.d.ts, 0, 0)) // values work var crunch = new ex.Crunch(1); >crunch : Symbol(crunch, Decl(use.js, 3, 3)) ->ex.Crunch : Symbol(Crunch, Decl(ex.d.ts, 0, 33)) +>ex.Crunch : Symbol(ex.Crunch, Decl(ex.d.ts, 0, 33)) >ex : Symbol(ex, Decl(use.js, 0, 3)) ->Crunch : Symbol(Crunch, Decl(ex.d.ts, 0, 33)) +>Crunch : Symbol(ex.Crunch, Decl(ex.d.ts, 0, 33)) crunch.n ->crunch.n : Symbol(Crunch.n, Decl(ex.d.ts, 1, 21)) +>crunch.n : Symbol(ex.Crunch.n, Decl(ex.d.ts, 1, 21)) >crunch : Symbol(crunch, Decl(use.js, 3, 3)) ->n : Symbol(Crunch.n, Decl(ex.d.ts, 1, 21)) +>n : Symbol(ex.Crunch.n, Decl(ex.d.ts, 1, 21)) // types work @@ -33,9 +33,9 @@ function f(greatest, wrap) { >day : Symbol(day, Decl(ex.d.ts, 0, 24)) wrap.n ->wrap.n : Symbol(Crunch.n, Decl(ex.d.ts, 1, 21)) +>wrap.n : Symbol(ex.Crunch.n, Decl(ex.d.ts, 1, 21)) >wrap : Symbol(wrap, Decl(use.js, 12, 20)) ->n : Symbol(Crunch.n, Decl(ex.d.ts, 1, 21)) +>n : Symbol(ex.Crunch.n, Decl(ex.d.ts, 1, 21)) } === tests/cases/conformance/salsa/ex.d.ts === diff --git a/tests/baselines/reference/varRequireFromTypescript.types b/tests/baselines/reference/varRequireFromTypescript.types index 7010bfaf1a800..931f95e9bd5a2 100644 --- a/tests/baselines/reference/varRequireFromTypescript.types +++ b/tests/baselines/reference/varRequireFromTypescript.types @@ -1,22 +1,22 @@ === tests/cases/conformance/salsa/use.js === var ex = require('./ex') ->ex : typeof import("tests/cases/conformance/salsa/ex") ->require('./ex') : typeof import("tests/cases/conformance/salsa/ex") +>ex : typeof ex +>require('./ex') : typeof ex >require : any >'./ex' : "./ex" // values work var crunch = new ex.Crunch(1); ->crunch : import("tests/cases/conformance/salsa/ex").Crunch ->new ex.Crunch(1) : import("tests/cases/conformance/salsa/ex").Crunch ->ex.Crunch : typeof import("tests/cases/conformance/salsa/ex").Crunch ->ex : typeof import("tests/cases/conformance/salsa/ex") ->Crunch : typeof import("tests/cases/conformance/salsa/ex").Crunch +>crunch : ex.Crunch +>new ex.Crunch(1) : ex.Crunch +>ex.Crunch : typeof ex.Crunch +>ex : typeof ex +>Crunch : typeof ex.Crunch >1 : 1 crunch.n >crunch.n : number ->crunch : import("tests/cases/conformance/salsa/ex").Crunch +>crunch : ex.Crunch >n : number @@ -26,18 +26,18 @@ crunch.n * @param {ex.Crunch} wrap */ function f(greatest, wrap) { ->f : (greatest: import("tests/cases/conformance/salsa/ex").Greatest, wrap: import("tests/cases/conformance/salsa/ex").Crunch) => void ->greatest : import("tests/cases/conformance/salsa/ex").Greatest ->wrap : import("tests/cases/conformance/salsa/ex").Crunch +>f : (greatest: ex.Greatest, wrap: ex.Crunch) => void +>greatest : ex.Greatest +>wrap : ex.Crunch greatest.day >greatest.day : 1 ->greatest : import("tests/cases/conformance/salsa/ex").Greatest +>greatest : ex.Greatest >day : 1 wrap.n >wrap.n : number ->wrap : import("tests/cases/conformance/salsa/ex").Crunch +>wrap : ex.Crunch >n : number } From f21370778c200fde6fa10787833097770d076e05 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Fri, 10 Jul 2020 10:42:22 -0700 Subject: [PATCH 05/30] support property access after require --- src/compiler/binder.ts | 1 - src/compiler/checker.ts | 11 +++++-- .../reference/ambientRequireFunction.symbols | 6 ++-- .../reference/ambientRequireFunction.types | 6 ++-- ...ignmentDefineProperrtyPotentialMerge.types | 4 +-- .../reference/jsdocImportType.symbols | 8 ++--- .../baselines/reference/jsdocImportType.types | 12 +++---- .../reference/jsdocImportType2.symbols | 8 ++--- .../reference/jsdocImportType2.types | 12 +++---- .../jsdocTypeFromChainedAssignment2.symbols | 18 +++++------ .../jsdocTypeFromChainedAssignment2.types | 12 +++---- .../jsdocTypeReferenceToImport.types | 32 +++++++++---------- ...peReferenceToImportOfClassExpression.types | 10 +++--- ...eferenceToImportOfFunctionExpression.types | 8 ++--- .../reference/localRequireFunction.types | 8 ++--- ...duleExportsElementAccessAssignment.symbols | 30 ++++++++--------- ...moduleExportsElementAccessAssignment.types | 24 +++++++------- .../noCrashOnParameterNamedRequire.errors.txt | 10 ++++++ 18 files changed, 118 insertions(+), 102 deletions(-) create mode 100644 tests/baselines/reference/noCrashOnParameterNamedRequire.errors.txt diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index f5705632ae361..5b95229afcd62 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -543,7 +543,6 @@ namespace ts { function declareModuleMember(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags): Symbol { const hasExportModifier = getCombinedModifierFlags(node) & ModifierFlags.Export; if (symbolFlags & SymbolFlags.Alias) { - // TODO: handle non-destructuring const x=require here (after altering flags from bindVariableDeclaration) if (node.kind === SyntaxKind.ExportSpecifier || (node.kind === SyntaxKind.ImportEqualsDeclaration && hasExportModifier)) { return declareSymbol(container.symbol.exports!, container.symbol, node, symbolFlags, symbolExcludes); } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index be04b956177a8..b46a34860c83d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2391,6 +2391,12 @@ namespace ts { ? (getFirstPropertyAccessExpression(node.initializer!) as CallExpression).arguments[0] : getExternalModuleImportEqualsDeclarationExpression(node)); const resolved = resolveExternalModuleSymbol(immediate); + if (isVariableDeclaration(node) && node.initializer && isPropertyAccessExpression(node.initializer)) { + // TODO: Relies on old code in resolveCallExpression that special-cases `require("x")` + return isIdentifier(node.initializer.name) + ? getPropertyOfType(checkExpression(node.initializer.expression), node.initializer.name.escapedText) + : undefined; + } markSymbolOfAliasDeclarationIfTypeOnly(node, immediate, resolved, /*overwriteEmpty*/ false); return resolved; } @@ -32764,11 +32770,12 @@ namespace ts { } // For a require binding element, validate the alias and exit // TODO: Probably should mark the symbol so I don't have to keep rescanning this - if (/*isBindingElement(node) && */isRequireVariableDeclaration(node, /*requireStringLiteralLikeArgument*/ true)) { + const symbol = getSymbolOfNode(node); + if (/*isBindingElement(node) && */isRequireVariableDeclaration(node, /*requireStringLiteralLikeArgument*/ true) && symbol.flags & SymbolFlags.Alias) { checkAliasSymbol(node); return; } - const symbol = getSymbolOfNode(node); + const type = convertAutoToAny(getTypeOfSymbol(symbol)); if (node === symbol.valueDeclaration) { // Node is the primary declaration of the symbol, just validate the initializer diff --git a/tests/baselines/reference/ambientRequireFunction.symbols b/tests/baselines/reference/ambientRequireFunction.symbols index b2e94e89a2cb9..3fb2c754805c6 100644 --- a/tests/baselines/reference/ambientRequireFunction.symbols +++ b/tests/baselines/reference/ambientRequireFunction.symbols @@ -4,13 +4,13 @@ const fs = require("fs"); >fs : Symbol(fs, Decl(app.js, 2, 5)) >require : Symbol(require, Decl(node.d.ts, 0, 0)) ->"fs" : Symbol("fs", Decl(node.d.ts, 0, 50)) +>"fs" : Symbol(fs, Decl(node.d.ts, 0, 50)) const text = fs.readFileSync("/a/b/c"); >text : Symbol(text, Decl(app.js, 3, 5)) ->fs.readFileSync : Symbol(readFileSync, Decl(node.d.ts, 2, 21)) +>fs.readFileSync : Symbol(fs.readFileSync, Decl(node.d.ts, 2, 21)) >fs : Symbol(fs, Decl(app.js, 2, 5)) ->readFileSync : Symbol(readFileSync, Decl(node.d.ts, 2, 21)) +>readFileSync : Symbol(fs.readFileSync, Decl(node.d.ts, 2, 21)) === tests/cases/compiler/node.d.ts === declare function require(moduleName: string): any; diff --git a/tests/baselines/reference/ambientRequireFunction.types b/tests/baselines/reference/ambientRequireFunction.types index d8d47964cfdfd..487305a139a33 100644 --- a/tests/baselines/reference/ambientRequireFunction.types +++ b/tests/baselines/reference/ambientRequireFunction.types @@ -2,8 +2,8 @@ /// const fs = require("fs"); ->fs : typeof import("fs") ->require("fs") : typeof import("fs") +>fs : typeof fs +>require("fs") : typeof fs >require : (moduleName: string) => any >"fs" : "fs" @@ -11,7 +11,7 @@ const text = fs.readFileSync("/a/b/c"); >text : string >fs.readFileSync("/a/b/c") : string >fs.readFileSync : (s: string) => string ->fs : typeof import("fs") +>fs : typeof fs >readFileSync : (s: string) => string >"/a/b/c" : "/a/b/c" diff --git a/tests/baselines/reference/ensureNoCrashExportAssignmentDefineProperrtyPotentialMerge.types b/tests/baselines/reference/ensureNoCrashExportAssignmentDefineProperrtyPotentialMerge.types index 95ac66a27c838..cb026f00735df 100644 --- a/tests/baselines/reference/ensureNoCrashExportAssignmentDefineProperrtyPotentialMerge.types +++ b/tests/baselines/reference/ensureNoCrashExportAssignmentDefineProperrtyPotentialMerge.types @@ -1,7 +1,7 @@ === tests/cases/compiler/index.js === const _item = require("./namespacer"); ->_item : typeof B ->require("./namespacer") : typeof B +>_item : typeof _item +>require("./namespacer") : typeof _item >require : any >"./namespacer" : "./namespacer" diff --git a/tests/baselines/reference/jsdocImportType.symbols b/tests/baselines/reference/jsdocImportType.symbols index dbe46e966e315..aeb548cd84fea 100644 --- a/tests/baselines/reference/jsdocImportType.symbols +++ b/tests/baselines/reference/jsdocImportType.symbols @@ -6,9 +6,9 @@ var c; >c : Symbol(c, Decl(use.js, 3, 3)) c.chunk; ->c.chunk : Symbol(Chunk.chunk, Decl(mod1.js, 2, 19)) +>c.chunk : Symbol(D.chunk, Decl(mod1.js, 2, 19)) >c : Symbol(c, Decl(use.js, 3, 3)) ->chunk : Symbol(Chunk.chunk, Decl(mod1.js, 2, 19)) +>chunk : Symbol(D.chunk, Decl(mod1.js, 2, 19)) const D = require("./mod1"); >D : Symbol(D, Decl(use.js, 6, 5)) @@ -20,9 +20,9 @@ var d; >d : Symbol(d, Decl(use.js, 8, 3)) d.chunk; ->d.chunk : Symbol(Chunk.chunk, Decl(mod1.js, 2, 19)) +>d.chunk : Symbol(D.chunk, Decl(mod1.js, 2, 19)) >d : Symbol(d, Decl(use.js, 8, 3)) ->chunk : Symbol(Chunk.chunk, Decl(mod1.js, 2, 19)) +>chunk : Symbol(D.chunk, Decl(mod1.js, 2, 19)) === tests/cases/conformance/jsdoc/types.d.ts === declare function require(name: string): any; diff --git a/tests/baselines/reference/jsdocImportType.types b/tests/baselines/reference/jsdocImportType.types index b1d7542475079..b5703459955c3 100644 --- a/tests/baselines/reference/jsdocImportType.types +++ b/tests/baselines/reference/jsdocImportType.types @@ -3,26 +3,26 @@ /** @typedef {import("./mod1")} C * @type {C} */ var c; ->c : import("tests/cases/conformance/jsdoc/mod1") +>c : D c.chunk; >c.chunk : number ->c : import("tests/cases/conformance/jsdoc/mod1") +>c : D >chunk : number const D = require("./mod1"); ->D : typeof import("tests/cases/conformance/jsdoc/mod1") ->require("./mod1") : typeof import("tests/cases/conformance/jsdoc/mod1") +>D : typeof D +>require("./mod1") : typeof D >require : (name: string) => any >"./mod1" : "./mod1" /** @type {D} */ var d; ->d : import("tests/cases/conformance/jsdoc/mod1") +>d : D d.chunk; >d.chunk : number ->d : import("tests/cases/conformance/jsdoc/mod1") +>d : D >chunk : number === tests/cases/conformance/jsdoc/types.d.ts === diff --git a/tests/baselines/reference/jsdocImportType2.symbols b/tests/baselines/reference/jsdocImportType2.symbols index a7ed5cc3d41c5..cecfd006ea89c 100644 --- a/tests/baselines/reference/jsdocImportType2.symbols +++ b/tests/baselines/reference/jsdocImportType2.symbols @@ -6,9 +6,9 @@ var c; >c : Symbol(c, Decl(use.js, 3, 3)) c.chunk; ->c.chunk : Symbol(Chunk.chunk, Decl(mod1.js, 2, 19)) +>c.chunk : Symbol(D.chunk, Decl(mod1.js, 2, 19)) >c : Symbol(c, Decl(use.js, 3, 3)) ->chunk : Symbol(Chunk.chunk, Decl(mod1.js, 2, 19)) +>chunk : Symbol(D.chunk, Decl(mod1.js, 2, 19)) const D = require("./mod1"); >D : Symbol(D, Decl(use.js, 6, 5)) @@ -20,9 +20,9 @@ var d; >d : Symbol(d, Decl(use.js, 8, 3)) d.chunk; ->d.chunk : Symbol(Chunk.chunk, Decl(mod1.js, 2, 19)) +>d.chunk : Symbol(D.chunk, Decl(mod1.js, 2, 19)) >d : Symbol(d, Decl(use.js, 8, 3)) ->chunk : Symbol(Chunk.chunk, Decl(mod1.js, 2, 19)) +>chunk : Symbol(D.chunk, Decl(mod1.js, 2, 19)) === tests/cases/conformance/jsdoc/types.d.ts === declare function require(name: string): any; diff --git a/tests/baselines/reference/jsdocImportType2.types b/tests/baselines/reference/jsdocImportType2.types index f4386faf5a695..b966871b9eff3 100644 --- a/tests/baselines/reference/jsdocImportType2.types +++ b/tests/baselines/reference/jsdocImportType2.types @@ -3,26 +3,26 @@ /** @typedef {import("./mod1")} C * @type {C} */ var c; ->c : import("tests/cases/conformance/jsdoc/mod1") +>c : D c.chunk; >c.chunk : number ->c : import("tests/cases/conformance/jsdoc/mod1") +>c : D >chunk : number const D = require("./mod1"); ->D : typeof import("tests/cases/conformance/jsdoc/mod1") ->require("./mod1") : typeof import("tests/cases/conformance/jsdoc/mod1") +>D : typeof D +>require("./mod1") : typeof D >require : (name: string) => any >"./mod1" : "./mod1" /** @type {D} */ var d; ->d : import("tests/cases/conformance/jsdoc/mod1") +>d : D d.chunk; >d.chunk : number ->d : import("tests/cases/conformance/jsdoc/mod1") +>d : D >chunk : number === tests/cases/conformance/jsdoc/types.d.ts === diff --git a/tests/baselines/reference/jsdocTypeFromChainedAssignment2.symbols b/tests/baselines/reference/jsdocTypeFromChainedAssignment2.symbols index ae7236a015641..646159ed41957 100644 --- a/tests/baselines/reference/jsdocTypeFromChainedAssignment2.symbols +++ b/tests/baselines/reference/jsdocTypeFromChainedAssignment2.symbols @@ -2,27 +2,27 @@ var mod = require('./mod'); >mod : Symbol(mod, Decl(use.js, 0, 3)) >require : Symbol(require) ->'./mod' : Symbol("tests/cases/conformance/jsdoc/mod", Decl(mod.js, 0, 0)) +>'./mod' : Symbol(mod, Decl(mod.js, 0, 0)) mod.f('no') ->mod.f : Symbol(f, Decl(mod.js, 0, 0)) +>mod.f : Symbol(mod.f, Decl(mod.js, 0, 0)) >mod : Symbol(mod, Decl(use.js, 0, 3)) ->f : Symbol(f, Decl(mod.js, 0, 0)) +>f : Symbol(mod.f, Decl(mod.js, 0, 0)) mod.g('also no') ->mod.g : Symbol(g, Decl(mod.js, 1, 11)) +>mod.g : Symbol(mod.g, Decl(mod.js, 1, 11)) >mod : Symbol(mod, Decl(use.js, 0, 3)) ->g : Symbol(g, Decl(mod.js, 1, 11)) +>g : Symbol(mod.g, Decl(mod.js, 1, 11)) mod.h(0) ->mod.h : Symbol(h, Decl(mod.js, 3, 1)) +>mod.h : Symbol(mod.h, Decl(mod.js, 3, 1)) >mod : Symbol(mod, Decl(use.js, 0, 3)) ->h : Symbol(h, Decl(mod.js, 3, 1)) +>h : Symbol(mod.h, Decl(mod.js, 3, 1)) mod.i(1) ->mod.i : Symbol(i, Decl(mod.js, 5, 18)) +>mod.i : Symbol(mod.i, Decl(mod.js, 5, 18)) >mod : Symbol(mod, Decl(use.js, 0, 3)) ->i : Symbol(i, Decl(mod.js, 5, 18)) +>i : Symbol(mod.i, Decl(mod.js, 5, 18)) === tests/cases/conformance/jsdoc/mod.js === /** @param {number} n */ diff --git a/tests/baselines/reference/jsdocTypeFromChainedAssignment2.types b/tests/baselines/reference/jsdocTypeFromChainedAssignment2.types index 75e198978f4d4..7bbcb5becabcb 100644 --- a/tests/baselines/reference/jsdocTypeFromChainedAssignment2.types +++ b/tests/baselines/reference/jsdocTypeFromChainedAssignment2.types @@ -1,35 +1,35 @@ === tests/cases/conformance/jsdoc/use.js === var mod = require('./mod'); ->mod : typeof import("tests/cases/conformance/jsdoc/mod") ->require('./mod') : typeof import("tests/cases/conformance/jsdoc/mod") +>mod : typeof mod +>require('./mod') : typeof mod >require : any >'./mod' : "./mod" mod.f('no') >mod.f('no') : number >mod.f : (n: number) => number ->mod : typeof import("tests/cases/conformance/jsdoc/mod") +>mod : typeof mod >f : (n: number) => number >'no' : "no" mod.g('also no') >mod.g('also no') : number >mod.g : (n: number) => number ->mod : typeof import("tests/cases/conformance/jsdoc/mod") +>mod : typeof mod >g : (n: number) => number >'also no' : "also no" mod.h(0) >mod.h(0) : string >mod.h : (mom: string) => string ->mod : typeof import("tests/cases/conformance/jsdoc/mod") +>mod : typeof mod >h : (mom: string) => string >0 : 0 mod.i(1) >mod.i(1) : string >mod.i : (mom: string) => string ->mod : typeof import("tests/cases/conformance/jsdoc/mod") +>mod : typeof mod >i : (mom: string) => string >1 : 1 diff --git a/tests/baselines/reference/jsdocTypeReferenceToImport.types b/tests/baselines/reference/jsdocTypeReferenceToImport.types index 4d4fe89ae02a5..7002b8d5bdc03 100644 --- a/tests/baselines/reference/jsdocTypeReferenceToImport.types +++ b/tests/baselines/reference/jsdocTypeReferenceToImport.types @@ -2,51 +2,51 @@ // #34802 const C = require('./ex').C; ->C : typeof import("tests/cases/conformance/jsdoc/ex").C ->require('./ex').C : typeof import("tests/cases/conformance/jsdoc/ex").C +>C : typeof C +>require('./ex').C : typeof C >require('./ex') : typeof import("tests/cases/conformance/jsdoc/ex") >require : any >'./ex' : "./ex" ->C : typeof import("tests/cases/conformance/jsdoc/ex").C +>C : typeof C const D = require('./ex')?.C; ->D : typeof import("tests/cases/conformance/jsdoc/ex").C ->require('./ex')?.C : typeof import("tests/cases/conformance/jsdoc/ex").C +>D : typeof C +>require('./ex')?.C : typeof C >require('./ex') : typeof import("tests/cases/conformance/jsdoc/ex") >require : any >'./ex' : "./ex" ->C : typeof import("tests/cases/conformance/jsdoc/ex").C +>C : typeof C /** @type {C} c */ var c = new C() ->c : import("tests/cases/conformance/jsdoc/ex").C ->new C() : import("tests/cases/conformance/jsdoc/ex").C ->C : typeof import("tests/cases/conformance/jsdoc/ex").C +>c : C +>new C() : C +>C : typeof C c.start >c.start : number ->c : import("tests/cases/conformance/jsdoc/ex").C +>c : C >start : number c.end >c.end : number ->c : import("tests/cases/conformance/jsdoc/ex").C +>c : C >end : number /** @type {D} c */ var d = new D() ->d : import("tests/cases/conformance/jsdoc/ex").C ->new D() : import("tests/cases/conformance/jsdoc/ex").C ->D : typeof import("tests/cases/conformance/jsdoc/ex").C +>d : C +>new D() : C +>D : typeof C d.start >d.start : number ->d : import("tests/cases/conformance/jsdoc/ex").C +>d : C >start : number d.end >d.end : number ->d : import("tests/cases/conformance/jsdoc/ex").C +>d : C >end : number === tests/cases/conformance/jsdoc/ex.d.ts === diff --git a/tests/baselines/reference/jsdocTypeReferenceToImportOfClassExpression.types b/tests/baselines/reference/jsdocTypeReferenceToImportOfClassExpression.types index 0645f6adfda1f..144cd81db37f2 100644 --- a/tests/baselines/reference/jsdocTypeReferenceToImportOfClassExpression.types +++ b/tests/baselines/reference/jsdocTypeReferenceToImportOfClassExpression.types @@ -1,7 +1,7 @@ === tests/cases/conformance/jsdoc/MC.js === const MW = require("./MW"); ->MW : typeof import("tests/cases/conformance/jsdoc/MW") ->require("./MW") : typeof import("tests/cases/conformance/jsdoc/MW") +>MW : typeof MW +>require("./MW") : typeof MW >require : any >"./MW" : "./MW" @@ -16,11 +16,11 @@ module.exports = class MC { >MC : typeof import("tests/cases/conformance/jsdoc/MC") watch() { ->watch : () => import("tests/cases/conformance/jsdoc/MW") +>watch : () => MW return new MW(this); ->new MW(this) : import("tests/cases/conformance/jsdoc/MW") ->MW : typeof import("tests/cases/conformance/jsdoc/MW") +>new MW(this) : MW +>MW : typeof MW >this : this } }; diff --git a/tests/baselines/reference/jsdocTypeReferenceToImportOfFunctionExpression.types b/tests/baselines/reference/jsdocTypeReferenceToImportOfFunctionExpression.types index 81422f0c76c9d..a6956b2bb558a 100644 --- a/tests/baselines/reference/jsdocTypeReferenceToImportOfFunctionExpression.types +++ b/tests/baselines/reference/jsdocTypeReferenceToImportOfFunctionExpression.types @@ -1,7 +1,7 @@ === tests/cases/conformance/jsdoc/MC.js === const MW = require("./MW"); ->MW : typeof import("tests/cases/conformance/jsdoc/MW") ->require("./MW") : typeof import("tests/cases/conformance/jsdoc/MW") +>MW : typeof MW +>require("./MW") : typeof MW >require : any >"./MW" : "./MW" @@ -22,8 +22,8 @@ module.exports = function MC() { >{} : {} return new MW(x); ->new MW(x) : import("tests/cases/conformance/jsdoc/MW") ->MW : typeof import("tests/cases/conformance/jsdoc/MW") +>new MW(x) : MW +>MW : typeof MW >x : any }; diff --git a/tests/baselines/reference/localRequireFunction.types b/tests/baselines/reference/localRequireFunction.types index 21f9c81bd29d2..4e1eb6f49c935 100644 --- a/tests/baselines/reference/localRequireFunction.types +++ b/tests/baselines/reference/localRequireFunction.types @@ -8,15 +8,15 @@ function require(a) { } const fs = require("fs"); ->fs : any +>fs : error >require("fs") : any >require : (a: any) => any >"fs" : "fs" const text = fs.readFileSync("/a/b/c"); ->text : any ->fs.readFileSync("/a/b/c") : any ->fs.readFileSync : any +>text : error +>fs.readFileSync("/a/b/c") : error +>fs.readFileSync : error >fs : any >readFileSync : any >"/a/b/c" : "/a/b/c" diff --git a/tests/baselines/reference/moduleExportsElementAccessAssignment.symbols b/tests/baselines/reference/moduleExportsElementAccessAssignment.symbols index 8032c898c934f..a13575852f071 100644 --- a/tests/baselines/reference/moduleExportsElementAccessAssignment.symbols +++ b/tests/baselines/reference/moduleExportsElementAccessAssignment.symbols @@ -2,39 +2,39 @@ const mod1 = require("./mod1"); >mod1 : Symbol(mod1, Decl(mod2.js, 0, 5)) >require : Symbol(require) ->"./mod1" : Symbol("tests/cases/conformance/jsdoc/mod1", Decl(mod1.js, 0, 0)) +>"./mod1" : Symbol(mod1, Decl(mod1.js, 0, 0)) mod1.a; ->mod1.a : Symbol(a, Decl(mod1.js, 0, 0)) +>mod1.a : Symbol(mod1.a, Decl(mod1.js, 0, 0)) >mod1 : Symbol(mod1, Decl(mod2.js, 0, 5)) ->a : Symbol(a, Decl(mod1.js, 0, 0)) +>a : Symbol(mod1.a, Decl(mod1.js, 0, 0)) mod1.b; ->mod1.b : Symbol("b", Decl(mod1.js, 0, 23)) +>mod1.b : Symbol(mod1["b"], Decl(mod1.js, 0, 23)) >mod1 : Symbol(mod1, Decl(mod2.js, 0, 5)) ->b : Symbol("b", Decl(mod1.js, 0, 23)) +>b : Symbol(mod1["b"], Decl(mod1.js, 0, 23)) mod1.c; ->mod1.c : Symbol("c", Decl(mod1.js, 2, 32)) +>mod1.c : Symbol(mod1["c"], Decl(mod1.js, 2, 32)) >mod1 : Symbol(mod1, Decl(mod2.js, 0, 5)) ->c : Symbol("c", Decl(mod1.js, 2, 32)) +>c : Symbol(mod1["c"], Decl(mod1.js, 2, 32)) mod1.d; ->mod1.d : Symbol("d", Decl(mod1.js, 3, 33), Decl(mod1.js, 5, 18)) +>mod1.d : Symbol(mod1["d"], Decl(mod1.js, 3, 33), Decl(mod1.js, 5, 18)) >mod1 : Symbol(mod1, Decl(mod2.js, 0, 5)) ->d : Symbol("d", Decl(mod1.js, 3, 33), Decl(mod1.js, 5, 18)) +>d : Symbol(mod1["d"], Decl(mod1.js, 3, 33), Decl(mod1.js, 5, 18)) mod1.d.e; ->mod1.d.e : Symbol("d".e, Decl(mod1.js, 4, 28)) ->mod1.d : Symbol("d", Decl(mod1.js, 3, 33), Decl(mod1.js, 5, 18)) +>mod1.d.e : Symbol(mod1["d"].e, Decl(mod1.js, 4, 28)) +>mod1.d : Symbol(mod1["d"], Decl(mod1.js, 3, 33), Decl(mod1.js, 5, 18)) >mod1 : Symbol(mod1, Decl(mod2.js, 0, 5)) ->d : Symbol("d", Decl(mod1.js, 3, 33), Decl(mod1.js, 5, 18)) ->e : Symbol("d".e, Decl(mod1.js, 4, 28)) +>d : Symbol(mod1["d"], Decl(mod1.js, 3, 33), Decl(mod1.js, 5, 18)) +>e : Symbol(mod1["d"].e, Decl(mod1.js, 4, 28)) mod1.default; ->mod1.default : Symbol(default, Decl(mod1.js, 1, 26)) +>mod1.default : Symbol(mod1.default, Decl(mod1.js, 1, 26)) >mod1 : Symbol(mod1, Decl(mod2.js, 0, 5)) ->default : Symbol(default, Decl(mod1.js, 1, 26)) +>default : Symbol(mod1.default, Decl(mod1.js, 1, 26)) === tests/cases/conformance/jsdoc/mod1.js === exports.a = { x: "x" }; diff --git a/tests/baselines/reference/moduleExportsElementAccessAssignment.types b/tests/baselines/reference/moduleExportsElementAccessAssignment.types index 39ff18ddd3411..b5f4c3e0e5ab0 100644 --- a/tests/baselines/reference/moduleExportsElementAccessAssignment.types +++ b/tests/baselines/reference/moduleExportsElementAccessAssignment.types @@ -1,40 +1,40 @@ === tests/cases/conformance/jsdoc/mod2.js === const mod1 = require("./mod1"); ->mod1 : typeof import("tests/cases/conformance/jsdoc/mod1") ->require("./mod1") : typeof import("tests/cases/conformance/jsdoc/mod1") +>mod1 : typeof mod1 +>require("./mod1") : typeof mod1 >require : any >"./mod1" : "./mod1" mod1.a; >mod1.a : { x: string; } ->mod1 : typeof import("tests/cases/conformance/jsdoc/mod1") +>mod1 : typeof mod1 >a : { x: string; } mod1.b; >mod1.b : { x: string; } ->mod1 : typeof import("tests/cases/conformance/jsdoc/mod1") +>mod1 : typeof mod1 >b : { x: string; } mod1.c; >mod1.c : { x: string; } ->mod1 : typeof import("tests/cases/conformance/jsdoc/mod1") +>mod1 : typeof mod1 >c : { x: string; } mod1.d; ->mod1.d : typeof import("tests/cases/conformance/jsdoc/mod1").d ->mod1 : typeof import("tests/cases/conformance/jsdoc/mod1") ->d : typeof import("tests/cases/conformance/jsdoc/mod1").d +>mod1.d : typeof mod1."d" +>mod1 : typeof mod1 +>d : typeof mod1."d" mod1.d.e; >mod1.d.e : number ->mod1.d : typeof import("tests/cases/conformance/jsdoc/mod1").d ->mod1 : typeof import("tests/cases/conformance/jsdoc/mod1") ->d : typeof import("tests/cases/conformance/jsdoc/mod1").d +>mod1.d : typeof mod1."d" +>mod1 : typeof mod1 +>d : typeof mod1."d" >e : number mod1.default; >mod1.default : { x: string; } ->mod1 : typeof import("tests/cases/conformance/jsdoc/mod1") +>mod1 : typeof mod1 >default : { x: string; } === tests/cases/conformance/jsdoc/mod1.js === diff --git a/tests/baselines/reference/noCrashOnParameterNamedRequire.errors.txt b/tests/baselines/reference/noCrashOnParameterNamedRequire.errors.txt new file mode 100644 index 0000000000000..847b16da03b5d --- /dev/null +++ b/tests/baselines/reference/noCrashOnParameterNamedRequire.errors.txt @@ -0,0 +1,10 @@ +tests/cases/compiler/index.js(2,25): error TS2307: Cannot find module './mod' or its corresponding type declarations. + + +==== tests/cases/compiler/index.js (1 errors) ==== + (function(require, module, exports){ + const mod = require("./mod"); + ~~~~~~~ +!!! error TS2307: Cannot find module './mod' or its corresponding type declarations. + mod.foo; + })(null, null, null); \ No newline at end of file From 122babdcf2d11793ed001f79b9baf7143d6f596d Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Fri, 10 Jul 2020 13:15:53 -0700 Subject: [PATCH 06/30] check @type tag on require --- src/compiler/checker.ts | 35 +++++++++++++++---- .../checkExportsObjectAssignProperty.symbols | 8 ++--- .../requireOfJsonFileInJsFile.errors.txt | 8 ++--- .../requireOfJsonFileInJsFile.symbols | 8 ++--- .../reference/requireOfJsonFileInJsFile.types | 6 ++-- 5 files changed, 44 insertions(+), 21 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b46a34860c83d..125ac7fc81c8c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2390,13 +2390,30 @@ namespace ts { const immediate = resolveExternalModuleName(node, isVariableDeclaration(node) ? (getFirstPropertyAccessExpression(node.initializer!) as CallExpression).arguments[0] : getExternalModuleImportEqualsDeclarationExpression(node)); - const resolved = resolveExternalModuleSymbol(immediate); - if (isVariableDeclaration(node) && node.initializer && isPropertyAccessExpression(node.initializer)) { - // TODO: Relies on old code in resolveCallExpression that special-cases `require("x")` - return isIdentifier(node.initializer.name) - ? getPropertyOfType(checkExpression(node.initializer.expression), node.initializer.name.escapedText) - : undefined; + if (isVariableDeclaration(node)) { + const typeTag = getJSDocTypeTag(node); + if (node.initializer && isPropertyAccessExpression(node.initializer)) { + if (!isIdentifier(node.initializer.name)) + return undefined; + // TODO: Relies on old code in resolveCallExpression that special-cases `require("x")` + const original = getPropertyOfType(checkExpression(node.initializer.expression), node.initializer.name.escapedText); + if (typeTag && original) { + const symbol: TransientSymbol = cloneSymbol(original) as TransientSymbol + symbol.type = getTypeFromTypeNode(typeTag.typeExpression); + return symbol; + } + // TODO: Might still want to resolveExternalModuleSymbol here? + return original; + } + else if (typeTag && immediate) { + // TODO: This is basically wrong. + const symbol: TransientSymbol = cloneSymbol(immediate) as TransientSymbol + symbol.type = getTypeFromTypeNode(typeTag.typeExpression); + return symbol; + } + return resolveExternalModuleSymbol(immediate); } + const resolved = resolveExternalModuleSymbol(immediate); markSymbolOfAliasDeclarationIfTypeOnly(node, immediate, resolved, /*overwriteEmpty*/ false); return resolved; } @@ -32773,6 +32790,12 @@ namespace ts { const symbol = getSymbolOfNode(node); if (/*isBindingElement(node) && */isRequireVariableDeclaration(node, /*requireStringLiteralLikeArgument*/ true) && symbol.flags & SymbolFlags.Alias) { checkAliasSymbol(node); + const typeTag = getJSDocTypeTag(node); + const initializer = node.initializer; + if (typeTag) { + const type = getTypeFromTypeNode(typeTag.typeExpression); + checkTypeAssignableToAndOptionallyElaborate(checkExpressionCached(initializer), type, node, initializer, /*headMessage*/ undefined); + } return; } diff --git a/tests/baselines/reference/checkExportsObjectAssignProperty.symbols b/tests/baselines/reference/checkExportsObjectAssignProperty.symbols index e1dcacbfe2c8f..15306b0f325b8 100644 --- a/tests/baselines/reference/checkExportsObjectAssignProperty.symbols +++ b/tests/baselines/reference/checkExportsObjectAssignProperty.symbols @@ -269,18 +269,18 @@ Object.defineProperty(module.exports, "setonlyAccessor", { */ const q = require("./mod1").thing; >q : Symbol(q, Decl(index.js, 3, 5)) ->require("./mod1").thing : Symbol(thing, Decl(mod1.js, 0, 0)) +>require("./mod1").thing : Symbol(q, Decl(mod1.js, 0, 0)) >require : Symbol(require) >"./mod1" : Symbol("tests/cases/conformance/jsdoc/mod1", Decl(mod1.js, 0, 0)) ->thing : Symbol(thing, Decl(mod1.js, 0, 0)) +>thing : Symbol(q, Decl(mod1.js, 0, 0)) /** * @type {string} */ const u = require("./mod2").thing; >u : Symbol(u, Decl(index.js, 8, 5)) ->require("./mod2").thing : Symbol(thing, Decl(mod2.js, 0, 0)) +>require("./mod2").thing : Symbol(u, Decl(mod2.js, 0, 0)) >require : Symbol(require) >"./mod2" : Symbol("tests/cases/conformance/jsdoc/mod2", Decl(mod2.js, 0, 0)) ->thing : Symbol(thing, Decl(mod2.js, 0, 0)) +>thing : Symbol(u, Decl(mod2.js, 0, 0)) diff --git a/tests/baselines/reference/requireOfJsonFileInJsFile.errors.txt b/tests/baselines/reference/requireOfJsonFileInJsFile.errors.txt index 247aaa31b570c..12faf377df693 100644 --- a/tests/baselines/reference/requireOfJsonFileInJsFile.errors.txt +++ b/tests/baselines/reference/requireOfJsonFileInJsFile.errors.txt @@ -1,6 +1,6 @@ -/user.js(2,7): error TS2339: Property 'b' does not exist on type '{ a: number; }'. +/user.js(2,7): error TS2339: Property 'b' does not exist on type 'typeof "/json"'. /user.js(5,7): error TS2741: Property 'b' is missing in type '{ a: number; }' but required in type '{ b: number; }'. -/user.js(9,7): error TS2339: Property 'b' does not exist on type '{ a: number; }'. +/user.js(9,7): error TS2339: Property 'b' does not exist on type 'typeof "/json"'. /user.js(12,7): error TS2741: Property 'b' is missing in type '{ a: number; }' but required in type '{ b: number; }'. @@ -8,7 +8,7 @@ const json0 = require("./json.json"); json0.b; // Error (good) ~ -!!! error TS2339: Property 'b' does not exist on type '{ a: number; }'. +!!! error TS2339: Property 'b' does not exist on type 'typeof "/json"'. /** @type {{ b: number }} */ const json1 = require("./json.json"); // No error (bad) @@ -20,7 +20,7 @@ const js0 = require("./js.js"); json0.b; // Error (good) ~ -!!! error TS2339: Property 'b' does not exist on type '{ a: number; }'. +!!! error TS2339: Property 'b' does not exist on type 'typeof "/json"'. /** @type {{ b: number }} */ const js1 = require("./js.js"); // Error (good) diff --git a/tests/baselines/reference/requireOfJsonFileInJsFile.symbols b/tests/baselines/reference/requireOfJsonFileInJsFile.symbols index 2a1e9b6ebd307..3ecee55fb42bc 100644 --- a/tests/baselines/reference/requireOfJsonFileInJsFile.symbols +++ b/tests/baselines/reference/requireOfJsonFileInJsFile.symbols @@ -2,7 +2,7 @@ const json0 = require("./json.json"); >json0 : Symbol(json0, Decl(user.js, 0, 5)) >require : Symbol(require) ->"./json.json" : Symbol("/json", Decl(json.json, 0, 0)) +>"./json.json" : Symbol(json0, Decl(json.json, 0, 0)) json0.b; // Error (good) >json0 : Symbol(json0, Decl(user.js, 0, 5)) @@ -11,7 +11,7 @@ json0.b; // Error (good) const json1 = require("./json.json"); // No error (bad) >json1 : Symbol(json1, Decl(user.js, 4, 5)) >require : Symbol(require) ->"./json.json" : Symbol("/json", Decl(json.json, 0, 0)) +>"./json.json" : Symbol(json0, Decl(json.json, 0, 0)) json1.b; // No error (OK since that's the type annotation) >json1.b : Symbol(b, Decl(user.js, 3, 12)) @@ -21,7 +21,7 @@ json1.b; // No error (OK since that's the type annotation) const js0 = require("./js.js"); >js0 : Symbol(js0, Decl(user.js, 7, 5)) >require : Symbol(require) ->"./js.js" : Symbol("/js", Decl(js.js, 0, 0)) +>"./js.js" : Symbol(js0, Decl(js.js, 0, 0)) json0.b; // Error (good) >json0 : Symbol(json0, Decl(user.js, 0, 5)) @@ -30,7 +30,7 @@ json0.b; // Error (good) const js1 = require("./js.js"); // Error (good) >js1 : Symbol(js1, Decl(user.js, 11, 5)) >require : Symbol(require) ->"./js.js" : Symbol("/js", Decl(js.js, 0, 0)) +>"./js.js" : Symbol(js0, Decl(js.js, 0, 0)) js1.b; >js1.b : Symbol(b, Decl(user.js, 10, 12)) diff --git a/tests/baselines/reference/requireOfJsonFileInJsFile.types b/tests/baselines/reference/requireOfJsonFileInJsFile.types index 0e8e9b847ab8f..144f7ceb63ef0 100644 --- a/tests/baselines/reference/requireOfJsonFileInJsFile.types +++ b/tests/baselines/reference/requireOfJsonFileInJsFile.types @@ -1,13 +1,13 @@ === /user.js === const json0 = require("./json.json"); ->json0 : { a: number; } +>json0 : typeof json0 >require("./json.json") : { a: number; } >require : any >"./json.json" : "./json.json" json0.b; // Error (good) >json0.b : any ->json0 : { a: number; } +>json0 : typeof json0 >b : any /** @type {{ b: number }} */ @@ -30,7 +30,7 @@ const js0 = require("./js.js"); json0.b; // Error (good) >json0.b : any ->json0 : { a: number; } +>json0 : typeof json0 >b : any /** @type {{ b: number }} */ From e1e32af9e7f686f2cdd1dfd8e9d51fa3abeb2583 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Fri, 10 Jul 2020 15:35:37 -0700 Subject: [PATCH 07/30] forbid expando missing namespaces on aliases taken from #39558 as soon as it was created --- src/compiler/binder.ts | 4 +- .../checkOtherObjectAssignProperty.symbols | 60 +++++++++---------- .../checkOtherObjectAssignProperty.types | 28 ++++----- 3 files changed, 47 insertions(+), 45 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 5b95229afcd62..82013e733dbec 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -2986,7 +2986,9 @@ namespace ts { const excludeFlags = SymbolFlags.ValueModuleExcludes & ~SymbolFlags.Assignment; namespaceSymbol = forEachIdentifierInEntityName(entityName, namespaceSymbol, (id, symbol, parent) => { if (symbol) { - addDeclarationToSymbol(symbol, id, flags); + if (!(symbol.flags & SymbolFlags.Alias)) { + addDeclarationToSymbol(symbol, id, flags); + } return symbol; } else { diff --git a/tests/baselines/reference/checkOtherObjectAssignProperty.symbols b/tests/baselines/reference/checkOtherObjectAssignProperty.symbols index 33e8560261950..10ff1067b34ce 100644 --- a/tests/baselines/reference/checkOtherObjectAssignProperty.symbols +++ b/tests/baselines/reference/checkOtherObjectAssignProperty.symbols @@ -1,61 +1,61 @@ === tests/cases/conformance/jsdoc/importer.js === const mod = require("./mod1"); ->mod : Symbol(mod, Decl(importer.js, 0, 5), Decl(importer.js, 6, 9), Decl(importer.js, 9, 14), Decl(importer.js, 10, 14), Decl(importer.js, 11, 13) ... and 2 more) +>mod : Symbol(mod, Decl(importer.js, 0, 5)) >require : Symbol(require) ->"./mod1" : Symbol("tests/cases/conformance/jsdoc/mod1", Decl(mod1.js, 0, 0)) +>"./mod1" : Symbol(mod, Decl(mod1.js, 0, 0)) mod.thing; ->mod.thing : Symbol(thing, Decl(mod1.js, 0, 42)) ->mod : Symbol(mod, Decl(importer.js, 0, 5), Decl(importer.js, 6, 9), Decl(importer.js, 9, 14), Decl(importer.js, 10, 14), Decl(importer.js, 11, 13) ... and 2 more) ->thing : Symbol(thing, Decl(mod1.js, 0, 42)) +>mod.thing : Symbol(mod.thing, Decl(mod1.js, 0, 42)) +>mod : Symbol(mod, Decl(importer.js, 0, 5)) +>thing : Symbol(mod.thing, Decl(mod1.js, 0, 42)) mod.other; ->mod : Symbol(mod, Decl(importer.js, 0, 5), Decl(importer.js, 6, 9), Decl(importer.js, 9, 14), Decl(importer.js, 10, 14), Decl(importer.js, 11, 13) ... and 2 more) +>mod : Symbol(mod, Decl(importer.js, 0, 5)) mod.prop; ->mod : Symbol(mod, Decl(importer.js, 0, 5), Decl(importer.js, 6, 9), Decl(importer.js, 9, 14), Decl(importer.js, 10, 14), Decl(importer.js, 11, 13) ... and 2 more) +>mod : Symbol(mod, Decl(importer.js, 0, 5)) mod.bad1; ->mod.bad1 : Symbol(bad1, Decl(mod1.js, 10, 72)) ->mod : Symbol(mod, Decl(importer.js, 0, 5), Decl(importer.js, 6, 9), Decl(importer.js, 9, 14), Decl(importer.js, 10, 14), Decl(importer.js, 11, 13) ... and 2 more) ->bad1 : Symbol(bad1, Decl(mod1.js, 10, 72)) +>mod.bad1 : Symbol(mod.bad1, Decl(mod1.js, 10, 72)) +>mod : Symbol(mod, Decl(importer.js, 0, 5)) +>bad1 : Symbol(mod.bad1, Decl(mod1.js, 10, 72)) mod.bad2; ->mod.bad2 : Symbol(bad2, Decl(mod1.js, 13, 44)) ->mod : Symbol(mod, Decl(importer.js, 0, 5), Decl(importer.js, 6, 9), Decl(importer.js, 9, 14), Decl(importer.js, 10, 14), Decl(importer.js, 11, 13) ... and 2 more) ->bad2 : Symbol(bad2, Decl(mod1.js, 13, 44)) +>mod.bad2 : Symbol(mod.bad2, Decl(mod1.js, 13, 44)) +>mod : Symbol(mod, Decl(importer.js, 0, 5)) +>bad2 : Symbol(mod.bad2, Decl(mod1.js, 13, 44)) mod.bad3; ->mod.bad3 : Symbol(bad3, Decl(mod1.js, 14, 77)) ->mod : Symbol(mod, Decl(importer.js, 0, 5), Decl(importer.js, 6, 9), Decl(importer.js, 9, 14), Decl(importer.js, 10, 14), Decl(importer.js, 11, 13) ... and 2 more) ->bad3 : Symbol(bad3, Decl(mod1.js, 14, 77)) +>mod.bad3 : Symbol(mod.bad3, Decl(mod1.js, 14, 77)) +>mod : Symbol(mod, Decl(importer.js, 0, 5)) +>bad3 : Symbol(mod.bad3, Decl(mod1.js, 14, 77)) mod.thing = 0; ->mod.thing : Symbol(thing, Decl(mod1.js, 0, 42)) ->mod : Symbol(mod, Decl(importer.js, 0, 5), Decl(importer.js, 6, 9), Decl(importer.js, 9, 14), Decl(importer.js, 10, 14), Decl(importer.js, 11, 13) ... and 2 more) ->thing : Symbol(thing, Decl(mod1.js, 0, 42)) +>mod.thing : Symbol(mod.thing, Decl(mod1.js, 0, 42)) +>mod : Symbol(mod, Decl(importer.js, 0, 5)) +>thing : Symbol(mod.thing, Decl(mod1.js, 0, 42)) mod.other = 0; ->mod : Symbol(mod, Decl(importer.js, 0, 5), Decl(importer.js, 6, 9), Decl(importer.js, 9, 14), Decl(importer.js, 10, 14), Decl(importer.js, 11, 13) ... and 2 more) +>mod : Symbol(mod, Decl(importer.js, 0, 5)) mod.prop = 0; ->mod : Symbol(mod, Decl(importer.js, 0, 5), Decl(importer.js, 6, 9), Decl(importer.js, 9, 14), Decl(importer.js, 10, 14), Decl(importer.js, 11, 13) ... and 2 more) +>mod : Symbol(mod, Decl(importer.js, 0, 5)) mod.bad1 = 0; ->mod.bad1 : Symbol(bad1, Decl(mod1.js, 10, 72)) ->mod : Symbol(mod, Decl(importer.js, 0, 5), Decl(importer.js, 6, 9), Decl(importer.js, 9, 14), Decl(importer.js, 10, 14), Decl(importer.js, 11, 13) ... and 2 more) ->bad1 : Symbol(bad1, Decl(mod1.js, 10, 72)) +>mod.bad1 : Symbol(mod.bad1, Decl(mod1.js, 10, 72)) +>mod : Symbol(mod, Decl(importer.js, 0, 5)) +>bad1 : Symbol(mod.bad1, Decl(mod1.js, 10, 72)) mod.bad2 = 0; ->mod.bad2 : Symbol(bad2, Decl(mod1.js, 13, 44)) ->mod : Symbol(mod, Decl(importer.js, 0, 5), Decl(importer.js, 6, 9), Decl(importer.js, 9, 14), Decl(importer.js, 10, 14), Decl(importer.js, 11, 13) ... and 2 more) ->bad2 : Symbol(bad2, Decl(mod1.js, 13, 44)) +>mod.bad2 : Symbol(mod.bad2, Decl(mod1.js, 13, 44)) +>mod : Symbol(mod, Decl(importer.js, 0, 5)) +>bad2 : Symbol(mod.bad2, Decl(mod1.js, 13, 44)) mod.bad3 = 0; ->mod.bad3 : Symbol(bad3, Decl(mod1.js, 14, 77)) ->mod : Symbol(mod, Decl(importer.js, 0, 5), Decl(importer.js, 6, 9), Decl(importer.js, 9, 14), Decl(importer.js, 10, 14), Decl(importer.js, 11, 13) ... and 2 more) ->bad3 : Symbol(bad3, Decl(mod1.js, 14, 77)) +>mod.bad3 : Symbol(mod.bad3, Decl(mod1.js, 14, 77)) +>mod : Symbol(mod, Decl(importer.js, 0, 5)) +>bad3 : Symbol(mod.bad3, Decl(mod1.js, 14, 77)) === tests/cases/conformance/jsdoc/mod1.js === const obj = { value: 42, writable: true }; diff --git a/tests/baselines/reference/checkOtherObjectAssignProperty.types b/tests/baselines/reference/checkOtherObjectAssignProperty.types index d9b68d71745e8..950e1266154e2 100644 --- a/tests/baselines/reference/checkOtherObjectAssignProperty.types +++ b/tests/baselines/reference/checkOtherObjectAssignProperty.types @@ -1,80 +1,80 @@ === tests/cases/conformance/jsdoc/importer.js === const mod = require("./mod1"); ->mod : typeof import("tests/cases/conformance/jsdoc/mod1") ->require("./mod1") : typeof import("tests/cases/conformance/jsdoc/mod1") +>mod : typeof mod +>require("./mod1") : typeof mod >require : any >"./mod1" : "./mod1" mod.thing; >mod.thing : number ->mod : typeof import("tests/cases/conformance/jsdoc/mod1") +>mod : typeof mod >thing : number mod.other; >mod.other : any ->mod : typeof import("tests/cases/conformance/jsdoc/mod1") +>mod : typeof mod >other : any mod.prop; >mod.prop : any ->mod : typeof import("tests/cases/conformance/jsdoc/mod1") +>mod : typeof mod >prop : any mod.bad1; >mod.bad1 : any ->mod : typeof import("tests/cases/conformance/jsdoc/mod1") +>mod : typeof mod >bad1 : any mod.bad2; >mod.bad2 : string ->mod : typeof import("tests/cases/conformance/jsdoc/mod1") +>mod : typeof mod >bad2 : string mod.bad3; >mod.bad3 : any ->mod : typeof import("tests/cases/conformance/jsdoc/mod1") +>mod : typeof mod >bad3 : any mod.thing = 0; >mod.thing = 0 : 0 >mod.thing : number ->mod : typeof import("tests/cases/conformance/jsdoc/mod1") +>mod : typeof mod >thing : number >0 : 0 mod.other = 0; >mod.other = 0 : 0 >mod.other : any ->mod : typeof import("tests/cases/conformance/jsdoc/mod1") +>mod : typeof mod >other : any >0 : 0 mod.prop = 0; >mod.prop = 0 : 0 >mod.prop : any ->mod : typeof import("tests/cases/conformance/jsdoc/mod1") +>mod : typeof mod >prop : any >0 : 0 mod.bad1 = 0; >mod.bad1 = 0 : 0 >mod.bad1 : any ->mod : typeof import("tests/cases/conformance/jsdoc/mod1") +>mod : typeof mod >bad1 : any >0 : 0 mod.bad2 = 0; >mod.bad2 = 0 : 0 >mod.bad2 : any ->mod : typeof import("tests/cases/conformance/jsdoc/mod1") +>mod : typeof mod >bad2 : any >0 : 0 mod.bad3 = 0; >mod.bad3 = 0 : 0 >mod.bad3 : any ->mod : typeof import("tests/cases/conformance/jsdoc/mod1") +>mod : typeof mod >bad3 : any >0 : 0 From 4ddb3d08c7c2a8ef1503d973d2d04360e90273d9 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Fri, 10 Jul 2020 15:59:45 -0700 Subject: [PATCH 08/30] accept error baselines that are good, actually --- ...controlFlowPropertyDeclarations.errors.txt | 154 ++++++++++++++++++ .../didYouMeanSuggestionErrors.errors.txt | 6 +- ...exportDefaultMarksIdentifierAsUsed.symbols | 6 +- .../exportDefaultMarksIdentifierAsUsed.types | 8 +- .../reference/parser509534.errors.txt | 6 +- .../reference/parserharness.errors.txt | 10 +- ...propertyAssignmentOnImportedSymbol.symbols | 6 +- .../propertyAssignmentOnImportedSymbol.types | 8 +- .../requireOfJsonFileInJsFile.errors.txt | 8 +- .../requireOfJsonFileInJsFile.symbols | 8 +- .../reference/requireOfJsonFileInJsFile.types | 6 +- 11 files changed, 188 insertions(+), 38 deletions(-) create mode 100644 tests/baselines/reference/controlFlowPropertyDeclarations.errors.txt diff --git a/tests/baselines/reference/controlFlowPropertyDeclarations.errors.txt b/tests/baselines/reference/controlFlowPropertyDeclarations.errors.txt new file mode 100644 index 0000000000000..be638164c79fb --- /dev/null +++ b/tests/baselines/reference/controlFlowPropertyDeclarations.errors.txt @@ -0,0 +1,154 @@ +tests/cases/compiler/controlFlowPropertyDeclarations.ts(5,37): error TS2307: Cannot find module 'react/lib/HTMLDOMPropertyConfig' or its corresponding type declarations. + + +==== tests/cases/compiler/controlFlowPropertyDeclarations.ts (1 errors) ==== + // Repro from ##8913 + + declare var require:any; + + var HTMLDOMPropertyConfig = require('react/lib/HTMLDOMPropertyConfig'); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'react/lib/HTMLDOMPropertyConfig' or its corresponding type declarations. + + // Populate property map with ReactJS's attribute and property mappings + // TODO handle/use .Properties value eg: MUST_USE_PROPERTY is not HTML attr + for (var propname in HTMLDOMPropertyConfig.Properties) { + if (!HTMLDOMPropertyConfig.Properties.hasOwnProperty(propname)) { + continue; + } + + var mapFrom = HTMLDOMPropertyConfig.DOMAttributeNames[propname] || propname.toLowerCase(); + } + + /** + * Repeats a string a certain number of times. + * Also: the future is bright and consists of native string repetition: + * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat + * + * @param {string} string String to repeat + * @param {number} times Number of times to repeat string. Integer. + * @see http://jsperf.com/string-repeater/2 + */ + function repeatString(string, times) { + if (times === 1) { + return string; + } + if (times < 0) { throw new Error(); } + var repeated = ''; + while (times) { + if (times & 1) { + repeated += string; + } + if (times >>= 1) { + string += string; + } + } + return repeated; + } + + /** + * Determine if the string ends with the specified substring. + * + * @param {string} haystack String to search in + * @param {string} needle String to search for + * @return {boolean} + */ + function endsWith(haystack, needle) { + return haystack.slice(-needle.length) === needle; + } + + /** + * Trim the specified substring off the string. If the string does not end + * with the specified substring, this is a no-op. + * + * @param {string} haystack String to search in + * @param {string} needle String to search for + * @return {string} + */ + function trimEnd(haystack, needle) { + return endsWith(haystack, needle) + ? haystack.slice(0, -needle.length) + : haystack; + } + + /** + * Convert a hyphenated string to camelCase. + */ + function hyphenToCamelCase(string) { + return string.replace(/-(.)/g, function(match, chr) { + return chr.toUpperCase(); + }); + } + + /** + * Determines if the specified string consists entirely of whitespace. + */ + function isEmpty(string) { + return !/[^\s]/.test(string); + } + + /** + * Determines if the CSS value can be converted from a + * 'px' suffixed string to a numeric value + * + * @param {string} value CSS property value + * @return {boolean} + */ + function isConvertiblePixelValue(value) { + return /^\d+px$/.test(value); + } + + export class HTMLtoJSX { + private output: string; + private level: number; + private _inPreTag: boolean; + + + /** + * Handles processing of the specified text node + * + * @param {TextNode} node + */ + _visitText = (node) => { + var parentTag = node.parentNode && node.parentNode.tagName.toLowerCase(); + if (parentTag === 'textarea' || parentTag === 'style') { + // Ignore text content of textareas and styles, as it will have already been moved + // to a "defaultValue" attribute and "dangerouslySetInnerHTML" attribute respectively. + return; + } + + var text = '' + + if (this._inPreTag) { + // If this text is contained within a
, we need to ensure the JSX
+          // whitespace coalescing rules don't eat the whitespace. This means
+          // wrapping newlines and sequences of two or more spaces in variables.
+          text = text
+            .replace(/\r/g, '')
+            .replace(/( {2,}|\n|\t|\{|\})/g, function(whitespace) {
+              return '{' + JSON.stringify(whitespace) + '}';
+            });
+        } else {
+          // If there's a newline in the text, adjust the indent level
+          if (text.indexOf('\n') > -1) {
+          }
+        }
+        this.output += text;
+      }
+    
+    
+    
+    };
+    
+    /**
+     * Handles parsing of inline styles
+     */
+    export class StyleParser {
+      styles = {};
+      toJSXString = () => {
+        for (var key in this.styles) {
+          if (!this.styles.hasOwnProperty(key)) {
+          }
+        }
+      }
+    }
\ No newline at end of file
diff --git a/tests/baselines/reference/didYouMeanSuggestionErrors.errors.txt b/tests/baselines/reference/didYouMeanSuggestionErrors.errors.txt
index a41b19ecd9d60..c85fb04210fad 100644
--- a/tests/baselines/reference/didYouMeanSuggestionErrors.errors.txt
+++ b/tests/baselines/reference/didYouMeanSuggestionErrors.errors.txt
@@ -6,7 +6,7 @@ tests/cases/compiler/didYouMeanSuggestionErrors.ts(8,5): error TS2582: Cannot fi
 tests/cases/compiler/didYouMeanSuggestionErrors.ts(9,9): error TS2584: Cannot find name 'console'. Do you need to change your target library? Try changing the `lib` compiler option to include 'dom'.
 tests/cases/compiler/didYouMeanSuggestionErrors.ts(9,21): error TS2580: Cannot find name 'process'. Do you need to install type definitions for node? Try `npm i @types/node`.
 tests/cases/compiler/didYouMeanSuggestionErrors.ts(10,9): error TS2584: Cannot find name 'document'. Do you need to change your target library? Try changing the `lib` compiler option to include 'dom'.
-tests/cases/compiler/didYouMeanSuggestionErrors.ts(12,19): error TS2580: Cannot find name 'require'. Do you need to install type definitions for node? Try `npm i @types/node`.
+tests/cases/compiler/didYouMeanSuggestionErrors.ts(12,27): error TS2307: Cannot find module 'fs' or its corresponding type declarations.
 tests/cases/compiler/didYouMeanSuggestionErrors.ts(13,19): error TS2580: Cannot find name 'Buffer'. Do you need to install type definitions for node? Try `npm i @types/node`.
 tests/cases/compiler/didYouMeanSuggestionErrors.ts(14,19): error TS2580: Cannot find name 'module'. Do you need to install type definitions for node? Try `npm i @types/node`.
 tests/cases/compiler/didYouMeanSuggestionErrors.ts(16,23): error TS2583: Cannot find name 'Map'. Do you need to change your target library? Try changing the `lib` compiler option to es2015 or later.
@@ -48,8 +48,8 @@ tests/cases/compiler/didYouMeanSuggestionErrors.ts(24,18): error TS2583: Cannot
 !!! error TS2584: Cannot find name 'document'. Do you need to change your target library? Try changing the `lib` compiler option to include 'dom'.
     
             const x = require("fs");
-                      ~~~~~~~
-!!! error TS2580: Cannot find name 'require'. Do you need to install type definitions for node? Try `npm i @types/node`.
+                              ~~~~
+!!! error TS2307: Cannot find module 'fs' or its corresponding type declarations.
             const y = Buffer.from([]);
                       ~~~~~~
 !!! error TS2580: Cannot find name 'Buffer'. Do you need to install type definitions for node? Try `npm i @types/node`.
diff --git a/tests/baselines/reference/exportDefaultMarksIdentifierAsUsed.symbols b/tests/baselines/reference/exportDefaultMarksIdentifierAsUsed.symbols
index ffb9643c6bb41..9dbdf4e44db36 100644
--- a/tests/baselines/reference/exportDefaultMarksIdentifierAsUsed.symbols
+++ b/tests/baselines/reference/exportDefaultMarksIdentifierAsUsed.symbols
@@ -7,10 +7,8 @@ export default Obj;
 
 === tests/cases/compiler/b.js ===
 import Obj from './a';
->Obj : Symbol(Obj, Decl(b.js, 0, 6), Decl(b.js, 0, 22))
+>Obj : Symbol(Obj, Decl(b.js, 0, 6))
 
 Obj.fn = function() {};
->Obj.fn : Symbol(Obj.fn, Decl(b.js, 0, 22))
->Obj : Symbol(Obj, Decl(b.js, 0, 6), Decl(b.js, 0, 22))
->fn : Symbol(Obj.fn, Decl(b.js, 0, 22))
+>Obj : Symbol(Obj, Decl(b.js, 0, 6))
 
diff --git a/tests/baselines/reference/exportDefaultMarksIdentifierAsUsed.types b/tests/baselines/reference/exportDefaultMarksIdentifierAsUsed.types
index f2c20778de05f..68ec7924aa183 100644
--- a/tests/baselines/reference/exportDefaultMarksIdentifierAsUsed.types
+++ b/tests/baselines/reference/exportDefaultMarksIdentifierAsUsed.types
@@ -8,12 +8,12 @@ export default Obj;
 
 === tests/cases/compiler/b.js ===
 import Obj from './a';
->Obj : typeof Obj
+>Obj : {}
 
 Obj.fn = function() {};
 >Obj.fn = function() {} : () => void
->Obj.fn : () => void
->Obj : typeof Obj
->fn : () => void
+>Obj.fn : error
+>Obj : {}
+>fn : any
 >function() {} : () => void
 
diff --git a/tests/baselines/reference/parser509534.errors.txt b/tests/baselines/reference/parser509534.errors.txt
index ff5eb131b5ce4..b02ceeb0ae1ec 100644
--- a/tests/baselines/reference/parser509534.errors.txt
+++ b/tests/baselines/reference/parser509534.errors.txt
@@ -1,12 +1,12 @@
-tests/cases/conformance/parser/ecmascript5/RegressionTests/parser509534.ts(2,14): error TS2580: Cannot find name 'require'. Do you need to install type definitions for node? Try `npm i @types/node`.
+tests/cases/conformance/parser/ecmascript5/RegressionTests/parser509534.ts(2,22): error TS2307: Cannot find module '../config' or its corresponding type declarations.
 tests/cases/conformance/parser/ecmascript5/RegressionTests/parser509534.ts(3,1): error TS2580: Cannot find name 'module'. Do you need to install type definitions for node? Try `npm i @types/node`.
 
 
 ==== tests/cases/conformance/parser/ecmascript5/RegressionTests/parser509534.ts (2 errors) ====
     "use strict";
     var config = require("../config");
-                 ~~~~~~~
-!!! error TS2580: Cannot find name 'require'. Do you need to install type definitions for node? Try `npm i @types/node`.
+                         ~~~~~~~~~~~
+!!! error TS2307: Cannot find module '../config' or its corresponding type declarations.
     module.exports.route = function (server) {
     ~~~~~~
 !!! error TS2580: Cannot find name 'module'. Do you need to install type definitions for node? Try `npm i @types/node`.
diff --git a/tests/baselines/reference/parserharness.errors.txt b/tests/baselines/reference/parserharness.errors.txt
index 990fa5816c787..2636e6901b5e0 100644
--- a/tests/baselines/reference/parserharness.errors.txt
+++ b/tests/baselines/reference/parserharness.errors.txt
@@ -6,7 +6,7 @@ tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(21,29): er
 tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(25,17): error TS2304: Cannot find name 'IIO'.
 tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(41,12): error TS2304: Cannot find name 'ActiveXObject'.
 tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(43,19): error TS2580: Cannot find name 'require'. Do you need to install type definitions for node? Try `npm i @types/node`.
-tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(44,14): error TS2580: Cannot find name 'require'. Do you need to install type definitions for node? Try `npm i @types/node`.
+tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(44,22): error TS2307: Cannot find module 'vm' or its corresponding type declarations.
 tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(341,13): error TS2662: Cannot find name 'errorHandlerStack'. Did you mean the static member 'Runnable.errorHandlerStack'?
 tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(347,13): error TS2662: Cannot find name 'errorHandlerStack'. Did you mean the static member 'Runnable.errorHandlerStack'?
 tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(351,17): error TS2662: Cannot find name 'errorHandlerStack'. Did you mean the static member 'Runnable.errorHandlerStack'?
@@ -18,7 +18,7 @@ tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(721,62): e
 tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(724,29): error TS2304: Cannot find name 'ITextWriter'.
 tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(754,53): error TS2552: Cannot find name 'TypeScript'. Did you mean 'TypeScriptLS'?
 tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(764,56): error TS2503: Cannot find namespace 'TypeScript'.
-tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(765,37): error TS2304: Cannot find name 'TypeScript'.
+tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(765,37): error TS2552: Cannot find name 'TypeScript'. Did you mean 'TypeScriptLS'?
 tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(767,47): error TS2304: Cannot find name 'TypeScript'.
 tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(776,13): error TS2304: Cannot find name 'TypeScript'.
 tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(776,42): error TS2304: Cannot find name 'TypeScript'.
@@ -171,8 +171,8 @@ tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(2030,32):
                       ~~~~~~~
 !!! error TS2580: Cannot find name 'require'. Do you need to install type definitions for node? Try `npm i @types/node`.
         var vm = require('vm');
-                 ~~~~~~~
-!!! error TS2580: Cannot find name 'require'. Do you need to install type definitions for node? Try `npm i @types/node`.
+                         ~~~~
+!!! error TS2307: Cannot find module 'vm' or its corresponding type declarations.
         vm.runInThisContext(typescriptServiceFile, 'typescriptServices.js');
     } else {
         throw new Error('Unknown context');
@@ -917,7 +917,7 @@ tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(2030,32):
 !!! error TS2503: Cannot find namespace 'TypeScript'.
                 var compiler = c || new TypeScript.TypeScriptCompiler(stderr);
                                         ~~~~~~~~~~
-!!! error TS2304: Cannot find name 'TypeScript'.
+!!! error TS2552: Cannot find name 'TypeScript'. Did you mean 'TypeScriptLS'?
                 compiler.parser.errorRecovery = true;
                 compiler.settings.codeGenTarget = TypeScript.CodeGenTarget.ES5;
                                                   ~~~~~~~~~~
diff --git a/tests/baselines/reference/propertyAssignmentOnImportedSymbol.symbols b/tests/baselines/reference/propertyAssignmentOnImportedSymbol.symbols
index 453816e38cf38..f8d01ae69819d 100644
--- a/tests/baselines/reference/propertyAssignmentOnImportedSymbol.symbols
+++ b/tests/baselines/reference/propertyAssignmentOnImportedSymbol.symbols
@@ -4,10 +4,8 @@ export var hurk = {}
 
 === tests/cases/conformance/salsa/bug24658.js ===
 import { hurk } from './mod1'
->hurk : Symbol(hurk, Decl(bug24658.js, 0, 8), Decl(bug24658.js, 0, 29))
+>hurk : Symbol(hurk, Decl(bug24658.js, 0, 8))
 
 hurk.expando = 4
->hurk.expando : Symbol(hurk.expando, Decl(bug24658.js, 0, 29))
->hurk : Symbol(hurk, Decl(bug24658.js, 0, 8), Decl(bug24658.js, 0, 29))
->expando : Symbol(hurk.expando, Decl(bug24658.js, 0, 29))
+>hurk : Symbol(hurk, Decl(bug24658.js, 0, 8))
 
diff --git a/tests/baselines/reference/propertyAssignmentOnImportedSymbol.types b/tests/baselines/reference/propertyAssignmentOnImportedSymbol.types
index 53930f09a6589..8df4f984574a8 100644
--- a/tests/baselines/reference/propertyAssignmentOnImportedSymbol.types
+++ b/tests/baselines/reference/propertyAssignmentOnImportedSymbol.types
@@ -5,12 +5,12 @@ export var hurk = {}
 
 === tests/cases/conformance/salsa/bug24658.js ===
 import { hurk } from './mod1'
->hurk : typeof hurk
+>hurk : {}
 
 hurk.expando = 4
 >hurk.expando = 4 : 4
->hurk.expando : number
->hurk : typeof hurk
->expando : number
+>hurk.expando : any
+>hurk : {}
+>expando : any
 >4 : 4
 
diff --git a/tests/baselines/reference/requireOfJsonFileInJsFile.errors.txt b/tests/baselines/reference/requireOfJsonFileInJsFile.errors.txt
index 12faf377df693..247aaa31b570c 100644
--- a/tests/baselines/reference/requireOfJsonFileInJsFile.errors.txt
+++ b/tests/baselines/reference/requireOfJsonFileInJsFile.errors.txt
@@ -1,6 +1,6 @@
-/user.js(2,7): error TS2339: Property 'b' does not exist on type 'typeof "/json"'.
+/user.js(2,7): error TS2339: Property 'b' does not exist on type '{ a: number; }'.
 /user.js(5,7): error TS2741: Property 'b' is missing in type '{ a: number; }' but required in type '{ b: number; }'.
-/user.js(9,7): error TS2339: Property 'b' does not exist on type 'typeof "/json"'.
+/user.js(9,7): error TS2339: Property 'b' does not exist on type '{ a: number; }'.
 /user.js(12,7): error TS2741: Property 'b' is missing in type '{ a: number; }' but required in type '{ b: number; }'.
 
 
@@ -8,7 +8,7 @@
     const json0 = require("./json.json");
     json0.b; // Error (good)
           ~
-!!! error TS2339: Property 'b' does not exist on type 'typeof "/json"'.
+!!! error TS2339: Property 'b' does not exist on type '{ a: number; }'.
     
     /** @type {{ b: number }} */
     const json1 = require("./json.json"); // No error (bad)
@@ -20,7 +20,7 @@
     const js0 = require("./js.js");
     json0.b; // Error (good)
           ~
-!!! error TS2339: Property 'b' does not exist on type 'typeof "/json"'.
+!!! error TS2339: Property 'b' does not exist on type '{ a: number; }'.
     
     /** @type {{ b: number }} */
     const js1 = require("./js.js"); // Error (good)
diff --git a/tests/baselines/reference/requireOfJsonFileInJsFile.symbols b/tests/baselines/reference/requireOfJsonFileInJsFile.symbols
index 3ecee55fb42bc..7f3247069cf85 100644
--- a/tests/baselines/reference/requireOfJsonFileInJsFile.symbols
+++ b/tests/baselines/reference/requireOfJsonFileInJsFile.symbols
@@ -2,7 +2,7 @@
 const json0 = require("./json.json");
 >json0 : Symbol(json0, Decl(user.js, 0, 5))
 >require : Symbol(require)
->"./json.json" : Symbol(json0, Decl(json.json, 0, 0))
+>"./json.json" : Symbol(json1, Decl(json.json, 0, 0))
 
 json0.b; // Error (good)
 >json0 : Symbol(json0, Decl(user.js, 0, 5))
@@ -11,7 +11,7 @@ json0.b; // Error (good)
 const json1 = require("./json.json"); // No error (bad)
 >json1 : Symbol(json1, Decl(user.js, 4, 5))
 >require : Symbol(require)
->"./json.json" : Symbol(json0, Decl(json.json, 0, 0))
+>"./json.json" : Symbol(json1, Decl(json.json, 0, 0))
 
 json1.b; // No error (OK since that's the type annotation)
 >json1.b : Symbol(b, Decl(user.js, 3, 12))
@@ -21,7 +21,7 @@ json1.b; // No error (OK since that's the type annotation)
 const js0 = require("./js.js");
 >js0 : Symbol(js0, Decl(user.js, 7, 5))
 >require : Symbol(require)
->"./js.js" : Symbol(js0, Decl(js.js, 0, 0))
+>"./js.js" : Symbol(js1, Decl(js.js, 0, 0))
 
 json0.b; // Error (good)
 >json0 : Symbol(json0, Decl(user.js, 0, 5))
@@ -30,7 +30,7 @@ json0.b; // Error (good)
 const js1 = require("./js.js"); // Error (good)
 >js1 : Symbol(js1, Decl(user.js, 11, 5))
 >require : Symbol(require)
->"./js.js" : Symbol(js0, Decl(js.js, 0, 0))
+>"./js.js" : Symbol(js1, Decl(js.js, 0, 0))
 
 js1.b;
 >js1.b : Symbol(b, Decl(user.js, 10, 12))
diff --git a/tests/baselines/reference/requireOfJsonFileInJsFile.types b/tests/baselines/reference/requireOfJsonFileInJsFile.types
index 144f7ceb63ef0..0e8e9b847ab8f 100644
--- a/tests/baselines/reference/requireOfJsonFileInJsFile.types
+++ b/tests/baselines/reference/requireOfJsonFileInJsFile.types
@@ -1,13 +1,13 @@
 === /user.js ===
 const json0 = require("./json.json");
->json0 : typeof json0
+>json0 : { a: number; }
 >require("./json.json") : { a: number; }
 >require : any
 >"./json.json" : "./json.json"
 
 json0.b; // Error (good)
 >json0.b : any
->json0 : typeof json0
+>json0 : { a: number; }
 >b : any
 
 /** @type {{ b: number }} */
@@ -30,7 +30,7 @@ const js0 = require("./js.js");
 
 json0.b; // Error (good)
 >json0.b : any
->json0 : typeof json0
+>json0 : { a: number; }
 >b : any
 
 /** @type {{ b: number }} */

From 58a0b651b00876e0a854f24c29a3fb4f86e0353e Mon Sep 17 00:00:00 2001
From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com>
Date: Wed, 15 Jul 2020 09:29:03 -0700
Subject: [PATCH 09/30] Scribbling on d.ts emit code

---
 src/compiler/binder.ts                        |  7 ++-
 src/compiler/checker.ts                       | 63 ++++++++++++++++++-
 .../reference/jsDeclarationsCrossfileMerge.js |  3 +-
 .../jsDeclarationsCrossfileMerge.symbols      |  6 +-
 .../jsDeclarationsCrossfileMerge.types        | 20 +++---
 .../jsDeclarationsExportAssignedVisibility.js |  3 +-
 ...DeclarationsExportAssignedVisibility.types | 10 +--
 .../jsDeclarationsExportForms.symbols         |  8 +--
 .../reference/jsDeclarationsExportForms.types | 54 ++++++++--------
 .../jsDeclarationsTypeReferences.types        | 24 +++----
 .../jsDeclarationsTypeReferences.ts           |  2 +-
 11 files changed, 130 insertions(+), 70 deletions(-)

diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts
index 82013e733dbec..08b12e23fc684 100644
--- a/src/compiler/binder.ts
+++ b/src/compiler/binder.ts
@@ -2980,15 +2980,16 @@ namespace ts {
         }
 
         function bindPotentiallyMissingNamespaces(namespaceSymbol: Symbol | undefined, entityName: BindableStaticNameExpression, isToplevel: boolean, isPrototypeProperty: boolean, containerIsClass: boolean) {
+            if (namespaceSymbol?.flags! & SymbolFlags.Alias) {
+                return namespaceSymbol;
+            }
             if (isToplevel && !isPrototypeProperty) {
                 // make symbols or add declarations for intermediate containers
                 const flags = SymbolFlags.Module | SymbolFlags.Assignment;
                 const excludeFlags = SymbolFlags.ValueModuleExcludes & ~SymbolFlags.Assignment;
                 namespaceSymbol = forEachIdentifierInEntityName(entityName, namespaceSymbol, (id, symbol, parent) => {
                     if (symbol) {
-                        if (!(symbol.flags & SymbolFlags.Alias)) {
-                            addDeclarationToSymbol(symbol, id, flags);
-                        }
+                        addDeclarationToSymbol(symbol, id, flags);
                         return symbol;
                     }
                     else {
diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts
index b53f01e5671e6..c41c741c24980 100644
--- a/src/compiler/checker.ts
+++ b/src/compiler/checker.ts
@@ -6612,6 +6612,18 @@ namespace ts {
                     ), symbol.declarations && filter(symbol.declarations, d => isClassDeclaration(d) || isClassExpression(d))[0]), modifierFlags);
                 }
 
+                function blug(node: Node) {
+                    const file = getSourceFileOfNode(node);
+                    const ranges = getLeadingCommentRangesOfNode(node, file);
+                    if (!ranges) return undefined;
+                    // return ranges;
+                    let res = "";
+                    for (const r of ranges) {
+                        res += file.text.substring(r.pos, r.end)
+                    }
+                    return res.slice(2);
+                }
+
                 function serializeAsAlias(symbol: Symbol, localName: string, modifierFlags: ModifierFlags) {
                     // synthesize an alias, eg `export { symbolName as Name }`
                     // need to mark the alias `symbol` points at
@@ -6630,18 +6642,60 @@ namespace ts {
                     const targetName = getInternalSymbolName(target, verbatimTargetName);
                     includePrivateSymbol(target); // the target may be within the same scope - attempt to serialize it first
                     switch (node.kind) {
+                        case SyntaxKind.VariableDeclaration:
+                            // commonjs require
+                            if (isPropertyAccessExpression((node as VariableDeclaration).initializer!)) {
+                                // const x = require('x').x
+                                const access = (node as VariableDeclaration).initializer! as PropertyAccessExpression;
+                                const moduleName = (getFirstPropertyAccessExpression(access) as CallExpression).arguments[0] as StringLiteral;
+                                const tmp = factory.createUniqueName(moduleName.text);
+                                // import _x = require('x')
+
+                                let n = factory.createImportEqualsDeclaration(
+                                    /*decorators*/ undefined,
+                                    /*modifiers*/ undefined,
+                                    tmp,
+                                    factory.createExternalModuleReference(factory.createStringLiteral(moduleName.text))
+                                );
+                                const comments = blug(node.parent);
+                                if (comments) {
+                                    // n = setCommentRange(n, comments[0]);
+                                    n = addSyntheticLeadingComment(n, SyntaxKind.SingleLineCommentTrivia, comments);
+                                }
+                                addResult(n, ModifierFlags.None);
+                                // import x = _x.X
+                                addResult(factory.createImportEqualsDeclaration(
+                                    /*decorators*/ undefined,
+                                    /*modifiers*/ undefined,
+                                    factory.createIdentifier(localName),
+                                    factory.createQualifiedName(tmp, access.name as Identifier), // TODO: symbolToName handles the recursive case (but may do some extra stuff we don't want)
+                                ), modifierFlags);
+                                break;
+                            }
+                            // else fall through and treat require just like import=
                         case SyntaxKind.ImportEqualsDeclaration:
                             // Could be a local `import localName = ns.member` or
                             // an external `import localName = require("whatever")`
                             const isLocalImport = !(target.flags & SymbolFlags.ValueModule);
-                            addResult(factory.createImportEqualsDeclaration(
+                            // TODO: Do this the right way in getSpecifierForModuleSymbol
+                            const naam = isVariableDeclaration(node)
+                                ? ((getFirstPropertyAccessExpression((node as VariableDeclaration).initializer! as PropertyAccessExpression) as CallExpression).arguments[0] as StringLiteral).text
+                                : getSpecifierForModuleSymbol(symbol, context)
+                            let n = factory.createImportEqualsDeclaration(
                                 /*decorators*/ undefined,
                                 /*modifiers*/ undefined,
                                 factory.createIdentifier(localName),
                                 isLocalImport
                                     ? symbolToName(target, context, SymbolFlags.All, /*expectsIdentifier*/ false)
-                                    : factory.createExternalModuleReference(factory.createStringLiteral(getSpecifierForModuleSymbol(symbol, context)))
-                            ), isLocalImport ? modifierFlags : ModifierFlags.None);
+                                // TODO: make getSpecifierForModuleSymbol work with require Symbols
+                                    : factory.createExternalModuleReference(factory.createStringLiteral(naam))
+                            )
+                            const comments = blug(node.parent);
+                            if (comments) {
+                                // n = setCommentRange(n, comments[0]);
+                                n = addSyntheticLeadingComment(n, SyntaxKind.SingleLineCommentTrivia, comments);
+                            }
+                            addResult(n, isLocalImport ? modifierFlags : ModifierFlags.None);
                             break;
                         case SyntaxKind.NamespaceExportDeclaration:
                             // export as namespace foo
@@ -6677,6 +6731,9 @@ namespace ts {
                                 factory.createStringLiteral(getSpecifierForModuleSymbol(target, context))
                             ), ModifierFlags.None);
                             break;
+                        case SyntaxKind.BindingElement:
+                            // TODO: remember to handle postfix property access~~~
+                            // TODO: Actually write tests for this, there aren't any that I can see
                         case SyntaxKind.ImportSpecifier:
                             addResult(factory.createImportDeclaration(
                                 /*decorators*/ undefined,
diff --git a/tests/baselines/reference/jsDeclarationsCrossfileMerge.js b/tests/baselines/reference/jsDeclarationsCrossfileMerge.js
index 9e99ba43fc55e..f4b06e5eaa883 100644
--- a/tests/baselines/reference/jsDeclarationsCrossfileMerge.js
+++ b/tests/baselines/reference/jsDeclarationsCrossfileMerge.js
@@ -24,5 +24,6 @@ module.exports.memberName = "thing";
 
 
 //// [index.d.ts]
-declare const _exports: typeof import("./exporter").default;
+declare const _exports: typeof m.default;
 export = _exports;
+import m = require("./exporter");
diff --git a/tests/baselines/reference/jsDeclarationsCrossfileMerge.symbols b/tests/baselines/reference/jsDeclarationsCrossfileMerge.symbols
index 64753e212bef9..859c94328a408 100644
--- a/tests/baselines/reference/jsDeclarationsCrossfileMerge.symbols
+++ b/tests/baselines/reference/jsDeclarationsCrossfileMerge.symbols
@@ -2,15 +2,15 @@
 const m = require("./exporter");
 >m : Symbol(m, Decl(index.js, 0, 5))
 >require : Symbol(require)
->"./exporter" : Symbol("tests/cases/conformance/jsdoc/declarations/exporter", Decl(exporter.js, 0, 0))
+>"./exporter" : Symbol(m, Decl(exporter.js, 0, 0))
 
 module.exports = m.default;
 >module.exports : Symbol("tests/cases/conformance/jsdoc/declarations/index", Decl(index.js, 0, 0))
 >module : Symbol(export=, Decl(index.js, 0, 32))
 >exports : Symbol(export=, Decl(index.js, 0, 32))
->m.default : Symbol(default, Decl(exporter.js, 0, 22))
+>m.default : Symbol(m.default, Decl(exporter.js, 0, 22))
 >m : Symbol(m, Decl(index.js, 0, 5))
->default : Symbol(default, Decl(exporter.js, 0, 22))
+>default : Symbol(m.default, Decl(exporter.js, 0, 22))
 
 module.exports.memberName = "thing";
 >module.exports.memberName : Symbol(memberName, Decl(index.js, 2, 27))
diff --git a/tests/baselines/reference/jsDeclarationsCrossfileMerge.types b/tests/baselines/reference/jsDeclarationsCrossfileMerge.types
index 8de95cf8567eb..83e978857ee34 100644
--- a/tests/baselines/reference/jsDeclarationsCrossfileMerge.types
+++ b/tests/baselines/reference/jsDeclarationsCrossfileMerge.types
@@ -1,25 +1,25 @@
 === tests/cases/conformance/jsdoc/declarations/index.js ===
 const m = require("./exporter");
->m : typeof import("tests/cases/conformance/jsdoc/declarations/exporter")
->require("./exporter") : typeof import("tests/cases/conformance/jsdoc/declarations/exporter")
+>m : typeof m
+>require("./exporter") : typeof m
 >require : any
 >"./exporter" : "./exporter"
 
 module.exports = m.default;
->module.exports = m.default : typeof import("tests/cases/conformance/jsdoc/declarations/exporter").default
->module.exports : typeof import("tests/cases/conformance/jsdoc/declarations/exporter").default
->module : { "\"tests/cases/conformance/jsdoc/declarations/index\"": typeof import("tests/cases/conformance/jsdoc/declarations/exporter").default; }
->exports : typeof import("tests/cases/conformance/jsdoc/declarations/exporter").default
+>module.exports = m.default : typeof m.default
+>module.exports : typeof m.default
+>module : { "\"tests/cases/conformance/jsdoc/declarations/index\"": typeof m.default; }
+>exports : typeof m.default
 >m.default : { (): void; memberName: string; }
->m : typeof import("tests/cases/conformance/jsdoc/declarations/exporter")
+>m : typeof m
 >default : { (): void; memberName: string; }
 
 module.exports.memberName = "thing";
 >module.exports.memberName = "thing" : "thing"
 >module.exports.memberName : string
->module.exports : typeof import("tests/cases/conformance/jsdoc/declarations/exporter").default
->module : { "\"tests/cases/conformance/jsdoc/declarations/index\"": typeof import("tests/cases/conformance/jsdoc/declarations/exporter").default; }
->exports : typeof import("tests/cases/conformance/jsdoc/declarations/exporter").default
+>module.exports : typeof m.default
+>module : { "\"tests/cases/conformance/jsdoc/declarations/index\"": typeof m.default; }
+>exports : typeof m.default
 >memberName : string
 >"thing" : "thing"
 
diff --git a/tests/baselines/reference/jsDeclarationsExportAssignedVisibility.js b/tests/baselines/reference/jsDeclarationsExportAssignedVisibility.js
index c900f28602e57..3935a7a2264f0 100644
--- a/tests/baselines/reference/jsDeclarationsExportAssignedVisibility.js
+++ b/tests/baselines/reference/jsDeclarationsExportAssignedVisibility.js
@@ -43,5 +43,6 @@ declare class Obj {
 //// [index.d.ts]
 export = Container;
 declare class Container {
-    usage: import("./obj");
+    usage: Obj;
 }
+import Obj = require(".");
diff --git a/tests/baselines/reference/jsDeclarationsExportAssignedVisibility.types b/tests/baselines/reference/jsDeclarationsExportAssignedVisibility.types
index a76835e3105a6..179947956bee7 100644
--- a/tests/baselines/reference/jsDeclarationsExportAssignedVisibility.types
+++ b/tests/baselines/reference/jsDeclarationsExportAssignedVisibility.types
@@ -1,7 +1,7 @@
 === tests/cases/conformance/jsdoc/declarations/index.js ===
 const Obj = require("./obj");
->Obj : typeof import("tests/cases/conformance/jsdoc/declarations/obj")
->require("./obj") : typeof import("tests/cases/conformance/jsdoc/declarations/obj")
+>Obj : typeof Obj
+>require("./obj") : typeof Obj
 >require : any
 >"./obj" : "./obj"
 
@@ -10,12 +10,12 @@ class Container {
 
     constructor() {
         this.usage = new Obj();
->this.usage = new Obj() : import("tests/cases/conformance/jsdoc/declarations/obj")
+>this.usage = new Obj() : Obj
 >this.usage : any
 >this : this
 >usage : any
->new Obj() : import("tests/cases/conformance/jsdoc/declarations/obj")
->Obj : typeof import("tests/cases/conformance/jsdoc/declarations/obj")
+>new Obj() : Obj
+>Obj : typeof Obj
     }
 }
 
diff --git a/tests/baselines/reference/jsDeclarationsExportForms.symbols b/tests/baselines/reference/jsDeclarationsExportForms.symbols
index 300425b5c96e9..b42d528f92626 100644
--- a/tests/baselines/reference/jsDeclarationsExportForms.symbols
+++ b/tests/baselines/reference/jsDeclarationsExportForms.symbols
@@ -46,7 +46,7 @@ export { ns as classContainer };
 const ns = require("./cls");
 >ns : Symbol(ns, Decl(cjs.js, 0, 5))
 >require : Symbol(require)
->"./cls" : Symbol("tests/cases/conformance/jsdoc/declarations/cls", Decl(cls.js, 0, 0))
+>"./cls" : Symbol(ns, Decl(cls.js, 0, 0))
 
 module.exports = { ns };
 >module.exports : Symbol("tests/cases/conformance/jsdoc/declarations/cjs", Decl(cjs.js, 0, 0))
@@ -58,7 +58,7 @@ module.exports = { ns };
 const ns = require("./cls");
 >ns : Symbol(ns, Decl(cjs2.js, 0, 5))
 >require : Symbol(require)
->"./cls" : Symbol("tests/cases/conformance/jsdoc/declarations/cls", Decl(cls.js, 0, 0))
+>"./cls" : Symbol(ns, Decl(cls.js, 0, 0))
 
 module.exports = ns;
 >module.exports : Symbol("tests/cases/conformance/jsdoc/declarations/cjs2", Decl(cjs2.js, 0, 0))
@@ -70,7 +70,7 @@ module.exports = ns;
 const ns = require("./cls");
 >ns : Symbol(ns, Decl(cjs3.js, 0, 5))
 >require : Symbol(require)
->"./cls" : Symbol("tests/cases/conformance/jsdoc/declarations/cls", Decl(cls.js, 0, 0))
+>"./cls" : Symbol(ns, Decl(cls.js, 0, 0))
 
 module.exports.ns = ns;
 >module.exports.ns : Symbol(ns, Decl(cjs3.js, 0, 28))
@@ -84,7 +84,7 @@ module.exports.ns = ns;
 const ns = require("./cls");
 >ns : Symbol(ns, Decl(cjs4.js, 0, 5))
 >require : Symbol(require)
->"./cls" : Symbol("tests/cases/conformance/jsdoc/declarations/cls", Decl(cls.js, 0, 0))
+>"./cls" : Symbol(ns, Decl(cls.js, 0, 0))
 
 module.exports.names = ns;
 >module.exports.names : Symbol(names, Decl(cjs4.js, 0, 28))
diff --git a/tests/baselines/reference/jsDeclarationsExportForms.types b/tests/baselines/reference/jsDeclarationsExportForms.types
index c850d4b8a2323..496a58e9ac8a9 100644
--- a/tests/baselines/reference/jsDeclarationsExportForms.types
+++ b/tests/baselines/reference/jsDeclarationsExportForms.types
@@ -44,64 +44,64 @@ export { ns as classContainer };
 
 === tests/cases/conformance/jsdoc/declarations/cjs.js ===
 const ns = require("./cls");
->ns : typeof import("tests/cases/conformance/jsdoc/declarations/cls")
->require("./cls") : typeof import("tests/cases/conformance/jsdoc/declarations/cls")
+>ns : typeof ns
+>require("./cls") : typeof ns
 >require : any
 >"./cls" : "./cls"
 
 module.exports = { ns };
->module.exports = { ns } : { ns: typeof import("tests/cases/conformance/jsdoc/declarations/cls"); }
->module.exports : { ns: typeof import("tests/cases/conformance/jsdoc/declarations/cls"); }
->module : { "\"tests/cases/conformance/jsdoc/declarations/cjs\"": { ns: typeof import("tests/cases/conformance/jsdoc/declarations/cls"); }; }
->exports : { ns: typeof import("tests/cases/conformance/jsdoc/declarations/cls"); }
->{ ns } : { ns: typeof import("tests/cases/conformance/jsdoc/declarations/cls"); }
->ns : typeof import("tests/cases/conformance/jsdoc/declarations/cls")
+>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; }
+>{ ns } : { ns: typeof ns; }
+>ns : typeof ns
 
 === tests/cases/conformance/jsdoc/declarations/cjs2.js ===
 const ns = require("./cls");
->ns : typeof import("tests/cases/conformance/jsdoc/declarations/cls")
->require("./cls") : typeof import("tests/cases/conformance/jsdoc/declarations/cls")
+>ns : typeof ns
+>require("./cls") : typeof ns
 >require : any
 >"./cls" : "./cls"
 
 module.exports = ns;
->module.exports = ns : typeof import("tests/cases/conformance/jsdoc/declarations/cls")
->module.exports : typeof import("tests/cases/conformance/jsdoc/declarations/cls")
->module : { "\"tests/cases/conformance/jsdoc/declarations/cjs2\"": typeof import("tests/cases/conformance/jsdoc/declarations/cls"); }
->exports : typeof import("tests/cases/conformance/jsdoc/declarations/cls")
->ns : typeof import("tests/cases/conformance/jsdoc/declarations/cls")
+>module.exports = ns : typeof ns
+>module.exports : typeof ns
+>module : { "\"tests/cases/conformance/jsdoc/declarations/cjs2\"": typeof ns; }
+>exports : typeof ns
+>ns : typeof ns
 
 === tests/cases/conformance/jsdoc/declarations/cjs3.js ===
 const ns = require("./cls");
->ns : typeof import("tests/cases/conformance/jsdoc/declarations/cls")
->require("./cls") : typeof import("tests/cases/conformance/jsdoc/declarations/cls")
+>ns : typeof ns
+>require("./cls") : typeof ns
 >require : any
 >"./cls" : "./cls"
 
 module.exports.ns = ns;
->module.exports.ns = ns : typeof import("tests/cases/conformance/jsdoc/declarations/cls")
->module.exports.ns : typeof import("tests/cases/conformance/jsdoc/declarations/cls")
+>module.exports.ns = ns : typeof ns
+>module.exports.ns : typeof ns
 >module.exports : typeof import("tests/cases/conformance/jsdoc/declarations/cjs3")
 >module : { "\"tests/cases/conformance/jsdoc/declarations/cjs3\"": typeof import("tests/cases/conformance/jsdoc/declarations/cjs3"); }
 >exports : typeof import("tests/cases/conformance/jsdoc/declarations/cjs3")
->ns : typeof import("tests/cases/conformance/jsdoc/declarations/cls")
->ns : typeof import("tests/cases/conformance/jsdoc/declarations/cls")
+>ns : typeof ns
+>ns : typeof ns
 
 === tests/cases/conformance/jsdoc/declarations/cjs4.js ===
 const ns = require("./cls");
->ns : typeof import("tests/cases/conformance/jsdoc/declarations/cls")
->require("./cls") : typeof import("tests/cases/conformance/jsdoc/declarations/cls")
+>ns : typeof ns
+>require("./cls") : typeof ns
 >require : any
 >"./cls" : "./cls"
 
 module.exports.names = ns;
->module.exports.names = ns : typeof import("tests/cases/conformance/jsdoc/declarations/cls")
->module.exports.names : typeof import("tests/cases/conformance/jsdoc/declarations/cls")
+>module.exports.names = ns : typeof ns
+>module.exports.names : typeof ns
 >module.exports : typeof import("tests/cases/conformance/jsdoc/declarations/cjs4")
 >module : { "\"tests/cases/conformance/jsdoc/declarations/cjs4\"": typeof import("tests/cases/conformance/jsdoc/declarations/cjs4"); }
 >exports : typeof import("tests/cases/conformance/jsdoc/declarations/cjs4")
->names : typeof import("tests/cases/conformance/jsdoc/declarations/cls")
->ns : typeof import("tests/cases/conformance/jsdoc/declarations/cls")
+>names : typeof ns
+>ns : typeof ns
 
 === tests/cases/conformance/jsdoc/declarations/includeAll.js ===
 import "./cjs4";
diff --git a/tests/baselines/reference/jsDeclarationsTypeReferences.types b/tests/baselines/reference/jsDeclarationsTypeReferences.types
index 59f515e400072..deb8790ca75e5 100644
--- a/tests/baselines/reference/jsDeclarationsTypeReferences.types
+++ b/tests/baselines/reference/jsDeclarationsTypeReferences.types
@@ -2,27 +2,27 @@
 /// 
 
 const Something = require("fs").Something;
->Something : typeof import("fs").Something
->require("fs").Something : typeof import("fs").Something
+>Something : typeof Something
+>require("fs").Something : typeof Something
 >require("fs") : typeof import("fs")
 >require : any
 >"fs" : "fs"
->Something : typeof import("fs").Something
+>Something : typeof Something
 
 const thing = new Something();
->thing : import("fs").Something
->new Something() : import("fs").Something
->Something : typeof import("fs").Something
+>thing : Something
+>new Something() : Something
+>Something : typeof Something
 
 module.exports = {
->module.exports = {    thing} : { thing: import("fs").Something; }
->module.exports : { thing: import("fs").Something; }
->module : { "\"tests/cases/conformance/jsdoc/declarations/index\"": { thing: import("fs").Something; }; }
->exports : { thing: import("fs").Something; }
->{    thing} : { thing: import("fs").Something; }
+>module.exports = {    thing} : { thing: Something; }
+>module.exports : { thing: Something; }
+>module : { "\"tests/cases/conformance/jsdoc/declarations/index\"": { thing: Something; }; }
+>exports : { thing: Something; }
+>{    thing} : { thing: Something; }
 
     thing
->thing : import("fs").Something
+>thing : Something
 
 };
 === tests/cases/conformance/jsdoc/declarations/node_modules/@types/node/index.d.ts ===
diff --git a/tests/cases/conformance/jsdoc/declarations/jsDeclarationsTypeReferences.ts b/tests/cases/conformance/jsdoc/declarations/jsDeclarationsTypeReferences.ts
index 29151bf965625..5d96e640242e4 100644
--- a/tests/cases/conformance/jsdoc/declarations/jsDeclarationsTypeReferences.ts
+++ b/tests/cases/conformance/jsdoc/declarations/jsDeclarationsTypeReferences.ts
@@ -16,4 +16,4 @@ const thing = new Something();
 
 module.exports = {
     thing
-};
\ No newline at end of file
+};

From d885b67acb8cadffbb40313124afa2a635a94d94 Mon Sep 17 00:00:00 2001
From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com>
Date: Wed, 15 Jul 2020 11:10:09 -0700
Subject: [PATCH 10/30] use getSpecifierForModuleSymbol

---
 src/compiler/checker.ts                       | 33 ++++---------------
 .../reference/jsDeclarationsTypeReferences.js |  7 ++--
 .../jsDeclarationsTypeReferences.symbols      |  1 +
 .../jsDeclarationsTypeReferences.types        |  1 +
 4 files changed, 13 insertions(+), 29 deletions(-)

diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts
index c41c741c24980..f5df51eb32deb 100644
--- a/src/compiler/checker.ts
+++ b/src/compiler/checker.ts
@@ -6612,18 +6612,6 @@ namespace ts {
                     ), symbol.declarations && filter(symbol.declarations, d => isClassDeclaration(d) || isClassExpression(d))[0]), modifierFlags);
                 }
 
-                function blug(node: Node) {
-                    const file = getSourceFileOfNode(node);
-                    const ranges = getLeadingCommentRangesOfNode(node, file);
-                    if (!ranges) return undefined;
-                    // return ranges;
-                    let res = "";
-                    for (const r of ranges) {
-                        res += file.text.substring(r.pos, r.end)
-                    }
-                    return res.slice(2);
-                }
-
                 function serializeAsAlias(symbol: Symbol, localName: string, modifierFlags: ModifierFlags) {
                     // synthesize an alias, eg `export { symbolName as Name }`
                     // need to mark the alias `symbol` points at
@@ -6647,21 +6635,18 @@ namespace ts {
                             if (isPropertyAccessExpression((node as VariableDeclaration).initializer!)) {
                                 // const x = require('x').x
                                 const access = (node as VariableDeclaration).initializer! as PropertyAccessExpression;
-                                const moduleName = (getFirstPropertyAccessExpression(access) as CallExpression).arguments[0] as StringLiteral;
+                                const require = getFirstPropertyAccessExpression(access) as CallExpression;
+                                const moduleName = require.arguments[0] as StringLiteral;
                                 const tmp = factory.createUniqueName(moduleName.text);
                                 // import _x = require('x')
-
                                 let n = factory.createImportEqualsDeclaration(
                                     /*decorators*/ undefined,
                                     /*modifiers*/ undefined,
                                     tmp,
-                                    factory.createExternalModuleReference(factory.createStringLiteral(moduleName.text))
+                                    // TODO: Use target.parent here because alias resolution on post-property-access over-resolves to a module export
+                                    // *probably* I should fix this in type-checking instead, but I'm not sure how to request an additional resolution step during checking
+                                    factory.createExternalModuleReference(factory.createStringLiteral(getSpecifierForModuleSymbol(target.parent || target, context)))
                                 );
-                                const comments = blug(node.parent);
-                                if (comments) {
-                                    // n = setCommentRange(n, comments[0]);
-                                    n = addSyntheticLeadingComment(n, SyntaxKind.SingleLineCommentTrivia, comments);
-                                }
                                 addResult(n, ModifierFlags.None);
                                 // import x = _x.X
                                 addResult(factory.createImportEqualsDeclaration(
@@ -6677,9 +6662,8 @@ namespace ts {
                             // Could be a local `import localName = ns.member` or
                             // an external `import localName = require("whatever")`
                             const isLocalImport = !(target.flags & SymbolFlags.ValueModule);
-                            // TODO: Do this the right way in getSpecifierForModuleSymbol
                             const naam = isVariableDeclaration(node)
-                                ? ((getFirstPropertyAccessExpression((node as VariableDeclaration).initializer! as PropertyAccessExpression) as CallExpression).arguments[0] as StringLiteral).text
+                                ? getSpecifierForModuleSymbol(target, context)
                                 : getSpecifierForModuleSymbol(symbol, context)
                             let n = factory.createImportEqualsDeclaration(
                                 /*decorators*/ undefined,
@@ -6690,11 +6674,6 @@ namespace ts {
                                 // TODO: make getSpecifierForModuleSymbol work with require Symbols
                                     : factory.createExternalModuleReference(factory.createStringLiteral(naam))
                             )
-                            const comments = blug(node.parent);
-                            if (comments) {
-                                // n = setCommentRange(n, comments[0]);
-                                n = addSyntheticLeadingComment(n, SyntaxKind.SingleLineCommentTrivia, comments);
-                            }
                             addResult(n, isLocalImport ? modifierFlags : ModifierFlags.None);
                             break;
                         case SyntaxKind.NamespaceExportDeclaration:
diff --git a/tests/baselines/reference/jsDeclarationsTypeReferences.js b/tests/baselines/reference/jsDeclarationsTypeReferences.js
index 9e6a95d32e190..d302fc8a5ef61 100644
--- a/tests/baselines/reference/jsDeclarationsTypeReferences.js
+++ b/tests/baselines/reference/jsDeclarationsTypeReferences.js
@@ -13,7 +13,8 @@ const thing = new Something();
 
 module.exports = {
     thing
-};
+};
+
 
 //// [index.js]
 /// 
@@ -26,4 +27,6 @@ module.exports = {
 
 //// [index.d.ts]
 /// 
-export const thing: import("fs").Something;
+export const thing: Something;
+import fs_1 = require("fs");
+import Something = fs_1.Something;
diff --git a/tests/baselines/reference/jsDeclarationsTypeReferences.symbols b/tests/baselines/reference/jsDeclarationsTypeReferences.symbols
index 258b4d224a807..d0bf2caa029ba 100644
--- a/tests/baselines/reference/jsDeclarationsTypeReferences.symbols
+++ b/tests/baselines/reference/jsDeclarationsTypeReferences.symbols
@@ -21,6 +21,7 @@ module.exports = {
 >thing : Symbol(thing, Decl(index.js, 6, 18))
 
 };
+
 === tests/cases/conformance/jsdoc/declarations/node_modules/@types/node/index.d.ts ===
 declare module "fs" {
 >"fs" : Symbol("fs", Decl(index.d.ts, 0, 0))
diff --git a/tests/baselines/reference/jsDeclarationsTypeReferences.types b/tests/baselines/reference/jsDeclarationsTypeReferences.types
index deb8790ca75e5..8cadeb608f611 100644
--- a/tests/baselines/reference/jsDeclarationsTypeReferences.types
+++ b/tests/baselines/reference/jsDeclarationsTypeReferences.types
@@ -25,6 +25,7 @@ module.exports = {
 >thing : Something
 
 };
+
 === tests/cases/conformance/jsdoc/declarations/node_modules/@types/node/index.d.ts ===
 declare module "fs" {
 >"fs" : typeof import("fs")

From 5a0b092e4f8ee9beb46c779764a8d9d0fcddd0d6 Mon Sep 17 00:00:00 2001
From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com>
Date: Wed, 15 Jul 2020 14:51:18 -0700
Subject: [PATCH 11/30] hideous hack for module.exports of aliases

---
 src/compiler/checker.ts | 73 +++++++++++++++++++++++++----------------
 1 file changed, 45 insertions(+), 28 deletions(-)

diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts
index f5df51eb32deb..a2d84f74a12cb 100644
--- a/src/compiler/checker.ts
+++ b/src/compiler/checker.ts
@@ -6227,43 +6227,59 @@ namespace ts {
                                 if (textRange && isVariableDeclarationList(textRange.parent) && textRange.parent.declarations.length === 1) {
                                     textRange = textRange.parent.parent;
                                 }
-                                const statement = setTextRange(factory.createVariableStatement(/*modifiers*/ undefined, factory.createVariableDeclarationList([
-                                    factory.createVariableDeclaration(name, /*exclamationToken*/ undefined, serializeTypeForDeclaration(context, type, symbol, enclosingDeclaration, includePrivateSymbol, bundled))
-                                ], flags)), textRange);
-                                addResult(statement, name !== localName ? modifierFlags & ~ModifierFlags.Export : modifierFlags);
-                                if (name !== localName && !isPrivate) {
-                                    // We rename the variable declaration we generate for Property symbols since they may have a name which
-                                    // conflicts with a local declaration. For example, given input:
-                                    // ```
-                                    // function g() {}
-                                    // module.exports.g = g
-                                    // ```
-                                    // In such a situation, we have a local variable named `g`, and a separate exported variable named `g`.
-                                    // Naively, we would emit
-                                    // ```
-                                    // function g() {}
-                                    // export const g: typeof g;
-                                    // ```
-                                    // That's obviously incorrect - the `g` in the type annotation needs to refer to the local `g`, but
-                                    // the export declaration shadows it.
-                                    // To work around that, we instead write
-                                    // ```
-                                    // function g() {}
-                                    // const g_1: typeof g;
-                                    // export { g_1 as g };
-                                    // ```
-                                    // To create an export named `g` that does _not_ shadow the local `g`
+                                if (find(symbol.declarations, isPropertyAccessExpression) && isSourceFile(type.symbol.valueDeclaration)) {
+                                    // TODO: Don't really need to do this, just whatever symbol-visiting code that this function actually calls
+                                    serializeTypeForDeclaration(context, type, symbol, enclosingDeclaration, includePrivateSymbol, bundled);
                                     addResult(
                                         factory.createExportDeclaration(
                                             /*decorators*/ undefined,
                                             /*modifiers*/ undefined,
                                             /*isTypeOnly*/ false,
+                                            // TODO: name is not right here, should be based on ???
                                             factory.createNamedExports([factory.createExportSpecifier(name, localName)])
                                         ),
                                         ModifierFlags.None
                                     );
-                                    needsExportDeclaration = false;
-                                    needsPostExportDefault = false;
+                                }
+                                else {
+                                    const statement = setTextRange(factory.createVariableStatement(/*modifiers*/ undefined, factory.createVariableDeclarationList([
+                                        factory.createVariableDeclaration(name, /*exclamationToken*/ undefined, serializeTypeForDeclaration(context, type, symbol, enclosingDeclaration, includePrivateSymbol, bundled))
+                                    ], flags)), textRange);
+                                    addResult(statement, name !== localName ? modifierFlags & ~ModifierFlags.Export : modifierFlags);
+                                    if (name !== localName && !isPrivate) {
+                                        // We rename the variable declaration we generate for Property symbols since they may have a name which
+                                        // conflicts with a local declaration. For example, given input:
+                                        // ```
+                                        // function g() {}
+                                        // module.exports.g = g
+                                        // ```
+                                        // In such a situation, we have a local variable named `g`, and a separate exported variable named `g`.
+                                        // Naively, we would emit
+                                        // ```
+                                        // function g() {}
+                                        // export const g: typeof g;
+                                        // ```
+                                        // That's obviously incorrect - the `g` in the type annotation needs to refer to the local `g`, but
+                                        // the export declaration shadows it.
+                                        // To work around that, we instead write
+                                        // ```
+                                        // function g() {}
+                                        // const g_1: typeof g;
+                                        // export { g_1 as g };
+                                        // ```
+                                        // To create an export named `g` that does _not_ shadow the local `g`
+                                        addResult(
+                                            factory.createExportDeclaration(
+                                                /*decorators*/ undefined,
+                                                /*modifiers*/ undefined,
+                                                /*isTypeOnly*/ false,
+                                                factory.createNamedExports([factory.createExportSpecifier(name, localName)])
+                                            ),
+                                            ModifierFlags.None
+                                        );
+                                        needsExportDeclaration = false;
+                                        needsPostExportDefault = false;
+                                    }
                                 }
                             }
                         }
@@ -6662,6 +6678,7 @@ namespace ts {
                             // Could be a local `import localName = ns.member` or
                             // an external `import localName = require("whatever")`
                             const isLocalImport = !(target.flags & SymbolFlags.ValueModule);
+                            // TODO: It's very likely that this should always use target and using symbol was a bug
                             const naam = isVariableDeclaration(node)
                                 ? getSpecifierForModuleSymbol(target, context)
                                 : getSpecifierForModuleSymbol(symbol, context)

From 55a13b76364bd941715d24c632af746743480f67 Mon Sep 17 00:00:00 2001
From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com>
Date: Thu, 23 Jul 2020 16:39:41 -0700
Subject: [PATCH 12/30] Fix module.exports.x --> export list emit

---
 src/compiler/checker.ts                               |  8 ++++----
 .../baselines/reference/jsDeclarationsExportForms.js  | 11 +++++++----
 2 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts
index ef76cf6359a8b..83a3c0be24681 100644
--- a/src/compiler/checker.ts
+++ b/src/compiler/checker.ts
@@ -6235,16 +6235,16 @@ namespace ts {
                                 if (textRange && isVariableDeclarationList(textRange.parent) && textRange.parent.declarations.length === 1) {
                                     textRange = textRange.parent.parent;
                                 }
-                                if (find(symbol.declarations, isPropertyAccessExpression) && isSourceFile(type.symbol.valueDeclaration)) {
-                                    // TODO: Don't really need to do this, just whatever symbol-visiting code that this function actually calls
+                                const ex = find(symbol.declarations, isPropertyAccessExpression);
+                                if (ex && isBinaryExpression(ex.parent) && isIdentifier(ex.parent.right) && type.symbol && isSourceFile(type.symbol.valueDeclaration)) {
+                                    // TODO: Don't really need to do this, just whatever symbol-visiting code that this function actually calls, to mark it as used
                                     serializeTypeForDeclaration(context, type, symbol, enclosingDeclaration, includePrivateSymbol, bundled);
                                     addResult(
                                         factory.createExportDeclaration(
                                             /*decorators*/ undefined,
                                             /*modifiers*/ undefined,
                                             /*isTypeOnly*/ false,
-                                            // TODO: name is not right here, should be based on ???
-                                            factory.createNamedExports([factory.createExportSpecifier(name, localName)])
+                                            factory.createNamedExports([factory.createExportSpecifier(localName === ex.parent.right.escapedText ? undefined : ex.parent.right, localName)])
                                         ),
                                         ModifierFlags.None
                                     );
diff --git a/tests/baselines/reference/jsDeclarationsExportForms.js b/tests/baselines/reference/jsDeclarationsExportForms.js
index d39e44d875c0f..eb6fd8ee81f5a 100644
--- a/tests/baselines/reference/jsDeclarationsExportForms.js
+++ b/tests/baselines/reference/jsDeclarationsExportForms.js
@@ -176,13 +176,16 @@ import * as ns from "./cls";
 export { ns as classContainer };
 import * as ns from "./cls";
 //// [cjs.d.ts]
-export const ns: typeof import("./cls");
+import ns = require("./cls");
+export { ns };
 //// [cjs2.d.ts]
 export = ns;
-declare const ns: typeof import("./cls");
+import ns = require("./cls");
 //// [cjs3.d.ts]
-export var ns: typeof import("./cls");
+export { ns };
+import ns = require("./cls");
 //// [cjs4.d.ts]
-export var names: typeof import("./cls");
+export { ns as names };
+import ns = require("./cls");
 //// [includeAll.d.ts]
 export {};

From 7ce7c8cc7bedf952744d7347a7a99537f736a8e4 Mon Sep 17 00:00:00 2001
From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com>
Date: Thu, 23 Jul 2020 17:02:20 -0700
Subject: [PATCH 13/30] fix isLocalImport predicate

---
 src/compiler/checker.ts                                     | 2 +-
 .../reference/jsDeclarationsClassExtendsVisibility.js       | 4 ++--
 .../reference/jsDeclarationsClassExtendsVisibility.types    | 6 +++---
 .../reference/jsDeclarationsExportAssignedVisibility.js     | 2 +-
 4 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts
index 83a3c0be24681..2aeefee5fc6d6 100644
--- a/src/compiler/checker.ts
+++ b/src/compiler/checker.ts
@@ -6685,7 +6685,7 @@ namespace ts {
                         case SyntaxKind.ImportEqualsDeclaration:
                             // Could be a local `import localName = ns.member` or
                             // an external `import localName = require("whatever")`
-                            const isLocalImport = !(target.flags & SymbolFlags.ValueModule);
+                            const isLocalImport = !(target.flags & SymbolFlags.ValueModule) && !isVariableDeclaration(node);
                             // TODO: It's very likely that this should always use target and using symbol was a bug
                             const naam = isVariableDeclaration(node)
                                 ? getSpecifierForModuleSymbol(target, context)
diff --git a/tests/baselines/reference/jsDeclarationsClassExtendsVisibility.js b/tests/baselines/reference/jsDeclarationsClassExtendsVisibility.js
index 653fed447c485..1e270f2231b7b 100644
--- a/tests/baselines/reference/jsDeclarationsClassExtendsVisibility.js
+++ b/tests/baselines/reference/jsDeclarationsClassExtendsVisibility.js
@@ -56,12 +56,12 @@ declare class Bar {
 }
 //// [cls.d.ts]
 export = Foo;
-declare const Foo_base: typeof import("./bar");
-declare class Foo extends Foo_base {
+declare class Foo extends Bar {
 }
 declare namespace Foo {
     export { Strings };
 }
+import Bar = require("./bar");
 declare namespace Strings {
     const a: string;
     const b: string;
diff --git a/tests/baselines/reference/jsDeclarationsClassExtendsVisibility.types b/tests/baselines/reference/jsDeclarationsClassExtendsVisibility.types
index ff1086ebd2de1..b73577a1133b1 100644
--- a/tests/baselines/reference/jsDeclarationsClassExtendsVisibility.types
+++ b/tests/baselines/reference/jsDeclarationsClassExtendsVisibility.types
@@ -1,7 +1,7 @@
 === tests/cases/conformance/jsdoc/declarations/cls.js ===
 const Bar = require("./bar");
->Bar : typeof import("tests/cases/conformance/jsdoc/declarations/bar")
->require("./bar") : typeof import("tests/cases/conformance/jsdoc/declarations/bar")
+>Bar : typeof Bar
+>require("./bar") : typeof Bar
 >require : any
 >"./bar" : "./bar"
 
@@ -20,7 +20,7 @@ const Strings = {
 };
 class Foo extends Bar {}
 >Foo : Foo
->Bar : import("tests/cases/conformance/jsdoc/declarations/bar")
+>Bar : Bar
 
 module.exports = Foo;
 >module.exports = Foo : typeof Foo
diff --git a/tests/baselines/reference/jsDeclarationsExportAssignedVisibility.js b/tests/baselines/reference/jsDeclarationsExportAssignedVisibility.js
index 3935a7a2264f0..018aebdfec9cf 100644
--- a/tests/baselines/reference/jsDeclarationsExportAssignedVisibility.js
+++ b/tests/baselines/reference/jsDeclarationsExportAssignedVisibility.js
@@ -45,4 +45,4 @@ export = Container;
 declare class Container {
     usage: Obj;
 }
-import Obj = require(".");
+import Obj = require("./obj");

From ca5a57bd7aaf480ff916155331486dc6c55faaf8 Mon Sep 17 00:00:00 2001
From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com>
Date: Fri, 24 Jul 2020 09:04:30 -0700
Subject: [PATCH 14/30] require only creates aliases in JS

---
 src/compiler/binder.ts                        |   4 +-
 ...controlFlowPropertyDeclarations.errors.txt | 154 ------------------
 .../didYouMeanSuggestionErrors.errors.txt     |   6 +-
 .../reference/parser509534.errors.txt         |   6 +-
 .../reference/parserharness.errors.txt        |  10 +-
 5 files changed, 13 insertions(+), 167 deletions(-)
 delete mode 100644 tests/baselines/reference/controlFlowPropertyDeclarations.errors.txt

diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts
index 912d0ec671050..01fb07989843b 100644
--- a/src/compiler/binder.ts
+++ b/src/compiler/binder.ts
@@ -3187,7 +3187,7 @@ namespace ts {
             if (!isBindingPattern(node.name)) {
                 if (isBlockOrCatchScoped(node)) {
                     // TODO: This can probably come first, and be mutex with the succeeding 3 branches
-                    if (isRequireVariableDeclaration(node, /*requireStringLiteralLikeArgument*/ true)) {
+                    if (isInJSFile(node) && isRequireVariableDeclaration(node, /*requireStringLiteralLikeArgument*/ true)) {
                         declareSymbolAndAddToSymbolTable(node, SymbolFlags.Alias, SymbolFlags.AliasExcludes);
                     }
                     else {
@@ -3207,7 +3207,7 @@ namespace ts {
                     declareSymbolAndAddToSymbolTable(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.ParameterExcludes);
                 }
                 else {
-                    if (isRequireVariableDeclaration(node, /*requireStringLiteralLikeArgument*/ true)) {
+                    if (isInJSFile(node) && isRequireVariableDeclaration(node, /*requireStringLiteralLikeArgument*/ true)) {
                         declareSymbolAndAddToSymbolTable(node, SymbolFlags.Alias, SymbolFlags.AliasExcludes);
                     }
                     else {
diff --git a/tests/baselines/reference/controlFlowPropertyDeclarations.errors.txt b/tests/baselines/reference/controlFlowPropertyDeclarations.errors.txt
deleted file mode 100644
index be638164c79fb..0000000000000
--- a/tests/baselines/reference/controlFlowPropertyDeclarations.errors.txt
+++ /dev/null
@@ -1,154 +0,0 @@
-tests/cases/compiler/controlFlowPropertyDeclarations.ts(5,37): error TS2307: Cannot find module 'react/lib/HTMLDOMPropertyConfig' or its corresponding type declarations.
-
-
-==== tests/cases/compiler/controlFlowPropertyDeclarations.ts (1 errors) ====
-    // Repro from ##8913
-    
-    declare var require:any;
-    
-    var HTMLDOMPropertyConfig = require('react/lib/HTMLDOMPropertyConfig');
-                                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-!!! error TS2307: Cannot find module 'react/lib/HTMLDOMPropertyConfig' or its corresponding type declarations.
-    
-    // Populate property map with ReactJS's attribute and property mappings
-    // TODO handle/use .Properties value eg: MUST_USE_PROPERTY is not HTML attr
-    for (var propname in HTMLDOMPropertyConfig.Properties) {
-      if (!HTMLDOMPropertyConfig.Properties.hasOwnProperty(propname)) {
-        continue;
-      }
-    
-      var mapFrom = HTMLDOMPropertyConfig.DOMAttributeNames[propname] || propname.toLowerCase();
-    }
-    
-    /**
-     * Repeats a string a certain number of times.
-     * Also: the future is bright and consists of native string repetition:
-     * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat
-     *
-     * @param {string} string  String to repeat
-     * @param {number} times   Number of times to repeat string. Integer.
-     * @see http://jsperf.com/string-repeater/2
-     */
-    function repeatString(string, times) {
-      if (times === 1) {
-        return string;
-      }
-      if (times < 0) { throw new Error(); }
-      var repeated = '';
-      while (times) {
-        if (times & 1) {
-          repeated += string;
-        }
-        if (times >>= 1) {
-          string += string;
-        }
-      }
-      return repeated;
-    }
-    
-    /**
-     * Determine if the string ends with the specified substring.
-     *
-     * @param {string} haystack String to search in
-     * @param {string} needle   String to search for
-     * @return {boolean}
-     */
-    function endsWith(haystack, needle) {
-      return haystack.slice(-needle.length) === needle;
-    }
-    
-    /**
-     * Trim the specified substring off the string. If the string does not end
-     * with the specified substring, this is a no-op.
-     *
-     * @param {string} haystack String to search in
-     * @param {string} needle   String to search for
-     * @return {string}
-     */
-    function trimEnd(haystack, needle) {
-      return endsWith(haystack, needle)
-        ? haystack.slice(0, -needle.length)
-        : haystack;
-    }
-    
-    /**
-     * Convert a hyphenated string to camelCase.
-     */
-    function hyphenToCamelCase(string) {
-      return string.replace(/-(.)/g, function(match, chr) {
-        return chr.toUpperCase();
-      });
-    }
-    
-    /**
-     * Determines if the specified string consists entirely of whitespace.
-     */
-    function isEmpty(string) {
-       return !/[^\s]/.test(string);
-    }
-    
-    /**
-     * Determines if the CSS value can be converted from a
-     * 'px' suffixed string to a numeric value
-     *
-     * @param {string} value CSS property value
-     * @return {boolean}
-     */
-    function isConvertiblePixelValue(value) {
-      return /^\d+px$/.test(value);
-    }
-    
-    export class HTMLtoJSX {
-        private output: string;
-        private level: number;
-        private _inPreTag: boolean;
-    
-    
-      /**
-       * Handles processing of the specified text node
-       *
-       * @param {TextNode} node
-       */
-      _visitText = (node) => {
-        var parentTag = node.parentNode && node.parentNode.tagName.toLowerCase();
-        if (parentTag === 'textarea' || parentTag === 'style') {
-          // Ignore text content of textareas and styles, as it will have already been moved
-          // to a "defaultValue" attribute and "dangerouslySetInnerHTML" attribute respectively.
-          return;
-        }
-    
-        var text = ''
-    
-        if (this._inPreTag) {
-          // If this text is contained within a 
, we need to ensure the JSX
-          // whitespace coalescing rules don't eat the whitespace. This means
-          // wrapping newlines and sequences of two or more spaces in variables.
-          text = text
-            .replace(/\r/g, '')
-            .replace(/( {2,}|\n|\t|\{|\})/g, function(whitespace) {
-              return '{' + JSON.stringify(whitespace) + '}';
-            });
-        } else {
-          // If there's a newline in the text, adjust the indent level
-          if (text.indexOf('\n') > -1) {
-          }
-        }
-        this.output += text;
-      }
-    
-    
-    
-    };
-    
-    /**
-     * Handles parsing of inline styles
-     */
-    export class StyleParser {
-      styles = {};
-      toJSXString = () => {
-        for (var key in this.styles) {
-          if (!this.styles.hasOwnProperty(key)) {
-          }
-        }
-      }
-    }
\ No newline at end of file
diff --git a/tests/baselines/reference/didYouMeanSuggestionErrors.errors.txt b/tests/baselines/reference/didYouMeanSuggestionErrors.errors.txt
index c85fb04210fad..a41b19ecd9d60 100644
--- a/tests/baselines/reference/didYouMeanSuggestionErrors.errors.txt
+++ b/tests/baselines/reference/didYouMeanSuggestionErrors.errors.txt
@@ -6,7 +6,7 @@ tests/cases/compiler/didYouMeanSuggestionErrors.ts(8,5): error TS2582: Cannot fi
 tests/cases/compiler/didYouMeanSuggestionErrors.ts(9,9): error TS2584: Cannot find name 'console'. Do you need to change your target library? Try changing the `lib` compiler option to include 'dom'.
 tests/cases/compiler/didYouMeanSuggestionErrors.ts(9,21): error TS2580: Cannot find name 'process'. Do you need to install type definitions for node? Try `npm i @types/node`.
 tests/cases/compiler/didYouMeanSuggestionErrors.ts(10,9): error TS2584: Cannot find name 'document'. Do you need to change your target library? Try changing the `lib` compiler option to include 'dom'.
-tests/cases/compiler/didYouMeanSuggestionErrors.ts(12,27): error TS2307: Cannot find module 'fs' or its corresponding type declarations.
+tests/cases/compiler/didYouMeanSuggestionErrors.ts(12,19): error TS2580: Cannot find name 'require'. Do you need to install type definitions for node? Try `npm i @types/node`.
 tests/cases/compiler/didYouMeanSuggestionErrors.ts(13,19): error TS2580: Cannot find name 'Buffer'. Do you need to install type definitions for node? Try `npm i @types/node`.
 tests/cases/compiler/didYouMeanSuggestionErrors.ts(14,19): error TS2580: Cannot find name 'module'. Do you need to install type definitions for node? Try `npm i @types/node`.
 tests/cases/compiler/didYouMeanSuggestionErrors.ts(16,23): error TS2583: Cannot find name 'Map'. Do you need to change your target library? Try changing the `lib` compiler option to es2015 or later.
@@ -48,8 +48,8 @@ tests/cases/compiler/didYouMeanSuggestionErrors.ts(24,18): error TS2583: Cannot
 !!! error TS2584: Cannot find name 'document'. Do you need to change your target library? Try changing the `lib` compiler option to include 'dom'.
     
             const x = require("fs");
-                              ~~~~
-!!! error TS2307: Cannot find module 'fs' or its corresponding type declarations.
+                      ~~~~~~~
+!!! error TS2580: Cannot find name 'require'. Do you need to install type definitions for node? Try `npm i @types/node`.
             const y = Buffer.from([]);
                       ~~~~~~
 !!! error TS2580: Cannot find name 'Buffer'. Do you need to install type definitions for node? Try `npm i @types/node`.
diff --git a/tests/baselines/reference/parser509534.errors.txt b/tests/baselines/reference/parser509534.errors.txt
index b02ceeb0ae1ec..ff5eb131b5ce4 100644
--- a/tests/baselines/reference/parser509534.errors.txt
+++ b/tests/baselines/reference/parser509534.errors.txt
@@ -1,12 +1,12 @@
-tests/cases/conformance/parser/ecmascript5/RegressionTests/parser509534.ts(2,22): error TS2307: Cannot find module '../config' or its corresponding type declarations.
+tests/cases/conformance/parser/ecmascript5/RegressionTests/parser509534.ts(2,14): error TS2580: Cannot find name 'require'. Do you need to install type definitions for node? Try `npm i @types/node`.
 tests/cases/conformance/parser/ecmascript5/RegressionTests/parser509534.ts(3,1): error TS2580: Cannot find name 'module'. Do you need to install type definitions for node? Try `npm i @types/node`.
 
 
 ==== tests/cases/conformance/parser/ecmascript5/RegressionTests/parser509534.ts (2 errors) ====
     "use strict";
     var config = require("../config");
-                         ~~~~~~~~~~~
-!!! error TS2307: Cannot find module '../config' or its corresponding type declarations.
+                 ~~~~~~~
+!!! error TS2580: Cannot find name 'require'. Do you need to install type definitions for node? Try `npm i @types/node`.
     module.exports.route = function (server) {
     ~~~~~~
 !!! error TS2580: Cannot find name 'module'. Do you need to install type definitions for node? Try `npm i @types/node`.
diff --git a/tests/baselines/reference/parserharness.errors.txt b/tests/baselines/reference/parserharness.errors.txt
index 2636e6901b5e0..990fa5816c787 100644
--- a/tests/baselines/reference/parserharness.errors.txt
+++ b/tests/baselines/reference/parserharness.errors.txt
@@ -6,7 +6,7 @@ tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(21,29): er
 tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(25,17): error TS2304: Cannot find name 'IIO'.
 tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(41,12): error TS2304: Cannot find name 'ActiveXObject'.
 tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(43,19): error TS2580: Cannot find name 'require'. Do you need to install type definitions for node? Try `npm i @types/node`.
-tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(44,22): error TS2307: Cannot find module 'vm' or its corresponding type declarations.
+tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(44,14): error TS2580: Cannot find name 'require'. Do you need to install type definitions for node? Try `npm i @types/node`.
 tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(341,13): error TS2662: Cannot find name 'errorHandlerStack'. Did you mean the static member 'Runnable.errorHandlerStack'?
 tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(347,13): error TS2662: Cannot find name 'errorHandlerStack'. Did you mean the static member 'Runnable.errorHandlerStack'?
 tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(351,17): error TS2662: Cannot find name 'errorHandlerStack'. Did you mean the static member 'Runnable.errorHandlerStack'?
@@ -18,7 +18,7 @@ tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(721,62): e
 tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(724,29): error TS2304: Cannot find name 'ITextWriter'.
 tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(754,53): error TS2552: Cannot find name 'TypeScript'. Did you mean 'TypeScriptLS'?
 tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(764,56): error TS2503: Cannot find namespace 'TypeScript'.
-tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(765,37): error TS2552: Cannot find name 'TypeScript'. Did you mean 'TypeScriptLS'?
+tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(765,37): error TS2304: Cannot find name 'TypeScript'.
 tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(767,47): error TS2304: Cannot find name 'TypeScript'.
 tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(776,13): error TS2304: Cannot find name 'TypeScript'.
 tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(776,42): error TS2304: Cannot find name 'TypeScript'.
@@ -171,8 +171,8 @@ tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(2030,32):
                       ~~~~~~~
 !!! error TS2580: Cannot find name 'require'. Do you need to install type definitions for node? Try `npm i @types/node`.
         var vm = require('vm');
-                         ~~~~
-!!! error TS2307: Cannot find module 'vm' or its corresponding type declarations.
+                 ~~~~~~~
+!!! error TS2580: Cannot find name 'require'. Do you need to install type definitions for node? Try `npm i @types/node`.
         vm.runInThisContext(typescriptServiceFile, 'typescriptServices.js');
     } else {
         throw new Error('Unknown context');
@@ -917,7 +917,7 @@ tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(2030,32):
 !!! error TS2503: Cannot find namespace 'TypeScript'.
                 var compiler = c || new TypeScript.TypeScriptCompiler(stderr);
                                         ~~~~~~~~~~
-!!! error TS2552: Cannot find name 'TypeScript'. Did you mean 'TypeScriptLS'?
+!!! error TS2304: Cannot find name 'TypeScript'.
                 compiler.parser.errorRecovery = true;
                 compiler.settings.codeGenTarget = TypeScript.CodeGenTarget.ES5;
                                                   ~~~~~~~~~~

From e9a355de57283d8e0bbd22043c4383edd7a5df52 Mon Sep 17 00:00:00 2001
From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com>
Date: Fri, 24 Jul 2020 12:08:01 -0700
Subject: [PATCH 15/30] re-handle json imports

---
 src/compiler/checker.ts                     | 13 +++++++++++--
 tests/cases/fourslash/jsRequireQuickInfo.ts |  2 +-
 tests/cases/fourslash/renameJsExports02.ts  |  4 ++--
 tests/cases/fourslash/renameJsExports03.ts  |  8 ++++----
 4 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts
index 2aeefee5fc6d6..0b90ba0dfc07e 100644
--- a/src/compiler/checker.ts
+++ b/src/compiler/checker.ts
@@ -6315,7 +6315,7 @@ namespace ts {
                     if (symbol.flags & SymbolFlags.Alias) {
                         serializeAsAlias(symbol, getInternalSymbolName(symbol, symbolName), modifierFlags);
                     }
-                    if (symbol.flags & SymbolFlags.Property && symbol.escapedName === InternalSymbolName.ExportEquals) {
+                    if (symbol.flags & SymbolFlags.Property && symbol.escapedName === InternalSymbolName.ExportEquals) { // TODO: Delete this probably
                         serializeMaybeAliasAssignment(symbol);
                     }
                     if (symbol.flags & SymbolFlags.ExportStar) {
@@ -6683,6 +6683,10 @@ namespace ts {
                             }
                             // else fall through and treat require just like import=
                         case SyntaxKind.ImportEqualsDeclaration:
+                             if (target.escapedName === InternalSymbolName.ExportEquals) {
+                                serializeMaybeAliasAssignment(symbol);
+                                break;
+                            }
                             // Could be a local `import localName = ns.member` or
                             // an external `import localName = require("whatever")`
                             const isLocalImport = !(target.flags & SymbolFlags.ValueModule) && !isVariableDeclaration(node);
@@ -6797,6 +6801,7 @@ namespace ts {
                 }
 
                 /**
+                 * TODO: doesn't need to handle imports anymore
                  * Returns `true` if an export assignment or declaration was produced for the symbol
                  */
                 function serializeMaybeAliasAssignment(symbol: Symbol): boolean {
@@ -6877,7 +6882,11 @@ namespace ts {
                             const statement = factory.createVariableStatement(/*modifiers*/ undefined, factory.createVariableDeclarationList([
                                 factory.createVariableDeclaration(varName, /*exclamationToken*/ undefined, serializeTypeForDeclaration(context, typeToSerialize, symbol, enclosingDeclaration, includePrivateSymbol, bundled))
                             ], NodeFlags.Const));
-                            addResult(statement, name === varName ? ModifierFlags.Export : ModifierFlags.None);
+
+                            addResult(statement,
+                                target && target.flags & SymbolFlags.Property && target.escapedName === InternalSymbolName.ExportEquals ? ModifierFlags.Ambient
+                                : name === varName ? ModifierFlags.Export
+                                : ModifierFlags.None);
                         }
                         if (isExportAssignment) {
                             results.push(factory.createExportAssignment(
diff --git a/tests/cases/fourslash/jsRequireQuickInfo.ts b/tests/cases/fourslash/jsRequireQuickInfo.ts
index 5c78e87815a60..ee6ddc61d7a43 100644
--- a/tests/cases/fourslash/jsRequireQuickInfo.ts
+++ b/tests/cases/fourslash/jsRequireQuickInfo.ts
@@ -7,4 +7,4 @@
 // @Filename: b.js
 ////exports.x = 0;
 
-verify.quickInfoAt("",'const x: typeof import("/tests/cases/fourslash/b")');
+verify.quickInfoAt("",'import x');
diff --git a/tests/cases/fourslash/renameJsExports02.ts b/tests/cases/fourslash/renameJsExports02.ts
index 17f69760931c9..976d9b6c9e9cd 100644
--- a/tests/cases/fourslash/renameJsExports02.ts
+++ b/tests/cases/fourslash/renameJsExports02.ts
@@ -10,7 +10,7 @@
 const [rDef, r0, r1Def, r1] = test.ranges();
 verify.referenceGroups(r0, [
     { definition: "(local class) A", ranges: [r0] },
-    { definition: "const A: typeof A", ranges: [r1] }
+    { definition: "(alias) (local class) A\nimport A", ranges: [r1] }
 ]);
 
-verify.singleReferenceGroup("const A: typeof A", [r1]);
+verify.singleReferenceGroup("(alias) (local class) A\nimport A", [r1]);
diff --git a/tests/cases/fourslash/renameJsExports03.ts b/tests/cases/fourslash/renameJsExports03.ts
index 02704eda8c7dc..f283d6bf45070 100644
--- a/tests/cases/fourslash/renameJsExports03.ts
+++ b/tests/cases/fourslash/renameJsExports03.ts
@@ -14,18 +14,18 @@
 const [r0Def, r0, r1Def, r1, r2Def, r2, r3Def, r3, r4] = test.ranges();
 verify.referenceGroups([r0, r2], [
     { definition: "class A", ranges: [r0, r2] },
-    { definition: "const A: typeof A", ranges: [r3, r4] }
+    { definition: "(alias) class A\nimport A", ranges: [r3, r4] }
 ]);
 
 verify.referenceGroups(r1, [
     { definition: "class A", ranges: [r1] },
-    { definition: "const A: typeof A", ranges: [r4] }
+    { definition: "(alias) class A\nimport A", ranges: [r4] }
 ]);
 
 verify.referenceGroups(r3, [
-    { definition: "const A: typeof A", ranges: [r3, r4] }
+    { definition: "(alias) class A\nimport A", ranges: [r3, r4] }
 ]);
 verify.referenceGroups(r4, [
-    { definition: "const A: typeof A", ranges: [r3, r4] }
+    { definition: "(alias) class A\nimport A", ranges: [r3, r4] }
 ]);
 

From febcf0e326d716982ed499ea3bf0856d5a24ef2b Mon Sep 17 00:00:00 2001
From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com>
Date: Fri, 24 Jul 2020 13:19:02 -0700
Subject: [PATCH 16/30] update fourslash baseline

---
 tests/cases/fourslash/findAllRefsImportEqualsJsonFile.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/cases/fourslash/findAllRefsImportEqualsJsonFile.ts b/tests/cases/fourslash/findAllRefsImportEqualsJsonFile.ts
index 2969ef07638bd..d047ed4e11e4e 100644
--- a/tests/cases/fourslash/findAllRefsImportEqualsJsonFile.ts
+++ b/tests/cases/fourslash/findAllRefsImportEqualsJsonFile.ts
@@ -20,5 +20,5 @@ verify.noErrors();
 const [r0Def, r0, r1, r2, r3Def, r3, r4, r5, r6] = test.ranges();
 verify.singleReferenceGroup('import j = require("./j.json")', [r0, r2]);
 verify.referenceGroups([r1, r4], [{ definition: 'module "/j"', ranges: [r1, r4, r6] }]);
-verify.singleReferenceGroup('const j: {\n    x: number;\n}', [r3, r5]);
+verify.singleReferenceGroup('import j', [r3, r5]);
 verify.referenceGroups(r6, undefined);

From 3ee9b6fe18388c8df296fff107df86e82ad98aa1 Mon Sep 17 00:00:00 2001
From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com>
Date: Fri, 24 Jul 2020 15:08:44 -0700
Subject: [PATCH 17/30] Cleanup in the checker

1. Simplify alias resolution.
2. Simplify variable-like checking.
3. Make binding skip require calls with type tags -- they fall back to
the old require-call code and then check from there.

I haven't started on the declaration emit code since I don't know what
is going on there nearly as well.
---
 src/compiler/binder.ts                        | 20 ++++-------
 src/compiler/checker.ts                       | 36 ++++---------------
 .../checkExportsObjectAssignProperty.symbols  |  8 ++---
 .../requireOfJsonFileInJsFile.symbols         |  8 ++---
 4 files changed, 20 insertions(+), 52 deletions(-)

diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts
index 01fb07989843b..1fc549e05e0ed 100644
--- a/src/compiler/binder.ts
+++ b/src/compiler/binder.ts
@@ -3185,14 +3185,11 @@ namespace ts {
             }
 
             if (!isBindingPattern(node.name)) {
-                if (isBlockOrCatchScoped(node)) {
-                    // TODO: This can probably come first, and be mutex with the succeeding 3 branches
-                    if (isInJSFile(node) && isRequireVariableDeclaration(node, /*requireStringLiteralLikeArgument*/ true)) {
-                        declareSymbolAndAddToSymbolTable(node, SymbolFlags.Alias, SymbolFlags.AliasExcludes);
-                    }
-                    else {
-                        bindBlockScopedDeclaration(node, SymbolFlags.BlockScopedVariable, SymbolFlags.BlockScopedVariableExcludes);
-                    }
+                if (isInJSFile(node) && isRequireVariableDeclaration(node, /*requireStringLiteralLikeArgument*/ true) && !getJSDocTypeTag(node)) {
+                    declareSymbolAndAddToSymbolTable(node as Declaration, SymbolFlags.Alias, SymbolFlags.AliasExcludes);
+                }
+                else if (isBlockOrCatchScoped(node)) {
+                    bindBlockScopedDeclaration(node, SymbolFlags.BlockScopedVariable, SymbolFlags.BlockScopedVariableExcludes);
                 }
                 else if (isParameterDeclaration(node)) {
                     // It is safe to walk up parent chain to find whether the node is a destructuring parameter declaration
@@ -3207,12 +3204,7 @@ namespace ts {
                     declareSymbolAndAddToSymbolTable(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.ParameterExcludes);
                 }
                 else {
-                    if (isInJSFile(node) && isRequireVariableDeclaration(node, /*requireStringLiteralLikeArgument*/ true)) {
-                        declareSymbolAndAddToSymbolTable(node, SymbolFlags.Alias, SymbolFlags.AliasExcludes);
-                    }
-                    else {
-                        declareSymbolAndAddToSymbolTable(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.FunctionScopedVariableExcludes);
-                    }
+                    declareSymbolAndAddToSymbolTable(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.FunctionScopedVariableExcludes);
                 }
             }
         }
diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts
index 0b90ba0dfc07e..15a80086cfa2b 100644
--- a/src/compiler/checker.ts
+++ b/src/compiler/checker.ts
@@ -2397,28 +2397,11 @@ namespace ts {
                 const immediate = resolveExternalModuleName(node, isVariableDeclaration(node)
                     ? (getFirstPropertyAccessExpression(node.initializer!) as CallExpression).arguments[0]
                     : getExternalModuleImportEqualsDeclarationExpression(node));
-                if (isVariableDeclaration(node)) {
-                    const typeTag = getJSDocTypeTag(node);
-                    if (node.initializer && isPropertyAccessExpression(node.initializer)) {
-                        if (!isIdentifier(node.initializer.name))
-                            return undefined;
-                        // TODO: Relies on old code in resolveCallExpression that special-cases `require("x")`
-                        const original = getPropertyOfType(checkExpression(node.initializer.expression), node.initializer.name.escapedText);
-                        if (typeTag && original) {
-                            const symbol: TransientSymbol = cloneSymbol(original) as TransientSymbol
-                            symbol.type = getTypeFromTypeNode(typeTag.typeExpression);
-                            return symbol;
-                        }
-                        // TODO: Might still want to resolveExternalModuleSymbol here?
-                        return original;
-                    }
-                    else if (typeTag && immediate) {
-                        // TODO: This is basically wrong.
-                        const symbol: TransientSymbol = cloneSymbol(immediate) as TransientSymbol
-                        symbol.type = getTypeFromTypeNode(typeTag.typeExpression);
-                        return symbol;
-                    }
-                    return resolveExternalModuleSymbol(immediate);
+                if (isVariableDeclaration(node) && node.initializer && isPropertyAccessExpression(node.initializer)) {
+                    // Use the ad-hoc require-as-CallExpression code to create a fresh anonymous type and retrieve the property by name.
+                    return isIdentifier(node.initializer.name)
+                        ? getPropertyOfType(checkExpression(node.initializer.expression), node.initializer.name.escapedText)
+                        : undefined;
                 }
                 const resolved = resolveExternalModuleSymbol(immediate);
                 markSymbolOfAliasDeclarationIfTypeOnly(node, immediate, resolved, /*overwriteEmpty*/ false);
@@ -32889,16 +32872,9 @@ namespace ts {
                 return;
             }
             // For a require binding element, validate the alias and exit
-            // TODO: Probably should mark the symbol so I don't have to keep rescanning this
             const symbol = getSymbolOfNode(node);
-            if (/*isBindingElement(node) && */isRequireVariableDeclaration(node, /*requireStringLiteralLikeArgument*/ true) && symbol.flags & SymbolFlags.Alias) {
+            if (symbol.flags & SymbolFlags.Alias && isRequireVariableDeclaration(node, /*requireStringLiteralLikeArgument*/ true)) {
                 checkAliasSymbol(node);
-                const typeTag = getJSDocTypeTag(node);
-                const initializer = node.initializer;
-                if (typeTag) {
-                    const type = getTypeFromTypeNode(typeTag.typeExpression);
-                    checkTypeAssignableToAndOptionallyElaborate(checkExpressionCached(initializer), type, node, initializer, /*headMessage*/ undefined);
-                }
                 return;
             }
 
diff --git a/tests/baselines/reference/checkExportsObjectAssignProperty.symbols b/tests/baselines/reference/checkExportsObjectAssignProperty.symbols
index 15306b0f325b8..e1dcacbfe2c8f 100644
--- a/tests/baselines/reference/checkExportsObjectAssignProperty.symbols
+++ b/tests/baselines/reference/checkExportsObjectAssignProperty.symbols
@@ -269,18 +269,18 @@ Object.defineProperty(module.exports, "setonlyAccessor", {
  */
 const q = require("./mod1").thing;
 >q : Symbol(q, Decl(index.js, 3, 5))
->require("./mod1").thing : Symbol(q, Decl(mod1.js, 0, 0))
+>require("./mod1").thing : Symbol(thing, Decl(mod1.js, 0, 0))
 >require : Symbol(require)
 >"./mod1" : Symbol("tests/cases/conformance/jsdoc/mod1", Decl(mod1.js, 0, 0))
->thing : Symbol(q, Decl(mod1.js, 0, 0))
+>thing : Symbol(thing, Decl(mod1.js, 0, 0))
 
 /**
  * @type {string}
  */
 const u = require("./mod2").thing;
 >u : Symbol(u, Decl(index.js, 8, 5))
->require("./mod2").thing : Symbol(u, Decl(mod2.js, 0, 0))
+>require("./mod2").thing : Symbol(thing, Decl(mod2.js, 0, 0))
 >require : Symbol(require)
 >"./mod2" : Symbol("tests/cases/conformance/jsdoc/mod2", Decl(mod2.js, 0, 0))
->thing : Symbol(u, Decl(mod2.js, 0, 0))
+>thing : Symbol(thing, Decl(mod2.js, 0, 0))
 
diff --git a/tests/baselines/reference/requireOfJsonFileInJsFile.symbols b/tests/baselines/reference/requireOfJsonFileInJsFile.symbols
index 7f3247069cf85..2a1e9b6ebd307 100644
--- a/tests/baselines/reference/requireOfJsonFileInJsFile.symbols
+++ b/tests/baselines/reference/requireOfJsonFileInJsFile.symbols
@@ -2,7 +2,7 @@
 const json0 = require("./json.json");
 >json0 : Symbol(json0, Decl(user.js, 0, 5))
 >require : Symbol(require)
->"./json.json" : Symbol(json1, Decl(json.json, 0, 0))
+>"./json.json" : Symbol("/json", Decl(json.json, 0, 0))
 
 json0.b; // Error (good)
 >json0 : Symbol(json0, Decl(user.js, 0, 5))
@@ -11,7 +11,7 @@ json0.b; // Error (good)
 const json1 = require("./json.json"); // No error (bad)
 >json1 : Symbol(json1, Decl(user.js, 4, 5))
 >require : Symbol(require)
->"./json.json" : Symbol(json1, Decl(json.json, 0, 0))
+>"./json.json" : Symbol("/json", Decl(json.json, 0, 0))
 
 json1.b; // No error (OK since that's the type annotation)
 >json1.b : Symbol(b, Decl(user.js, 3, 12))
@@ -21,7 +21,7 @@ json1.b; // No error (OK since that's the type annotation)
 const js0 = require("./js.js");
 >js0 : Symbol(js0, Decl(user.js, 7, 5))
 >require : Symbol(require)
->"./js.js" : Symbol(js1, Decl(js.js, 0, 0))
+>"./js.js" : Symbol("/js", Decl(js.js, 0, 0))
 
 json0.b; // Error (good)
 >json0 : Symbol(json0, Decl(user.js, 0, 5))
@@ -30,7 +30,7 @@ json0.b; // Error (good)
 const js1 = require("./js.js"); // Error (good)
 >js1 : Symbol(js1, Decl(user.js, 11, 5))
 >require : Symbol(require)
->"./js.js" : Symbol(js1, Decl(js.js, 0, 0))
+>"./js.js" : Symbol("/js", Decl(js.js, 0, 0))
 
 js1.b;
 >js1.b : Symbol(b, Decl(user.js, 10, 12))

From a671b454f4c86dd0aa65a695d8203e7ac39e30bc Mon Sep 17 00:00:00 2001
From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com>
Date: Fri, 24 Jul 2020 16:08:08 -0700
Subject: [PATCH 18/30] Function for getting module name from require call

---
 src/compiler/checker.ts   | 45 ++++++++++++++++++++-------------------
 src/compiler/utilities.ts |  6 +++++-
 2 files changed, 28 insertions(+), 23 deletions(-)

diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts
index 15a80086cfa2b..41b25f80ca097 100644
--- a/src/compiler/checker.ts
+++ b/src/compiler/checker.ts
@@ -2394,9 +2394,9 @@ namespace ts {
 
         function getTargetOfImportEqualsDeclaration(node: ImportEqualsDeclaration | VariableDeclaration, dontResolveAlias: boolean): Symbol | undefined {
             if (isVariableDeclaration(node) || node.moduleReference.kind === SyntaxKind.ExternalModuleReference) {
-                const immediate = resolveExternalModuleName(node, isVariableDeclaration(node)
-                    ? (getFirstPropertyAccessExpression(node.initializer!) as CallExpression).arguments[0]
-                    : getExternalModuleImportEqualsDeclarationExpression(node));
+                const immediate = resolveExternalModuleName(
+                    node,
+                    getExternalModuleRequireArgument(node) || getExternalModuleImportEqualsDeclarationExpression(node));
                 if (isVariableDeclaration(node) && node.initializer && isPropertyAccessExpression(node.initializer)) {
                     // Use the ad-hoc require-as-CallExpression code to create a fresh anonymous type and retrieve the property by name.
                     return isIdentifier(node.initializer.name)
@@ -2593,8 +2593,11 @@ namespace ts {
 
         function getExportOfModule(symbol: Symbol, specifier: ImportOrExportSpecifier | BindingElement, dontResolveAlias: boolean): Symbol | undefined {
             if (symbol.flags & SymbolFlags.Module) {
-                const name = ((specifier.propertyName ?? specifier.name) as Identifier).escapedText;
-                const exportSymbol = getExportsOfSymbol(symbol).get(name);
+                const name = specifier.propertyName ?? specifier.name;
+                if (!isIdentifier(name)) {
+                    return undefined;
+                }
+                const exportSymbol = getExportsOfSymbol(symbol).get(name.escapedText);
                 const resolved = resolveSymbol(exportSymbol, dontResolveAlias);
                 markSymbolOfAliasDeclarationIfTypeOnly(specifier, exportSymbol, resolved, /*overwriteEmpty*/ false);
                 return resolved;
@@ -2611,10 +2614,12 @@ namespace ts {
         }
 
         function getExternalModuleMember(node: ImportDeclaration | ExportDeclaration | VariableDeclaration, specifier: ImportOrExportSpecifier | BindingElement, dontResolveAlias = false): Symbol | undefined {
-            const moduleSpecifier = isVariableDeclaration(node) ? (getFirstPropertyAccessExpression(node.initializer!) as CallExpression).arguments[0] : node.moduleSpecifier!;
+            const moduleSpecifier = getExternalModuleRequireArgument(node) || (node as ImportDeclaration | ExportDeclaration).moduleSpecifier!;
             const moduleSymbol = resolveExternalModuleName(node, moduleSpecifier)!; // TODO: GH#18217
             const name = specifier.propertyName || specifier.name;
-            Debug.assert(isIdentifier(name)); // :eyes:
+            if (!isIdentifier(name)) {
+                return undefined;
+            }
             const suppressInteropError = name.escapedText === InternalSymbolName.Default && !!(compilerOptions.allowSyntheticDefaultImports || compilerOptions.esModuleInterop);
             const targetSymbol = resolveESModuleSymbol(moduleSymbol, moduleSpecifier, dontResolveAlias, suppressInteropError);
             if (targetSymbol) {
@@ -6638,33 +6643,29 @@ namespace ts {
                     includePrivateSymbol(target); // the target may be within the same scope - attempt to serialize it first
                     switch (node.kind) {
                         case SyntaxKind.VariableDeclaration:
-                            // commonjs require
+                            // commonjs require: const x = require('y')
                             if (isPropertyAccessExpression((node as VariableDeclaration).initializer!)) {
-                                // const x = require('x').x
-                                const access = (node as VariableDeclaration).initializer! as PropertyAccessExpression;
-                                const require = getFirstPropertyAccessExpression(access) as CallExpression;
-                                const moduleName = require.arguments[0] as StringLiteral;
-                                const tmp = factory.createUniqueName(moduleName.text);
-                                // import _x = require('x')
-                                let n = factory.createImportEqualsDeclaration(
+                                // const x = require('y').z --> import _x = require('y'); import z = _x.z
+                                const access = (node as VariableDeclaration).initializer! as PropertyAccessExpression; // require('y').z
+                                const moduleName = getExternalModuleRequireArgument(node) as StringLiteral; // 'y'
+                                const uniqueName = factory.createUniqueName(moduleName.text); // _x
+                                addResult(factory.createImportEqualsDeclaration(
                                     /*decorators*/ undefined,
                                     /*modifiers*/ undefined,
-                                    tmp,
+                                    uniqueName,
                                     // TODO: Use target.parent here because alias resolution on post-property-access over-resolves to a module export
                                     // *probably* I should fix this in type-checking instead, but I'm not sure how to request an additional resolution step during checking
                                     factory.createExternalModuleReference(factory.createStringLiteral(getSpecifierForModuleSymbol(target.parent || target, context)))
-                                );
-                                addResult(n, ModifierFlags.None);
-                                // import x = _x.X
+                                ), ModifierFlags.None);
                                 addResult(factory.createImportEqualsDeclaration(
                                     /*decorators*/ undefined,
                                     /*modifiers*/ undefined,
                                     factory.createIdentifier(localName),
-                                    factory.createQualifiedName(tmp, access.name as Identifier), // TODO: symbolToName handles the recursive case (but may do some extra stuff we don't want)
+                                    factory.createQualifiedName(uniqueName, access.name as Identifier),
                                 ), modifierFlags);
                                 break;
                             }
-                            // else fall through and treat require just like import=
+                            // else fall through and treat commonjs require just like import=
                         case SyntaxKind.ImportEqualsDeclaration:
                              if (target.escapedName === InternalSymbolName.ExportEquals) {
                                 serializeMaybeAliasAssignment(symbol);
@@ -32871,7 +32872,7 @@ namespace ts {
                 }
                 return;
             }
-            // For a require binding element, validate the alias and exit
+            // For a commonjs `const x = require`, validate the alias and exit
             const symbol = getSymbolOfNode(node);
             if (symbol.flags & SymbolFlags.Alias && isRequireVariableDeclaration(node, /*requireStringLiteralLikeArgument*/ true)) {
                 checkAliasSymbol(node);
diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts
index 182c5a589608b..586cb1bb97ee0 100644
--- a/src/compiler/utilities.ts
+++ b/src/compiler/utilities.ts
@@ -1847,6 +1847,11 @@ namespace ts {
         return ((node).moduleReference).expression;
     }
 
+    export function getExternalModuleRequireArgument(node: Node) {
+        return isRequireVariableDeclaration(node, /*requireStringLiteralLikeArgument*/ true)
+            && (getFirstPropertyAccessExpression(node.initializer!) as CallExpression).arguments[0] as StringLiteral;
+    }
+
     export function isInternalModuleImportEqualsDeclaration(node: Node): node is ImportEqualsDeclaration {
         return node.kind === SyntaxKind.ImportEqualsDeclaration && (node).moduleReference.kind !== SyntaxKind.ExternalModuleReference;
     }
@@ -1910,7 +1915,6 @@ namespace ts {
     /**
      * Returns true if the node is a VariableDeclaration initialized to a require call (see `isRequireCall`).
      * This function does not test if the node is in a JavaScript file or not.
-     * TODO: But probably should???!
      */
     export function isRequireVariableDeclaration(node: Node, requireStringLiteralLikeArgument: true): node is RequireVariableDeclaration;
     export function isRequireVariableDeclaration(node: Node, requireStringLiteralLikeArgument: boolean): node is VariableDeclaration;

From 0c922773a779dd6320dc8982e83fad91f900b9d6 Mon Sep 17 00:00:00 2001
From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com>
Date: Mon, 27 Jul 2020 08:41:44 -0700
Subject: [PATCH 19/30] First round of cleanup plus a new test

Found one missing feature, not sure it's worth adding.
---
 src/compiler/checker.ts                       | 31 +++++---------
 .../reference/jsDeclarationsExportFormsErr.js |  2 +-
 .../jsDeclarationsTypeReferences2.errors.txt  | 23 ++++++++++
 .../jsDeclarationsTypeReferences2.js          | 41 ++++++++++++++++++
 .../jsDeclarationsTypeReferences2.symbols     | 35 ++++++++++++++++
 .../jsDeclarationsTypeReferences2.types       | 42 +++++++++++++++++++
 .../jsDeclarationsTypeReferences2.ts          | 20 +++++++++
 7 files changed, 173 insertions(+), 21 deletions(-)
 create mode 100644 tests/baselines/reference/jsDeclarationsTypeReferences2.errors.txt
 create mode 100644 tests/baselines/reference/jsDeclarationsTypeReferences2.js
 create mode 100644 tests/baselines/reference/jsDeclarationsTypeReferences2.symbols
 create mode 100644 tests/baselines/reference/jsDeclarationsTypeReferences2.types
 create mode 100644 tests/cases/conformance/jsdoc/declarations/jsDeclarationsTypeReferences2.ts

diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts
index 6601bd0146941..4d07bdb8107ad 100644
--- a/src/compiler/checker.ts
+++ b/src/compiler/checker.ts
@@ -6645,23 +6645,23 @@ namespace ts {
                         case SyntaxKind.VariableDeclaration:
                             // commonjs require: const x = require('y')
                             if (isPropertyAccessExpression((node as VariableDeclaration).initializer!)) {
-                                // const x = require('y').z --> import _x = require('y'); import z = _x.z
-                                const access = (node as VariableDeclaration).initializer! as PropertyAccessExpression; // require('y').z
-                                const moduleName = getExternalModuleRequireArgument(node) as StringLiteral; // 'y'
-                                const uniqueName = factory.createUniqueName(moduleName.text); // _x
+                                // const x = require('y').z
+                                const initializer = (node as VariableDeclaration).initializer! as PropertyAccessExpression; // require('y').z
+                                const uniqueName = factory.createUniqueName((getExternalModuleRequireArgument(node) as StringLiteral).text); // _y
+                                const specifier = getSpecifierForModuleSymbol(target.parent || target, context); // 'y'
+                                // import _y = require('y');
                                 addResult(factory.createImportEqualsDeclaration(
                                     /*decorators*/ undefined,
                                     /*modifiers*/ undefined,
                                     uniqueName,
-                                    // TODO: Use target.parent here because alias resolution on post-property-access over-resolves to a module export
-                                    // *probably* I should fix this in type-checking instead, but I'm not sure how to request an additional resolution step during checking
-                                    factory.createExternalModuleReference(factory.createStringLiteral(getSpecifierForModuleSymbol(target.parent || target, context)))
+                                    factory.createExternalModuleReference(factory.createStringLiteral(specifier))
                                 ), ModifierFlags.None);
+                                // import x = _y.z
                                 addResult(factory.createImportEqualsDeclaration(
                                     /*decorators*/ undefined,
                                     /*modifiers*/ undefined,
                                     factory.createIdentifier(localName),
-                                    factory.createQualifiedName(uniqueName, access.name as Identifier),
+                                    factory.createQualifiedName(uniqueName, initializer.name as Identifier),
                                 ), modifierFlags);
                                 break;
                             }
@@ -6674,20 +6674,14 @@ namespace ts {
                             // Could be a local `import localName = ns.member` or
                             // an external `import localName = require("whatever")`
                             const isLocalImport = !(target.flags & SymbolFlags.ValueModule) && !isVariableDeclaration(node);
-                            // TODO: It's very likely that this should always use target and using symbol was a bug
-                            const naam = isVariableDeclaration(node)
-                                ? getSpecifierForModuleSymbol(target, context)
-                                : getSpecifierForModuleSymbol(symbol, context)
-                            let n = factory.createImportEqualsDeclaration(
+                            addResult(factory.createImportEqualsDeclaration(
                                 /*decorators*/ undefined,
                                 /*modifiers*/ undefined,
                                 factory.createIdentifier(localName),
                                 isLocalImport
                                     ? symbolToName(target, context, SymbolFlags.All, /*expectsIdentifier*/ false)
-                                // TODO: make getSpecifierForModuleSymbol work with require Symbols
-                                    : factory.createExternalModuleReference(factory.createStringLiteral(naam))
-                            )
-                            addResult(n, isLocalImport ? modifierFlags : ModifierFlags.None);
+                                    : factory.createExternalModuleReference(factory.createStringLiteral(getSpecifierForModuleSymbol(target, context)))
+                            ), isLocalImport ? modifierFlags : ModifierFlags.None);
                             break;
                         case SyntaxKind.NamespaceExportDeclaration:
                             // export as namespace foo
@@ -6723,9 +6717,6 @@ namespace ts {
                                 factory.createStringLiteral(getSpecifierForModuleSymbol(target, context))
                             ), ModifierFlags.None);
                             break;
-                        case SyntaxKind.BindingElement:
-                            // TODO: remember to handle postfix property access~~~
-                            // TODO: Actually write tests for this, there aren't any that I can see
                         case SyntaxKind.ImportSpecifier:
                             addResult(factory.createImportDeclaration(
                                 /*decorators*/ undefined,
diff --git a/tests/baselines/reference/jsDeclarationsExportFormsErr.js b/tests/baselines/reference/jsDeclarationsExportFormsErr.js
index 14c94dd65dcce..3146597117146 100644
--- a/tests/baselines/reference/jsDeclarationsExportFormsErr.js
+++ b/tests/baselines/reference/jsDeclarationsExportFormsErr.js
@@ -67,7 +67,7 @@ export class Foo {
 }
 //// [bar.d.ts]
 export = ns;
-import ns = require("./bar");
+import ns = require("./cls");
 //// [bin.d.ts]
 export {};
 //// [globalNs.d.ts]
diff --git a/tests/baselines/reference/jsDeclarationsTypeReferences2.errors.txt b/tests/baselines/reference/jsDeclarationsTypeReferences2.errors.txt
new file mode 100644
index 0000000000000..e16b5cca80bab
--- /dev/null
+++ b/tests/baselines/reference/jsDeclarationsTypeReferences2.errors.txt
@@ -0,0 +1,23 @@
+tests/cases/conformance/jsdoc/declarations/index.js(1,8): error TS2305: Module '"./something"' has no exported member 'a'.
+tests/cases/conformance/jsdoc/declarations/index.js(1,11): error TS2305: Module '"./something"' has no exported member 'm'.
+
+
+==== tests/cases/conformance/jsdoc/declarations/index.js (2 errors) ====
+    const{ a, m } = require("./something").o;
+           ~
+!!! error TS2305: Module '"./something"' has no exported member 'a'.
+              ~
+!!! error TS2305: Module '"./something"' has no exported member 'm'.
+    
+    const thing = a + m
+    
+    module.exports = {
+        thing
+    };
+    
+==== tests/cases/conformance/jsdoc/declarations/something.ts (0 errors) ====
+    export const o = {
+        a: 1,
+        m: 1
+    }
+    
\ No newline at end of file
diff --git a/tests/baselines/reference/jsDeclarationsTypeReferences2.js b/tests/baselines/reference/jsDeclarationsTypeReferences2.js
new file mode 100644
index 0000000000000..a38563cf374b8
--- /dev/null
+++ b/tests/baselines/reference/jsDeclarationsTypeReferences2.js
@@ -0,0 +1,41 @@
+//// [tests/cases/conformance/jsdoc/declarations/jsDeclarationsTypeReferences2.ts] ////
+
+//// [something.ts]
+export const o = {
+    a: 1,
+    m: 1
+}
+
+//// [index.js]
+const{ a, m } = require("./something").o;
+
+const thing = a + m
+
+module.exports = {
+    thing
+};
+
+
+//// [something.js]
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.o = void 0;
+exports.o = {
+    a: 1,
+    m: 1
+};
+//// [index.js]
+var _a = require("./something").o, a = _a.a, m = _a.m;
+var thing = a + m;
+module.exports = {
+    thing: thing
+};
+
+
+//// [something.d.ts]
+export declare const o: {
+    a: number;
+    m: number;
+};
+//// [index.d.ts]
+export const thing: any;
diff --git a/tests/baselines/reference/jsDeclarationsTypeReferences2.symbols b/tests/baselines/reference/jsDeclarationsTypeReferences2.symbols
new file mode 100644
index 0000000000000..ecab617947465
--- /dev/null
+++ b/tests/baselines/reference/jsDeclarationsTypeReferences2.symbols
@@ -0,0 +1,35 @@
+=== tests/cases/conformance/jsdoc/declarations/index.js ===
+const{ a, m } = require("./something").o;
+>a : Symbol(a, Decl(index.js, 0, 6))
+>m : Symbol(m, Decl(index.js, 0, 9))
+>require("./something").o : Symbol(o, Decl(something.ts, 0, 12))
+>require : Symbol(require)
+>"./something" : Symbol("tests/cases/conformance/jsdoc/declarations/something", Decl(something.ts, 0, 0))
+>o : Symbol(o, Decl(something.ts, 0, 12))
+
+const thing = a + m
+>thing : Symbol(thing, Decl(index.js, 2, 5))
+>a : Symbol(a, Decl(index.js, 0, 6))
+>m : Symbol(m, Decl(index.js, 0, 9))
+
+module.exports = {
+>module.exports : Symbol("tests/cases/conformance/jsdoc/declarations/index", Decl(index.js, 0, 0))
+>module : Symbol(export=, Decl(index.js, 2, 19))
+>exports : Symbol(export=, Decl(index.js, 2, 19))
+
+    thing
+>thing : Symbol(thing, Decl(index.js, 4, 18))
+
+};
+
+=== tests/cases/conformance/jsdoc/declarations/something.ts ===
+export const o = {
+>o : Symbol(o, Decl(something.ts, 0, 12))
+
+    a: 1,
+>a : Symbol(a, Decl(something.ts, 0, 18))
+
+    m: 1
+>m : Symbol(m, Decl(something.ts, 1, 9))
+}
+
diff --git a/tests/baselines/reference/jsDeclarationsTypeReferences2.types b/tests/baselines/reference/jsDeclarationsTypeReferences2.types
new file mode 100644
index 0000000000000..e57c2b57c6511
--- /dev/null
+++ b/tests/baselines/reference/jsDeclarationsTypeReferences2.types
@@ -0,0 +1,42 @@
+=== tests/cases/conformance/jsdoc/declarations/index.js ===
+const{ a, m } = require("./something").o;
+>a : any
+>m : any
+>require("./something").o : { a: number; m: number; }
+>require("./something") : typeof import("tests/cases/conformance/jsdoc/declarations/something")
+>require : any
+>"./something" : "./something"
+>o : { a: number; m: number; }
+
+const thing = a + m
+>thing : any
+>a + m : any
+>a : any
+>m : any
+
+module.exports = {
+>module.exports = {    thing} : { thing: any; }
+>module.exports : { thing: any; }
+>module : { "\"tests/cases/conformance/jsdoc/declarations/index\"": { thing: any; }; }
+>exports : { thing: any; }
+>{    thing} : { thing: any; }
+
+    thing
+>thing : any
+
+};
+
+=== tests/cases/conformance/jsdoc/declarations/something.ts ===
+export const o = {
+>o : { a: number; m: number; }
+>{    a: 1,    m: 1} : { a: number; m: number; }
+
+    a: 1,
+>a : number
+>1 : 1
+
+    m: 1
+>m : number
+>1 : 1
+}
+
diff --git a/tests/cases/conformance/jsdoc/declarations/jsDeclarationsTypeReferences2.ts b/tests/cases/conformance/jsdoc/declarations/jsDeclarationsTypeReferences2.ts
new file mode 100644
index 0000000000000..bd67ecd26e060
--- /dev/null
+++ b/tests/cases/conformance/jsdoc/declarations/jsDeclarationsTypeReferences2.ts
@@ -0,0 +1,20 @@
+// @allowJs: true
+// @checkJs: true
+// @target: es5
+// @outDir: tests/cases/conformance/jsdoc/declarations/out
+// @declaration: true
+// @filename: something.ts
+export const o = {
+    a: 1,
+    m: 1
+}
+
+// @filename: index.js
+
+const{ a, m } = require("./something").o;
+
+const thing = a + m
+
+module.exports = {
+    thing
+};

From dee056103bd760c3343ec30264890b785fbd7c7b Mon Sep 17 00:00:00 2001
From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com>
Date: Mon, 27 Jul 2020 10:24:11 -0700
Subject: [PATCH 20/30] more small cleanup

---
 src/compiler/checker.ts | 15 +++++++--------
 src/compiler/types.ts   |  1 -
 2 files changed, 7 insertions(+), 9 deletions(-)

diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts
index 4d07bdb8107ad..cba395a58bb42 100644
--- a/src/compiler/checker.ts
+++ b/src/compiler/checker.ts
@@ -6223,19 +6223,20 @@ namespace ts {
                                 if (textRange && isVariableDeclarationList(textRange.parent) && textRange.parent.declarations.length === 1) {
                                     textRange = textRange.parent.parent;
                                 }
-                                const ex = find(symbol.declarations, isPropertyAccessExpression);
-                                if (ex && isBinaryExpression(ex.parent) && isIdentifier(ex.parent.right) && type.symbol && isSourceFile(type.symbol.valueDeclaration)) {
-                                    // TODO: Don't really need to do this, just whatever symbol-visiting code that this function actually calls, to mark it as used
-                                    serializeTypeForDeclaration(context, type, symbol, enclosingDeclaration, includePrivateSymbol, bundled);
+                                const propertyAccessRequire = find(symbol.declarations, isPropertyAccessExpression);
+                                if (propertyAccessRequire && isBinaryExpression(propertyAccessRequire.parent) && isIdentifier(propertyAccessRequire.parent.right)
+                                    && type.symbol && isSourceFile(type.symbol.valueDeclaration)) {
+                                    const alias = localName === propertyAccessRequire.parent.right.escapedText ? undefined : propertyAccessRequire.parent.right;
                                     addResult(
                                         factory.createExportDeclaration(
                                             /*decorators*/ undefined,
                                             /*modifiers*/ undefined,
                                             /*isTypeOnly*/ false,
-                                            factory.createNamedExports([factory.createExportSpecifier(localName === ex.parent.right.escapedText ? undefined : ex.parent.right, localName)])
+                                            factory.createNamedExports([factory.createExportSpecifier(alias, localName)])
                                         ),
                                         ModifierFlags.None
                                     );
+                                    serializeTypeForDeclaration(context, type, symbol, enclosingDeclaration, includePrivateSymbol, bundled);
                                 }
                                 else {
                                     const statement = setTextRange(factory.createVariableStatement(/*modifiers*/ undefined, factory.createVariableDeclarationList([
@@ -6303,7 +6304,7 @@ namespace ts {
                     if (symbol.flags & SymbolFlags.Alias) {
                         serializeAsAlias(symbol, getInternalSymbolName(symbol, symbolName), modifierFlags);
                     }
-                    if (symbol.flags & SymbolFlags.Property && symbol.escapedName === InternalSymbolName.ExportEquals) { // TODO: Delete this probably
+                    if (symbol.flags & SymbolFlags.Property && symbol.escapedName === InternalSymbolName.ExportEquals) {
                         serializeMaybeAliasAssignment(symbol);
                     }
                     if (symbol.flags & SymbolFlags.ExportStar) {
@@ -6776,7 +6777,6 @@ namespace ts {
                 }
 
                 /**
-                 * TODO: doesn't need to handle imports anymore
                  * Returns `true` if an export assignment or declaration was produced for the symbol
                  */
                 function serializeMaybeAliasAssignment(symbol: Symbol): boolean {
@@ -6857,7 +6857,6 @@ namespace ts {
                             const statement = factory.createVariableStatement(/*modifiers*/ undefined, factory.createVariableDeclarationList([
                                 factory.createVariableDeclaration(varName, /*exclamationToken*/ undefined, serializeTypeForDeclaration(context, typeToSerialize, symbol, enclosingDeclaration, includePrivateSymbol, bundled))
                             ], NodeFlags.Const));
-
                             addResult(statement,
                                 target && target.flags & SymbolFlags.Property && target.escapedName === InternalSymbolName.ExportEquals ? ModifierFlags.Ambient
                                 : name === varName ? ModifierFlags.Export
diff --git a/src/compiler/types.ts b/src/compiler/types.ts
index cfc2f1a96e6df..7ab69edd538ea 100644
--- a/src/compiler/types.ts
+++ b/src/compiler/types.ts
@@ -3005,7 +3005,6 @@ namespace ts {
         readonly name: Identifier;           // Declared name
     }
 
-    // TODO: Probably should now include BindingElement
     export type ImportOrExportSpecifier =
         | ImportSpecifier
         | ExportSpecifier

From e32df8379601fc35d6fd8178a69cd98004d35730 Mon Sep 17 00:00:00 2001
From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com>
Date: Mon, 27 Jul 2020 11:42:34 -0700
Subject: [PATCH 21/30] more cleanup, including lint

---
 src/compiler/checker.ts   | 15 ++++++++-------
 src/compiler/utilities.ts |  2 +-
 2 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts
index cba395a58bb42..d8edec6dca8c5 100644
--- a/src/compiler/checker.ts
+++ b/src/compiler/checker.ts
@@ -2393,17 +2393,18 @@ namespace ts {
         }
 
         function getTargetOfImportEqualsDeclaration(node: ImportEqualsDeclaration | VariableDeclaration, dontResolveAlias: boolean): Symbol | undefined {
+            if (isVariableDeclaration(node) && node.initializer && isPropertyAccessExpression(node.initializer)) {
+                // Use the ad-hoc require-as-CallExpression code to create a fresh anonymous type and retrieve the property by name.
+                const name = (node.initializer.expression as CallExpression).arguments[0] as StringLiteral;
+                return isIdentifier(node.initializer.name)
+                    ? getPropertyOfType(resolveExternalModuleTypeByLiteral(name), node.initializer.name.escapedText)
+                    : undefined;
+            }
             if (isVariableDeclaration(node) || node.moduleReference.kind === SyntaxKind.ExternalModuleReference) {
                 const immediate = resolveExternalModuleName(
                     node,
                     getExternalModuleRequireArgument(node) || getExternalModuleImportEqualsDeclarationExpression(node));
-                if (isVariableDeclaration(node) && node.initializer && isPropertyAccessExpression(node.initializer)) {
-                    // Use the ad-hoc require-as-CallExpression code to create a fresh anonymous type and retrieve the property by name.
-                    return isIdentifier(node.initializer.name)
-                        ? getPropertyOfType(checkExpression(node.initializer.expression), node.initializer.name.escapedText)
-                        : undefined;
-                }
-                const resolved = resolveExternalModuleSymbol(immediate);
+               const resolved = resolveExternalModuleSymbol(immediate);
                 markSymbolOfAliasDeclarationIfTypeOnly(node, immediate, resolved, /*overwriteEmpty*/ false);
                 return resolved;
             }
diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts
index 586cb1bb97ee0..2142c8ede2280 100644
--- a/src/compiler/utilities.ts
+++ b/src/compiler/utilities.ts
@@ -1849,7 +1849,7 @@ namespace ts {
 
     export function getExternalModuleRequireArgument(node: Node) {
         return isRequireVariableDeclaration(node, /*requireStringLiteralLikeArgument*/ true)
-            && (getFirstPropertyAccessExpression(node.initializer!) as CallExpression).arguments[0] as StringLiteral;
+            && (getFirstPropertyAccessExpression(node.initializer) as CallExpression).arguments[0] as StringLiteral;
     }
 
     export function isInternalModuleImportEqualsDeclaration(node: Node): node is ImportEqualsDeclaration {

From f4b5124c7426fe9fc7b3fe95db5ca59dc0314bd5 Mon Sep 17 00:00:00 2001
From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com>
Date: Mon, 27 Jul 2020 13:34:47 -0700
Subject: [PATCH 22/30] use trackSymbol, not serializeTypeForDeclaration

---
 src/compiler/checker.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts
index d8edec6dca8c5..4b169612194da 100644
--- a/src/compiler/checker.ts
+++ b/src/compiler/checker.ts
@@ -6237,7 +6237,7 @@ namespace ts {
                                         ),
                                         ModifierFlags.None
                                     );
-                                    serializeTypeForDeclaration(context, type, symbol, enclosingDeclaration, includePrivateSymbol, bundled);
+                                    context.tracker.trackSymbol!(type.symbol, context.enclosingDeclaration, SymbolFlags.Value);
                                 }
                                 else {
                                     const statement = setTextRange(factory.createVariableStatement(/*modifiers*/ undefined, factory.createVariableDeclarationList([

From 781bec2c6a9c429079ebc32a90ebf41ac328ea8d Mon Sep 17 00:00:00 2001
From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com>
Date: Tue, 11 Aug 2020 10:19:31 -0700
Subject: [PATCH 23/30] Code review comments, plus remove unneeded code

Ad-hoc type reference resolution for `require` isn't needed anymore.
---
 src/compiler/checker.ts   | 34 ++++++++++++++++------------------
 src/compiler/utilities.ts | 18 +++++++++---------
 2 files changed, 25 insertions(+), 27 deletions(-)

diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts
index e32aa6695cc9a..bdb4ef1f577e3 100644
--- a/src/compiler/checker.ts
+++ b/src/compiler/checker.ts
@@ -2369,23 +2369,23 @@ namespace ts {
          * {name: }
          */
         function isAliasSymbolDeclaration(node: Node): boolean {
-            return node.kind === SyntaxKind.ImportEqualsDeclaration ||
-                node.kind === SyntaxKind.NamespaceExportDeclaration ||
-                node.kind === SyntaxKind.ImportClause && !!(node).name ||
-                node.kind === SyntaxKind.NamespaceImport ||
-                node.kind === SyntaxKind.NamespaceExport ||
-                node.kind === SyntaxKind.ImportSpecifier ||
-                node.kind === SyntaxKind.ExportSpecifier ||
-                node.kind === SyntaxKind.ExportAssignment && exportAssignmentIsAlias(node) ||
-                isBinaryExpression(node) && getAssignmentDeclarationKind(node) === AssignmentDeclarationKind.ModuleExports && exportAssignmentIsAlias(node) ||
-                isPropertyAccessExpression(node)
+            return node.kind === SyntaxKind.ImportEqualsDeclaration
+                || node.kind === SyntaxKind.NamespaceExportDeclaration
+                || node.kind === SyntaxKind.ImportClause && !!(node).name
+                || node.kind === SyntaxKind.NamespaceImport
+                || node.kind === SyntaxKind.NamespaceExport
+                || node.kind === SyntaxKind.ImportSpecifier
+                || node.kind === SyntaxKind.ExportSpecifier
+                || node.kind === SyntaxKind.ExportAssignment && exportAssignmentIsAlias(node)
+                || isBinaryExpression(node) && getAssignmentDeclarationKind(node) === AssignmentDeclarationKind.ModuleExports && exportAssignmentIsAlias(node)
+                || isPropertyAccessExpression(node)
                     && isBinaryExpression(node.parent)
                     && node.parent.left === node
                     && node.parent.operatorToken.kind === SyntaxKind.EqualsToken
-                    && isAliasableOrJsExpression(node.parent.right) ||
-                node.kind === SyntaxKind.ShorthandPropertyAssignment ||
-                node.kind === SyntaxKind.PropertyAssignment && isAliasableOrJsExpression((node as PropertyAssignment).initializer) ||
-                isRequireVariableDeclaration(node, /*requireStringLiteralLikeArgument*/ true);
+                && isAliasableOrJsExpression(node.parent.right)
+                || node.kind === SyntaxKind.ShorthandPropertyAssignment
+                || node.kind === SyntaxKind.PropertyAssignment && isAliasableOrJsExpression((node as PropertyAssignment).initializer)
+                || isRequireVariableDeclaration(node, /*requireStringLiteralLikeArgument*/ true);
         }
 
         function isAliasableOrJsExpression(e: Expression) {
@@ -12125,8 +12125,7 @@ namespace ts {
 
         /**
          * A JSdoc TypeReference may be to a value, but resolve it as a type anyway.
-         * Note: If the value is imported from commonjs, it should really be an alias,
-         * but this function's special-case code fakes alias resolution as well.
+         * Example: import('./b').ConstructorFunction
          */
         function getTypeFromJSDocValueReference(node: NodeWithTypeArguments, symbol: Symbol): Type | undefined {
             const links = getNodeLinks(node);
@@ -12134,10 +12133,9 @@ namespace ts {
                 const valueType = getTypeOfSymbol(symbol);
                 let typeType = valueType;
                 if (symbol.valueDeclaration) {
-                    const isRequireAlias = isRequireVariableDeclaration(symbol.valueDeclaration, /*requireStringLiteralLikeArgument*/ true);
                     const isImportTypeWithQualifier = node.kind === SyntaxKind.ImportType && (node as ImportTypeNode).qualifier;
                     // valueType might not have a symbol, eg, {import('./b').STRING_LITERAL}
-                    if (valueType.symbol && (isRequireAlias || isImportTypeWithQualifier)) {
+                    if (valueType.symbol && isImportTypeWithQualifier) {
                         typeType = getTypeReferenceType(node, valueType.symbol);
                     }
                 }
diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts
index 15b47b4d0e834..d4404401ff0e6 100644
--- a/src/compiler/utilities.ts
+++ b/src/compiler/utilities.ts
@@ -1850,7 +1850,7 @@ namespace ts {
 
     export function getExternalModuleRequireArgument(node: Node) {
         return isRequireVariableDeclaration(node, /*requireStringLiteralLikeArgument*/ true)
-            && (getFirstPropertyAccessExpression(node.initializer) as CallExpression).arguments[0] as StringLiteral;
+            && (getLeftmostPropertyAccessExpression(node.initializer) as CallExpression).arguments[0] as StringLiteral;
     }
 
     export function isInternalModuleImportEqualsDeclaration(node: Node): node is ImportEqualsDeclaration {
@@ -1921,7 +1921,7 @@ namespace ts {
     export function isRequireVariableDeclaration(node: Node, requireStringLiteralLikeArgument: boolean): node is VariableDeclaration;
     export function isRequireVariableDeclaration(node: Node, requireStringLiteralLikeArgument: boolean): node is VariableDeclaration {
         node = getRootDeclaration(node);
-        return isVariableDeclaration(node) && !!node.initializer && isRequireCall(getFirstPropertyAccessExpression(node.initializer), requireStringLiteralLikeArgument);
+        return isVariableDeclaration(node) && !!node.initializer && isRequireCall(getLeftmostPropertyAccessExpression(node.initializer), requireStringLiteralLikeArgument);
     }
 
     export function isRequireVariableStatement(node: Node, requireStringLiteralLikeArgument = true): node is RequireVariableStatement {
@@ -4733,13 +4733,6 @@ namespace ts {
         }
     }
 
-    export function getFirstPropertyAccessExpression(expr: Expression): Expression {
-        while (isPropertyAccessExpression(expr)) {
-            expr = expr.expression;
-        }
-        return expr;
-    }
-
     export function isDottedName(node: Expression): boolean {
         return node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.ThisKeyword || node.kind === SyntaxKind.SuperKeyword ||
             node.kind === SyntaxKind.PropertyAccessExpression && isDottedName((node).expression) ||
@@ -5451,6 +5444,13 @@ namespace ts {
         return node.kind === SyntaxKind.NamedImports || node.kind === SyntaxKind.NamedExports;
     }
 
+    export function getLeftmostPropertyAccessExpression(expr: Expression): Expression {
+        while (isPropertyAccessExpression(expr)) {
+            expr = expr.expression;
+        }
+        return expr;
+    }
+
     export function getLeftmostExpression(node: Expression, stopAtCallExpressions: boolean) {
         while (true) {
             switch (node.kind) {

From 2bfeeebb668f9bd108a9b7104c88b7bd76c1a26a Mon Sep 17 00:00:00 2001
From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com>
Date: Wed, 12 Aug 2020 13:30:23 -0700
Subject: [PATCH 24/30] find all refs works

---
 src/compiler/checker.ts                       |  13 +-
 src/compiler/types.ts                         |   3 +-
 src/services/goToDefinition.ts                |   4 +-
 src/services/importTracker.ts                 |  13 +-
 .../findAllRefsCommonJsRequire.baseline.jsonc | 196 ++++++++++++++++
 ...findAllRefsCommonJsRequire2.baseline.jsonc | 216 ++++++++++++++++++
 ...findAllRefsCommonJsRequire3.baseline.jsonc | 212 +++++++++++++++++
 .../fourslash/findAllRefsCommonJsRequire.ts   |  14 ++
 .../fourslash/findAllRefsCommonJsRequire2.ts  |  14 ++
 .../fourslash/findAllRefsCommonJsRequire3.ts  |  14 ++
 tests/cases/fourslash/fourslash.ts            |   1 +
 11 files changed, 689 insertions(+), 11 deletions(-)
 create mode 100644 tests/baselines/reference/findAllRefsCommonJsRequire.baseline.jsonc
 create mode 100644 tests/baselines/reference/findAllRefsCommonJsRequire2.baseline.jsonc
 create mode 100644 tests/baselines/reference/findAllRefsCommonJsRequire3.baseline.jsonc
 create mode 100644 tests/cases/fourslash/findAllRefsCommonJsRequire.ts
 create mode 100644 tests/cases/fourslash/findAllRefsCommonJsRequire2.ts
 create mode 100644 tests/cases/fourslash/findAllRefsCommonJsRequire3.ts

diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts
index bdb4ef1f577e3..f088970f9dfa4 100644
--- a/src/compiler/checker.ts
+++ b/src/compiler/checker.ts
@@ -36634,10 +36634,15 @@ namespace ts {
         }
 
         /** Returns the target of an export specifier without following aliases */
-        function getExportSpecifierLocalTargetSymbol(node: ExportSpecifier): Symbol | undefined {
-            return node.parent.parent.moduleSpecifier ?
-                getExternalModuleMember(node.parent.parent, node) :
-                resolveEntityName(node.propertyName || node.name, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Alias);
+        function getExportSpecifierLocalTargetSymbol(node: ExportSpecifier | Identifier): Symbol | undefined {
+            if (isExportSpecifier(node)) {
+                return node.parent.parent.moduleSpecifier ?
+                    getExternalModuleMember(node.parent.parent, node) :
+                    resolveEntityName(node.propertyName || node.name, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Alias);
+            }
+            else {
+                return resolveEntityName(node, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Alias);
+            }
         }
 
         function getTypeOfNode(node: Node): Type {
diff --git a/src/compiler/types.ts b/src/compiler/types.ts
index d9468bd51234e..5a1619901bc8e 100644
--- a/src/compiler/types.ts
+++ b/src/compiler/types.ts
@@ -3939,7 +3939,8 @@ namespace ts {
          * This is necessary as an identifier in short-hand property assignment can contains two meaning: property name and property value.
          */
         getShorthandAssignmentValueSymbol(location: Node): Symbol | undefined;
-        getExportSpecifierLocalTargetSymbol(location: ExportSpecifier): Symbol | undefined;
+
+        getExportSpecifierLocalTargetSymbol(location: ExportSpecifier | Identifier): Symbol | undefined;
         /**
          * If a symbol is a local symbol with an associated exported symbol, returns the exported symbol.
          * Otherwise returns its input.
diff --git a/src/services/goToDefinition.ts b/src/services/goToDefinition.ts
index 4b39a90c880c7..84a888bfeee2c 100644
--- a/src/services/goToDefinition.ts
+++ b/src/services/goToDefinition.ts
@@ -34,9 +34,7 @@ namespace ts.GoToDefinition {
             const sigInfo = createDefinitionFromSignatureDeclaration(typeChecker, calledDeclaration);
             // For a function, if this is the original function definition, return just sigInfo.
             // If this is the original constructor definition, parent is the class.
-            if (typeChecker.getRootSymbols(symbol).some(s => symbolMatchesSignature(s, calledDeclaration)) ||
-                // TODO: GH#25533 Following check shouldn't be necessary if 'require' is an alias
-                symbol.declarations && symbol.declarations.some(d => isVariableDeclaration(d) && !!d.initializer && isRequireCall(d.initializer, /*checkArgumentIsStringLiteralLike*/ false))) {
+            if (typeChecker.getRootSymbols(symbol).some(s => symbolMatchesSignature(s, calledDeclaration))) {
                 return [sigInfo];
             }
             else {
diff --git a/src/services/importTracker.ts b/src/services/importTracker.ts
index 59c7e8c2745ac..41df9bcd5836b 100644
--- a/src/services/importTracker.ts
+++ b/src/services/importTracker.ts
@@ -93,9 +93,6 @@ namespace ts.FindAllReferences {
                                         break;
                                     }
                                 }
-
-                                // Don't support re-exporting 'require()' calls, so just add a single indirect user.
-                                addIndirectUser(direct.getSourceFile());
                             }
                             break;
 
@@ -607,6 +604,8 @@ namespace ts.FindAllReferences {
             case SyntaxKind.NamespaceImport:
                 Debug.assert((parent as ImportClause | NamespaceImport).name === node);
                 return true;
+            case SyntaxKind.BindingElement:
+                return isInJSFile(node) && isRequireVariableDeclaration(parent, /*requireStringLiteralLikeArgument*/ true);
             default:
                 return false;
         }
@@ -628,6 +627,14 @@ namespace ts.FindAllReferences {
                 if (isExportSpecifier(declaration) && !declaration.propertyName && !declaration.parent.parent.moduleSpecifier) {
                     return checker.getExportSpecifierLocalTargetSymbol(declaration)!;
                 }
+                else if (isPropertyAccessExpression(declaration) && isModuleExportsAccessExpression(declaration.expression) && !isPrivateIdentifier(declaration.name)) {
+                    return checker.getExportSpecifierLocalTargetSymbol(declaration.name)!;
+                }
+                else if (isShorthandPropertyAssignment(declaration)
+                    && isBinaryExpression(declaration.parent.parent)
+                    && getAssignmentDeclarationKind(declaration.parent.parent) === AssignmentDeclarationKind.ModuleExports) {
+                    return checker.getExportSpecifierLocalTargetSymbol(declaration.name)!;
+                }
             }
         }
         return symbol;
diff --git a/tests/baselines/reference/findAllRefsCommonJsRequire.baseline.jsonc b/tests/baselines/reference/findAllRefsCommonJsRequire.baseline.jsonc
new file mode 100644
index 0000000000000..675238f9655e0
--- /dev/null
+++ b/tests/baselines/reference/findAllRefsCommonJsRequire.baseline.jsonc
@@ -0,0 +1,196 @@
+// === /b.js ===
+// const { [|f|]/*FIND ALL REFS*/ } = require('./a')
+// [|f|]
+
+// === /a.js ===
+// function [|f|]() { }
+// export { [|f|] }
+
+[
+  {
+    "definition": {
+      "containerKind": "",
+      "containerName": "",
+      "fileName": "/b.js",
+      "kind": "alias",
+      "name": "(alias) function f(): void\nimport f",
+      "textSpan": {
+        "start": 8,
+        "length": 1
+      },
+      "displayParts": [
+        {
+          "text": "(",
+          "kind": "punctuation"
+        },
+        {
+          "text": "alias",
+          "kind": "text"
+        },
+        {
+          "text": ")",
+          "kind": "punctuation"
+        },
+        {
+          "text": " ",
+          "kind": "space"
+        },
+        {
+          "text": "function",
+          "kind": "keyword"
+        },
+        {
+          "text": " ",
+          "kind": "space"
+        },
+        {
+          "text": "f",
+          "kind": "aliasName"
+        },
+        {
+          "text": "(",
+          "kind": "punctuation"
+        },
+        {
+          "text": ")",
+          "kind": "punctuation"
+        },
+        {
+          "text": ":",
+          "kind": "punctuation"
+        },
+        {
+          "text": " ",
+          "kind": "space"
+        },
+        {
+          "text": "void",
+          "kind": "keyword"
+        },
+        {
+          "text": "\n",
+          "kind": "lineBreak"
+        },
+        {
+          "text": "import",
+          "kind": "keyword"
+        },
+        {
+          "text": " ",
+          "kind": "space"
+        },
+        {
+          "text": "f",
+          "kind": "aliasName"
+        }
+      ],
+      "contextSpan": {
+        "start": 0,
+        "length": 28
+      }
+    },
+    "references": [
+      {
+        "textSpan": {
+          "start": 8,
+          "length": 1
+        },
+        "fileName": "/b.js",
+        "contextSpan": {
+          "start": 0,
+          "length": 28
+        },
+        "isWriteAccess": true,
+        "isDefinition": true
+      },
+      {
+        "textSpan": {
+          "start": 29,
+          "length": 1
+        },
+        "fileName": "/b.js",
+        "isWriteAccess": false,
+        "isDefinition": false
+      }
+    ]
+  },
+  {
+    "definition": {
+      "containerKind": "",
+      "containerName": "",
+      "fileName": "/a.js",
+      "kind": "function",
+      "name": "function f(): void",
+      "textSpan": {
+        "start": 9,
+        "length": 1
+      },
+      "displayParts": [
+        {
+          "text": "function",
+          "kind": "keyword"
+        },
+        {
+          "text": " ",
+          "kind": "space"
+        },
+        {
+          "text": "f",
+          "kind": "functionName"
+        },
+        {
+          "text": "(",
+          "kind": "punctuation"
+        },
+        {
+          "text": ")",
+          "kind": "punctuation"
+        },
+        {
+          "text": ":",
+          "kind": "punctuation"
+        },
+        {
+          "text": " ",
+          "kind": "space"
+        },
+        {
+          "text": "void",
+          "kind": "keyword"
+        }
+      ],
+      "contextSpan": {
+        "start": 0,
+        "length": 16
+      }
+    },
+    "references": [
+      {
+        "textSpan": {
+          "start": 9,
+          "length": 1
+        },
+        "fileName": "/a.js",
+        "contextSpan": {
+          "start": 0,
+          "length": 16
+        },
+        "isWriteAccess": true,
+        "isDefinition": true
+      },
+      {
+        "textSpan": {
+          "start": 26,
+          "length": 1
+        },
+        "fileName": "/a.js",
+        "contextSpan": {
+          "start": 17,
+          "length": 12
+        },
+        "isWriteAccess": true,
+        "isDefinition": true
+      }
+    ]
+  }
+]
\ No newline at end of file
diff --git a/tests/baselines/reference/findAllRefsCommonJsRequire2.baseline.jsonc b/tests/baselines/reference/findAllRefsCommonJsRequire2.baseline.jsonc
new file mode 100644
index 0000000000000..f7b3b0ca60b74
--- /dev/null
+++ b/tests/baselines/reference/findAllRefsCommonJsRequire2.baseline.jsonc
@@ -0,0 +1,216 @@
+// === /b.js ===
+// const { [|f|]/*FIND ALL REFS*/ } = require('./a')
+// [|f|]
+
+// === /a.js ===
+// function [|f|]() { }
+// module.exports.f = [|f|]
+
+[
+  {
+    "definition": {
+      "containerKind": "",
+      "containerName": "",
+      "fileName": "/b.js",
+      "kind": "alias",
+      "name": "(alias) (property) f: () => void\nimport f",
+      "textSpan": {
+        "start": 8,
+        "length": 1
+      },
+      "displayParts": [
+        {
+          "text": "(",
+          "kind": "punctuation"
+        },
+        {
+          "text": "alias",
+          "kind": "text"
+        },
+        {
+          "text": ")",
+          "kind": "punctuation"
+        },
+        {
+          "text": " ",
+          "kind": "space"
+        },
+        {
+          "text": "(",
+          "kind": "punctuation"
+        },
+        {
+          "text": "property",
+          "kind": "text"
+        },
+        {
+          "text": ")",
+          "kind": "punctuation"
+        },
+        {
+          "text": " ",
+          "kind": "space"
+        },
+        {
+          "text": "f",
+          "kind": "aliasName"
+        },
+        {
+          "text": ":",
+          "kind": "punctuation"
+        },
+        {
+          "text": " ",
+          "kind": "space"
+        },
+        {
+          "text": "(",
+          "kind": "punctuation"
+        },
+        {
+          "text": ")",
+          "kind": "punctuation"
+        },
+        {
+          "text": " ",
+          "kind": "space"
+        },
+        {
+          "text": "=>",
+          "kind": "punctuation"
+        },
+        {
+          "text": " ",
+          "kind": "space"
+        },
+        {
+          "text": "void",
+          "kind": "keyword"
+        },
+        {
+          "text": "\n",
+          "kind": "lineBreak"
+        },
+        {
+          "text": "import",
+          "kind": "keyword"
+        },
+        {
+          "text": " ",
+          "kind": "space"
+        },
+        {
+          "text": "f",
+          "kind": "aliasName"
+        }
+      ],
+      "contextSpan": {
+        "start": 0,
+        "length": 28
+      }
+    },
+    "references": [
+      {
+        "textSpan": {
+          "start": 8,
+          "length": 1
+        },
+        "fileName": "/b.js",
+        "contextSpan": {
+          "start": 0,
+          "length": 28
+        },
+        "isWriteAccess": true,
+        "isDefinition": true
+      },
+      {
+        "textSpan": {
+          "start": 29,
+          "length": 1
+        },
+        "fileName": "/b.js",
+        "isWriteAccess": false,
+        "isDefinition": false
+      }
+    ]
+  },
+  {
+    "definition": {
+      "containerKind": "",
+      "containerName": "",
+      "fileName": "/a.js",
+      "kind": "function",
+      "name": "function f(): void",
+      "textSpan": {
+        "start": 9,
+        "length": 1
+      },
+      "displayParts": [
+        {
+          "text": "function",
+          "kind": "keyword"
+        },
+        {
+          "text": " ",
+          "kind": "space"
+        },
+        {
+          "text": "f",
+          "kind": "functionName"
+        },
+        {
+          "text": "(",
+          "kind": "punctuation"
+        },
+        {
+          "text": ")",
+          "kind": "punctuation"
+        },
+        {
+          "text": ":",
+          "kind": "punctuation"
+        },
+        {
+          "text": " ",
+          "kind": "space"
+        },
+        {
+          "text": "void",
+          "kind": "keyword"
+        }
+      ],
+      "contextSpan": {
+        "start": 0,
+        "length": 16
+      }
+    },
+    "references": [
+      {
+        "textSpan": {
+          "start": 9,
+          "length": 1
+        },
+        "fileName": "/a.js",
+        "contextSpan": {
+          "start": 0,
+          "length": 16
+        },
+        "isWriteAccess": true,
+        "isDefinition": true
+      },
+      {
+        "textSpan": {
+          "start": 36,
+          "length": 1
+        },
+        "fileName": "/a.js",
+        "contextSpan": {
+          "start": 17,
+          "length": 20
+        },
+        "isWriteAccess": false,
+        "isDefinition": false
+      }
+    ]
+  }
+]
\ No newline at end of file
diff --git a/tests/baselines/reference/findAllRefsCommonJsRequire3.baseline.jsonc b/tests/baselines/reference/findAllRefsCommonJsRequire3.baseline.jsonc
new file mode 100644
index 0000000000000..bb4c2c66ec641
--- /dev/null
+++ b/tests/baselines/reference/findAllRefsCommonJsRequire3.baseline.jsonc
@@ -0,0 +1,212 @@
+// === /b.js ===
+// const { [|f|]/*FIND ALL REFS*/ } = require('./a')
+// [|f|]
+
+// === /a.js ===
+// function [|f|]() { }
+// module.exports = { [|f|] }
+
+[
+  {
+    "definition": {
+      "containerKind": "",
+      "containerName": "",
+      "fileName": "/b.js",
+      "kind": "alias",
+      "name": "(alias) (property) f: () => void\nimport f",
+      "textSpan": {
+        "start": 8,
+        "length": 1
+      },
+      "displayParts": [
+        {
+          "text": "(",
+          "kind": "punctuation"
+        },
+        {
+          "text": "alias",
+          "kind": "text"
+        },
+        {
+          "text": ")",
+          "kind": "punctuation"
+        },
+        {
+          "text": " ",
+          "kind": "space"
+        },
+        {
+          "text": "(",
+          "kind": "punctuation"
+        },
+        {
+          "text": "property",
+          "kind": "text"
+        },
+        {
+          "text": ")",
+          "kind": "punctuation"
+        },
+        {
+          "text": " ",
+          "kind": "space"
+        },
+        {
+          "text": "f",
+          "kind": "aliasName"
+        },
+        {
+          "text": ":",
+          "kind": "punctuation"
+        },
+        {
+          "text": " ",
+          "kind": "space"
+        },
+        {
+          "text": "(",
+          "kind": "punctuation"
+        },
+        {
+          "text": ")",
+          "kind": "punctuation"
+        },
+        {
+          "text": " ",
+          "kind": "space"
+        },
+        {
+          "text": "=>",
+          "kind": "punctuation"
+        },
+        {
+          "text": " ",
+          "kind": "space"
+        },
+        {
+          "text": "void",
+          "kind": "keyword"
+        },
+        {
+          "text": "\n",
+          "kind": "lineBreak"
+        },
+        {
+          "text": "import",
+          "kind": "keyword"
+        },
+        {
+          "text": " ",
+          "kind": "space"
+        },
+        {
+          "text": "f",
+          "kind": "aliasName"
+        }
+      ],
+      "contextSpan": {
+        "start": 0,
+        "length": 28
+      }
+    },
+    "references": [
+      {
+        "textSpan": {
+          "start": 8,
+          "length": 1
+        },
+        "fileName": "/b.js",
+        "contextSpan": {
+          "start": 0,
+          "length": 28
+        },
+        "isWriteAccess": true,
+        "isDefinition": true
+      },
+      {
+        "textSpan": {
+          "start": 29,
+          "length": 1
+        },
+        "fileName": "/b.js",
+        "isWriteAccess": false,
+        "isDefinition": false
+      }
+    ]
+  },
+  {
+    "definition": {
+      "containerKind": "",
+      "containerName": "",
+      "fileName": "/a.js",
+      "kind": "function",
+      "name": "function f(): void",
+      "textSpan": {
+        "start": 9,
+        "length": 1
+      },
+      "displayParts": [
+        {
+          "text": "function",
+          "kind": "keyword"
+        },
+        {
+          "text": " ",
+          "kind": "space"
+        },
+        {
+          "text": "f",
+          "kind": "functionName"
+        },
+        {
+          "text": "(",
+          "kind": "punctuation"
+        },
+        {
+          "text": ")",
+          "kind": "punctuation"
+        },
+        {
+          "text": ":",
+          "kind": "punctuation"
+        },
+        {
+          "text": " ",
+          "kind": "space"
+        },
+        {
+          "text": "void",
+          "kind": "keyword"
+        }
+      ],
+      "contextSpan": {
+        "start": 0,
+        "length": 16
+      }
+    },
+    "references": [
+      {
+        "textSpan": {
+          "start": 9,
+          "length": 1
+        },
+        "fileName": "/a.js",
+        "contextSpan": {
+          "start": 0,
+          "length": 16
+        },
+        "isWriteAccess": true,
+        "isDefinition": true
+      },
+      {
+        "textSpan": {
+          "start": 36,
+          "length": 1
+        },
+        "fileName": "/a.js",
+        "isWriteAccess": true,
+        "isDefinition": true
+      }
+    ]
+  }
+]
\ No newline at end of file
diff --git a/tests/cases/fourslash/findAllRefsCommonJsRequire.ts b/tests/cases/fourslash/findAllRefsCommonJsRequire.ts
new file mode 100644
index 0000000000000..387aaa07de45a
--- /dev/null
+++ b/tests/cases/fourslash/findAllRefsCommonJsRequire.ts
@@ -0,0 +1,14 @@
+/// 
+
+// @allowJs: true
+
+// @Filename: /a.js
+//// function f() { }
+//// export { f }
+
+// @Filename: /b.js
+//// const { f } = require('./a')
+//// /**/f
+
+
+verify.baselineFindAllReferences("");
diff --git a/tests/cases/fourslash/findAllRefsCommonJsRequire2.ts b/tests/cases/fourslash/findAllRefsCommonJsRequire2.ts
new file mode 100644
index 0000000000000..ff8275b7ef5fe
--- /dev/null
+++ b/tests/cases/fourslash/findAllRefsCommonJsRequire2.ts
@@ -0,0 +1,14 @@
+/// 
+
+// @allowJs: true
+
+// @Filename: /a.js
+//// function f() { }
+//// module.exports.f = f
+
+// @Filename: /b.js
+//// const { f } = require('./a')
+//// /**/f
+
+
+verify.baselineFindAllReferences("");
diff --git a/tests/cases/fourslash/findAllRefsCommonJsRequire3.ts b/tests/cases/fourslash/findAllRefsCommonJsRequire3.ts
new file mode 100644
index 0000000000000..b9687b417d75e
--- /dev/null
+++ b/tests/cases/fourslash/findAllRefsCommonJsRequire3.ts
@@ -0,0 +1,14 @@
+/// 
+
+// @allowJs: true
+
+// @Filename: /a.js
+//// function f() { }
+//// module.exports = { f }
+
+// @Filename: /b.js
+//// const { f } = require('./a')
+//// /**/f
+
+
+verify.baselineFindAllReferences("");
diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts
index f50cb18774415..daab0d3266c01 100644
--- a/tests/cases/fourslash/fourslash.ts
+++ b/tests/cases/fourslash/fourslash.ts
@@ -294,6 +294,7 @@ declare namespace FourSlashInterface {
         symbolAtLocation(startRange: Range, ...declarationRanges: Range[]): void;
         typeOfSymbolAtLocation(range: Range, symbol: any, expected: string): void;
         /**
+         * @deprecated Use baselineFindAllReferences instead
          * For each of starts, asserts the ranges that are referenced from there.
          * This uses the 'findReferences' command instead of 'getReferencesAtPosition', so references are grouped by their definition.
          */

From 62e5b18749e8e85e4a59c5d16840ae6258a3b496 Mon Sep 17 00:00:00 2001
From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com>
Date: Thu, 13 Aug 2020 09:18:37 -0700
Subject: [PATCH 25/30] remove old ad-hoc code

---
 src/services/goToDefinition.ts                    | 12 +++---------
 .../fourslash/goToDefinitionImportedNames10.ts    | 15 +++++++++++++++
 .../fourslash/goToDefinitionImportedNames11.ts    | 15 +++++++++++++++
 .../fourslash/goToDefinitionImportedNames8.ts     | 14 ++++++++++++++
 .../fourslash/goToDefinitionImportedNames9.ts     | 15 +++++++++++++++
 5 files changed, 62 insertions(+), 9 deletions(-)
 create mode 100644 tests/cases/fourslash/goToDefinitionImportedNames10.ts
 create mode 100644 tests/cases/fourslash/goToDefinitionImportedNames11.ts
 create mode 100644 tests/cases/fourslash/goToDefinitionImportedNames8.ts
 create mode 100644 tests/cases/fourslash/goToDefinitionImportedNames9.ts

diff --git a/src/services/goToDefinition.ts b/src/services/goToDefinition.ts
index 84a888bfeee2c..f0ec33c88842b 100644
--- a/src/services/goToDefinition.ts
+++ b/src/services/goToDefinition.ts
@@ -208,15 +208,6 @@ namespace ts.GoToDefinition {
                 return aliased;
             }
         }
-        if (symbol && isInJSFile(node)) {
-            const requireCall = forEach(symbol.declarations, d => isVariableDeclaration(d) && !!d.initializer && isRequireCall(d.initializer, /*checkArgumentIsStringLiteralLike*/ true) ? d.initializer : undefined);
-            if (requireCall) {
-                const moduleSymbol = checker.getSymbolAtLocation(requireCall.arguments[0]);
-                if (moduleSymbol) {
-                    return checker.resolveExternalModuleSymbol(moduleSymbol);
-                }
-            }
-        }
         return symbol;
     }
 
@@ -238,6 +229,9 @@ namespace ts.GoToDefinition {
                 return true;
             case SyntaxKind.ImportSpecifier:
                 return declaration.parent.kind === SyntaxKind.NamedImports;
+            case SyntaxKind.BindingElement:
+            case SyntaxKind.VariableDeclaration:
+                return isInJSFile(declaration) && isRequireVariableDeclaration(declaration, /*requireStringLiteralLikeArgument*/ true);
             default:
                 return false;
         }
diff --git a/tests/cases/fourslash/goToDefinitionImportedNames10.ts b/tests/cases/fourslash/goToDefinitionImportedNames10.ts
new file mode 100644
index 0000000000000..faa9ed745cc36
--- /dev/null
+++ b/tests/cases/fourslash/goToDefinitionImportedNames10.ts
@@ -0,0 +1,15 @@
+/// 
+// @allowjs: true
+
+// @Filename: a.js
+//// class Class {
+////   f;
+//// }
+//// module.exports./*classDefinition*/Class = Class;
+
+// @Filename: b.js
+////const { Class } = require("./a");
+//// [|/*classAliasDefinition*/Class|];
+
+
+verify.goToDefinition("classAliasDefinition", "classDefinition");
diff --git a/tests/cases/fourslash/goToDefinitionImportedNames11.ts b/tests/cases/fourslash/goToDefinitionImportedNames11.ts
new file mode 100644
index 0000000000000..f34b3543881a6
--- /dev/null
+++ b/tests/cases/fourslash/goToDefinitionImportedNames11.ts
@@ -0,0 +1,15 @@
+/// 
+// @allowjs: true
+
+// @Filename: a.js
+//// class Class {
+////     f;
+//// }
+//// module.exports = { /*classDefinition*/Class };
+
+// @Filename: b.js
+////const { Class } = require("./a");
+//// [|/*classAliasDefinition*/Class|];
+
+
+verify.goToDefinition("classAliasDefinition", "classDefinition");
diff --git a/tests/cases/fourslash/goToDefinitionImportedNames8.ts b/tests/cases/fourslash/goToDefinitionImportedNames8.ts
new file mode 100644
index 0000000000000..ad3d1c107853d
--- /dev/null
+++ b/tests/cases/fourslash/goToDefinitionImportedNames8.ts
@@ -0,0 +1,14 @@
+/// 
+// @allowjs: true
+
+// @Filename: b.js
+////import { [|/*classAliasDefinition*/Class|] } from "./a";
+
+
+// @Filename: a.js
+////class /*classDefinition*/Class {
+////    private f;
+////}
+//// export { Class };
+
+verify.goToDefinition("classAliasDefinition", "classDefinition");
diff --git a/tests/cases/fourslash/goToDefinitionImportedNames9.ts b/tests/cases/fourslash/goToDefinitionImportedNames9.ts
new file mode 100644
index 0000000000000..2f838efca26b1
--- /dev/null
+++ b/tests/cases/fourslash/goToDefinitionImportedNames9.ts
@@ -0,0 +1,15 @@
+/// 
+// @allowjs: true
+
+// @Filename: a.js
+////class /*classDefinition*/Class {
+////    f;
+////}
+//// export { Class };
+
+// @Filename: b.js
+////const { Class } = require("./a");
+//// [|/*classAliasDefinition*/Class|];
+
+
+verify.goToDefinition("classAliasDefinition", "classDefinition");

From 2679b03609d080cab5b33ac437868449730a5add Mon Sep 17 00:00:00 2001
From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com>
Date: Thu, 13 Aug 2020 09:41:57 -0700
Subject: [PATCH 26/30] make it clear that old behaviour is not that correct

---
 .../fourslash/goToDefinitionJsModuleNameAtImportName.ts    | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/tests/cases/fourslash/goToDefinitionJsModuleNameAtImportName.ts b/tests/cases/fourslash/goToDefinitionJsModuleNameAtImportName.ts
index d0b5e61c44357..3763387efd24a 100644
--- a/tests/cases/fourslash/goToDefinitionJsModuleNameAtImportName.ts
+++ b/tests/cases/fourslash/goToDefinitionJsModuleNameAtImportName.ts
@@ -3,10 +3,11 @@
 // @allowJs: true
 
 // @Filename: /foo.js
-//// /*moduleDef*/class Blah {
+//// /*moduleDef*/function notExported() { }
+//// class Blah {
 ////    abc = 123;
-////}
-////module.exports.Blah = Blah;
+//// }
+//// module.exports.Blah = Blah;
 
 // @Filename: /bar.js
 ////const [|/*importDef*/BlahModule|] = require("./foo.js");

From 03fb2d4f62d4148160663a66f861c635644b300a Mon Sep 17 00:00:00 2001
From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com>
Date: Thu, 13 Aug 2020 09:44:31 -0700
Subject: [PATCH 27/30] update api baselines

---
 tests/baselines/reference/api/tsserverlibrary.d.ts | 2 +-
 tests/baselines/reference/api/typescript.d.ts      | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts
index db58c35ac46e0..0ed23cb6a1e17 100644
--- a/tests/baselines/reference/api/tsserverlibrary.d.ts
+++ b/tests/baselines/reference/api/tsserverlibrary.d.ts
@@ -2159,7 +2159,7 @@ declare namespace ts {
          * This is necessary as an identifier in short-hand property assignment can contains two meaning: property name and property value.
          */
         getShorthandAssignmentValueSymbol(location: Node): Symbol | undefined;
-        getExportSpecifierLocalTargetSymbol(location: ExportSpecifier): Symbol | undefined;
+        getExportSpecifierLocalTargetSymbol(location: ExportSpecifier | Identifier): Symbol | undefined;
         /**
          * If a symbol is a local symbol with an associated exported symbol, returns the exported symbol.
          * Otherwise returns its input.
diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts
index a0dab441a385f..8ce652135b6d5 100644
--- a/tests/baselines/reference/api/typescript.d.ts
+++ b/tests/baselines/reference/api/typescript.d.ts
@@ -2159,7 +2159,7 @@ declare namespace ts {
          * This is necessary as an identifier in short-hand property assignment can contains two meaning: property name and property value.
          */
         getShorthandAssignmentValueSymbol(location: Node): Symbol | undefined;
-        getExportSpecifierLocalTargetSymbol(location: ExportSpecifier): Symbol | undefined;
+        getExportSpecifierLocalTargetSymbol(location: ExportSpecifier | Identifier): Symbol | undefined;
         /**
          * If a symbol is a local symbol with an associated exported symbol, returns the exported symbol.
          * Otherwise returns its input.

From 7aeb306be64fa95523d3059a1ead00987f0750aa Mon Sep 17 00:00:00 2001
From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com>
Date: Thu, 13 Aug 2020 10:06:31 -0700
Subject: [PATCH 28/30] remove outdated comment

---
 src/compiler/checker.ts | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts
index 1c1f8eec0ed1d..92925233925a0 100644
--- a/src/compiler/checker.ts
+++ b/src/compiler/checker.ts
@@ -2394,7 +2394,6 @@ namespace ts {
 
         function getTargetOfImportEqualsDeclaration(node: ImportEqualsDeclaration | VariableDeclaration, dontResolveAlias: boolean): Symbol | undefined {
             if (isVariableDeclaration(node) && node.initializer && isPropertyAccessExpression(node.initializer)) {
-                // Use the ad-hoc require-as-CallExpression code to create a fresh anonymous type and retrieve the property by name.
                 const name = (node.initializer.expression as CallExpression).arguments[0] as StringLiteral;
                 return isIdentifier(node.initializer.name)
                     ? getPropertyOfType(resolveExternalModuleTypeByLiteral(name), node.initializer.name.escapedText)

From 283a520f197256be06996a3a202a76de4f6b7706 Mon Sep 17 00:00:00 2001
From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com>
Date: Mon, 17 Aug 2020 13:27:37 -0700
Subject: [PATCH 29/30] PR feedback

1. Fix indentation
2. Add comment for exported JSON emit
3. Add test case for nested-namespace exports.
---
 src/compiler/checker.ts                       |  4 +-
 .../jsDeclarationsTypeReferences3.js          | 34 ++++++++++++++
 .../jsDeclarationsTypeReferences3.symbols     | 38 ++++++++++++++++
 .../jsDeclarationsTypeReferences3.types       | 44 +++++++++++++++++++
 .../jsDeclarationsTypeReferences3.ts          | 17 +++++++
 5 files changed, 136 insertions(+), 1 deletion(-)
 create mode 100644 tests/baselines/reference/jsDeclarationsTypeReferences3.js
 create mode 100644 tests/baselines/reference/jsDeclarationsTypeReferences3.symbols
 create mode 100644 tests/baselines/reference/jsDeclarationsTypeReferences3.types
 create mode 100644 tests/cases/conformance/jsdoc/declarations/jsDeclarationsTypeReferences3.ts

diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts
index 6d807f42d9f51..52b3494002cb7 100644
--- a/src/compiler/checker.ts
+++ b/src/compiler/checker.ts
@@ -2382,7 +2382,7 @@ namespace ts {
                     && isBinaryExpression(node.parent)
                     && node.parent.left === node
                     && node.parent.operatorToken.kind === SyntaxKind.EqualsToken
-                && isAliasableOrJsExpression(node.parent.right)
+                    && isAliasableOrJsExpression(node.parent.right)
                 || node.kind === SyntaxKind.ShorthandPropertyAssignment
                 || node.kind === SyntaxKind.PropertyAssignment && isAliasableOrJsExpression((node as PropertyAssignment).initializer)
                 || isRequireVariableDeclaration(node, /*requireStringLiteralLikeArgument*/ true);
@@ -6876,6 +6876,8 @@ namespace ts {
                             const statement = factory.createVariableStatement(/*modifiers*/ undefined, factory.createVariableDeclarationList([
                                 factory.createVariableDeclaration(varName, /*exclamationToken*/ undefined, serializeTypeForDeclaration(context, typeToSerialize, symbol, enclosingDeclaration, includePrivateSymbol, bundled))
                             ], NodeFlags.Const));
+                            // Inlined JSON types exported with [module.]exports= will already emit an export=, so should use `declare`.
+                            // Otherwise, the type itself should be exported.
                             addResult(statement,
                                 target && target.flags & SymbolFlags.Property && target.escapedName === InternalSymbolName.ExportEquals ? ModifierFlags.Ambient
                                 : name === varName ? ModifierFlags.Export
diff --git a/tests/baselines/reference/jsDeclarationsTypeReferences3.js b/tests/baselines/reference/jsDeclarationsTypeReferences3.js
new file mode 100644
index 0000000000000..e765cc6164325
--- /dev/null
+++ b/tests/baselines/reference/jsDeclarationsTypeReferences3.js
@@ -0,0 +1,34 @@
+//// [tests/cases/conformance/jsdoc/declarations/jsDeclarationsTypeReferences3.ts] ////
+
+//// [index.d.ts]
+declare module "fs" {
+    export class Something {}
+}
+//// [index.js]
+/// 
+
+const Something = require("fs").Something;
+module.exports.A = {}
+module.exports.A.B = {
+    thing: new Something()
+}
+
+
+//// [index.js]
+/// 
+var Something = require("fs").Something;
+module.exports.A = {};
+module.exports.A.B = {
+    thing: new Something()
+};
+
+
+//// [index.d.ts]
+/// 
+export namespace A {
+    namespace B {
+        const thing: Something;
+    }
+}
+import fs_1 = require("fs");
+import Something = fs_1.Something;
diff --git a/tests/baselines/reference/jsDeclarationsTypeReferences3.symbols b/tests/baselines/reference/jsDeclarationsTypeReferences3.symbols
new file mode 100644
index 0000000000000..018debbe2277f
--- /dev/null
+++ b/tests/baselines/reference/jsDeclarationsTypeReferences3.symbols
@@ -0,0 +1,38 @@
+=== tests/cases/conformance/jsdoc/declarations/index.js ===
+/// 
+
+const Something = require("fs").Something;
+>Something : Symbol(Something, Decl(index.js, 2, 5))
+>require("fs").Something : Symbol(Something, Decl(index.d.ts, 0, 21))
+>require : Symbol(require)
+>"fs" : Symbol("fs", Decl(index.d.ts, 0, 0))
+>Something : Symbol(Something, Decl(index.d.ts, 0, 21))
+
+module.exports.A = {}
+>module.exports.A : Symbol(A, Decl(index.js, 2, 42), Decl(index.js, 4, 15))
+>module.exports : Symbol(A, Decl(index.js, 2, 42), Decl(index.js, 4, 15))
+>module : Symbol(module, Decl(index.js, 2, 42))
+>exports : Symbol("tests/cases/conformance/jsdoc/declarations/index", Decl(index.js, 0, 0))
+>A : Symbol(A, Decl(index.js, 2, 42), Decl(index.js, 4, 15))
+
+module.exports.A.B = {
+>module.exports.A.B : Symbol(A.B, Decl(index.js, 3, 21))
+>module.exports.A : Symbol(A.B, Decl(index.js, 3, 21))
+>module.exports : Symbol("tests/cases/conformance/jsdoc/declarations/index", Decl(index.js, 0, 0))
+>module : Symbol(module, Decl(index.js, 2, 42))
+>exports : Symbol("tests/cases/conformance/jsdoc/declarations/index", Decl(index.js, 0, 0))
+>A : Symbol(A, Decl(index.js, 2, 42), Decl(index.js, 4, 15))
+>B : Symbol(A.B, Decl(index.js, 3, 21))
+
+    thing: new Something()
+>thing : Symbol(thing, Decl(index.js, 4, 22))
+>Something : Symbol(Something, Decl(index.js, 2, 5))
+}
+
+=== tests/cases/conformance/jsdoc/declarations/node_modules/@types/node/index.d.ts ===
+declare module "fs" {
+>"fs" : Symbol("fs", Decl(index.d.ts, 0, 0))
+
+    export class Something {}
+>Something : Symbol(Something, Decl(index.d.ts, 0, 21))
+}
diff --git a/tests/baselines/reference/jsDeclarationsTypeReferences3.types b/tests/baselines/reference/jsDeclarationsTypeReferences3.types
new file mode 100644
index 0000000000000..bb41517417b59
--- /dev/null
+++ b/tests/baselines/reference/jsDeclarationsTypeReferences3.types
@@ -0,0 +1,44 @@
+=== tests/cases/conformance/jsdoc/declarations/index.js ===
+/// 
+
+const Something = require("fs").Something;
+>Something : typeof Something
+>require("fs").Something : typeof Something
+>require("fs") : typeof import("fs")
+>require : any
+>"fs" : "fs"
+>Something : typeof Something
+
+module.exports.A = {}
+>module.exports.A = {} : typeof A
+>module.exports.A : typeof A
+>module.exports : typeof import("tests/cases/conformance/jsdoc/declarations/index")
+>module : { "\"tests/cases/conformance/jsdoc/declarations/index\"": typeof import("tests/cases/conformance/jsdoc/declarations/index"); }
+>exports : typeof import("tests/cases/conformance/jsdoc/declarations/index")
+>A : typeof A
+>{} : {}
+
+module.exports.A.B = {
+>module.exports.A.B = {    thing: new Something()} : { thing: Something; }
+>module.exports.A.B : { thing: Something; }
+>module.exports.A : typeof A
+>module.exports : typeof import("tests/cases/conformance/jsdoc/declarations/index")
+>module : { "\"tests/cases/conformance/jsdoc/declarations/index\"": typeof import("tests/cases/conformance/jsdoc/declarations/index"); }
+>exports : typeof import("tests/cases/conformance/jsdoc/declarations/index")
+>A : typeof A
+>B : { thing: Something; }
+>{    thing: new Something()} : { thing: Something; }
+
+    thing: new Something()
+>thing : Something
+>new Something() : Something
+>Something : typeof Something
+}
+
+=== tests/cases/conformance/jsdoc/declarations/node_modules/@types/node/index.d.ts ===
+declare module "fs" {
+>"fs" : typeof import("fs")
+
+    export class Something {}
+>Something : Something
+}
diff --git a/tests/cases/conformance/jsdoc/declarations/jsDeclarationsTypeReferences3.ts b/tests/cases/conformance/jsdoc/declarations/jsDeclarationsTypeReferences3.ts
new file mode 100644
index 0000000000000..a78ca90d3b728
--- /dev/null
+++ b/tests/cases/conformance/jsdoc/declarations/jsDeclarationsTypeReferences3.ts
@@ -0,0 +1,17 @@
+// @allowJs: true
+// @checkJs: true
+// @target: es5
+// @outDir: tests/cases/conformance/jsdoc/declarations/out
+// @declaration: true
+// @filename: node_modules/@types/node/index.d.ts
+declare module "fs" {
+    export class Something {}
+}
+// @filename: index.js
+/// 
+
+const Something = require("fs").Something;
+module.exports.A = {}
+module.exports.A.B = {
+    thing: new Something()
+}

From 6c7897e4d227ce492dedd2e7966d7d7a1aac18b5 Mon Sep 17 00:00:00 2001
From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com>
Date: Mon, 17 Aug 2020 13:37:40 -0700
Subject: [PATCH 30/30] add a fail-case test (which passes!)

---
 .../jsDeclarationsTypeReferences4.errors.txt  | 23 +++++++++
 .../jsDeclarationsTypeReferences4.js          | 48 +++++++++++++++++++
 .../jsDeclarationsTypeReferences4.symbols     | 37 ++++++++++++++
 .../jsDeclarationsTypeReferences4.types       | 40 ++++++++++++++++
 .../jsDeclarationsTypeReferences4.ts          | 22 +++++++++
 5 files changed, 170 insertions(+)
 create mode 100644 tests/baselines/reference/jsDeclarationsTypeReferences4.errors.txt
 create mode 100644 tests/baselines/reference/jsDeclarationsTypeReferences4.js
 create mode 100644 tests/baselines/reference/jsDeclarationsTypeReferences4.symbols
 create mode 100644 tests/baselines/reference/jsDeclarationsTypeReferences4.types
 create mode 100644 tests/cases/conformance/jsdoc/declarations/jsDeclarationsTypeReferences4.ts

diff --git a/tests/baselines/reference/jsDeclarationsTypeReferences4.errors.txt b/tests/baselines/reference/jsDeclarationsTypeReferences4.errors.txt
new file mode 100644
index 0000000000000..1d04247967531
--- /dev/null
+++ b/tests/baselines/reference/jsDeclarationsTypeReferences4.errors.txt
@@ -0,0 +1,23 @@
+tests/cases/conformance/jsdoc/declarations/index.js(4,18): error TS8006: 'namespace' declarations can only be used in TypeScript files.
+
+
+==== tests/cases/conformance/jsdoc/declarations/index.js (1 errors) ====
+    /// 
+    export const Something = 2; // to show conflict that can occur
+    // @ts-ignore
+    export namespace A {
+                     ~
+!!! error TS8006: 'namespace' declarations can only be used in TypeScript files.
+        // @ts-ignore
+        export namespace B {
+            const Something = require("fs").Something;
+            const thing = new Something();
+            // @ts-ignore
+            export { thing };
+        }
+    }
+    
+==== tests/cases/conformance/jsdoc/declarations/node_modules/@types/node/index.d.ts (0 errors) ====
+    declare module "fs" {
+        export class Something {}
+    }
\ No newline at end of file
diff --git a/tests/baselines/reference/jsDeclarationsTypeReferences4.js b/tests/baselines/reference/jsDeclarationsTypeReferences4.js
new file mode 100644
index 0000000000000..063aca33d76f0
--- /dev/null
+++ b/tests/baselines/reference/jsDeclarationsTypeReferences4.js
@@ -0,0 +1,48 @@
+//// [tests/cases/conformance/jsdoc/declarations/jsDeclarationsTypeReferences4.ts] ////
+
+//// [index.d.ts]
+declare module "fs" {
+    export class Something {}
+}
+//// [index.js]
+/// 
+export const Something = 2; // to show conflict that can occur
+// @ts-ignore
+export namespace A {
+    // @ts-ignore
+    export namespace B {
+        const Something = require("fs").Something;
+        const thing = new Something();
+        // @ts-ignore
+        export { thing };
+    }
+}
+
+
+//// [index.js]
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.A = exports.Something = void 0;
+/// 
+exports.Something = 2; // to show conflict that can occur
+// @ts-ignore
+var A;
+(function (A) {
+    // @ts-ignore
+    var B;
+    (function (B) {
+        var Something = require("fs").Something;
+        var thing = new Something();
+    })(B = A.B || (A.B = {}));
+})(A = exports.A || (exports.A = {}));
+
+
+//// [index.d.ts]
+/// 
+export const Something: 2;
+export namespace A {
+    namespace B {
+        export { thing };
+        export const thing: import("fs").Something;
+    }
+}
diff --git a/tests/baselines/reference/jsDeclarationsTypeReferences4.symbols b/tests/baselines/reference/jsDeclarationsTypeReferences4.symbols
new file mode 100644
index 0000000000000..0f30ae0d30f8b
--- /dev/null
+++ b/tests/baselines/reference/jsDeclarationsTypeReferences4.symbols
@@ -0,0 +1,37 @@
+=== tests/cases/conformance/jsdoc/declarations/index.js ===
+/// 
+export const Something = 2; // to show conflict that can occur
+>Something : Symbol(Something, Decl(index.js, 1, 12))
+
+// @ts-ignore
+export namespace A {
+>A : Symbol(A, Decl(index.js, 1, 27))
+
+    // @ts-ignore
+    export namespace B {
+>B : Symbol(B, Decl(index.js, 3, 20))
+
+        const Something = require("fs").Something;
+>Something : Symbol(Something, Decl(index.js, 6, 13))
+>require("fs").Something : Symbol(Something, Decl(index.d.ts, 0, 21))
+>require : Symbol(require)
+>"fs" : Symbol("fs", Decl(index.d.ts, 0, 0))
+>Something : Symbol(Something, Decl(index.d.ts, 0, 21))
+
+        const thing = new Something();
+>thing : Symbol(thing, Decl(index.js, 7, 13))
+>Something : Symbol(Something, Decl(index.js, 6, 13))
+
+        // @ts-ignore
+        export { thing };
+>thing : Symbol(thing, Decl(index.js, 9, 16))
+    }
+}
+
+=== tests/cases/conformance/jsdoc/declarations/node_modules/@types/node/index.d.ts ===
+declare module "fs" {
+>"fs" : Symbol("fs", Decl(index.d.ts, 0, 0))
+
+    export class Something {}
+>Something : Symbol(Something, Decl(index.d.ts, 0, 21))
+}
diff --git a/tests/baselines/reference/jsDeclarationsTypeReferences4.types b/tests/baselines/reference/jsDeclarationsTypeReferences4.types
new file mode 100644
index 0000000000000..33de92f8e60a4
--- /dev/null
+++ b/tests/baselines/reference/jsDeclarationsTypeReferences4.types
@@ -0,0 +1,40 @@
+=== tests/cases/conformance/jsdoc/declarations/index.js ===
+/// 
+export const Something = 2; // to show conflict that can occur
+>Something : 2
+>2 : 2
+
+// @ts-ignore
+export namespace A {
+>A : typeof A
+
+    // @ts-ignore
+    export namespace B {
+>B : typeof B
+
+        const Something = require("fs").Something;
+>Something : typeof Something
+>require("fs").Something : typeof Something
+>require("fs") : typeof import("fs")
+>require : any
+>"fs" : "fs"
+>Something : typeof Something
+
+        const thing = new Something();
+>thing : Something
+>new Something() : Something
+>Something : typeof Something
+
+        // @ts-ignore
+        export { thing };
+>thing : Something
+    }
+}
+
+=== tests/cases/conformance/jsdoc/declarations/node_modules/@types/node/index.d.ts ===
+declare module "fs" {
+>"fs" : typeof import("fs")
+
+    export class Something {}
+>Something : Something
+}
diff --git a/tests/cases/conformance/jsdoc/declarations/jsDeclarationsTypeReferences4.ts b/tests/cases/conformance/jsdoc/declarations/jsDeclarationsTypeReferences4.ts
new file mode 100644
index 0000000000000..6134603f226b5
--- /dev/null
+++ b/tests/cases/conformance/jsdoc/declarations/jsDeclarationsTypeReferences4.ts
@@ -0,0 +1,22 @@
+// @allowJs: true
+// @checkJs: true
+// @target: es5
+// @outDir: tests/cases/conformance/jsdoc/declarations/out
+// @declaration: true
+// @filename: node_modules/@types/node/index.d.ts
+declare module "fs" {
+    export class Something {}
+}
+// @filename: index.js
+/// 
+export const Something = 2; // to show conflict that can occur
+// @ts-ignore
+export namespace A {
+    // @ts-ignore
+    export namespace B {
+        const Something = require("fs").Something;
+        const thing = new Something();
+        // @ts-ignore
+        export { thing };
+    }
+}