Skip to content

Commit 4d05bfd

Browse files
author
Andy
authored
moduleAugmentations may contain an Identifier (microsoft#18009)
* `moduleAugmentations` may contain an `Identifier` * Add comment * Rename function
1 parent eb75619 commit 4d05bfd

File tree

3 files changed

+27
-17
lines changed

3 files changed

+27
-17
lines changed

src/compiler/checker.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -640,7 +640,7 @@ namespace ts {
640640
});
641641
}
642642

643-
function mergeModuleAugmentation(moduleName: LiteralExpression): void {
643+
function mergeModuleAugmentation(moduleName: StringLiteral | Identifier): void {
644644
const moduleAugmentation = <ModuleDeclaration>moduleName.parent;
645645
if (moduleAugmentation.symbol.declarations[0] !== moduleAugmentation) {
646646
// this is a combined symbol for multiple augmentations within the same file.
@@ -672,7 +672,8 @@ namespace ts {
672672
mergeSymbol(mainModule, moduleAugmentation.symbol);
673673
}
674674
else {
675-
error(moduleName, Diagnostics.Cannot_augment_module_0_because_it_resolves_to_a_non_module_entity, moduleName.text);
675+
// moduleName will be a StringLiteral since this is not `declare global`.
676+
error(moduleName, Diagnostics.Cannot_augment_module_0_because_it_resolves_to_a_non_module_entity, (moduleName as StringLiteral).text);
676677
}
677678
}
678679
}
@@ -23800,7 +23801,7 @@ namespace ts {
2380023801
}
2380123802

2380223803
// Initialize global symbol table
23803-
let augmentations: ReadonlyArray<StringLiteral>[];
23804+
let augmentations: ReadonlyArray<StringLiteral | Identifier>[];
2380423805
for (const file of host.getSourceFiles()) {
2380523806
if (!isExternalOrCommonJsModule(file)) {
2380623807
mergeSymbolTable(globals, file.locals);

src/compiler/program.ts

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -890,7 +890,7 @@ namespace ts {
890890
for (const { oldFile: oldSourceFile, newFile: newSourceFile } of modifiedSourceFiles) {
891891
const newSourceFilePath = getNormalizedAbsolutePath(newSourceFile.fileName, currentDirectory);
892892
if (resolveModuleNamesWorker) {
893-
const moduleNames = map(concatenate(newSourceFile.imports, newSourceFile.moduleAugmentations), getTextOfLiteral);
893+
const moduleNames = getModuleNames(newSourceFile);
894894
const oldProgramState = { program: oldProgram, file: oldSourceFile, modifiedFilePaths };
895895
const resolutions = resolveModuleNamesReusingOldState(moduleNames, newSourceFilePath, newSourceFile, oldProgramState);
896896
// ensure that module resolution results are still correct
@@ -1434,12 +1434,10 @@ namespace ts {
14341434
return a.fileName === b.fileName;
14351435
}
14361436

1437-
function moduleNameIsEqualTo(a: LiteralExpression, b: LiteralExpression): boolean {
1438-
return a.text === b.text;
1439-
}
1440-
1441-
function getTextOfLiteral(literal: LiteralExpression): string {
1442-
return literal.text;
1437+
function moduleNameIsEqualTo(a: StringLiteral | Identifier, b: StringLiteral | Identifier): boolean {
1438+
return a.kind === SyntaxKind.StringLiteral
1439+
? b.kind === SyntaxKind.StringLiteral && a.text === b.text
1440+
: b.kind === SyntaxKind.Identifier && a.escapedText === b.escapedText;
14431441
}
14441442

14451443
function collectExternalModuleReferences(file: SourceFile): void {
@@ -1452,7 +1450,7 @@ namespace ts {
14521450

14531451
// file.imports may not be undefined if there exists dynamic import
14541452
let imports: StringLiteral[];
1455-
let moduleAugmentations: StringLiteral[];
1453+
let moduleAugmentations: Array<StringLiteral | Identifier>;
14561454
let ambientModules: string[];
14571455

14581456
// If we are importing helpers, we need to add a synthetic reference to resolve the
@@ -1481,7 +1479,7 @@ namespace ts {
14811479

14821480
return;
14831481

1484-
function collectModuleReferences(node: Node, inAmbientModule: boolean): void {
1482+
function collectModuleReferences(node: Statement, inAmbientModule: boolean): void {
14851483
switch (node.kind) {
14861484
case SyntaxKind.ImportDeclaration:
14871485
case SyntaxKind.ImportEqualsDeclaration:
@@ -1503,8 +1501,8 @@ namespace ts {
15031501
break;
15041502
case SyntaxKind.ModuleDeclaration:
15051503
if (isAmbientModule(<ModuleDeclaration>node) && (inAmbientModule || hasModifier(node, ModifierFlags.Ambient) || file.isDeclarationFile)) {
1506-
const moduleName = <StringLiteral>(<ModuleDeclaration>node).name; // TODO: GH#17347
1507-
const nameText = ts.getTextOfIdentifierOrLiteral(moduleName);
1504+
const moduleName = (<ModuleDeclaration>node).name;
1505+
const nameText = getTextOfIdentifierOrLiteral(moduleName);
15081506
// Ambient module declarations can be interpreted as augmentations for some existing external modules.
15091507
// This will happen in two cases:
15101508
// - if current file is external module then module augmentation is a ambient module declaration defined in the top level scope
@@ -1821,8 +1819,7 @@ namespace ts {
18211819
collectExternalModuleReferences(file);
18221820
if (file.imports.length || file.moduleAugmentations.length) {
18231821
// Because global augmentation doesn't have string literal name, we can check for global augmentation as such.
1824-
const nonGlobalAugmentation = filter(file.moduleAugmentations, (moduleAugmentation) => moduleAugmentation.kind === SyntaxKind.StringLiteral);
1825-
const moduleNames = map(concatenate(file.imports, nonGlobalAugmentation), getTextOfLiteral);
1822+
const moduleNames = getModuleNames(file);
18261823
const oldProgramState = { program: oldProgram, file, modifiedFilePaths };
18271824
const resolutions = resolveModuleNamesReusingOldState(moduleNames, getNormalizedAbsolutePath(file.fileName, currentDirectory), file, oldProgramState);
18281825
Debug.assert(resolutions.length === moduleNames.length);
@@ -2233,4 +2230,15 @@ namespace ts {
22332230
Debug.assert(names.every(name => name !== undefined), "A name is undefined.", () => JSON.stringify(names));
22342231
return names;
22352232
}
2233+
2234+
function getModuleNames({ imports, moduleAugmentations }: SourceFile): string[] {
2235+
const res = imports.map(i => i.text);
2236+
for (const aug of moduleAugmentations) {
2237+
if (aug.kind === SyntaxKind.StringLiteral) {
2238+
res.push(aug.text);
2239+
}
2240+
// Do nothing if it's an Identifier; we don't need to do module resolution for `declare global`.
2241+
}
2242+
return res;
2243+
}
22362244
}

src/compiler/types.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2343,7 +2343,8 @@ namespace ts {
23432343
/* @internal */ resolvedModules: Map<ResolvedModuleFull>;
23442344
/* @internal */ resolvedTypeReferenceDirectiveNames: Map<ResolvedTypeReferenceDirective>;
23452345
/* @internal */ imports: ReadonlyArray<StringLiteral>;
2346-
/* @internal */ moduleAugmentations: ReadonlyArray<StringLiteral>;
2346+
// Identifier only if `declare global`
2347+
/* @internal */ moduleAugmentations: ReadonlyArray<StringLiteral | Identifier>;
23472348
/* @internal */ patternAmbientModules?: PatternAmbientModule[];
23482349
/* @internal */ ambientModuleNames: ReadonlyArray<string>;
23492350
/* @internal */ checkJsDirective: CheckJsDirective | undefined;

0 commit comments

Comments
 (0)