Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/compiler/moduleNameResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,7 @@ export interface PackageJsonPathFields {
imports?: object;
exports?: object;
name?: string;
dependencies?: object;
}

interface PackageJson extends PackageJsonPathFields {
Expand Down
27 changes: 27 additions & 0 deletions src/compiler/moduleSpecifiers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,15 @@ import {
getOwnKeys,
getPackageJsonTypesVersionsPaths,
getPackageNameFromTypesPackageName,
getPackageScopeForPath,
getPathsBasePath,
getRelativePathFromDirectory,
getRelativePathToDirectoryOrUrl,
getResolvePackageJsonExports,
getResolvePackageJsonImports,
getSourceFileOfModule,
getSupportedExtensions,
getTemporaryModuleResolutionState,
getTextOfIdentifierOrLiteral,
hasJSFileExtension,
hasTSFileExtension,
Expand Down Expand Up @@ -84,6 +86,7 @@ import {
ModuleDeclaration,
ModuleKind,
ModulePath,
ModuleResolutionHost,
ModuleResolutionKind,
ModuleSpecifierCache,
ModuleSpecifierEnding,
Expand All @@ -102,6 +105,7 @@ import {
removeTrailingDirectorySeparator,
replaceFirstStar,
ResolutionMode,
resolveModuleName,
resolvePath,
ScriptKind,
shouldAllowImportingTsExtension,
Expand Down Expand Up @@ -708,6 +712,29 @@ function getAllModulePaths(
}

function getAllModulePathsWorker(info: Info, importedFileName: string, host: ModuleSpecifierResolutionHost): readonly ModulePath[] {
const cache = host.getModuleResolutionCache?.();
const links = host.getSymlinkCache?.();
if (cache && links && host.readFile && !pathContainsNodeModules(info.importingSourceFileName)) {
Debug.type<ModuleResolutionHost>(host);
// Cache resolutions for all `dependencies` of the `package.json` context of the input file.
// This should populate all the relevant symlinks in the symlink cache, and most, if not all, of these resolutions
// should get (re)used.
const state = getTemporaryModuleResolutionState(cache.getPackageJsonInfoCache(), host, {});
const packageJson = getPackageScopeForPath(info.importingSourceFileName, state);
if (packageJson) {
const deps = packageJson.contents.packageJsonContent.dependencies;
Comment thread
weswigham marked this conversation as resolved.
Outdated
if (deps && typeof deps === "object") {
const toResolve = getOwnKeys(deps as MapLike<unknown>);
for (const depName of toResolve) {
const cached = cache.getOrCreateCacheForNonRelativeName(depName, /*mode*/ undefined, /*redirectedReference*/ undefined).get(info.canonicalSourceDirectory);
Comment thread
weswigham marked this conversation as resolved.
Outdated
if (cached) continue;
const resolved = resolveModuleName(depName, info.importingSourceFileName, {}, host, cache);
Comment thread
weswigham marked this conversation as resolved.
Outdated
links.setSymlinksFromResolution(resolved.resolvedModule);
}
}
}
}

const allFileNames = new Map<string, { path: string; isRedirect: boolean; isInNodeModules: boolean; }>();
let importedFileFromNodeModules = false;
forEachFileNameOfModule(
Expand Down
2 changes: 2 additions & 0 deletions src/compiler/program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2698,12 +2698,14 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
// Before falling back to the host
return host.fileExists(f);
},
realpath: maybeBind(host, host.realpath),
useCaseSensitiveFileNames: () => host.useCaseSensitiveFileNames(),
getBuildInfo: () => program.getBuildInfo?.(),
getSourceFileFromReference: (file, ref) => program.getSourceFileFromReference(file, ref),
redirectTargetsMap,
getFileIncludeReasons: program.getFileIncludeReasons,
createHash: maybeBind(host, host.createHash),
getModuleResolutionCache: () => program.getModuleResolutionCache(),
};
}

Expand Down
2 changes: 2 additions & 0 deletions src/compiler/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9706,6 +9706,8 @@ export interface ModuleSpecifierResolutionHost {
getCommonSourceDirectory(): string;
getDefaultResolutionModeForFile(sourceFile: SourceFile): ResolutionMode;
getModeForResolutionAtIndex(file: SourceFile, index: number): ResolutionMode;

getModuleResolutionCache?(): ModuleResolutionCache | undefined;
}

/** @internal */
Expand Down
4 changes: 4 additions & 0 deletions src/compiler/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9079,6 +9079,7 @@ export interface SymlinkCache {
) => void,
typeReferenceDirectives: ModeAwareCache<ResolvedTypeReferenceDirectiveWithFailedLookupLocations>,
): void;
setSymlinksFromResolution(resolution: ResolvedModuleFull | undefined): void;
/**
* @internal
* Whether `setSymlinksFromResolutions` has already been called.
Expand Down Expand Up @@ -9118,6 +9119,9 @@ export function createSymlinkCache(cwd: string, getCanonicalFileName: GetCanonic
typeReferenceDirectives.forEach(resolution => processResolution(this, resolution.resolvedTypeReferenceDirective));
},
hasProcessedResolutions: () => hasProcessedResolutions,
setSymlinksFromResolution(resolution) {
processResolution(this, resolution);
},
};

function processResolution(cache: SymlinkCache, resolution: ResolvedModuleFull | ResolvedTypeReferenceDirective | undefined) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
//// [tests/cases/compiler/symlinkedWorkspaceDependenciesNoDirectLinkGeneratesDeepNonrelativeName.ts] ////

//// [foo.d.ts]
export declare class Foo {
private f: any;
}
//// [index.d.ts]
import { Foo } from "./foo.js";
export function create(): Foo;
//// [package.json]
{
"name": "package-a",
"version": "0.0.1",
"exports": {
".": "./index.js",
"./cls": "./foo.js"
}
}
//// [package.json]
{
"private": true,
"dependencies": {
"package-a": "file:../packageA"
}
}
//// [index.d.ts]
import { create } from "package-a";
export declare function invoke(): ReturnType<typeof create>;
//// [package.json]
{
"private": true,
"dependencies": {
"package-b": "file:../packageB",
"package-a": "file:../packageA"
}
}
//// [index.ts]
import * as pkg from "package-b";

export const a = pkg.invoke();

//// [index.js]
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.a = void 0;
const pkg = __importStar(require("package-b"));
exports.a = pkg.invoke();


//// [index.d.ts]
export declare const a: import("package-a/cls").Foo;
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//// [tests/cases/compiler/symlinkedWorkspaceDependenciesNoDirectLinkGeneratesDeepNonrelativeName.ts] ////

=== workspace/packageA/foo.d.ts ===
export declare class Foo {
>Foo : Symbol(Foo, Decl(foo.d.ts, 0, 0))

private f: any;
>f : Symbol(Foo.f, Decl(foo.d.ts, 0, 26))
}
=== workspace/packageA/index.d.ts ===
import { Foo } from "./foo.js";
>Foo : Symbol(Foo, Decl(index.d.ts, 0, 8))

export function create(): Foo;
>create : Symbol(create, Decl(index.d.ts, 0, 31))
>Foo : Symbol(Foo, Decl(index.d.ts, 0, 8))

=== workspace/packageB/index.d.ts ===
import { create } from "package-a";
>create : Symbol(create, Decl(index.d.ts, 0, 8))

export declare function invoke(): ReturnType<typeof create>;
>invoke : Symbol(invoke, Decl(index.d.ts, 0, 35))
>ReturnType : Symbol(ReturnType, Decl(lib.es5.d.ts, --, --))
>create : Symbol(create, Decl(index.d.ts, 0, 8))

=== workspace/packageC/index.ts ===
import * as pkg from "package-b";
>pkg : Symbol(pkg, Decl(index.ts, 0, 6))

export const a = pkg.invoke();
>a : Symbol(a, Decl(index.ts, 2, 12))
>pkg.invoke : Symbol(pkg.invoke, Decl(index.d.ts, 0, 35))
>pkg : Symbol(pkg, Decl(index.ts, 0, 6))
>invoke : Symbol(pkg.invoke, Decl(index.d.ts, 0, 35))

Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//// [tests/cases/compiler/symlinkedWorkspaceDependenciesNoDirectLinkGeneratesDeepNonrelativeName.ts] ////

=== workspace/packageA/foo.d.ts ===
export declare class Foo {
>Foo : Foo
> : ^^^

private f: any;
>f : any
}
=== workspace/packageA/index.d.ts ===
import { Foo } from "./foo.js";
>Foo : typeof Foo
> : ^^^^^^^^^^

export function create(): Foo;
>create : () => Foo
> : ^^^^^^

=== workspace/packageB/index.d.ts ===
import { create } from "package-a";
>create : () => import("workspace/packageA/foo").Foo
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

export declare function invoke(): ReturnType<typeof create>;
>invoke : () => ReturnType<typeof create>
> : ^^^^^^
>create : () => import("workspace/packageA/foo").Foo
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

=== workspace/packageC/index.ts ===
import * as pkg from "package-b";
>pkg : typeof pkg
> : ^^^^^^^^^^

export const a = pkg.invoke();
>a : import("workspace/packageA/foo").Foo
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>pkg.invoke() : import("workspace/packageA/foo").Foo
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>pkg.invoke : () => import("workspace/packageA/foo").Foo
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>pkg : typeof pkg
> : ^^^^^^^^^^
>invoke : () => import("workspace/packageA/foo").Foo
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//// [tests/cases/compiler/symlinkedWorkspaceDependenciesNoDirectLinkGeneratesNonrelativeName.ts] ////

//// [index.d.ts]
export declare class Foo {
private f: any;
}
//// [package.json]
{
"private": true,
"dependencies": {
"package-a": "file:../packageA"
}
}
//// [index.d.ts]
import { Foo } from "package-a";
export declare function invoke(): Foo;
//// [package.json]
{
"private": true,
"dependencies": {
"package-b": "file:../packageB",
"package-a": "file:../packageA"
}
}
//// [index.ts]
import * as pkg from "package-b";

export const a = pkg.invoke();

//// [index.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.a = void 0;
var pkg = require("package-b");
exports.a = pkg.invoke();


//// [index.d.ts]
export declare const a: import("package-a").Foo;
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//// [tests/cases/compiler/symlinkedWorkspaceDependenciesNoDirectLinkGeneratesNonrelativeName.ts] ////

=== workspace/packageA/index.d.ts ===
export declare class Foo {
>Foo : Symbol(Foo, Decl(index.d.ts, 0, 0))

private f: any;
>f : Symbol(Foo.f, Decl(index.d.ts, 0, 26))
}
=== workspace/packageB/index.d.ts ===
import { Foo } from "package-a";
>Foo : Symbol(Foo, Decl(index.d.ts, 0, 8))

export declare function invoke(): Foo;
>invoke : Symbol(invoke, Decl(index.d.ts, 0, 32))
>Foo : Symbol(Foo, Decl(index.d.ts, 0, 8))

=== workspace/packageC/index.ts ===
import * as pkg from "package-b";
>pkg : Symbol(pkg, Decl(index.ts, 0, 6))

export const a = pkg.invoke();
>a : Symbol(a, Decl(index.ts, 2, 12))
>pkg.invoke : Symbol(pkg.invoke, Decl(index.d.ts, 0, 32))
>pkg : Symbol(pkg, Decl(index.ts, 0, 6))
>invoke : Symbol(pkg.invoke, Decl(index.d.ts, 0, 32))

Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//// [tests/cases/compiler/symlinkedWorkspaceDependenciesNoDirectLinkGeneratesNonrelativeName.ts] ////

=== workspace/packageA/index.d.ts ===
export declare class Foo {
>Foo : Foo
> : ^^^

private f: any;
>f : any
}
=== workspace/packageB/index.d.ts ===
import { Foo } from "package-a";
>Foo : typeof Foo
> : ^^^^^^^^^^

export declare function invoke(): Foo;
>invoke : () => Foo
> : ^^^^^^

=== workspace/packageC/index.ts ===
import * as pkg from "package-b";
>pkg : typeof pkg
> : ^^^^^^^^^^

export const a = pkg.invoke();
>a : import("workspace/packageA/index").Foo
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>pkg.invoke() : import("workspace/packageA/index").Foo
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>pkg.invoke : () => import("workspace/packageA/index").Foo
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>pkg : typeof pkg
> : ^^^^^^^^^^
>invoke : () => import("workspace/packageA/index").Foo
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Loading