mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-04 05:39:27 -05:00
* fix as suggestion. * Update moduleSpecifiers.ts * compare symbol rather than string * fix typo. * fix * fix lint. * better name and more clear code * fix comment. Co-authored-by: Orta Therox <git@orta.io>
This commit is contained in:
@@ -5494,6 +5494,7 @@ namespace ts {
|
||||
const specifierCompilerOptions = isBundle ? { ...compilerOptions, baseUrl: moduleResolverHost.getCommonSourceDirectory() } : compilerOptions;
|
||||
specifier = first(moduleSpecifiers.getModuleSpecifiers(
|
||||
symbol,
|
||||
checker,
|
||||
specifierCompilerOptions,
|
||||
contextFile,
|
||||
moduleResolverHost,
|
||||
|
||||
@@ -1422,8 +1422,7 @@ namespace ts {
|
||||
export function getPackageNameFromTypesPackageName(mangledName: string): string {
|
||||
const withoutAtTypePrefix = removePrefix(mangledName, "@types/");
|
||||
if (withoutAtTypePrefix !== mangledName) {
|
||||
const withoutAtTypeNodePrefix = removePrefix(withoutAtTypePrefix, "node/");
|
||||
return unmangleScopedPackageName(withoutAtTypeNodePrefix);
|
||||
return unmangleScopedPackageName(withoutAtTypePrefix);
|
||||
}
|
||||
return mangledName;
|
||||
}
|
||||
|
||||
@@ -92,12 +92,13 @@ namespace ts.moduleSpecifiers {
|
||||
/** Returns an import for each symlink and for the realpath. */
|
||||
export function getModuleSpecifiers(
|
||||
moduleSymbol: Symbol,
|
||||
checker: TypeChecker,
|
||||
compilerOptions: CompilerOptions,
|
||||
importingSourceFile: SourceFile,
|
||||
host: ModuleSpecifierResolutionHost,
|
||||
userPreferences: UserPreferences,
|
||||
): readonly string[] {
|
||||
const ambient = tryGetModuleNameFromAmbientModule(moduleSymbol);
|
||||
const ambient = tryGetModuleNameFromAmbientModule(moduleSymbol, checker);
|
||||
if (ambient) return [ambient];
|
||||
|
||||
const info = getInfo(importingSourceFile.path, host);
|
||||
@@ -369,13 +370,49 @@ namespace ts.moduleSpecifiers {
|
||||
return sortedPaths;
|
||||
}
|
||||
|
||||
function tryGetModuleNameFromAmbientModule(moduleSymbol: Symbol): string | undefined {
|
||||
function tryGetModuleNameFromAmbientModule(moduleSymbol: Symbol, checker: TypeChecker): string | undefined {
|
||||
const decl = find(moduleSymbol.declarations,
|
||||
d => isNonGlobalAmbientModule(d) && (!isExternalModuleAugmentation(d) || !isExternalModuleNameRelative(getTextOfIdentifierOrLiteral(d.name)))
|
||||
) as (ModuleDeclaration & { name: StringLiteral }) | undefined;
|
||||
if (decl) {
|
||||
return decl.name.text;
|
||||
}
|
||||
|
||||
// the module could be a namespace, which is export through "export=" from an ambient module.
|
||||
/**
|
||||
* declare module "m" {
|
||||
* namespace ns {
|
||||
* class c {}
|
||||
* }
|
||||
* export = ns;
|
||||
* }
|
||||
*/
|
||||
// `import {c} from "m";` is valid, in which case, `moduleSymbol` is "ns", but the module name should be "m"
|
||||
const ambientModuleDeclareCandidates = mapDefined(moduleSymbol.declarations,
|
||||
d => {
|
||||
if (!isModuleDeclaration(d)) return;
|
||||
const topNamespace = getTopNamespace(d);
|
||||
if (!(topNamespace?.parent?.parent
|
||||
&& isModuleBlock(topNamespace.parent) && isAmbientModule(topNamespace.parent.parent) && isSourceFile(topNamespace.parent.parent.parent))) return;
|
||||
const exportAssignment = ((topNamespace.parent.parent.symbol.exports?.get("export=" as __String)?.valueDeclaration as ExportAssignment)?.expression as PropertyAccessExpression | Identifier);
|
||||
if (!exportAssignment) return;
|
||||
const exportSymbol = checker.getSymbolAtLocation(exportAssignment);
|
||||
if (!exportSymbol) return;
|
||||
const originalExportSymbol = exportSymbol?.flags & SymbolFlags.Alias ? checker.getAliasedSymbol(exportSymbol) : exportSymbol;
|
||||
if (originalExportSymbol === d.symbol) return topNamespace.parent.parent;
|
||||
|
||||
function getTopNamespace(namespaceDeclaration: ModuleDeclaration) {
|
||||
while (namespaceDeclaration.flags & NodeFlags.NestedNamespace) {
|
||||
namespaceDeclaration = namespaceDeclaration.parent as ModuleDeclaration;
|
||||
}
|
||||
return namespaceDeclaration;
|
||||
}
|
||||
}
|
||||
);
|
||||
const ambientModuleDeclare = ambientModuleDeclareCandidates[0] as (AmbientModuleDeclaration & { name: StringLiteral }) | undefined;
|
||||
if (ambientModuleDeclare) {
|
||||
return ambientModuleDeclare.name.text;
|
||||
}
|
||||
}
|
||||
|
||||
function tryGetModuleNameFromPaths(relativeToBaseUrlWithIndex: string, relativeToBaseUrl: string, paths: MapLike<readonly string[]>): string | undefined {
|
||||
|
||||
@@ -404,7 +404,7 @@ namespace ts.codefix {
|
||||
const { allowsImportingSpecifier } = createAutoImportFilter(sourceFile, program, host);
|
||||
|
||||
const choicesForEachExportingModule = flatMap(moduleSymbols, ({ moduleSymbol, importKind, exportedSymbolIsTypeOnly }) =>
|
||||
moduleSpecifiers.getModuleSpecifiers(moduleSymbol, compilerOptions, sourceFile, createModuleSpecifierResolutionHost(program, host) , preferences)
|
||||
moduleSpecifiers.getModuleSpecifiers(moduleSymbol, program.getTypeChecker(), compilerOptions, sourceFile, createModuleSpecifierResolutionHost(program, host), preferences)
|
||||
.map((moduleSpecifier): FixAddNewImport | FixUseImportType =>
|
||||
// `position` should only be undefined at a missing jsx namespace, in which case we shouldn't be looking for pure types.
|
||||
exportedSymbolIsTypeOnly && isJs
|
||||
|
||||
@@ -11,30 +11,73 @@ declare module "events" {
|
||||
}
|
||||
export = EventEmitter;
|
||||
}
|
||||
declare module "nestNamespaceModule" {
|
||||
namespace a1.a2 {
|
||||
class d { }
|
||||
}
|
||||
|
||||
namespace a1.a2.n3 {
|
||||
class c { }
|
||||
}
|
||||
export = a1.a2;
|
||||
}
|
||||
declare module "renameModule" {
|
||||
namespace a.b {
|
||||
class c { }
|
||||
}
|
||||
import d = a.b;
|
||||
export = d;
|
||||
}
|
||||
|
||||
//// [b.js]
|
||||
import { EventEmitter } from 'events';
|
||||
class Foo extends EventEmitter {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
import { n3, d } from 'nestNamespaceModule';
|
||||
import { c } from 'renameModule';
|
||||
|
||||
export class Foo extends EventEmitter {
|
||||
}
|
||||
export default Foo;
|
||||
|
||||
export class Foo2 extends n3.c {
|
||||
}
|
||||
|
||||
export class Foo3 extends d {
|
||||
}
|
||||
|
||||
export class Foo4 extends c {
|
||||
|
||||
}
|
||||
|
||||
//// [b.js]
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Foo4 = exports.Foo3 = exports.Foo2 = exports.Foo = void 0;
|
||||
const events_1 = require("events");
|
||||
const nestNamespaceModule_1 = require("nestNamespaceModule");
|
||||
const renameModule_1 = require("renameModule");
|
||||
class Foo extends events_1.EventEmitter {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
exports.default = Foo;
|
||||
exports.Foo = Foo;
|
||||
class Foo2 extends nestNamespaceModule_1.n3.c {
|
||||
}
|
||||
exports.Foo2 = Foo2;
|
||||
class Foo3 extends nestNamespaceModule_1.d {
|
||||
}
|
||||
exports.Foo3 = Foo3;
|
||||
class Foo4 extends renameModule_1.c {
|
||||
}
|
||||
exports.Foo4 = Foo4;
|
||||
|
||||
|
||||
//// [b.d.ts]
|
||||
export default Foo;
|
||||
declare class Foo extends EventEmitter {
|
||||
export class Foo extends EventEmitter {
|
||||
}
|
||||
export class Foo2 extends n3.c {
|
||||
}
|
||||
export class Foo3 extends d {
|
||||
}
|
||||
export class Foo4 extends c {
|
||||
}
|
||||
import { EventEmitter } from "events";
|
||||
import { n3 } from "nestNamespaceModule";
|
||||
import { d } from "nestNamespaceModule";
|
||||
import { c } from "renameModule";
|
||||
|
||||
@@ -16,20 +16,79 @@ declare module "events" {
|
||||
export = EventEmitter;
|
||||
>EventEmitter : Symbol(EventEmitter, Decl(events.d.ts, 0, 25))
|
||||
}
|
||||
declare module "nestNamespaceModule" {
|
||||
>"nestNamespaceModule" : Symbol("nestNamespaceModule", Decl(events.d.ts, 7, 1))
|
||||
|
||||
namespace a1.a2 {
|
||||
>a1 : Symbol(a1, Decl(events.d.ts, 8, 38), Decl(events.d.ts, 11, 5))
|
||||
>a2 : Symbol(a2, Decl(events.d.ts, 9, 17), Decl(events.d.ts, 13, 17))
|
||||
|
||||
class d { }
|
||||
>d : Symbol(d, Decl(events.d.ts, 9, 21))
|
||||
}
|
||||
|
||||
namespace a1.a2.n3 {
|
||||
>a1 : Symbol(a1, Decl(events.d.ts, 8, 38), Decl(events.d.ts, 11, 5))
|
||||
>a2 : Symbol(a2, Decl(events.d.ts, 9, 17), Decl(events.d.ts, 13, 17))
|
||||
>n3 : Symbol(n3, Decl(events.d.ts, 13, 20))
|
||||
|
||||
class c { }
|
||||
>c : Symbol(c, Decl(events.d.ts, 13, 24))
|
||||
}
|
||||
export = a1.a2;
|
||||
>a1.a2 : Symbol(a1.a2, Decl(events.d.ts, 9, 17), Decl(events.d.ts, 13, 17))
|
||||
>a1 : Symbol(a1, Decl(events.d.ts, 8, 38), Decl(events.d.ts, 11, 5))
|
||||
>a2 : Symbol(a1.a2, Decl(events.d.ts, 9, 17), Decl(events.d.ts, 13, 17))
|
||||
}
|
||||
declare module "renameModule" {
|
||||
>"renameModule" : Symbol("renameModule", Decl(events.d.ts, 17, 1))
|
||||
|
||||
namespace a.b {
|
||||
>a : Symbol(a, Decl(events.d.ts, 18, 31))
|
||||
>b : Symbol(b, Decl(events.d.ts, 19, 16))
|
||||
|
||||
class c { }
|
||||
>c : Symbol(c, Decl(events.d.ts, 19, 19))
|
||||
}
|
||||
import d = a.b;
|
||||
>d : Symbol(d, Decl(events.d.ts, 21, 5))
|
||||
>a : Symbol(a, Decl(events.d.ts, 18, 31))
|
||||
>b : Symbol(d, Decl(events.d.ts, 19, 16))
|
||||
|
||||
export = d;
|
||||
>d : Symbol(d, Decl(events.d.ts, 21, 5))
|
||||
}
|
||||
|
||||
=== /src/b.js ===
|
||||
import { EventEmitter } from 'events';
|
||||
>EventEmitter : Symbol(EventEmitter, Decl(b.js, 0, 8))
|
||||
|
||||
class Foo extends EventEmitter {
|
||||
>Foo : Symbol(Foo, Decl(b.js, 0, 38))
|
||||
import { n3, d } from 'nestNamespaceModule';
|
||||
>n3 : Symbol(n3, Decl(b.js, 1, 8))
|
||||
>d : Symbol(d, Decl(b.js, 1, 12))
|
||||
|
||||
import { c } from 'renameModule';
|
||||
>c : Symbol(c, Decl(b.js, 2, 8))
|
||||
|
||||
export class Foo extends EventEmitter {
|
||||
>Foo : Symbol(Foo, Decl(b.js, 2, 33))
|
||||
>EventEmitter : Symbol(EventEmitter, Decl(b.js, 0, 8))
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
>super : Symbol(EventEmitter, Decl(events.d.ts, 1, 28))
|
||||
}
|
||||
}
|
||||
export default Foo;
|
||||
>Foo : Symbol(Foo, Decl(b.js, 0, 38))
|
||||
|
||||
export class Foo2 extends n3.c {
|
||||
>Foo2 : Symbol(Foo2, Decl(b.js, 5, 1))
|
||||
>n3.c : Symbol(n3.c, Decl(events.d.ts, 13, 24))
|
||||
>n3 : Symbol(n3, Decl(b.js, 1, 8))
|
||||
>c : Symbol(n3.c, Decl(events.d.ts, 13, 24))
|
||||
}
|
||||
|
||||
export class Foo3 extends d {
|
||||
>Foo3 : Symbol(Foo3, Decl(b.js, 8, 1))
|
||||
>d : Symbol(d, Decl(b.js, 1, 12))
|
||||
}
|
||||
|
||||
export class Foo4 extends c {
|
||||
>Foo4 : Symbol(Foo4, Decl(b.js, 11, 1))
|
||||
>c : Symbol(c, Decl(b.js, 2, 8))
|
||||
|
||||
}
|
||||
|
||||
@@ -16,21 +16,79 @@ declare module "events" {
|
||||
export = EventEmitter;
|
||||
>EventEmitter : typeof EventEmitter
|
||||
}
|
||||
declare module "nestNamespaceModule" {
|
||||
>"nestNamespaceModule" : typeof import("nestNamespaceModule")
|
||||
|
||||
namespace a1.a2 {
|
||||
>a1 : typeof a1
|
||||
>a2 : typeof a2
|
||||
|
||||
class d { }
|
||||
>d : d
|
||||
}
|
||||
|
||||
namespace a1.a2.n3 {
|
||||
>a1 : typeof a1
|
||||
>a2 : typeof a2
|
||||
>n3 : typeof n3
|
||||
|
||||
class c { }
|
||||
>c : c
|
||||
}
|
||||
export = a1.a2;
|
||||
>a1.a2 : typeof a1.a2
|
||||
>a1 : typeof a1
|
||||
>a2 : typeof a1.a2
|
||||
}
|
||||
declare module "renameModule" {
|
||||
>"renameModule" : typeof import("renameModule")
|
||||
|
||||
namespace a.b {
|
||||
>a : typeof a
|
||||
>b : typeof b
|
||||
|
||||
class c { }
|
||||
>c : c
|
||||
}
|
||||
import d = a.b;
|
||||
>d : typeof d
|
||||
>a : typeof a
|
||||
>b : typeof d
|
||||
|
||||
export = d;
|
||||
>d : typeof d
|
||||
}
|
||||
|
||||
=== /src/b.js ===
|
||||
import { EventEmitter } from 'events';
|
||||
>EventEmitter : typeof EventEmitter
|
||||
|
||||
class Foo extends EventEmitter {
|
||||
import { n3, d } from 'nestNamespaceModule';
|
||||
>n3 : typeof n3
|
||||
>d : typeof d
|
||||
|
||||
import { c } from 'renameModule';
|
||||
>c : typeof c
|
||||
|
||||
export class Foo extends EventEmitter {
|
||||
>Foo : Foo
|
||||
>EventEmitter : EventEmitter
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
>super() : void
|
||||
>super : typeof EventEmitter
|
||||
}
|
||||
}
|
||||
export default Foo;
|
||||
>Foo : Foo
|
||||
|
||||
export class Foo2 extends n3.c {
|
||||
>Foo2 : Foo2
|
||||
>n3.c : n3.c
|
||||
>n3 : typeof n3
|
||||
>c : typeof n3.c
|
||||
}
|
||||
|
||||
export class Foo3 extends d {
|
||||
>Foo3 : Foo3
|
||||
>d : d
|
||||
}
|
||||
|
||||
export class Foo4 extends c {
|
||||
>Foo4 : Foo4
|
||||
>c : c
|
||||
|
||||
}
|
||||
|
||||
@@ -15,12 +15,38 @@ declare module "events" {
|
||||
}
|
||||
export = EventEmitter;
|
||||
}
|
||||
declare module "nestNamespaceModule" {
|
||||
namespace a1.a2 {
|
||||
class d { }
|
||||
}
|
||||
|
||||
namespace a1.a2.n3 {
|
||||
class c { }
|
||||
}
|
||||
export = a1.a2;
|
||||
}
|
||||
declare module "renameModule" {
|
||||
namespace a.b {
|
||||
class c { }
|
||||
}
|
||||
import d = a.b;
|
||||
export = d;
|
||||
}
|
||||
|
||||
// @filename: /src/b.js
|
||||
import { EventEmitter } from 'events';
|
||||
class Foo extends EventEmitter {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
import { n3, d } from 'nestNamespaceModule';
|
||||
import { c } from 'renameModule';
|
||||
|
||||
export class Foo extends EventEmitter {
|
||||
}
|
||||
export default Foo;
|
||||
|
||||
export class Foo2 extends n3.c {
|
||||
}
|
||||
|
||||
export class Foo3 extends d {
|
||||
}
|
||||
|
||||
export class Foo4 extends c {
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user