mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-25 18:50:29 -06:00
Handle caching of module resolution depending on project references
This commit is contained in:
parent
0e4b10d726
commit
6923f2cdb0
@ -345,7 +345,7 @@ namespace ts {
|
||||
}
|
||||
let result: SearchResult<Resolved> | undefined;
|
||||
if (!isExternalModuleNameRelative(typeReferenceDirectiveName)) {
|
||||
result = loadModuleFromNearestNodeModulesDirectory(Extensions.DtsOnly, typeReferenceDirectiveName, initialLocationForSecondaryLookup, moduleResolutionState, /*cache*/ undefined);
|
||||
result = loadModuleFromNearestNodeModulesDirectory(Extensions.DtsOnly, typeReferenceDirectiveName, initialLocationForSecondaryLookup, moduleResolutionState, /*cache*/ undefined, /*redirectedReference*/ undefined);
|
||||
}
|
||||
else {
|
||||
const { path: candidate } = normalizePathAndParts(combinePaths(initialLocationForSecondaryLookup, typeReferenceDirectiveName));
|
||||
@ -415,7 +415,7 @@ namespace ts {
|
||||
* This assumes that any module id will have the same resolution for sibling files located in the same folder.
|
||||
*/
|
||||
export interface ModuleResolutionCache extends NonRelativeModuleNameResolutionCache {
|
||||
getOrCreateCacheForDirectory(directoryName: string): Map<ResolvedModuleWithFailedLookupLocations>;
|
||||
getOrCreateCacheForDirectory(directoryName: string, redirectedReference?: ResolvedProjectReference): Map<ResolvedModuleWithFailedLookupLocations>;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -423,7 +423,7 @@ namespace ts {
|
||||
* We support only non-relative module names because resolution of relative module names is usually more deterministic and thus less expensive.
|
||||
*/
|
||||
export interface NonRelativeModuleNameResolutionCache {
|
||||
getOrCreateCacheForModuleName(nonRelativeModuleName: string): PerModuleNameCache;
|
||||
getOrCreateCacheForModuleName(nonRelativeModuleName: string, redirectedReference?: ResolvedProjectReference): PerModuleNameCache;
|
||||
}
|
||||
|
||||
export interface PerModuleNameCache {
|
||||
@ -433,40 +433,78 @@ namespace ts {
|
||||
|
||||
export function createModuleResolutionCache(currentDirectory: string, getCanonicalFileName: (s: string) => string): ModuleResolutionCache {
|
||||
return createModuleResolutionCacheWithMaps(
|
||||
createMap<Map<ResolvedModuleWithFailedLookupLocations>>(),
|
||||
createMap<PerModuleNameCache>(),
|
||||
createCacheWithRedirects(),
|
||||
createCacheWithRedirects(),
|
||||
currentDirectory,
|
||||
getCanonicalFileName
|
||||
);
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export interface CacheWithRedirects<T> {
|
||||
ownMap: Map<T>;
|
||||
redirectsMap: Map<Map<T>>;
|
||||
getOrCreateMapOfCacheRedirects(redirectedReference: ResolvedProjectReference | undefined): Map<T>;
|
||||
clear(): void;
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export function createCacheWithRedirects<T>(): CacheWithRedirects<T> {
|
||||
const ownMap: Map<T> = createMap();
|
||||
const redirectsMap: Map<Map<T>> = createMap();
|
||||
return {
|
||||
ownMap,
|
||||
redirectsMap,
|
||||
getOrCreateMapOfCacheRedirects,
|
||||
clear
|
||||
};
|
||||
|
||||
function getOrCreateMapOfCacheRedirects(redirectedReference: ResolvedProjectReference | undefined) {
|
||||
if (!redirectedReference) {
|
||||
return ownMap;
|
||||
}
|
||||
const path = redirectedReference.sourceFile.path;
|
||||
let redirects = redirectsMap.get(path);
|
||||
if (!redirects) {
|
||||
redirects = createMap();
|
||||
redirectsMap.set(path, redirects);
|
||||
}
|
||||
return redirects;
|
||||
}
|
||||
|
||||
function clear() {
|
||||
ownMap.clear();
|
||||
redirectsMap.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export function createModuleResolutionCacheWithMaps(
|
||||
directoryToModuleNameMap: Map<Map<ResolvedModuleWithFailedLookupLocations>>,
|
||||
moduleNameToDirectoryMap: Map<PerModuleNameCache>,
|
||||
directoryToModuleNameMap: CacheWithRedirects<Map<ResolvedModuleWithFailedLookupLocations>>,
|
||||
moduleNameToDirectoryMap: CacheWithRedirects<PerModuleNameCache>,
|
||||
currentDirectory: string,
|
||||
getCanonicalFileName: GetCanonicalFileName): ModuleResolutionCache {
|
||||
|
||||
return { getOrCreateCacheForDirectory, getOrCreateCacheForModuleName };
|
||||
|
||||
function getOrCreateCacheForDirectory(directoryName: string) {
|
||||
function getOrCreateCacheForDirectory(directoryName: string, redirectedReference?: ResolvedProjectReference) {
|
||||
const path = toPath(directoryName, currentDirectory, getCanonicalFileName);
|
||||
let perFolderCache = directoryToModuleNameMap.get(path);
|
||||
if (!perFolderCache) {
|
||||
perFolderCache = createMap<ResolvedModuleWithFailedLookupLocations>();
|
||||
directoryToModuleNameMap.set(path, perFolderCache);
|
||||
}
|
||||
return perFolderCache;
|
||||
return getOrCreateCache<Map<ResolvedModuleWithFailedLookupLocations>>(directoryToModuleNameMap, redirectedReference, path, createMap);
|
||||
}
|
||||
|
||||
function getOrCreateCacheForModuleName(nonRelativeModuleName: string): PerModuleNameCache {
|
||||
function getOrCreateCacheForModuleName(nonRelativeModuleName: string, redirectedReference?: ResolvedProjectReference): PerModuleNameCache {
|
||||
Debug.assert(!isExternalModuleNameRelative(nonRelativeModuleName));
|
||||
let perModuleNameCache = moduleNameToDirectoryMap.get(nonRelativeModuleName);
|
||||
if (!perModuleNameCache) {
|
||||
perModuleNameCache = createPerModuleNameCache();
|
||||
moduleNameToDirectoryMap.set(nonRelativeModuleName, perModuleNameCache);
|
||||
return getOrCreateCache(moduleNameToDirectoryMap, redirectedReference, nonRelativeModuleName, createPerModuleNameCache);
|
||||
}
|
||||
|
||||
function getOrCreateCache<T>(cacheWithRedirects: CacheWithRedirects<T>, redirectedReference: ResolvedProjectReference | undefined, key: string, create: () => T): T {
|
||||
const cache = cacheWithRedirects.getOrCreateMapOfCacheRedirects(redirectedReference);
|
||||
let result = cache.get(key);
|
||||
if (!result) {
|
||||
result = create();
|
||||
cache.set(key, result);
|
||||
}
|
||||
return perModuleNameCache;
|
||||
return result;
|
||||
}
|
||||
|
||||
function createPerModuleNameCache(): PerModuleNameCache {
|
||||
@ -560,7 +598,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
const containingDirectory = getDirectoryPath(containingFile);
|
||||
const perFolderCache = cache && cache.getOrCreateCacheForDirectory(containingDirectory);
|
||||
const perFolderCache = cache && cache.getOrCreateCacheForDirectory(containingDirectory, redirectedReference);
|
||||
let result = perFolderCache && perFolderCache.get(moduleName);
|
||||
|
||||
if (result) {
|
||||
@ -584,10 +622,10 @@ namespace ts {
|
||||
|
||||
switch (moduleResolution) {
|
||||
case ModuleResolutionKind.NodeJs:
|
||||
result = nodeModuleNameResolver(moduleName, containingFile, compilerOptions, host, cache);
|
||||
result = nodeModuleNameResolver(moduleName, containingFile, compilerOptions, host, cache, redirectedReference);
|
||||
break;
|
||||
case ModuleResolutionKind.Classic:
|
||||
result = classicNameResolver(moduleName, containingFile, compilerOptions, host, cache);
|
||||
result = classicNameResolver(moduleName, containingFile, compilerOptions, host, cache, redirectedReference);
|
||||
break;
|
||||
default:
|
||||
return Debug.fail(`Unexpected moduleResolution: ${moduleResolution}`);
|
||||
@ -597,7 +635,7 @@ namespace ts {
|
||||
perFolderCache.set(moduleName, result);
|
||||
if (!isExternalModuleNameRelative(moduleName)) {
|
||||
// put result in per-module name cache
|
||||
cache!.getOrCreateCacheForModuleName(moduleName).set(containingDirectory, result);
|
||||
cache!.getOrCreateCacheForModuleName(moduleName, redirectedReference).set(containingDirectory, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -817,14 +855,14 @@ namespace ts {
|
||||
}
|
||||
|
||||
function tryResolveJSModuleWorker(moduleName: string, initialDir: string, host: ModuleResolutionHost): ResolvedModuleWithFailedLookupLocations {
|
||||
return nodeModuleNameResolverWorker(moduleName, initialDir, { moduleResolution: ModuleResolutionKind.NodeJs, allowJs: true }, host, /*cache*/ undefined, /*jsOnly*/ true);
|
||||
return nodeModuleNameResolverWorker(moduleName, initialDir, { moduleResolution: ModuleResolutionKind.NodeJs, allowJs: true }, host, /*cache*/ undefined, /*redirectedReference*/ undefined, /*jsOnly*/ true);
|
||||
}
|
||||
|
||||
export function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache): ResolvedModuleWithFailedLookupLocations {
|
||||
return nodeModuleNameResolverWorker(moduleName, getDirectoryPath(containingFile), compilerOptions, host, cache, /*jsOnly*/ false);
|
||||
export function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference): ResolvedModuleWithFailedLookupLocations {
|
||||
return nodeModuleNameResolverWorker(moduleName, getDirectoryPath(containingFile), compilerOptions, host, cache, redirectedReference, /*jsOnly*/ false);
|
||||
}
|
||||
|
||||
function nodeModuleNameResolverWorker(moduleName: string, containingDirectory: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache: ModuleResolutionCache | undefined, jsOnly: boolean): ResolvedModuleWithFailedLookupLocations {
|
||||
function nodeModuleNameResolverWorker(moduleName: string, containingDirectory: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache: ModuleResolutionCache | undefined, redirectedReference: ResolvedProjectReference | undefined, jsOnly: boolean): ResolvedModuleWithFailedLookupLocations {
|
||||
const traceEnabled = isTraceEnabled(compilerOptions, host);
|
||||
|
||||
const failedLookupLocations: string[] = [];
|
||||
@ -852,7 +890,7 @@ namespace ts {
|
||||
if (traceEnabled) {
|
||||
trace(host, Diagnostics.Loading_module_0_from_node_modules_folder_target_file_type_1, moduleName, Extensions[extensions]);
|
||||
}
|
||||
const resolved = loadModuleFromNearestNodeModulesDirectory(extensions, moduleName, containingDirectory, state, cache);
|
||||
const resolved = loadModuleFromNearestNodeModulesDirectory(extensions, moduleName, containingDirectory, state, cache, redirectedReference);
|
||||
if (!resolved) return undefined;
|
||||
|
||||
let resolvedValue = resolved.value;
|
||||
@ -1190,17 +1228,17 @@ namespace ts {
|
||||
return idx === -1 ? { packageName: moduleName, rest: "" } : { packageName: moduleName.slice(0, idx), rest: moduleName.slice(idx + 1) };
|
||||
}
|
||||
|
||||
function loadModuleFromNearestNodeModulesDirectory(extensions: Extensions, moduleName: string, directory: string, state: ModuleResolutionState, cache: NonRelativeModuleNameResolutionCache | undefined): SearchResult<Resolved> {
|
||||
return loadModuleFromNearestNodeModulesDirectoryWorker(extensions, moduleName, directory, state, /*typesScopeOnly*/ false, cache);
|
||||
function loadModuleFromNearestNodeModulesDirectory(extensions: Extensions, moduleName: string, directory: string, state: ModuleResolutionState, cache: NonRelativeModuleNameResolutionCache | undefined, redirectedReference: ResolvedProjectReference | undefined): SearchResult<Resolved> {
|
||||
return loadModuleFromNearestNodeModulesDirectoryWorker(extensions, moduleName, directory, state, /*typesScopeOnly*/ false, cache, redirectedReference);
|
||||
}
|
||||
|
||||
function loadModuleFromNearestNodeModulesDirectoryTypesScope(moduleName: string, directory: string, state: ModuleResolutionState): SearchResult<Resolved> {
|
||||
// Extensions parameter here doesn't actually matter, because typesOnly ensures we're just doing @types lookup, which is always DtsOnly.
|
||||
return loadModuleFromNearestNodeModulesDirectoryWorker(Extensions.DtsOnly, moduleName, directory, state, /*typesScopeOnly*/ true, /*cache*/ undefined);
|
||||
return loadModuleFromNearestNodeModulesDirectoryWorker(Extensions.DtsOnly, moduleName, directory, state, /*typesScopeOnly*/ true, /*cache*/ undefined, /*redirectedReference*/ undefined);
|
||||
}
|
||||
|
||||
function loadModuleFromNearestNodeModulesDirectoryWorker(extensions: Extensions, moduleName: string, directory: string, state: ModuleResolutionState, typesScopeOnly: boolean, cache: NonRelativeModuleNameResolutionCache | undefined): SearchResult<Resolved> {
|
||||
const perModuleNameCache = cache && cache.getOrCreateCacheForModuleName(moduleName);
|
||||
function loadModuleFromNearestNodeModulesDirectoryWorker(extensions: Extensions, moduleName: string, directory: string, state: ModuleResolutionState, typesScopeOnly: boolean, cache: NonRelativeModuleNameResolutionCache | undefined, redirectedReference: ResolvedProjectReference | undefined): SearchResult<Resolved> {
|
||||
const perModuleNameCache = cache && cache.getOrCreateCacheForModuleName(moduleName, redirectedReference);
|
||||
return forEachAncestorDirectory(normalizeSlashes(directory), ancestorDirectory => {
|
||||
if (getBaseFileName(ancestorDirectory) !== "node_modules") {
|
||||
const resolutionFromCache = tryFindNonRelativeModuleNameInCache(perModuleNameCache, moduleName, ancestorDirectory, state);
|
||||
@ -1368,7 +1406,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
export function classicNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: NonRelativeModuleNameResolutionCache): ResolvedModuleWithFailedLookupLocations {
|
||||
export function classicNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: NonRelativeModuleNameResolutionCache, redirectedReference?: ResolvedProjectReference): ResolvedModuleWithFailedLookupLocations {
|
||||
const traceEnabled = isTraceEnabled(compilerOptions, host);
|
||||
const failedLookupLocations: string[] = [];
|
||||
const state: ModuleResolutionState = { compilerOptions, host, traceEnabled, failedLookupLocations };
|
||||
@ -1385,7 +1423,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (!isExternalModuleNameRelative(moduleName)) {
|
||||
const perModuleNameCache = cache && cache.getOrCreateCacheForModuleName(moduleName);
|
||||
const perModuleNameCache = cache && cache.getOrCreateCacheForModuleName(moduleName, redirectedReference);
|
||||
// Climb up parent directories looking for a module.
|
||||
const resolved = forEachAncestorDirectory(containingDirectory, directory => {
|
||||
const resolutionFromCache = tryFindNonRelativeModuleNameInCache(perModuleNameCache, moduleName, directory, state);
|
||||
|
||||
@ -90,17 +90,17 @@ namespace ts {
|
||||
// The key in the map is source file's path.
|
||||
// The values are Map of resolutions with key being name lookedup.
|
||||
const resolvedModuleNames = createMap<Map<CachedResolvedModuleWithFailedLookupLocations>>();
|
||||
const perDirectoryResolvedModuleNames = createMap<Map<CachedResolvedModuleWithFailedLookupLocations>>();
|
||||
const nonRelaticeModuleNameCache = createMap<PerModuleNameCache>();
|
||||
const perDirectoryResolvedModuleNames: CacheWithRedirects<Map<CachedResolvedModuleWithFailedLookupLocations>> = createCacheWithRedirects();
|
||||
const nonRelativeModuleNameCache: CacheWithRedirects<PerModuleNameCache> = createCacheWithRedirects();
|
||||
const moduleResolutionCache = createModuleResolutionCacheWithMaps(
|
||||
perDirectoryResolvedModuleNames,
|
||||
nonRelaticeModuleNameCache,
|
||||
nonRelativeModuleNameCache,
|
||||
getCurrentDirectory(),
|
||||
resolutionHost.getCanonicalFileName
|
||||
);
|
||||
|
||||
const resolvedTypeReferenceDirectives = createMap<Map<CachedResolvedTypeReferenceDirectiveWithFailedLookupLocations>>();
|
||||
const perDirectoryResolvedTypeReferenceDirectives = createMap<Map<CachedResolvedTypeReferenceDirectiveWithFailedLookupLocations>>();
|
||||
const perDirectoryResolvedTypeReferenceDirectives: CacheWithRedirects<Map<CachedResolvedTypeReferenceDirectiveWithFailedLookupLocations>> = createCacheWithRedirects();
|
||||
|
||||
/**
|
||||
* These are the extensions that failed lookup files will have by default,
|
||||
@ -199,7 +199,7 @@ namespace ts {
|
||||
|
||||
function clearPerDirectoryResolutions() {
|
||||
perDirectoryResolvedModuleNames.clear();
|
||||
nonRelaticeModuleNameCache.clear();
|
||||
nonRelativeModuleNameCache.clear();
|
||||
perDirectoryResolvedTypeReferenceDirectives.clear();
|
||||
nonRelativeExternalModuleResolutions.forEach(watchFailedLookupLocationOfNonRelativeModuleResolutions);
|
||||
nonRelativeExternalModuleResolutions.clear();
|
||||
@ -244,7 +244,7 @@ namespace ts {
|
||||
containingFile: string,
|
||||
redirectedReference: ResolvedProjectReference | undefined,
|
||||
cache: Map<Map<T>>,
|
||||
perDirectoryCache: Map<Map<T>>,
|
||||
perDirectoryCacheWithRedirects: CacheWithRedirects<Map<T>>,
|
||||
loader: (name: string, containingFile: string, options: CompilerOptions, host: ModuleResolutionHost, redirectedReference?: ResolvedProjectReference) => T,
|
||||
getResolutionWithResolvedFileName: GetResolutionWithResolvedFileName<T, R>,
|
||||
reusedNames: string[] | undefined,
|
||||
@ -253,6 +253,7 @@ namespace ts {
|
||||
const path = resolutionHost.toPath(containingFile);
|
||||
const resolutionsInFile = cache.get(path) || cache.set(path, createMap()).get(path)!;
|
||||
const dirPath = getDirectoryPath(path);
|
||||
const perDirectoryCache = perDirectoryCacheWithRedirects.getOrCreateMapOfCacheRedirects(redirectedReference);
|
||||
let perDirectoryResolution = perDirectoryCache.get(dirPath);
|
||||
if (!perDirectoryResolution) {
|
||||
perDirectoryResolution = createMap();
|
||||
|
||||
@ -392,6 +392,7 @@ export class cNew {}`);
|
||||
...getLibs(),
|
||||
"/src/a.d.ts",
|
||||
"/src/b.d.ts",
|
||||
"/src/refs/a.d.ts",
|
||||
"/src/c.ts"
|
||||
]);
|
||||
});
|
||||
|
||||
@ -26,8 +26,23 @@ namespace ts.tscWatch {
|
||||
type SubProjectFiles = [ReadonlyFile, ReadonlyFile] | [ReadonlyFile, ReadonlyFile, ReadonlyFile, ReadonlyFile];
|
||||
const root = Harness.IO.getWorkspaceRoot();
|
||||
|
||||
function getProjectPath(project: string) {
|
||||
return `${projectsLocation}/${project}`;
|
||||
}
|
||||
|
||||
function getFilePathInProject(project: string, file: string) {
|
||||
return `${projectsLocation}/${project}/${file}`;
|
||||
}
|
||||
|
||||
function getFileFromProject(project: string, file: string): File {
|
||||
return {
|
||||
path: getFilePathInProject(project, file),
|
||||
content: Harness.IO.readFile(`${root}/tests/projects/${project}/${file}`)!
|
||||
};
|
||||
}
|
||||
|
||||
function projectPath(subProject: SubProject) {
|
||||
return `${projectsLocation}/${project}/${subProject}`;
|
||||
return getFilePathInProject(project, subProject);
|
||||
}
|
||||
|
||||
function projectFilePath(subProject: SubProject, baseFileName: string) {
|
||||
@ -39,10 +54,7 @@ namespace ts.tscWatch {
|
||||
}
|
||||
|
||||
function projectFile(subProject: SubProject, baseFileName: string): File {
|
||||
return {
|
||||
path: projectFilePath(subProject, baseFileName),
|
||||
content: Harness.IO.readFile(`${root}/tests/projects/${project}/${subProject}/${baseFileName}`)!
|
||||
};
|
||||
return getFileFromProject(project, `${subProject}/${baseFileName}`);
|
||||
}
|
||||
|
||||
function subProjectFiles(subProject: SubProject, anotherModuleAndSomeDecl?: true): SubProjectFiles {
|
||||
@ -97,7 +109,7 @@ namespace ts.tscWatch {
|
||||
const tests = subProjectFiles(SubProject.tests);
|
||||
const ui = subProjectFiles(SubProject.ui);
|
||||
const allFiles: ReadonlyArray<File> = [libFile, ...core, ...logic, ...tests, ...ui];
|
||||
const testProjectExpectedWatchedFiles = [core[0], core[1], core[2], ...logic, ...tests].map(f => f.path);
|
||||
const testProjectExpectedWatchedFiles = [core[0], core[1], core[2], ...logic, ...tests].map(f => f.path.toLowerCase());
|
||||
const testProjectExpectedWatchedDirectoriesRecursive = [projectPath(SubProject.core), projectPath(SubProject.logic)];
|
||||
|
||||
function createSolutionInWatchMode(allFiles: ReadonlyArray<File>, defaultOptions?: BuildOptions, disableConsoleClears?: boolean) {
|
||||
@ -244,7 +256,7 @@ export class someClass2 { }`);
|
||||
const allFiles = [libFile, ...core, logic[1], ...tests];
|
||||
const host = createWatchedSystem(allFiles, { currentDirectory: projectsLocation });
|
||||
createSolutionBuilderWithWatch(host, [`${project}/${SubProject.tests}`]);
|
||||
checkWatchedFiles(host, [core[0], core[1], core[2], logic[0], ...tests].map(f => f.path));
|
||||
checkWatchedFiles(host, [core[0], core[1], core[2], logic[0], ...tests].map(f => f.path.toLowerCase()));
|
||||
checkWatchedDirectories(host, emptyArray, /*recursive*/ false);
|
||||
checkWatchedDirectories(host, [projectPath(SubProject.core)], /*recursive*/ true);
|
||||
checkOutputErrorsInitial(host, [
|
||||
@ -395,99 +407,161 @@ let x: string = 10;`);
|
||||
});
|
||||
|
||||
describe("tsc-watch works with project references", () => {
|
||||
const coreIndexDts = projectFileName(SubProject.core, "index.d.ts");
|
||||
const coreAnotherModuleDts = projectFileName(SubProject.core, "anotherModule.d.ts");
|
||||
const logicIndexDts = projectFileName(SubProject.logic, "index.d.ts");
|
||||
const expectedWatchedFiles = [core[0], logic[0], ...tests, libFile].map(f => f.path).concat([coreIndexDts, coreAnotherModuleDts, logicIndexDts].map(f => f.toLowerCase()));
|
||||
const expectedWatchedDirectoriesRecursive = projectSystem.getTypeRootsFromLocation(projectPath(SubProject.tests));
|
||||
|
||||
function createSolution() {
|
||||
const host = createWatchedSystem(allFiles, { currentDirectory: projectsLocation });
|
||||
const solutionBuilder = createSolutionBuilder(host, [`${project}/${SubProject.tests}`], {});
|
||||
return { host, solutionBuilder };
|
||||
}
|
||||
|
||||
function createBuiltSolution() {
|
||||
const result = createSolution();
|
||||
const { host, solutionBuilder } = result;
|
||||
solutionBuilder.buildAllProjects();
|
||||
const outputFileStamps = getOutputFileStamps(host);
|
||||
for (const stamp of outputFileStamps) {
|
||||
assert.isDefined(stamp[1], `${stamp[0]} expected to be present`);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function verifyWatches(host: WatchedSystem) {
|
||||
checkWatchedFilesDetailed(host, expectedWatchedFiles, 1);
|
||||
checkWatchedDirectories(host, emptyArray, /*recursive*/ false);
|
||||
checkWatchedDirectoriesDetailed(host, expectedWatchedDirectoriesRecursive, 1, /*recursive*/ true);
|
||||
}
|
||||
|
||||
function createSolutionAndWatchMode() {
|
||||
// Build the composite project
|
||||
const { host, solutionBuilder } = createBuiltSolution();
|
||||
|
||||
// Build in watch mode
|
||||
const watch = createWatchOfConfigFileReturningBuilder(tests[0].path, host);
|
||||
checkOutputErrorsInitial(host, emptyArray);
|
||||
|
||||
return { host, solutionBuilder, watch };
|
||||
}
|
||||
|
||||
function verifyDependencies(watch: () => BuilderProgram, filePath: string, expected: ReadonlyArray<string>) {
|
||||
checkArray(`${filePath} dependencies`, watch().getAllDependencies(watch().getSourceFile(filePath)!), expected);
|
||||
}
|
||||
|
||||
describe("invoking when references are already built", () => {
|
||||
it("verifies dependencies and watches", () => {
|
||||
const { host, watch } = createSolutionAndWatchMode();
|
||||
function verifyWatchesOfProject(host: WatchedSystem, expectedWatchedFiles: ReadonlyArray<string>, expectedWatchedDirectoriesRecursive: ReadonlyArray<string>) {
|
||||
checkWatchedFilesDetailed(host, expectedWatchedFiles, 1);
|
||||
checkWatchedDirectories(host, emptyArray, /*recursive*/ false);
|
||||
checkWatchedDirectoriesDetailed(host, expectedWatchedDirectoriesRecursive, 1, /*recursive*/ true);
|
||||
}
|
||||
|
||||
verifyWatches(host);
|
||||
verifyDependencies(watch, coreIndexDts, [coreIndexDts]);
|
||||
verifyDependencies(watch, coreAnotherModuleDts, [coreAnotherModuleDts]);
|
||||
verifyDependencies(watch, logicIndexDts, [logicIndexDts, coreAnotherModuleDts]);
|
||||
verifyDependencies(watch, tests[1].path, [tests[1].path, coreAnotherModuleDts, logicIndexDts, coreAnotherModuleDts]);
|
||||
});
|
||||
function createSolutionAndWatchModeOfProject(
|
||||
allFiles: ReadonlyArray<File>,
|
||||
currentDirectory: string,
|
||||
solutionBuilderconfig: string,
|
||||
watchConfig: string,
|
||||
getOutputFileStamps: (host: WatchedSystem) => ReadonlyArray<OutputFileStamp>) {
|
||||
// Build the composite project
|
||||
const host = createWatchedSystem(allFiles, { currentDirectory });
|
||||
const solutionBuilder = createSolutionBuilder(host, [solutionBuilderconfig], {});
|
||||
solutionBuilder.buildAllProjects();
|
||||
const outputFileStamps = getOutputFileStamps(host);
|
||||
for (const stamp of outputFileStamps) {
|
||||
assert.isDefined(stamp[1], `${stamp[0]} expected to be present`);
|
||||
}
|
||||
|
||||
it("local edit in ts file, result in watch compilation because logic.d.ts is written", () => {
|
||||
const { host, solutionBuilder, watch } = createSolutionAndWatchMode();
|
||||
host.writeFile(logic[1].path, `${logic[1].content}
|
||||
// Build in watch mode
|
||||
const watch = createWatchOfConfigFileReturningBuilder(watchConfig, host);
|
||||
checkOutputErrorsInitial(host, emptyArray);
|
||||
|
||||
return { host, solutionBuilder, watch };
|
||||
}
|
||||
|
||||
function verifyDependencies(watch: () => BuilderProgram, filePath: string, expected: ReadonlyArray<string>) {
|
||||
checkArray(`${filePath} dependencies`, watch().getAllDependencies(watch().getSourceFile(filePath)!), expected);
|
||||
}
|
||||
|
||||
describe("on sample project", () => {
|
||||
const coreIndexDts = projectFileName(SubProject.core, "index.d.ts");
|
||||
const coreAnotherModuleDts = projectFileName(SubProject.core, "anotherModule.d.ts");
|
||||
const logicIndexDts = projectFileName(SubProject.logic, "index.d.ts");
|
||||
const expectedWatchedFiles = [core[0], logic[0], ...tests, libFile].map(f => f.path).concat([coreIndexDts, coreAnotherModuleDts, logicIndexDts].map(f => f.toLowerCase()));
|
||||
const expectedWatchedDirectoriesRecursive = projectSystem.getTypeRootsFromLocation(projectPath(SubProject.tests));
|
||||
|
||||
function createSolutionAndWatchMode() {
|
||||
return createSolutionAndWatchModeOfProject(allFiles, projectsLocation, `${project}/${SubProject.tests}`, tests[0].path, getOutputFileStamps);
|
||||
}
|
||||
|
||||
function verifyWatches(host: WatchedSystem) {
|
||||
verifyWatchesOfProject(host, expectedWatchedFiles, expectedWatchedDirectoriesRecursive);
|
||||
}
|
||||
|
||||
it("verifies dependencies and watches", () => {
|
||||
const { host, watch } = createSolutionAndWatchMode();
|
||||
|
||||
verifyWatches(host);
|
||||
verifyDependencies(watch, coreIndexDts, [coreIndexDts]);
|
||||
verifyDependencies(watch, coreAnotherModuleDts, [coreAnotherModuleDts]);
|
||||
verifyDependencies(watch, logicIndexDts, [logicIndexDts, coreAnotherModuleDts]);
|
||||
verifyDependencies(watch, tests[1].path, [tests[1].path, coreAnotherModuleDts, logicIndexDts, coreAnotherModuleDts]);
|
||||
});
|
||||
|
||||
it("local edit in ts file, result in watch compilation because logic.d.ts is written", () => {
|
||||
const { host, solutionBuilder, watch } = createSolutionAndWatchMode();
|
||||
host.writeFile(logic[1].path, `${logic[1].content}
|
||||
function foo() {
|
||||
}`);
|
||||
solutionBuilder.invalidateProject(`${project}/${SubProject.logic}`);
|
||||
solutionBuilder.buildInvalidatedProject();
|
||||
solutionBuilder.invalidateProject(`${project}/${SubProject.logic}`);
|
||||
solutionBuilder.buildInvalidatedProject();
|
||||
|
||||
host.checkTimeoutQueueLengthAndRun(1); // not ideal, but currently because of d.ts but no new file is written
|
||||
checkOutputErrorsIncremental(host, emptyArray);
|
||||
checkProgramActualFiles(watch().getProgram(), [tests[1].path, libFile.path, coreIndexDts, coreAnotherModuleDts, logicIndexDts]);
|
||||
});
|
||||
host.checkTimeoutQueueLengthAndRun(1); // not ideal, but currently because of d.ts but no new file is written
|
||||
checkOutputErrorsIncremental(host, emptyArray);
|
||||
checkProgramActualFiles(watch().getProgram(), [tests[1].path, libFile.path, coreIndexDts, coreAnotherModuleDts, logicIndexDts]);
|
||||
});
|
||||
|
||||
it("non local edit in ts file, rebuilds in watch compilation", () => {
|
||||
const { host, solutionBuilder, watch } = createSolutionAndWatchMode();
|
||||
host.writeFile(logic[1].path, `${logic[1].content}
|
||||
it("non local edit in ts file, rebuilds in watch compilation", () => {
|
||||
const { host, solutionBuilder, watch } = createSolutionAndWatchMode();
|
||||
host.writeFile(logic[1].path, `${logic[1].content}
|
||||
export function gfoo() {
|
||||
}`);
|
||||
solutionBuilder.invalidateProject(logic[0].path);
|
||||
solutionBuilder.buildInvalidatedProject();
|
||||
solutionBuilder.invalidateProject(logic[0].path);
|
||||
solutionBuilder.buildInvalidatedProject();
|
||||
|
||||
host.checkTimeoutQueueLengthAndRun(1);
|
||||
checkOutputErrorsIncremental(host, emptyArray);
|
||||
checkProgramActualFiles(watch().getProgram(), [tests[1].path, libFile.path, coreIndexDts, coreAnotherModuleDts, logicIndexDts]);
|
||||
host.checkTimeoutQueueLengthAndRun(1);
|
||||
checkOutputErrorsIncremental(host, emptyArray);
|
||||
checkProgramActualFiles(watch().getProgram(), [tests[1].path, libFile.path, coreIndexDts, coreAnotherModuleDts, logicIndexDts]);
|
||||
});
|
||||
|
||||
it("change in project reference config file builds correctly", () => {
|
||||
const { host, solutionBuilder, watch } = createSolutionAndWatchMode();
|
||||
host.writeFile(logic[0].path, JSON.stringify({
|
||||
compilerOptions: { composite: true, declaration: true, declarationDir: "decls" },
|
||||
references: [{ path: "../core" }]
|
||||
}));
|
||||
solutionBuilder.invalidateProject(logic[0].path, ConfigFileProgramReloadLevel.Full);
|
||||
solutionBuilder.buildInvalidatedProject();
|
||||
|
||||
host.checkTimeoutQueueLengthAndRun(1);
|
||||
checkOutputErrorsIncremental(host, emptyArray);
|
||||
checkProgramActualFiles(watch().getProgram(), [tests[1].path, libFile.path, coreIndexDts, coreAnotherModuleDts, projectFilePath(SubProject.logic, "decls/index.d.ts")]);
|
||||
});
|
||||
});
|
||||
|
||||
it("change in project reference config file builds correctly", () => {
|
||||
const { host, solutionBuilder, watch } = createSolutionAndWatchMode();
|
||||
host.writeFile(logic[0].path, JSON.stringify({
|
||||
compilerOptions: { composite: true, declaration: true, declarationDir: "decls" },
|
||||
references: [{ path: "../core" }]
|
||||
}));
|
||||
solutionBuilder.invalidateProject(logic[0].path, ConfigFileProgramReloadLevel.Full);
|
||||
solutionBuilder.buildInvalidatedProject();
|
||||
describe("on transitive references", () => {
|
||||
const project = "transitiveReferences";
|
||||
const aTs = getFileFromProject(project, "a.ts");
|
||||
const bTs = getFileFromProject(project, "b.ts");
|
||||
const cTs = getFileFromProject(project, "c.ts");
|
||||
|
||||
host.checkTimeoutQueueLengthAndRun(1);
|
||||
checkOutputErrorsIncremental(host, emptyArray);
|
||||
checkProgramActualFiles(watch().getProgram(), [tests[1].path, libFile.path, coreIndexDts, coreAnotherModuleDts, projectFilePath(SubProject.logic, "decls/index.d.ts")]);
|
||||
const configToBuild = "tsconfig.c.json";
|
||||
const aTsconfig = getFileFromProject(project, "tsconfig.a.json");
|
||||
const bTsconfig = getFileFromProject(project, "tsconfig.b.json");
|
||||
const cTsconfig = getFileFromProject(project, configToBuild);
|
||||
const refs = getFileFromProject(project, "refs/a.d.ts");
|
||||
const allFiles = [libFile, aTs, bTs, cTs, aTsconfig, bTsconfig, cTsconfig, refs];
|
||||
const aDts = dtsFile("a"), bDts = dtsFile("b");
|
||||
const expectedFiles = [jsFile("a"), aDts, jsFile("b"), bDts, jsFile("c")];
|
||||
const expectedProgramFiles = [cTs.path, libFile.path, aDts, refs.path, bDts];
|
||||
const expectedWatchedFiles = expectedProgramFiles.concat(cTsconfig.path, bTsconfig.path, aTsconfig.path).map(s => s.toLowerCase());
|
||||
const expectedWatchedDirectoriesRecursive = [
|
||||
getFilePathInProject(project, "refs").toLowerCase(), // Failed lookup since refs/a.ts does not exist
|
||||
...projectSystem.getTypeRootsFromLocation(getProjectPath(project).toLowerCase())];
|
||||
|
||||
function jsFile(extensionLessFile: string) {
|
||||
return getFilePathInProject(project, `${extensionLessFile}.js`);
|
||||
}
|
||||
|
||||
function dtsFile(extensionLessFile: string) {
|
||||
return getFilePathInProject(project, `${extensionLessFile}.d.ts`);
|
||||
}
|
||||
|
||||
function createSolutionAndWatchMode() {
|
||||
return createSolutionAndWatchModeOfProject(allFiles, getProjectPath(project), configToBuild, configToBuild, getOutputFileStamps);
|
||||
}
|
||||
|
||||
function getOutputFileStamps(host: WatchedSystem) {
|
||||
return expectedFiles.map(file => [file, host.getModifiedTime(file)] as OutputFileStamp);
|
||||
}
|
||||
|
||||
function verifyWatches(host: WatchedSystem) {
|
||||
verifyWatchesOfProject(host, expectedWatchedFiles, expectedWatchedDirectoriesRecursive);
|
||||
}
|
||||
|
||||
function verifyProgram(host: WatchedSystem, watch: () => BuilderProgram) {
|
||||
verifyWatches(host);
|
||||
|
||||
verifyDependencies(watch, aDts, [aDts]);
|
||||
verifyDependencies(watch, refs.path, [refs.path]);
|
||||
verifyDependencies(watch, bDts, [bDts, aDts]);
|
||||
verifyDependencies(watch, cTs.path, [cTs.path, refs.path, bDts]);
|
||||
|
||||
checkProgramActualFiles(watch().getProgram(), expectedProgramFiles);
|
||||
}
|
||||
|
||||
it("verifies dependencies and watches", () => {
|
||||
// Initial build
|
||||
const { host, watch } = createSolutionAndWatchMode();
|
||||
verifyProgram(host, watch);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -2688,11 +2688,11 @@ declare namespace ts {
|
||||
useCaseSensitiveFileNames(): boolean;
|
||||
getNewLine(): string;
|
||||
readDirectory?(rootDir: string, extensions: ReadonlyArray<string>, excludes: ReadonlyArray<string> | undefined, includes: ReadonlyArray<string>, depth?: number): string[];
|
||||
resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[]): (ResolvedModule | undefined)[];
|
||||
resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[], redirectedReference?: ResolvedProjectReference): (ResolvedModule | undefined)[];
|
||||
/**
|
||||
* This method is a companion for 'resolveModuleNames' and is used to resolve 'types' references to actual type declaration files
|
||||
*/
|
||||
resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[];
|
||||
resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string, redirectedReference?: ResolvedProjectReference): ResolvedTypeReferenceDirective[];
|
||||
getEnvironmentVariable?(name: string): string | undefined;
|
||||
createHash?(data: string): string;
|
||||
}
|
||||
@ -3606,7 +3606,7 @@ declare namespace ts {
|
||||
* This is possible in case if resolution is performed for directives specified via 'types' parameter. In this case initial path for secondary lookups
|
||||
* is assumed to be the same as root directory of the project.
|
||||
*/
|
||||
function resolveTypeReferenceDirective(typeReferenceDirectiveName: string, containingFile: string | undefined, options: CompilerOptions, host: ModuleResolutionHost): ResolvedTypeReferenceDirectiveWithFailedLookupLocations;
|
||||
function resolveTypeReferenceDirective(typeReferenceDirectiveName: string, containingFile: string | undefined, options: CompilerOptions, host: ModuleResolutionHost, redirectedReference?: ResolvedProjectReference): ResolvedTypeReferenceDirectiveWithFailedLookupLocations;
|
||||
/**
|
||||
* Given a set of options, returns the set of type directive names
|
||||
* that should be included for this program automatically.
|
||||
@ -3621,14 +3621,14 @@ declare namespace ts {
|
||||
* This assumes that any module id will have the same resolution for sibling files located in the same folder.
|
||||
*/
|
||||
interface ModuleResolutionCache extends NonRelativeModuleNameResolutionCache {
|
||||
getOrCreateCacheForDirectory(directoryName: string): Map<ResolvedModuleWithFailedLookupLocations>;
|
||||
getOrCreateCacheForDirectory(directoryName: string, redirectedReference?: ResolvedProjectReference): Map<ResolvedModuleWithFailedLookupLocations>;
|
||||
}
|
||||
/**
|
||||
* Stored map from non-relative module name to a table: directory -> result of module lookup in this directory
|
||||
* We support only non-relative module names because resolution of relative module names is usually more deterministic and thus less expensive.
|
||||
*/
|
||||
interface NonRelativeModuleNameResolutionCache {
|
||||
getOrCreateCacheForModuleName(nonRelativeModuleName: string): PerModuleNameCache;
|
||||
getOrCreateCacheForModuleName(nonRelativeModuleName: string, redirectedReference?: ResolvedProjectReference): PerModuleNameCache;
|
||||
}
|
||||
interface PerModuleNameCache {
|
||||
get(directory: string): ResolvedModuleWithFailedLookupLocations | undefined;
|
||||
@ -3636,9 +3636,9 @@ declare namespace ts {
|
||||
}
|
||||
function createModuleResolutionCache(currentDirectory: string, getCanonicalFileName: (s: string) => string): ModuleResolutionCache;
|
||||
function resolveModuleNameFromCache(moduleName: string, containingFile: string, cache: ModuleResolutionCache): ResolvedModuleWithFailedLookupLocations | undefined;
|
||||
function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache): ResolvedModuleWithFailedLookupLocations;
|
||||
function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache): ResolvedModuleWithFailedLookupLocations;
|
||||
function classicNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: NonRelativeModuleNameResolutionCache): ResolvedModuleWithFailedLookupLocations;
|
||||
function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference): ResolvedModuleWithFailedLookupLocations;
|
||||
function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference): ResolvedModuleWithFailedLookupLocations;
|
||||
function classicNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: NonRelativeModuleNameResolutionCache, redirectedReference?: ResolvedProjectReference): ResolvedModuleWithFailedLookupLocations;
|
||||
}
|
||||
declare namespace ts {
|
||||
function createNodeArray<T extends Node>(elements?: ReadonlyArray<T>, hasTrailingComma?: boolean): NodeArray<T>;
|
||||
@ -4384,9 +4384,9 @@ declare namespace ts {
|
||||
/** If provided is used to get the environment variable */
|
||||
getEnvironmentVariable?(name: string): string | undefined;
|
||||
/** If provided, used to resolve the module names, otherwise typescript's default module resolution */
|
||||
resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[]): ResolvedModule[];
|
||||
resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[], redirectedReference?: ResolvedProjectReference): ResolvedModule[];
|
||||
/** If provided, used to resolve type reference directives, otherwise typescript's default resolution */
|
||||
resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[];
|
||||
resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string, redirectedReference?: ResolvedProjectReference): ResolvedTypeReferenceDirective[];
|
||||
}
|
||||
/**
|
||||
* Host to create watch with root files and options
|
||||
@ -4654,9 +4654,9 @@ declare namespace ts {
|
||||
realpath?(path: string): string;
|
||||
fileExists?(path: string): boolean;
|
||||
getTypeRootsVersion?(): number;
|
||||
resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[]): ResolvedModule[];
|
||||
resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[], redirectedReference?: ResolvedProjectReference): ResolvedModule[];
|
||||
getResolvedModuleWithFailedLookupLocationsFromCache?(modulename: string, containingFile: string): ResolvedModuleWithFailedLookupLocations | undefined;
|
||||
resolveTypeReferenceDirectives?(typeDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[];
|
||||
resolveTypeReferenceDirectives?(typeDirectiveNames: string[], containingFile: string, redirectedReference?: ResolvedProjectReference): ResolvedTypeReferenceDirective[];
|
||||
getDirectories?(directoryName: string): string[];
|
||||
/**
|
||||
* Gets a set of custom transformers to use during emit.
|
||||
@ -8129,9 +8129,9 @@ declare namespace ts.server {
|
||||
readFile(fileName: string): string | undefined;
|
||||
writeFile(fileName: string, content: string): void;
|
||||
fileExists(file: string): boolean;
|
||||
resolveModuleNames(moduleNames: string[], containingFile: string, reusedNames?: string[]): ResolvedModuleFull[];
|
||||
resolveModuleNames(moduleNames: string[], containingFile: string, reusedNames?: string[], redirectedReference?: ResolvedProjectReference): ResolvedModuleFull[];
|
||||
getResolvedModuleWithFailedLookupLocationsFromCache(moduleName: string, containingFile: string): ResolvedModuleWithFailedLookupLocations | undefined;
|
||||
resolveTypeReferenceDirectives(typeDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[];
|
||||
resolveTypeReferenceDirectives(typeDirectiveNames: string[], containingFile: string, redirectedReference?: ResolvedProjectReference): ResolvedTypeReferenceDirective[];
|
||||
directoryExists(path: string): boolean;
|
||||
getDirectories(path: string): string[];
|
||||
log(s: string): void;
|
||||
|
||||
24
tests/baselines/reference/api/typescript.d.ts
vendored
24
tests/baselines/reference/api/typescript.d.ts
vendored
@ -2688,11 +2688,11 @@ declare namespace ts {
|
||||
useCaseSensitiveFileNames(): boolean;
|
||||
getNewLine(): string;
|
||||
readDirectory?(rootDir: string, extensions: ReadonlyArray<string>, excludes: ReadonlyArray<string> | undefined, includes: ReadonlyArray<string>, depth?: number): string[];
|
||||
resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[]): (ResolvedModule | undefined)[];
|
||||
resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[], redirectedReference?: ResolvedProjectReference): (ResolvedModule | undefined)[];
|
||||
/**
|
||||
* This method is a companion for 'resolveModuleNames' and is used to resolve 'types' references to actual type declaration files
|
||||
*/
|
||||
resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[];
|
||||
resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string, redirectedReference?: ResolvedProjectReference): ResolvedTypeReferenceDirective[];
|
||||
getEnvironmentVariable?(name: string): string | undefined;
|
||||
createHash?(data: string): string;
|
||||
}
|
||||
@ -3606,7 +3606,7 @@ declare namespace ts {
|
||||
* This is possible in case if resolution is performed for directives specified via 'types' parameter. In this case initial path for secondary lookups
|
||||
* is assumed to be the same as root directory of the project.
|
||||
*/
|
||||
function resolveTypeReferenceDirective(typeReferenceDirectiveName: string, containingFile: string | undefined, options: CompilerOptions, host: ModuleResolutionHost): ResolvedTypeReferenceDirectiveWithFailedLookupLocations;
|
||||
function resolveTypeReferenceDirective(typeReferenceDirectiveName: string, containingFile: string | undefined, options: CompilerOptions, host: ModuleResolutionHost, redirectedReference?: ResolvedProjectReference): ResolvedTypeReferenceDirectiveWithFailedLookupLocations;
|
||||
/**
|
||||
* Given a set of options, returns the set of type directive names
|
||||
* that should be included for this program automatically.
|
||||
@ -3621,14 +3621,14 @@ declare namespace ts {
|
||||
* This assumes that any module id will have the same resolution for sibling files located in the same folder.
|
||||
*/
|
||||
interface ModuleResolutionCache extends NonRelativeModuleNameResolutionCache {
|
||||
getOrCreateCacheForDirectory(directoryName: string): Map<ResolvedModuleWithFailedLookupLocations>;
|
||||
getOrCreateCacheForDirectory(directoryName: string, redirectedReference?: ResolvedProjectReference): Map<ResolvedModuleWithFailedLookupLocations>;
|
||||
}
|
||||
/**
|
||||
* Stored map from non-relative module name to a table: directory -> result of module lookup in this directory
|
||||
* We support only non-relative module names because resolution of relative module names is usually more deterministic and thus less expensive.
|
||||
*/
|
||||
interface NonRelativeModuleNameResolutionCache {
|
||||
getOrCreateCacheForModuleName(nonRelativeModuleName: string): PerModuleNameCache;
|
||||
getOrCreateCacheForModuleName(nonRelativeModuleName: string, redirectedReference?: ResolvedProjectReference): PerModuleNameCache;
|
||||
}
|
||||
interface PerModuleNameCache {
|
||||
get(directory: string): ResolvedModuleWithFailedLookupLocations | undefined;
|
||||
@ -3636,9 +3636,9 @@ declare namespace ts {
|
||||
}
|
||||
function createModuleResolutionCache(currentDirectory: string, getCanonicalFileName: (s: string) => string): ModuleResolutionCache;
|
||||
function resolveModuleNameFromCache(moduleName: string, containingFile: string, cache: ModuleResolutionCache): ResolvedModuleWithFailedLookupLocations | undefined;
|
||||
function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache): ResolvedModuleWithFailedLookupLocations;
|
||||
function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache): ResolvedModuleWithFailedLookupLocations;
|
||||
function classicNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: NonRelativeModuleNameResolutionCache): ResolvedModuleWithFailedLookupLocations;
|
||||
function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference): ResolvedModuleWithFailedLookupLocations;
|
||||
function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference): ResolvedModuleWithFailedLookupLocations;
|
||||
function classicNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: NonRelativeModuleNameResolutionCache, redirectedReference?: ResolvedProjectReference): ResolvedModuleWithFailedLookupLocations;
|
||||
}
|
||||
declare namespace ts {
|
||||
function createNodeArray<T extends Node>(elements?: ReadonlyArray<T>, hasTrailingComma?: boolean): NodeArray<T>;
|
||||
@ -4384,9 +4384,9 @@ declare namespace ts {
|
||||
/** If provided is used to get the environment variable */
|
||||
getEnvironmentVariable?(name: string): string | undefined;
|
||||
/** If provided, used to resolve the module names, otherwise typescript's default module resolution */
|
||||
resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[]): ResolvedModule[];
|
||||
resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[], redirectedReference?: ResolvedProjectReference): ResolvedModule[];
|
||||
/** If provided, used to resolve type reference directives, otherwise typescript's default resolution */
|
||||
resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[];
|
||||
resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string, redirectedReference?: ResolvedProjectReference): ResolvedTypeReferenceDirective[];
|
||||
}
|
||||
/**
|
||||
* Host to create watch with root files and options
|
||||
@ -4654,9 +4654,9 @@ declare namespace ts {
|
||||
realpath?(path: string): string;
|
||||
fileExists?(path: string): boolean;
|
||||
getTypeRootsVersion?(): number;
|
||||
resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[]): ResolvedModule[];
|
||||
resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[], redirectedReference?: ResolvedProjectReference): ResolvedModule[];
|
||||
getResolvedModuleWithFailedLookupLocationsFromCache?(modulename: string, containingFile: string): ResolvedModuleWithFailedLookupLocations | undefined;
|
||||
resolveTypeReferenceDirectives?(typeDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[];
|
||||
resolveTypeReferenceDirectives?(typeDirectiveNames: string[], containingFile: string, redirectedReference?: ResolvedProjectReference): ResolvedTypeReferenceDirective[];
|
||||
getDirectories?(directoryName: string): string[];
|
||||
/**
|
||||
* Gets a set of custom transformers to use during emit.
|
||||
|
||||
@ -1,2 +1,4 @@
|
||||
import {b} from './b';
|
||||
console.log(b);
|
||||
import {X} from "@ref/a";
|
||||
b;
|
||||
X;
|
||||
2
tests/projects/transitiveReferences/refs/a.d.ts
vendored
Normal file
2
tests/projects/transitiveReferences/refs/a.d.ts
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
export class X {}
|
||||
export class A {}
|
||||
@ -1 +1,10 @@
|
||||
{"files": ["c.ts"], "references": [{"path": "tsconfig.b.json"}]}
|
||||
{
|
||||
"files": [ "c.ts" ],
|
||||
"compilerOptions": {
|
||||
"baseUrl": "./",
|
||||
"paths": {
|
||||
"@ref/*": [ "./refs/*" ]
|
||||
}
|
||||
},
|
||||
"references": [ { "path": "tsconfig.b.json" } ]
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user