In bundle declaration emit, refuse to rewrite nonrelative references to files outside the common source directory (#42306)

This commit is contained in:
Wesley Wigham 2021-01-25 11:16:59 -08:00 committed by GitHub
parent 1b57a0395e
commit d7d8f33def
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 108 additions and 1 deletions

View File

@ -2430,7 +2430,7 @@ namespace ts {
}
}
export function getExternalModuleName(node: AnyImportOrReExport | ImportTypeNode | ImportCall): Expression | undefined {
export function getExternalModuleName(node: AnyImportOrReExport | ImportTypeNode | ImportCall | ModuleDeclaration): Expression | undefined {
switch (node.kind) {
case SyntaxKind.ImportDeclaration:
case SyntaxKind.ExportDeclaration:
@ -2441,6 +2441,8 @@ namespace ts {
return isLiteralImportTypeNode(node) ? node.argument.literal : undefined;
case SyntaxKind.CallExpression:
return node.arguments[0];
case SyntaxKind.ModuleDeclaration:
return node.name.kind === SyntaxKind.StringLiteral ? node.name : undefined;
default:
return Debug.assertNever(node);
}
@ -4118,11 +4120,21 @@ namespace ts {
return file.moduleName || getExternalModuleNameFromPath(host, file.fileName, referenceFile && referenceFile.fileName);
}
function getCanonicalAbsolutePath(host: ResolveModuleNameResolutionHost, path: string) {
return host.getCanonicalFileName(getNormalizedAbsolutePath(path, host.getCurrentDirectory()));
}
export function getExternalModuleNameFromDeclaration(host: ResolveModuleNameResolutionHost, resolver: EmitResolver, declaration: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration | ModuleDeclaration | ImportTypeNode): string | undefined {
const file = resolver.getExternalModuleFileFromDeclaration(declaration);
if (!file || file.isDeclarationFile) {
return undefined;
}
// If the declaration already uses a non-relative name, and is outside the common source directory, continue to use it
const specifier = getExternalModuleName(declaration);
if (specifier && isStringLiteralLike(specifier) && !pathIsRelative(specifier.text) &&
getCanonicalAbsolutePath(host, file.path).indexOf(getCanonicalAbsolutePath(host, ensureTrailingDirectorySeparator(host.getCommonSourceDirectory()))) === -1) {
return undefined;
}
return getResolvedExternalModuleName(host, file);
}

View File

@ -0,0 +1,44 @@
//// [tests/cases/compiler/declarationEmitCommonSourceDirectoryDoesNotContainAllFiles.ts] ////
//// [index.ts]
export * from "./src/"
//// [index.ts]
export class B {}
//// [index.ts]
import { B } from "b";
export default function () {
return new B();
}
//// [index.ts]
export * from "./src/"
//// [index.d.ts]
declare module "src/index" {
import { B } from "b";
export default function (): B;
}
declare module "index" {
export * from "src/index";
}
//// [DtsFileErrors]
dist/index.d.ts(2,23): error TS2307: Cannot find module 'b' or its corresponding type declarations.
==== dist/index.d.ts (1 errors) ====
declare module "src/index" {
import { B } from "b";
~~~
!!! error TS2307: Cannot find module 'b' or its corresponding type declarations.
export default function (): B;
}
declare module "index" {
export * from "src/index";
}

View File

@ -0,0 +1,16 @@
=== /a/index.ts ===
export * from "./src/"
No type information for this code.=== /b/index.ts ===
export * from "./src/"
No type information for this code.=== /b/src/index.ts ===
export class B {}
>B : Symbol(B, Decl(index.ts, 0, 0))
=== /a/src/index.ts ===
import { B } from "b";
>B : Symbol(B, Decl(index.ts, 0, 8))
export default function () {
return new B();
>B : Symbol(B, Decl(index.ts, 0, 8))
}

View File

@ -0,0 +1,17 @@
=== /a/index.ts ===
export * from "./src/"
No type information for this code.=== /b/index.ts ===
export * from "./src/"
No type information for this code.=== /b/src/index.ts ===
export class B {}
>B : B
=== /a/src/index.ts ===
import { B } from "b";
>B : typeof B
export default function () {
return new B();
>new B() : B
>B : typeof B
}

View File

@ -0,0 +1,18 @@
// @declaration: true
// @emitDeclarationOnly: true
// @outFile: dist/index.d.ts
// @currentDirectory: /a
// @noImplicitReferences: true
// @filename: /b/index.ts
export * from "./src/"
// @filename: /b/src/index.ts
export class B {}
// @filename: /a/src/index.ts
import { B } from "b";
export default function () {
return new B();
}
// @filename: /a/index.ts
export * from "./src/"
// @link: /b -> /a/node_modules/b