Skip to content

Commit 65655f2

Browse files
authored
Change import type determination to not use a RE on the symbol name (#25381)
1 parent 5c57e14 commit 65655f2

File tree

44 files changed

+189
-106
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+189
-106
lines changed

src/compiler/checker.ts

+43-41
Original file line numberDiff line numberDiff line change
@@ -3733,19 +3733,56 @@ namespace ts {
37333733
return top;
37343734
}
37353735

3736+
function getSpecifierForModuleSymbol(symbol: Symbol, context: NodeBuilderContext) {
3737+
const file = getDeclarationOfKind<SourceFile>(symbol, SyntaxKind.SourceFile);
3738+
if (file && file.moduleName !== undefined) {
3739+
// Use the amd name if it is available
3740+
return file.moduleName;
3741+
}
3742+
if (!file) {
3743+
if (context.tracker.trackReferencedAmbientModule) {
3744+
const ambientDecls = filter(symbol.declarations, isAmbientModule);
3745+
if (length(ambientDecls)) {
3746+
for (const decl of ambientDecls) {
3747+
context.tracker.trackReferencedAmbientModule(decl);
3748+
}
3749+
}
3750+
}
3751+
return (symbol.escapedName as string).substring(1, (symbol.escapedName as string).length - 1);
3752+
}
3753+
else {
3754+
if (!context.enclosingDeclaration || !context.tracker.moduleResolverHost) {
3755+
// If there's no context declaration, we can't lookup a non-ambient specifier, so we just use the symbol name
3756+
return (symbol.escapedName as string).substring(1, (symbol.escapedName as string).length - 1);
3757+
}
3758+
const contextFile = getSourceFileOfNode(getOriginalNode(context.enclosingDeclaration));
3759+
const links = getSymbolLinks(symbol);
3760+
let specifier = links.specifierCache && links.specifierCache.get(contextFile.path);
3761+
if (!specifier) {
3762+
specifier = flatten(moduleSpecifiers.getModuleSpecifiers(
3763+
symbol,
3764+
compilerOptions,
3765+
contextFile,
3766+
context.tracker.moduleResolverHost,
3767+
context.tracker.moduleResolverHost.getSourceFiles!(), // TODO: GH#18217
3768+
{ importModuleSpecifierPreference: "non-relative" }
3769+
))[0];
3770+
links.specifierCache = links.specifierCache || createMap();
3771+
links.specifierCache.set(contextFile.path, specifier);
3772+
}
3773+
return specifier;
3774+
}
3775+
}
3776+
37363777
function symbolToTypeNode(symbol: Symbol, context: NodeBuilderContext, meaning: SymbolFlags, overrideTypeArguments?: ReadonlyArray<TypeNode>): TypeNode {
37373778
const chain = lookupSymbolChain(symbol, context, meaning, !(context.flags & NodeBuilderFlags.UseAliasDefinedOutsideCurrentScope)); // If we're using aliases outside the current scope, dont bother with the module
37383779

3739-
context.flags |= NodeBuilderFlags.InInitialEntityName;
3740-
const rootName = getNameOfSymbolAsWritten(chain[0], context);
3741-
context.flags ^= NodeBuilderFlags.InInitialEntityName;
3742-
37433780
const isTypeOf = meaning === SymbolFlags.Value;
3744-
if (ambientModuleSymbolRegex.test(rootName)) {
3781+
if (some(chain[0].declarations, hasNonGlobalAugmentationExternalModuleSymbol)) {
37453782
// module is root, must use `ImportTypeNode`
37463783
const nonRootParts = chain.length > 1 ? createAccessFromSymbolChain(chain, chain.length - 1, 1) : undefined;
37473784
const typeParameterNodes = overrideTypeArguments || lookupTypeParameterNodes(chain, 0, context);
3748-
const lit = createLiteralTypeNode(createLiteral(rootName.substring(1, rootName.length - 1)));
3785+
const lit = createLiteralTypeNode(createLiteral(getSpecifierForModuleSymbol(chain[0], context)));
37493786
if (!nonRootParts || isEntityName(nonRootParts)) {
37503787
if (nonRootParts) {
37513788
const lastId = isIdentifier(nonRootParts) ? nonRootParts : nonRootParts.right;
@@ -3990,41 +4027,6 @@ namespace ts {
39904027
return "default";
39914028
}
39924029
if (symbol.declarations && symbol.declarations.length) {
3993-
if (some(symbol.declarations, hasExternalModuleSymbol) && context!.enclosingDeclaration) { // TODO: GH#18217
3994-
const file = getDeclarationOfKind<SourceFile>(symbol, SyntaxKind.SourceFile);
3995-
if (!file || !context!.tracker.moduleResolverHost) {
3996-
if (context!.tracker.trackReferencedAmbientModule) {
3997-
const ambientDecls = filter(symbol.declarations, isAmbientModule);
3998-
if (length(ambientDecls)) {
3999-
for (const decl of ambientDecls) {
4000-
context!.tracker.trackReferencedAmbientModule!(decl); // TODO: GH#18217
4001-
}
4002-
}
4003-
}
4004-
// ambient module, just use declaration/symbol name (fallthrough)
4005-
}
4006-
else {
4007-
if (file.moduleName) {
4008-
return `"${file.moduleName}"`;
4009-
}
4010-
const contextFile = getSourceFileOfNode(getOriginalNode(context!.enclosingDeclaration))!;
4011-
const links = getSymbolLinks(symbol);
4012-
let specifier = links.specifierCache && links.specifierCache.get(contextFile.path);
4013-
if (!specifier) {
4014-
specifier = flatten(moduleSpecifiers.getModuleSpecifiers(
4015-
symbol,
4016-
compilerOptions,
4017-
contextFile,
4018-
context!.tracker.moduleResolverHost!,
4019-
context!.tracker.moduleResolverHost!.getSourceFiles!(),
4020-
{ importModuleSpecifierPreference: "non-relative" }
4021-
))[0];
4022-
links.specifierCache = links.specifierCache || createMap();
4023-
links.specifierCache.set(contextFile.path, specifier);
4024-
}
4025-
return `"${specifier}"`;
4026-
}
4027-
}
40284030
const declaration = symbol.declarations[0];
40294031
const name = getNameOfDeclaration(declaration);
40304032
if (name) {

tests/baselines/reference/aliasDoesNotDuplicateSignatures.types

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ declare namespace demoNS {
66
>f : () => void
77
}
88
declare module 'demoModule' {
9-
>'demoModule' : typeof 'demoModule'
9+
>'demoModule' : typeof import("demoModule")
1010

1111
import alias = demoNS;
1212
>alias : typeof alias

tests/baselines/reference/ambientDeclarations.types

+1-1
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ var q = M1.fn();
163163
// Ambient external module in the global module
164164
// Ambient external module with a string literal name that is a top level external module name
165165
declare module 'external1' {
166-
>'external1' : typeof 'external1'
166+
>'external1' : typeof import("external1")
167167

168168
var q;
169169
>q : any

tests/baselines/reference/ambientDeclarationsExternal.types

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ var n: number;
2020
=== tests/cases/conformance/ambient/decls.ts ===
2121
// Ambient external module with export assignment
2222
declare module 'equ' {
23-
>'equ' : typeof 'equ'
23+
>'equ' : typeof import("equ")
2424

2525
var x;
2626
>x : any
@@ -30,7 +30,7 @@ declare module 'equ' {
3030
}
3131

3232
declare module 'equ2' {
33-
>'equ2' : typeof 'equ2'
33+
>'equ2' : typeof import("equ2")
3434

3535
var x: number;
3636
>x : number

tests/baselines/reference/ambientErrors.types

+3-3
Original file line numberDiff line numberDiff line change
@@ -97,16 +97,16 @@ module M2 {
9797
>M2 : any
9898

9999
declare module 'nope' { }
100-
>'nope' : typeof 'nope'
100+
>'nope' : typeof import("nope")
101101
}
102102

103103
// Ambient external module with a string literal name that isn't a top level external module name
104104
declare module '../foo' { }
105-
>'../foo' : typeof '../foo'
105+
>'../foo' : typeof import("../foo")
106106

107107
// Ambient external module with export assignment and other exported members
108108
declare module 'bar' {
109-
>'bar' : typeof 'bar'
109+
>'bar' : typeof import("bar")
110110

111111
var n;
112112
>n : any

tests/baselines/reference/ambientExternalModuleWithInternalImportDeclaration.types

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ var c = new A();
1010

1111
=== tests/cases/compiler/ambientExternalModuleWithInternalImportDeclaration_0.ts ===
1212
declare module 'M' {
13-
>'M' : typeof 'M'
13+
>'M' : typeof import("M")
1414

1515
module C {
1616
>C : typeof C

tests/baselines/reference/ambientExternalModuleWithRelativeModuleName.types

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ declare module "./relativeModule" {
77
}
88

99
declare module ".\\relativeModule" {
10-
>".\\relativeModule" : typeof import(".\\\\relativeModule")
10+
>".\\relativeModule" : typeof import(".\\relativeModule")
1111

1212
var x: string;
1313
>x : string

tests/baselines/reference/ambientExternalModuleWithoutInternalImportDeclaration.types

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ var c = new A();
1010

1111
=== tests/cases/compiler/ambientExternalModuleWithoutInternalImportDeclaration_0.ts ===
1212
declare module 'M' {
13-
>'M' : typeof 'M'
13+
>'M' : typeof import("M")
1414

1515
module C {
1616
>C : typeof C

tests/baselines/reference/augmentExportEquals3.types

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
=== tests/cases/compiler/file1.ts ===
22
function foo() {}
3-
>foo : typeof foo
3+
>foo : typeof import("o")
44

55
namespace foo {
6-
>foo : typeof foo
6+
>foo : typeof import("o")
77

88
export var v = 1;
99
>v : number

tests/baselines/reference/augmentExportEquals3_1.types

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ declare module "file1" {
33
>"file1" : typeof import("file1")
44

55
function foo(): void;
6-
>foo : typeof foo
6+
>foo : typeof import("o")
77

88
namespace foo {
9-
>foo : typeof foo
9+
>foo : typeof import("o")
1010

1111
export var v: number;
1212
>v : number

tests/baselines/reference/augmentExportEquals4.types

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
=== tests/cases/compiler/file1.ts ===
22
class foo {}
3-
>foo : foo
3+
>foo : import("o")
44

55
namespace foo {
6-
>foo : typeof foo
6+
>foo : typeof import("o")
77

88
export var v = 1;
99
>v : number

tests/baselines/reference/augmentExportEquals4_1.types

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ declare module "file1" {
33
>"file1" : typeof import("file1")
44

55
class foo {}
6-
>foo : foo
6+
>foo : import("o")
77

88
namespace foo {
9-
>foo : typeof foo
9+
>foo : typeof import("o")
1010

1111
export var v: number;
1212
>v : number

tests/baselines/reference/augmentExportEquals5.types

+3-3
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@ declare module "express" {
1616
>"express" : typeof import("express")
1717

1818
function e(): e.Express;
19-
>e : typeof e
19+
>e : typeof import("e")
2020
>e : any
21-
>Express : e.Express
21+
>Express : import("e").Express
2222

2323
namespace e {
24-
>e : typeof e
24+
>e : typeof import("e")
2525

2626
interface IRoute {
2727
>IRoute : IRoute

tests/baselines/reference/augmentExportEquals6.types

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
=== tests/cases/compiler/file1.ts ===
22
class foo {}
3-
>foo : foo
3+
>foo : import("o")
44

55
namespace foo {
6-
>foo : typeof foo
6+
>foo : typeof import("o")
77

88
export class A {}
99
>A : A

tests/baselines/reference/augmentExportEquals6_1.types

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ declare module "file1" {
33
>"file1" : typeof import("file1")
44

55
class foo {}
6-
>foo : foo
6+
>foo : import("o")
77

88
namespace foo {
9-
>foo : typeof foo
9+
>foo : typeof import("o")
1010

1111
class A {}
1212
>A : A

tests/baselines/reference/bangInModuleName.types

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ declare module "http" {
1010
}
1111

1212
declare module 'intern/dojo/node!http' {
13-
>'intern/dojo/node!http' : typeof 'intern/dojo/node!http'
13+
>'intern/dojo/node!http' : typeof import("intern/dojo/node!http")
1414

1515
import http = require('http');
1616
>http : typeof http

tests/baselines/reference/declFileImportedTypeUseInTypeArgPosition.types

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@ class List<T> { }
44
>T : T
55

66
declare module 'mod1' {
7-
>'mod1' : typeof 'mod1'
7+
>'mod1' : typeof import("mod1")
88

99
class Foo {
1010
>Foo : Foo
1111
}
1212
}
1313

1414
declare module 'moo' {
15-
>'moo' : typeof 'moo'
15+
>'moo' : typeof import("moo")
1616

1717
import x = require('mod1');
1818
>x : typeof x
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//// [tests/cases/compiler/declarationEmitCrossFileImportTypeOfAmbientModule.ts] ////
2+
3+
//// [component.d.ts]
4+
declare module '@namespace/component' {
5+
export class Foo {}
6+
}
7+
//// [index.d.ts]
8+
import { Foo } from "@namespace/component";
9+
export declare const item: typeof Foo;
10+
//// [index.ts]
11+
import { item } from "../somepackage";
12+
export const reeexported = item;
13+
14+
15+
//// [index.js]
16+
"use strict";
17+
exports.__esModule = true;
18+
var somepackage_1 = require("../somepackage");
19+
exports.reeexported = somepackage_1.item;
20+
21+
22+
//// [index.d.ts]
23+
/// <reference path="../../types/component.d.ts" />
24+
export declare const reeexported: typeof import("@namespace/component").Foo;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
=== tests/cases/compiler/types/component.d.ts ===
2+
declare module '@namespace/component' {
3+
>'@namespace/component' : Symbol('@namespace/component', Decl(component.d.ts, 0, 0))
4+
5+
export class Foo {}
6+
>Foo : Symbol(Foo, Decl(component.d.ts, 0, 39))
7+
}
8+
=== tests/cases/compiler/packages/somepackage/index.d.ts ===
9+
import { Foo } from "@namespace/component";
10+
>Foo : Symbol(Foo, Decl(index.d.ts, 0, 8))
11+
12+
export declare const item: typeof Foo;
13+
>item : Symbol(item, Decl(index.d.ts, 1, 20))
14+
>Foo : Symbol(Foo, Decl(index.d.ts, 0, 8))
15+
16+
=== tests/cases/compiler/packages/secondpackage/index.ts ===
17+
import { item } from "../somepackage";
18+
>item : Symbol(item, Decl(index.ts, 0, 8))
19+
20+
export const reeexported = item;
21+
>reeexported : Symbol(reeexported, Decl(index.ts, 1, 12))
22+
>item : Symbol(item, Decl(index.ts, 0, 8))
23+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
=== tests/cases/compiler/types/component.d.ts ===
2+
declare module '@namespace/component' {
3+
>'@namespace/component' : typeof import("@namespace/component")
4+
5+
export class Foo {}
6+
>Foo : Foo
7+
}
8+
=== tests/cases/compiler/packages/somepackage/index.d.ts ===
9+
import { Foo } from "@namespace/component";
10+
>Foo : typeof Foo
11+
12+
export declare const item: typeof Foo;
13+
>item : typeof Foo
14+
>Foo : typeof Foo
15+
16+
=== tests/cases/compiler/packages/secondpackage/index.ts ===
17+
import { item } from "../somepackage";
18+
>item : typeof import("@namespace/component").Foo
19+
20+
export const reeexported = item;
21+
>reeexported : typeof import("@namespace/component").Foo
22+
>item : typeof import("@namespace/component").Foo
23+

tests/baselines/reference/declaredExternalModule.types

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
=== tests/cases/compiler/declaredExternalModule.ts ===
22
declare module 'connect' {
3-
>'connect' : typeof 'connect'
3+
>'connect' : typeof import("connect")
44

55
interface connectModule {
66
>connectModule : connectModule

tests/baselines/reference/declaredExternalModuleWithExportAssignment.types

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
=== tests/cases/compiler/declaredExternalModuleWithExportAssignment.ts ===
22
declare module 'connect' {
3-
>'connect' : typeof 'connect'
3+
>'connect' : typeof import("connect")
44

55
interface connectModule {
66
>connectModule : connectModule

0 commit comments

Comments
 (0)