noDts project resolutions verification and updates for incremental behaviour (#56016)

This commit is contained in:
Sheetal Nandi 2023-10-10 10:24:08 -07:00 committed by GitHub
parent 521f8a8caf
commit 9473195b6c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 1198 additions and 125 deletions

View File

@ -225,6 +225,7 @@ function createResolvedModuleWithFailedLookupLocationsHandlingSymlink(
affectingLocations: string[],
diagnostics: Diagnostic[],
state: ModuleResolutionState,
cache: ModuleResolutionCache | NonRelativeModuleNameResolutionCache | undefined,
legacyResult?: string,
): ResolvedModuleWithFailedLookupLocations {
// If this is from node_modules for non relative name, always respect preserveSymlinks
@ -246,6 +247,7 @@ function createResolvedModuleWithFailedLookupLocationsHandlingSymlink(
affectingLocations,
diagnostics,
state.resultFromCache,
cache,
legacyResult,
);
}
@ -257,13 +259,24 @@ function createResolvedModuleWithFailedLookupLocations(
affectingLocations: string[],
diagnostics: Diagnostic[],
resultFromCache: ResolvedModuleWithFailedLookupLocations | undefined,
cache: ModuleResolutionCache | NonRelativeModuleNameResolutionCache | undefined,
legacyResult?: string,
): ResolvedModuleWithFailedLookupLocations {
if (resultFromCache) {
resultFromCache.failedLookupLocations = updateResolutionField(resultFromCache.failedLookupLocations, failedLookupLocations);
resultFromCache.affectingLocations = updateResolutionField(resultFromCache.affectingLocations, affectingLocations);
resultFromCache.resolutionDiagnostics = updateResolutionField(resultFromCache.resolutionDiagnostics, diagnostics);
return resultFromCache;
if (!cache?.isReadonly) {
resultFromCache.failedLookupLocations = updateResolutionField(resultFromCache.failedLookupLocations, failedLookupLocations);
resultFromCache.affectingLocations = updateResolutionField(resultFromCache.affectingLocations, affectingLocations);
resultFromCache.resolutionDiagnostics = updateResolutionField(resultFromCache.resolutionDiagnostics, diagnostics);
return resultFromCache;
}
else {
return {
...resultFromCache,
failedLookupLocations: initializeResolutionFieldForReadonlyCache(resultFromCache.failedLookupLocations, failedLookupLocations),
affectingLocations: initializeResolutionFieldForReadonlyCache(resultFromCache.affectingLocations, affectingLocations),
resolutionDiagnostics: initializeResolutionFieldForReadonlyCache(resultFromCache.resolutionDiagnostics, diagnostics),
};
}
}
return {
resolvedModule: resolved && {
@ -291,6 +304,12 @@ export function updateResolutionField<T>(to: T[] | undefined, value: T[] | undef
return to;
}
function initializeResolutionFieldForReadonlyCache<T>(fromCache: T[] | undefined, value: T[]): T[] | undefined {
if (!fromCache?.length) return initializeResolutionField(value);
if (!value.length) return fromCache.slice();
return [...fromCache, ...value];
}
/** @internal */
export interface ModuleResolutionState {
host: ModuleResolutionHost;
@ -612,10 +631,10 @@ export function resolveTypeReferenceDirective(typeReferenceDirectiveName: string
affectingLocations: initializeResolutionField(affectingLocations),
resolutionDiagnostics: initializeResolutionField(diagnostics),
};
if (containingDirectory) {
cache?.getOrCreateCacheForDirectory(containingDirectory, redirectedReference).set(typeReferenceDirectiveName, /*mode*/ resolutionMode, result);
if (containingDirectory && cache && !cache.isReadonly) {
cache.getOrCreateCacheForDirectory(containingDirectory, redirectedReference).set(typeReferenceDirectiveName, /*mode*/ resolutionMode, result);
if (!isExternalModuleNameRelative(typeReferenceDirectiveName)) {
cache?.getOrCreateCacheForNonRelativeName(typeReferenceDirectiveName, resolutionMode, redirectedReference).set(containingDirectory, result);
cache.getOrCreateCacheForNonRelativeName(typeReferenceDirectiveName, resolutionMode, redirectedReference).set(containingDirectory, result);
}
}
if (traceEnabled) traceResult(result);
@ -850,6 +869,8 @@ export interface PerDirectoryResolutionCache<T> {
* This updates the redirects map as well if needed so module resolutions are cached if they can across the projects
*/
update(options: CompilerOptions): void;
/** @internal */ directoryToModuleNameMap: CacheWithRedirects<Path, ModeAwareCache<T>>;
/** @internal */ isReadonly?: boolean;
}
export interface NonRelativeNameResolutionCache<T> {
@ -861,11 +882,13 @@ export interface NonRelativeNameResolutionCache<T> {
* This updates the redirects map as well if needed so module resolutions are cached if they can across the projects
*/
update(options: CompilerOptions): void;
/** @internal */ isReadonly?: boolean;
}
export interface PerNonRelativeNameCache<T> {
get(directory: string): T | undefined;
set(directory: string, result: T): void;
/** @internal */ isReadonly?: boolean;
}
export interface ModuleResolutionCache extends PerDirectoryResolutionCache<ResolvedModuleWithFailedLookupLocations>, NonRelativeModuleNameResolutionCache, PackageJsonInfoCache {
@ -889,6 +912,7 @@ export interface PackageJsonInfoCache {
/** @internal */ entries(): [Path, PackageJsonInfo | boolean][];
/** @internal */ getInternalMap(): Map<Path, PackageJsonInfo | boolean> | undefined;
clear(): void;
/** @internal */ isReadonly?: boolean;
}
export type PerModuleNameCache = PerNonRelativeNameCache<ResolvedModuleWithFailedLookupLocations>;
@ -920,6 +944,7 @@ export interface CacheWithRedirects<K, V> {
getOrCreateMapOfCacheRedirects(redirectedReference: ResolvedProjectReference | undefined): Map<K, V>;
update(newOptions: CompilerOptions): void;
clear(): void;
getOwnMap(): Map<K, V>;
}
/** @internal */
@ -936,6 +961,7 @@ export function createCacheWithRedirects<K, V>(ownOptions: CompilerOptions | und
getOrCreateMapOfCacheRedirects,
update,
clear,
getOwnMap: () => ownMap,
};
function getMapOfCacheRedirects(redirectedReference: ResolvedProjectReference | undefined): Map<K, V> | undefined {
@ -1042,6 +1068,7 @@ function createPerDirectoryResolutionCache<T>(
getOrCreateCacheForDirectory,
clear,
update,
directoryToModuleNameMap,
};
function clear() {
@ -1426,10 +1453,12 @@ export function resolveModuleName(moduleName: string, containingFile: string, co
if (result && result.resolvedModule) perfLogger?.logInfoEvent(`Module "${moduleName}" resolved to "${result.resolvedModule.resolvedFileName}"`);
perfLogger?.logStopResolveModule((result && result.resolvedModule) ? "" + result.resolvedModule.resolvedFileName : "null");
cache?.getOrCreateCacheForDirectory(containingDirectory, redirectedReference).set(moduleName, resolutionMode, result);
if (!isExternalModuleNameRelative(moduleName)) {
// put result in per-module name cache
cache?.getOrCreateCacheForNonRelativeName(moduleName, resolutionMode, redirectedReference).set(containingDirectory, result);
if (cache && !cache.isReadonly) {
cache.getOrCreateCacheForDirectory(containingDirectory, redirectedReference).set(moduleName, resolutionMode, result);
if (!isExternalModuleNameRelative(moduleName)) {
// put result in per-module name cache
cache.getOrCreateCacheForNonRelativeName(moduleName, resolutionMode, redirectedReference).set(containingDirectory, result);
}
}
}
@ -1850,6 +1879,7 @@ function nodeModuleNameResolverWorker(
affectingLocations,
diagnostics,
state,
cache,
legacyResult,
);
@ -2386,7 +2416,7 @@ export function getPackageJsonInfo(packageDirectory: string, onlyRecordFailures:
trace(host, Diagnostics.Found_package_json_at_0, packageJsonPath);
}
const result: PackageJsonInfo = { packageDirectory, contents: { packageJsonContent, versionPaths: undefined, resolvedEntrypoints: undefined } };
state.packageJsonInfoCache?.setPackageJsonInfo(packageJsonPath, result);
if (state.packageJsonInfoCache && !state.packageJsonInfoCache.isReadonly) state.packageJsonInfoCache.setPackageJsonInfo(packageJsonPath, result);
state.affectingLocations?.push(packageJsonPath);
return result;
}
@ -2394,7 +2424,7 @@ export function getPackageJsonInfo(packageDirectory: string, onlyRecordFailures:
if (directoryExists && traceEnabled) {
trace(host, Diagnostics.File_0_does_not_exist, packageJsonPath);
}
state.packageJsonInfoCache?.setPackageJsonInfo(packageJsonPath, directoryExists);
if (state.packageJsonInfoCache && !state.packageJsonInfoCache.isReadonly) state.packageJsonInfoCache.setPackageJsonInfo(packageJsonPath, directoryExists);
// record package json as one of failed lookup locations - in the future if this file will appear it will invalidate resolution results
state.failedLookupLocations?.push(packageJsonPath);
}
@ -3178,6 +3208,7 @@ export function classicNameResolver(moduleName: string, containingFile: string,
affectingLocations,
diagnostics,
state,
cache,
);
function tryResolve(extensions: Extensions): SearchResult<Resolved> {
@ -3273,6 +3304,7 @@ export function loadModuleFromGlobalCache(moduleName: string, projectName: strin
affectingLocations,
diagnostics,
state.resultFromCache,
/*cache*/ undefined,
);
}

View File

@ -205,6 +205,18 @@ export interface ResolutionCacheHost extends MinimalResolutionCacheHost {
getCurrentProgram(): Program | undefined;
fileIsOpen(filePath: Path): boolean;
onDiscoveredSymlink?(): void;
// For incremental testing
beforeResolveSingleModuleNameWithoutWatching?(
moduleResolutionCache: ModuleResolutionCache,
): any;
afterResolveSingleModuleNameWithoutWatching?(
moduleResolutionCache: ModuleResolutionCache,
moduleName: string,
containingFile: string,
result: ResolvedModuleWithFailedLookupLocations,
data: any,
): any;
}
/** @internal */
@ -439,6 +451,10 @@ export function getRootPathSplitLength(rootPath: Path) {
return rootPath.split(directorySeparator).length - (hasTrailingDirectorySeparator(rootPath) ? 1 : 0);
}
function getModuleResolutionHost(resolutionHost: ResolutionCacheHost) {
return resolutionHost.getCompilerHost?.() || resolutionHost;
}
/** @internal */
export function createModuleResolutionLoaderUsingGlobalCache(
containingFile: string,
@ -471,7 +487,7 @@ function resolveModuleNameUsingGlobalCache(
redirectedReference?: ResolvedProjectReference,
mode?: ResolutionMode,
): ResolvedModuleWithFailedLookupLocations {
const host = resolutionHost.getCompilerHost?.() || resolutionHost;
const host = getModuleResolutionHost(resolutionHost);
const primaryResult = ts_resolveModuleName(moduleName, containingFile, compilerOptions, host, moduleResolutionCache, redirectedReference, mode);
// return result immediately only if global cache support is not enabled or if it is .ts, .tsx or .d.ts
if (!resolutionHost.getGlobalCache) {
@ -686,6 +702,10 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
}
function startCachingPerDirectoryResolution() {
moduleResolutionCache.isReadonly = undefined;
typeReferenceDirectiveResolutionCache.isReadonly = undefined;
libraryResolutionCache.isReadonly = undefined;
moduleResolutionCache.getPackageJsonInfoCache().isReadonly = undefined;
moduleResolutionCache.clearAllExceptPackageJsonInfoCache();
typeReferenceDirectiveResolutionCache.clearAllExceptPackageJsonInfoCache();
libraryResolutionCache.clearAllExceptPackageJsonInfoCache();
@ -740,6 +760,10 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
directoryWatchesOfFailedLookups.forEach(closeDirectoryWatchesOfFailedLookup);
fileWatchesOfAffectingLocations.forEach(closeFileWatcherOfAffectingLocation);
hasChangedAutomaticTypeDirectiveNames = false;
moduleResolutionCache.isReadonly = true;
typeReferenceDirectiveResolutionCache.isReadonly = true;
libraryResolutionCache.isReadonly = true;
moduleResolutionCache.getPackageJsonInfoCache().isReadonly = true;
}
function closeDirectoryWatchesOfFailedLookup(watcher: DirectoryWatchesOfFailedLookup, path: Path) {
@ -828,7 +852,7 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
}
}
else {
const host = resolutionHost.getCompilerHost?.() || resolutionHost;
const host = getModuleResolutionHost(resolutionHost);
if (isTraceEnabled(options, host) && !seenNamesInFile.has(name, mode)) {
const resolved = getResolutionWithResolvedFileName(resolution!);
trace(
@ -912,7 +936,7 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
containingFile,
redirectedReference,
options,
resolutionHost.getCompilerHost?.() || resolutionHost,
getModuleResolutionHost(resolutionHost),
typeReferenceDirectiveResolutionCache,
),
getResolutionWithResolvedFileName: getResolvedTypeReferenceDirective,
@ -957,7 +981,7 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
options: CompilerOptions,
libFileName: string,
) {
const host = resolutionHost.getCompilerHost?.() || resolutionHost;
const host = getModuleResolutionHost(resolutionHost);
let resolution = resolvedLibraries?.get(libFileName);
if (!resolution || resolution.isInvalidated) {
const existingResolution = resolution;
@ -994,7 +1018,18 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
const resolutionsInFile = resolvedModuleNames.get(path);
const resolution = resolutionsInFile?.get(moduleName, /*mode*/ undefined);
if (resolution && !resolution.isInvalidated) return resolution;
return resolveModuleNameUsingGlobalCache(resolutionHost, moduleResolutionCache, moduleName, containingFile, resolutionHost.getCompilationSettings());
const data = resolutionHost.beforeResolveSingleModuleNameWithoutWatching?.(moduleResolutionCache);
const host = getModuleResolutionHost(resolutionHost);
// We are not resolving d.ts so just normal resolution instead of doing resolution pass to global cache
const result = ts_resolveModuleName(
moduleName,
containingFile,
resolutionHost.getCompilationSettings(),
host,
moduleResolutionCache,
);
resolutionHost.afterResolveSingleModuleNameWithoutWatching?.(moduleResolutionCache, moduleName, containingFile, result, data);
return result;
}
function isNodeModulesAtTypesDirectory(dirPath: Path) {

View File

@ -264,7 +264,7 @@ export function verifyResolutionCache(
resolutionToExpected.get(resolution)!.refCount === resolution.refCount,
`${projectName}:: Expected Resolution ref count ${resolutionToExpected.get(resolution)!.refCount} but got ${resolution.refCount}`,
);
verifySet(resolutionToExpected.get(resolution)!.files, resolution.files, `Resolution files`);
verifySet(resolutionToExpected.get(resolution)!.files, resolution.files, `${projectName}:: Resolution files`);
});
verifyMapOfResolutionSet(expected.resolvedFileToResolution, actual.resolvedFileToResolution, `resolvedFileToResolution`);
verifyResolutionSet(expected.resolutionsWithFailedLookups, actual.resolutionsWithFailedLookups, `resolutionsWithFailedLookups`);
@ -273,6 +273,7 @@ export function verifyResolutionCache(
verifyFileWatchesOfAffectingLocations(expected.fileWatchesOfAffectingLocations, actual.fileWatchesOfAffectingLocations);
// Stop watching resolutions to verify everything gets closed.
expected.startCachingPerDirectoryResolution();
actual.resolvedModuleNames.forEach((_resolutions, path) => expected.removeResolutionsOfFile(path));
actual.resolvedTypeReferenceDirectives.forEach((_resolutions, path) => expected.removeResolutionsOfFile(path));
expected.finishCachingPerDirectoryResolution(/*newProgram*/ undefined, actualProgram);
@ -339,35 +340,6 @@ export function verifyResolutionCache(
return expectedResolution;
}
function verifyMap<Expected, Actual>(
expected: Map<string, Expected> | undefined,
actual: Map<string, Actual> | undefined,
verifyValue: (expected: Expected | undefined, actual: Actual | undefined, key: string) => void,
caption: string,
) {
expected?.forEach((expected, path) => verifyValue(expected, actual?.get(path), `${caption}:: ${path}`));
actual?.forEach((actual, path) => verifyValue(expected?.get(path), actual, `${caption}:: ${path}`));
}
function verifySet(
expected: Set<string> | undefined,
actual: Set<string> | undefined,
caption: string,
) {
expected?.forEach(expected =>
ts.Debug.assert(
actual?.has(expected),
`${projectName}:: ${caption}:: Expected should be present in actual`,
)
);
actual?.forEach(actual =>
ts.Debug.assert(
expected?.has(actual),
`${projectName}:: ${caption}:: Actual should be present in expected`,
)
);
}
function verifyMapOfResolutionSet(
expected: Map<ts.Path, Set<ts.ResolutionWithFailedLookupLocations>> | undefined,
actual: Map<ts.Path, Set<ts.ResolutionWithFailedLookupLocations>> | undefined,
@ -421,6 +393,35 @@ export function verifyResolutionCache(
}
}
function verifyMap<Key extends string, Expected, Actual>(
expected: Map<Key, Expected> | undefined,
actual: Map<Key, Actual> | undefined,
verifyValue: (expected: Expected | undefined, actual: Actual | undefined, key: string) => void,
caption: string,
) {
expected?.forEach((expected, path) => verifyValue(expected, actual?.get(path), `${caption}:: ${path}`));
actual?.forEach((actual, path) => verifyValue(expected?.get(path), actual, `${caption}:: ${path}`));
}
function verifySet(
expected: Set<string> | undefined,
actual: Set<string> | undefined,
caption: string,
) {
expected?.forEach(expected =>
ts.Debug.assert(
actual?.has(expected),
`${caption}:: Expected should be present in actual`,
)
);
actual?.forEach(actual =>
ts.Debug.assert(
expected?.has(actual),
`${caption}:: Actual should be present in expected`,
)
);
}
function verifyProgram(service: ts.server.ProjectService, project: ts.server.Project) {
if (service.serverMode === ts.LanguageServiceMode.Syntactic) return;
const options = project.getCompilerOptions();
@ -510,6 +511,74 @@ function verifyProgram(service: ts.server.ProjectService, project: ts.server.Pro
verifyResolutionCache(project.resolutionCache, project.getCurrentProgram()!, resolutionHostCacheHost, project.projectName);
}
interface ResolveSingleModuleNameWithoutWatchingData {
resolutionToData: Map<ts.ResolutionWithFailedLookupLocations, Pick<ts.ResolvedModuleWithFailedLookupLocations, "failedLookupLocations" | "affectingLocations" | "resolutionDiagnostics">>;
packageJsonMap: Map<ts.Path, ts.PackageJsonInfo | boolean> | undefined;
}
function beforeResolveSingleModuleNameWithoutWatching(
moduleResolutionCache: ts.ModuleResolutionCache,
): ResolveSingleModuleNameWithoutWatchingData {
const resolutionToData: ResolveSingleModuleNameWithoutWatchingData["resolutionToData"] = new Map();
// Currently it doesnt matter if moduleResolutionCache itself changes or not so just verify resolutions:
moduleResolutionCache.directoryToModuleNameMap.getOwnMap().forEach(cache => {
cache.forEach(resolution => {
if (resolutionToData.has(resolution)) return;
resolutionToData.set(resolution, {
failedLookupLocations: resolution.failedLookupLocations?.slice(),
affectingLocations: resolution.affectingLocations?.slice(),
resolutionDiagnostics: resolution.resolutionDiagnostics?.slice(),
});
});
});
// We also care about package json info cache
const packageJsonMap = moduleResolutionCache.getPackageJsonInfoCache().getInternalMap();
return {
resolutionToData,
packageJsonMap: packageJsonMap && new Map(packageJsonMap),
};
}
function afterResolveSingleModuleNameWithoutWatching(
moduleResolutionCache: ts.ModuleResolutionCache,
moduleName: string,
containingFile: string,
result: ts.ResolvedModuleWithFailedLookupLocations,
data: ResolveSingleModuleNameWithoutWatchingData,
) {
const existing = data.resolutionToData.get(result);
if (existing) {
verifyArrayLength(existing.failedLookupLocations, result.failedLookupLocations, "failedLookupLocations");
verifyArrayLength(existing.affectingLocations, result.affectingLocations, "affectingLocations");
verifyArrayLength(existing.resolutionDiagnostics, result.resolutionDiagnostics, "resolutionDiagnostics");
}
verifyMap(
data.packageJsonMap,
moduleResolutionCache.getPackageJsonInfoCache().getInternalMap(),
(expected, actual, caption) => ts.Debug.assert(expected === actual, caption),
`Expected packageJsonInfo to not change: ${moduleName} ${containingFile}`,
);
function verifyArrayLength<T>(expected: T[] | undefined, actual: T[] | undefined, caption: string) {
ts.Debug.assert(
expected?.length === actual?.length,
`Expected ${caption} to not change: ${moduleName} ${containingFile}`,
() =>
`Expected: ${JSON.stringify(expected, undefined, " ")}` +
`Actual: ${JSON.stringify(actual, undefined, " ")}`,
);
}
}
function onProjectCreation(project: ts.server.Project) {
if (project.projectKind !== ts.server.ProjectKind.Auxiliary) return;
(project as ts.ResolutionCacheHost).beforeResolveSingleModuleNameWithoutWatching = beforeResolveSingleModuleNameWithoutWatching;
(project as ts.ResolutionCacheHost).afterResolveSingleModuleNameWithoutWatching = afterResolveSingleModuleNameWithoutWatching;
}
export interface IncrementalVerifierCallbacks {
beforeVerification?(): any;
afterVerification?(dataFromBefore: any): void;
@ -518,6 +587,7 @@ export interface IncrementalVerifierCallbacks {
export function incrementalVerifier(service: ts.server.ProjectService) {
service.verifyDocumentRegistry = withIncrementalVerifierCallbacks(service, verifyDocumentRegistry);
service.verifyProgram = withIncrementalVerifierCallbacks(service, verifyProgram);
service.onProjectCreation = onProjectCreation;
}
function withIncrementalVerifierCallbacks(

View File

@ -140,6 +140,7 @@ import {
ActionSet,
asNormalizedPath,
AutoImportProviderProject,
AuxiliaryProject,
BeginEnablePluginResult,
BeginInstallTypes,
ConfiguredProject,
@ -153,6 +154,7 @@ import {
hasNoTypeScriptSource,
InferredProject,
InvalidateCachedTypings,
isBackgroundProject,
isConfiguredProject,
isDynamicFileName,
isInferredProject,
@ -1129,6 +1131,7 @@ export class ProjectService {
/** @internal */ verifyDocumentRegistry = noop;
/** @internal */ verifyProgram: (project: Project) => void = noop;
/** @internal */ onProjectCreation: (project: Project) => void = noop;
readonly jsDocParsingMode: JSDocParsingMode | undefined;
@ -1325,15 +1328,14 @@ export class ProjectService {
private delayUpdateProjectGraph(project: Project) {
project.markAsDirty();
if (project.projectKind !== ProjectKind.AutoImportProvider && project.projectKind !== ProjectKind.Auxiliary) {
const projectName = project.getProjectName();
this.pendingProjectUpdates.set(projectName, project);
this.throttledOperations.schedule(projectName, /*delay*/ 250, () => {
if (this.pendingProjectUpdates.delete(projectName)) {
updateProjectIfDirty(project);
}
});
}
if (isBackgroundProject(project)) return;
const projectName = project.getProjectName();
this.pendingProjectUpdates.set(projectName, project);
this.throttledOperations.schedule(projectName, /*delay*/ 250, () => {
if (this.pendingProjectUpdates.delete(projectName)) {
updateProjectIfDirty(project);
}
});
}
/** @internal */
@ -2418,6 +2420,7 @@ export class ProjectService {
private addFilesToNonInferredProject<T>(project: ConfiguredProject | ExternalProject, files: T[], propertyReader: FilePropertyReader<T>, typeAcquisition: TypeAcquisition): void {
this.updateNonInferredProjectFiles(project, files, propertyReader);
project.setTypeAcquisition(typeAcquisition);
project.markAsDirty();
}
/** @internal */
@ -2669,7 +2672,7 @@ export class ProjectService {
configFileExistenceInfo.config.watchedDirectoriesStale = undefined;
}
private updateNonInferredProjectFiles<T>(project: Project, files: T[], propertyReader: FilePropertyReader<T>) {
private updateNonInferredProjectFiles<T>(project: Project, files: readonly T[], propertyReader: FilePropertyReader<T>) {
const projectRootFilesMap = project.getRootFilesMap();
const newRootScriptInfoMap = new Map<string, true>();
@ -2736,10 +2739,6 @@ export class ProjectService {
}
});
}
// Just to ensure that even if root files dont change, the changes to the non root file are picked up,
// mark the project as dirty unconditionally
project.markAsDirty();
}
private updateRootAndOptionsOfNonInferredProject<T>(project: ExternalProject | ConfiguredProject, newUncheckedFiles: T[], propertyReader: FilePropertyReader<T>, newOptions: CompilerOptions, newTypeAcquisition: TypeAcquisition, compileOnSave: boolean | undefined, watchOptions: WatchOptions | undefined) {
@ -2762,6 +2761,7 @@ export class ProjectService {
const fileNames = this.reloadFileNamesOfParsedConfig(project.getConfigFilePath(), this.configFileExistenceInfoCache.get(project.canonicalConfigFilePath)!.config!);
project.updateErrorOnNoInputFiles(fileNames);
this.updateNonInferredProjectFiles(project, fileNames.concat(project.getExternalFiles(ProgramUpdateLevel.RootNamesAndUpdate)), fileNamePropertyReader);
project.markAsDirty();
return project.updateGraph();
}
@ -2782,7 +2782,7 @@ export class ProjectService {
}
/** @internal */
setFileNamesOfAutoImportProviderProject(project: AutoImportProviderProject, fileNames: string[]) {
setFileNamesOfAutpImportProviderOrAuxillaryProject(project: AutoImportProviderProject | AuxiliaryProject, fileNames: readonly string[]) {
this.updateNonInferredProjectFiles(project, fileNames, fileNamePropertyReader);
}

View File

@ -579,9 +579,10 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo
this.disableLanguageService(lastFileExceededProgramSize);
}
this.markAsDirty();
if (projectKind !== ProjectKind.AutoImportProvider) {
if (!isBackgroundProject(this)) {
this.projectService.pendingEnsureProjectForOpenFiles = true;
}
this.projectService.onProjectCreation(this);
}
isKnownTypesPackageName(name: string): boolean {
@ -727,6 +728,7 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo
return this.resolutionCache.resolveModuleNameLiterals(moduleLiterals, containingFile, redirectedReference, options, containingSourceFile, reusedNames);
}
/** @internal */
getModuleResolutionCache(): ModuleResolutionCache | undefined {
return this.resolutionCache.getModuleResolutionCache();
}
@ -2185,35 +2187,15 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo
}
/** @internal */
getNoDtsResolutionProject(rootFileNames: readonly string[]): Project {
getNoDtsResolutionProject(rootFile: NormalizedPath): AuxiliaryProject {
Debug.assert(this.projectService.serverMode === LanguageServiceMode.Semantic);
if (!this.noDtsResolutionProject) {
this.noDtsResolutionProject = new AuxiliaryProject(this.projectService, this.documentRegistry, this.getCompilerOptionsForNoDtsResolutionProject(), this.currentDirectory);
}
enumerateInsertsAndDeletes<NormalizedPath, NormalizedPath>(
rootFileNames.map(toNormalizedPath),
this.noDtsResolutionProject.getRootFiles(),
getStringComparer(!this.useCaseSensitiveFileNames()),
pathToAdd => {
const info = this.projectService.getOrCreateScriptInfoNotOpenedByClient(
pathToAdd,
this.currentDirectory,
this.noDtsResolutionProject!.directoryStructureHost,
);
if (info) {
this.noDtsResolutionProject!.addRoot(info, pathToAdd);
}
},
pathToRemove => {
// It may be preferable to remove roots only once project grows to a certain size?
const info = this.noDtsResolutionProject!.getScriptInfo(pathToRemove);
if (info) {
this.noDtsResolutionProject!.removeRoot(info);
}
},
);
if (this.noDtsResolutionProject.rootFile !== rootFile) {
this.projectService.setFileNamesOfAutpImportProviderOrAuxillaryProject(this.noDtsResolutionProject, [rootFile]);
this.noDtsResolutionProject.rootFile = rootFile;
}
return this.noDtsResolutionProject;
}
@ -2394,6 +2376,7 @@ export class InferredProject extends Project {
/** @internal */
export class AuxiliaryProject extends Project {
/** @internal */ rootFile: NormalizedPath | undefined;
constructor(projectService: ProjectService, documentRegistry: DocumentRegistry, compilerOptions: CompilerOptions, currentDirectory: string) {
super(projectService.newAuxiliaryProjectName(), ProjectKind.Auxiliary, projectService, documentRegistry, /*hasExplicitListOfFiles*/ false, /*lastFileExceededProgramSize*/ undefined, compilerOptions, /*compileOnSaveEnabled*/ false, /*watchOptions*/ undefined, projectService.host, currentDirectory);
}
@ -2601,7 +2584,7 @@ export class AutoImportProviderProject extends Project {
);
}
this.projectService.setFileNamesOfAutoImportProviderProject(this, rootFileNames);
this.projectService.setFileNamesOfAutpImportProviderOrAuxillaryProject(this, rootFileNames);
this.rootFileNames = rootFileNames;
const oldProgram = this.getCurrentProgram();
const hasSameSetOfFiles = super.updateGraph();
@ -3015,3 +2998,8 @@ export function isConfiguredProject(project: Project): project is ConfiguredProj
export function isExternalProject(project: Project): project is ExternalProject {
return project.projectKind === ProjectKind.External;
}
/**@internal */
export function isBackgroundProject(project: Project): project is AutoImportProviderProject | AuxiliaryProject {
return project.projectKind === ProjectKind.AutoImportProvider || project.projectKind === ProjectKind.Auxiliary;
}

View File

@ -40,13 +40,13 @@ import {
Errors,
ExternalProject,
InferredProject,
isBackgroundProject,
isConfiguredProject,
isExternalProject,
isInferredProject,
maxFileSize,
NormalizedPath,
Project,
ProjectKind,
ScriptVersionCache,
ServerHost,
} from "./_namespaces/ts.server";
@ -682,7 +682,7 @@ export class ScriptInfo {
isContainedByBackgroundProject() {
return some(
this.containingProjects,
p => p.projectKind === ProjectKind.AutoImportProvider || p.projectKind === ProjectKind.Auxiliary,
isBackgroundProject,
);
}
@ -730,7 +730,7 @@ export class ScriptInfo {
* reported as the default project for a ScriptInfo.
*/
function ensurePrimaryProjectKind(project: Project | undefined) {
if (!project || project.projectKind === ProjectKind.AutoImportProvider || project.projectKind === ProjectKind.Auxiliary) {
if (!project || isBackgroundProject(project)) {
return Errors.ThrowNoProject();
}
return project;

View File

@ -139,6 +139,7 @@ import {
WithMetadata,
} from "./_namespaces/ts";
import {
AuxiliaryProject,
CloseFileWatcherEvent,
ConfigFileDiagEvent,
ConfiguredProject,
@ -1542,7 +1543,7 @@ export class Session<TMessage = string> implements EventSender {
if (needsJsResolution) {
const definitionSet = createSet<DefinitionInfo>(d => d.textSpan.start, documentSpansEqual);
definitions?.forEach(d => definitionSet.add(d));
const noDtsProject = project.getNoDtsResolutionProject([file]);
const noDtsProject = project.getNoDtsResolutionProject(file);
const ls = noDtsProject.getLanguageService();
const jsDefinitions = ls.getDefinitionAtPosition(file, position, /*searchOtherFilesOnly*/ true, /*stopAtAlias*/ false)
?.filter(d => toNormalizedPath(d.fileName) !== file);
@ -1564,8 +1565,16 @@ export class Session<TMessage = string> implements EventSender {
const ambientCandidates = definitions.filter(d => toNormalizedPath(d.fileName) !== file && d.isAmbient);
for (const candidate of some(ambientCandidates) ? ambientCandidates : getAmbientCandidatesByClimbingAccessChain()) {
const fileNameToSearch = findImplementationFileFromDtsFileName(candidate.fileName, file, noDtsProject);
if (!fileNameToSearch || !ensureRoot(noDtsProject, fileNameToSearch)) {
continue;
if (!fileNameToSearch) continue;
const info = this.projectService.getOrCreateScriptInfoNotOpenedByClient(
fileNameToSearch,
noDtsProject.currentDirectory,
noDtsProject.directoryStructureHost,
);
if (!info) continue;
if (!noDtsProject.containsScriptInfo(info)) {
noDtsProject.addRoot(info);
noDtsProject.updateGraph();
}
const noDtsProgram = ls.getProgram()!;
const fileToSearch = Debug.checkDefined(noDtsProgram.getSourceFile(fileNameToSearch));
@ -1580,7 +1589,7 @@ export class Session<TMessage = string> implements EventSender {
definitions = definitions.filter(d => !d.isAmbient && !d.failedAliasResolution);
return this.mapDefinitionInfo(definitions, project);
function findImplementationFileFromDtsFileName(fileName: string, resolveFromFile: string, auxiliaryProject: Project) {
function findImplementationFileFromDtsFileName(fileName: string, resolveFromFile: string, auxiliaryProject: AuxiliaryProject) {
const nodeModulesPathParts = getNodeModulePathParts(fileName);
if (nodeModulesPathParts && fileName.lastIndexOf(nodeModulesPathPart) === nodeModulesPathParts.topLevelNodeModulesIndex) {
// Second check ensures the fileName only contains one `/node_modules/`. If there's more than one I give up.
@ -1671,16 +1680,6 @@ export class Session<TMessage = string> implements EventSender {
}
});
}
function ensureRoot(project: Project, fileName: string) {
const info = project.getScriptInfo(fileName);
if (!info) return false;
if (!project.containsScriptInfo(info)) {
project.addRoot(info);
project.updateGraph();
}
return true;
}
}
private getEmitOutput(args: protocol.EmitOutputRequestArgs): EmitOutput | protocol.EmitOutput {

View File

@ -1,29 +1,34 @@
import * as ts from "../../_namespaces/ts";
import {
dedent,
} from "../../_namespaces/Utils";
import {
baselineTsserverLogs,
createLoggerWithInMemoryLogs,
createSession,
openFilesForSession,
protocolFileLocationFromSubstring,
} from "../helpers/tsserver";
import {
createServerHost,
File,
libFile,
} from "../helpers/virtualFileSystemWithWatch";
const aTs: File = {
path: "/a.ts",
content: `import { B } from "./b";`,
};
const bDts: File = {
path: "/b.d.ts",
content: `export declare class B {}`,
};
const bJs: File = {
path: "/b.js",
content: `export class B {}`,
};
describe("unittests:: tsserver:: auxiliaryProject", () => {
describe("unittests:: tsserver:: auxiliaryProject::", () => {
it("AuxiliaryProject does not remove scrips from InferredProject", () => {
const aTs: File = {
path: "/a.ts",
content: `import { B } from "./b";`,
};
const bDts: File = {
path: "/b.d.ts",
content: `export declare class B {}`,
};
const bJs: File = {
path: "/b.js",
content: `export class B {}`,
};
const host = createServerHost([aTs, bDts, bJs]);
const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
const projectService = session.getProjectService();
@ -33,8 +38,11 @@ describe("unittests:: tsserver:: auxiliaryProject", () => {
const inferredProject = projectService.inferredProjects[0];
// getNoDtsResolutionProject will create an AuxiliaryProject with a.ts and b.js
const auxProject = inferredProject.getNoDtsResolutionProject([aTs.path]);
auxProject.updateGraph();
session.executeCommandSeq<ts.server.protocol.FindSourceDefinitionRequest>({
command: ts.server.protocol.CommandTypes.FindSourceDefinition,
arguments: protocolFileLocationFromSubstring(aTs, "B"),
});
const auxProject = inferredProject.getNoDtsResolutionProject(aTs.path as ts.server.NormalizedPath);
// b.js ScriptInfo is now available because it's contained by the AuxiliaryProject.
// The AuxiliaryProject should never be the default project for anything, so
@ -54,4 +62,126 @@ describe("unittests:: tsserver:: auxiliaryProject", () => {
assert.equal(bJsScriptInfo.getDefaultProject().projectKind, ts.server.ProjectKind.Inferred);
baselineTsserverLogs("auxiliaryProject", "does not remove scrips from InferredProject", session);
});
it("file is added later through finding definition", () => {
const indexFile: File = {
path: "/user/users/projects/myproject/index.ts",
content: dedent`
import { command } from "yargs";
command("foo", yargs => {
yargs.positional();
});
`,
};
const host = createServerHost({
"/user/users/projects/myproject/node_modules/@types/yargs/package.json": JSON.stringify(
{
name: "@types/yargs",
version: "1.0.0",
types: "./index.d.ts",
},
undefined,
" ",
),
"/user/users/projects/myproject/node_modules/@types/yargs/callback.d.ts": dedent`
export declare class Yargs { positional(): Yargs; }
`,
"/user/users/projects/myproject/node_modules/@types/yargs/index.d.ts": dedent`
import { Yargs } from "./callback";
export declare function command(command: string, cb: (yargs: Yargs) => void): void;
`,
"/user/users/projects/myproject/node_modules/yargs/package.json": JSON.stringify(
{
name: "yargs",
version: "1.0.0",
main: "index.js",
},
undefined,
" ",
),
"/user/users/projects/myproject/node_modules/yargs/callback.js": dedent`
export class Yargs { positional() { } }
`,
"/user/users/projects/myproject/node_modules/yargs/index.js": dedent`
// Specifically didnt have ./callback import to ensure that resolving module sepcifier adds the file to project at later stage
export function command(cmd, cb) { cb(Yargs) }
`,
[indexFile.path]: indexFile.content,
[libFile.path]: libFile.content,
});
const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
openFilesForSession([indexFile], session);
session.executeCommandSeq<ts.server.protocol.FindSourceDefinitionRequest>({
command: ts.server.protocol.CommandTypes.FindSourceDefinition,
arguments: protocolFileLocationFromSubstring(indexFile, "positional"),
});
session.executeCommandSeq<ts.server.protocol.FindSourceDefinitionRequest>({
command: ts.server.protocol.CommandTypes.FindSourceDefinition,
arguments: protocolFileLocationFromSubstring(indexFile, "positional"),
});
session.executeCommandSeq<ts.server.protocol.FindSourceDefinitionRequest>({
command: ts.server.protocol.CommandTypes.FindSourceDefinition,
arguments: protocolFileLocationFromSubstring(indexFile, "command", { index: 1 }),
});
baselineTsserverLogs("auxiliaryProject", "file is added later through finding definition", session);
});
it("resolution is reused from different folder", () => {
const indexFile: File = {
path: "/user/users/projects/myproject/some/index.ts",
content: dedent`
import { random } from "../folder/random";
import { command } from "yargs";
command("foo", yargs => {
yargs.positional();
});
`,
};
const host = createServerHost({
"/user/users/projects/myproject/node_modules/@types/yargs/package.json": JSON.stringify(
{
name: "@types/yargs",
version: "1.0.0",
types: "./index.d.ts",
},
undefined,
" ",
),
"/user/users/projects/myproject/node_modules/@types/yargs/callback.d.ts": dedent`
export declare class Yargs { positional(): Yargs; }
`,
"/user/users/projects/myproject/node_modules/@types/yargs/index.d.ts": dedent`
import { Yargs } from "./callback";
export declare function command(command: string, cb: (yargs: Yargs) => void): void;
`,
"/user/users/projects/myproject/node_modules/yargs/package.json": JSON.stringify(
{
name: "yargs",
version: "1.0.0",
main: "index.js",
},
undefined,
" ",
),
"/user/users/projects/myproject/node_modules/yargs/callback.js": dedent`
export class Yargs { positional() { } }
`,
"/user/users/projects/myproject/node_modules/yargs/index.js": dedent`
// Specifically didnt have ./callback import to ensure that resolving module sepcifier adds the file to project at later stage
export function command(cmd, cb) { cb(Yargs) }
`,
"/user/users/projects/myproject/folder/random.ts": dedent`
import { Yargs } from "yargs/callback";
`,
[indexFile.path]: indexFile.content,
[libFile.path]: libFile.content,
});
const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
openFilesForSession([indexFile], session);
session.executeCommandSeq<ts.server.protocol.FindSourceDefinitionRequest>({
command: ts.server.protocol.CommandTypes.FindSourceDefinition,
arguments: protocolFileLocationFromSubstring(indexFile, "positional"),
});
baselineTsserverLogs("auxiliaryProject", "resolution is reused from different folder", session);
});
});

View File

@ -3354,7 +3354,6 @@ declare namespace ts {
readFile(fileName: string): string | undefined;
writeFile(fileName: string, content: string): void;
fileExists(file: string): boolean;
getModuleResolutionCache(): ModuleResolutionCache | undefined;
directoryExists(path: string): boolean;
getDirectories(path: string): string[];
log(s: string): void;

View File

@ -0,0 +1,20 @@
// === goToSourceDefinition ===
// === /node_modules/yargs/callback.js ===
// export class Yargs { [|positional|]() { } }
// === /index.ts ===
// import { command } from "yargs";
// command("foo", yargs => {
// yargs./*GOTO SOURCE DEF*/positional();
// });
// === Details ===
[
{
"containerKind": "",
"containerName": "",
"kind": "",
"name": "",
"unverified": true
}
]

View File

@ -0,0 +1,20 @@
// === goToSourceDefinition ===
// === /node_modules/yargs/callback.js ===
// export class Yargs { [|positional|]() { } }
// === /index.ts ===
// import { command } from "yargs";
// command("foo", yargs => {
// yargs./*GOTO SOURCE DEF*/positional();
// });
// === Details ===
[
{
"containerKind": "",
"containerName": "",
"kind": "",
"name": "",
"unverified": true
}
]

View File

@ -0,0 +1,21 @@
// === goToSourceDefinition ===
// === /node_modules/yargs/callback.js ===
// export class Yargs { [|positional|]() { } }
// === /some/index.ts ===
// import { random } from "../folder/random";
// import { command } from "yargs";
// command("foo", yargs => {
// yargs./*GOTO SOURCE DEF*/positional();
// });
// === Details ===
[
{
"containerKind": "",
"containerName": "",
"kind": "",
"name": "",
"unverified": true
}
]

View File

@ -59,6 +59,19 @@ FsWatches::
/b.d.ts: *new*
{}
Before request
Info seq [hh:mm:ss:mss] request:
{
"command": "findSourceDefinition",
"arguments": {
"file": "/a.ts",
"line": 1,
"offset": 10
},
"seq": 2,
"type": "request"
}
Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /dev/null/auxiliaryProject1*
Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /b.js 500 undefined WatchType: Closed Script info
Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /dev/null/auxiliaryProject1* Version: 1 structureChanged: true structureIsReused:: Not Elapsed:: *ms
@ -74,7 +87,32 @@ Info seq [hh:mm:ss:mss] Files (2)
Root file specified for compilation
Info seq [hh:mm:ss:mss] -----------------------------------------------
Before request
Info seq [hh:mm:ss:mss] response:
{
"response": [
{
"file": "/b.js",
"start": {
"line": 1,
"offset": 14
},
"end": {
"line": 1,
"offset": 15
},
"contextStart": {
"line": 1,
"offset": 1
},
"contextEnd": {
"line": 1,
"offset": 18
}
}
],
"responseRequired": true
}
After request
PolledWatches::
/a/lib/lib.d.ts:
@ -86,13 +124,15 @@ FsWatches::
/b.js: *new*
{}
Before request
Info seq [hh:mm:ss:mss] request:
{
"command": "open",
"arguments": {
"file": "/b.js"
},
"seq": 2,
"seq": 3,
"type": "request"
}
Info seq [hh:mm:ss:mss] FileWatcher:: Close:: WatchInfo: /b.js 500 undefined WatchType: Closed Script info

View File

@ -0,0 +1,318 @@
currentDirectory:: / useCaseSensitiveFileNames: false
Info seq [hh:mm:ss:mss] Provided types map file "/a/lib/typesMap.json" doesn't exist
Before request
//// [/user/users/projects/myproject/node_modules/@types/yargs/package.json]
{
"name": "@types/yargs",
"version": "1.0.0",
"types": "./index.d.ts"
}
//// [/user/users/projects/myproject/node_modules/@types/yargs/callback.d.ts]
export declare class Yargs { positional(): Yargs; }
//// [/user/users/projects/myproject/node_modules/@types/yargs/index.d.ts]
import { Yargs } from "./callback";
export declare function command(command: string, cb: (yargs: Yargs) => void): void;
//// [/user/users/projects/myproject/node_modules/yargs/package.json]
{
"name": "yargs",
"version": "1.0.0",
"main": "index.js"
}
//// [/user/users/projects/myproject/node_modules/yargs/callback.js]
export class Yargs { positional() { } }
//// [/user/users/projects/myproject/node_modules/yargs/index.js]
// Specifically didnt have ./callback import to ensure that resolving module sepcifier adds the file to project at later stage
export function command(cmd, cb) { cb(Yargs) }
//// [/user/users/projects/myproject/index.ts]
import { command } from "yargs";
command("foo", yargs => {
yargs.positional();
});
//// [/a/lib/lib.d.ts]
/// <reference no-default-lib="true"/>
interface Boolean {}
interface Function {}
interface CallableFunction {}
interface NewableFunction {}
interface IArguments {}
interface Number { toExponential: any; }
interface Object {}
interface RegExp {}
interface String { charAt: any; }
interface Array<T> { length: number; [n: number]: T; }
Info seq [hh:mm:ss:mss] request:
{
"command": "open",
"arguments": {
"file": "/user/users/projects/myproject/index.ts"
},
"seq": 1,
"type": "request"
}
Info seq [hh:mm:ss:mss] Search path: /user/users/projects/myproject
Info seq [hh:mm:ss:mss] For info: /user/users/projects/myproject/index.ts :: No config files found.
Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /user/users/projects/myproject/tsconfig.json 2000 undefined WatchType: Config file for the inferred project root
Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /user/users/projects/myproject/jsconfig.json 2000 undefined WatchType: Config file for the inferred project root
Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /dev/null/inferredProject1*
Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /user/users/projects/myproject/node_modules 1 undefined WatchType: node_modules for closed script infos and package.jsons affecting module specifier cache
Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/users/projects/myproject/node_modules 1 undefined WatchType: node_modules for closed script infos and package.jsons affecting module specifier cache
Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /user/users/projects/myproject/node_modules 1 undefined Project: /dev/null/inferredProject1* WatchType: Failed Lookup Locations
Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/users/projects/myproject/node_modules 1 undefined Project: /dev/null/inferredProject1* WatchType: Failed Lookup Locations
Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /user/users/projects/myproject/node_modules/@types/yargs/package.json 2000 undefined Project: /dev/null/inferredProject1* WatchType: File location affecting resolution
Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /a/lib/lib.d.ts 500 undefined WatchType: Closed Script info
Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /user/users/projects/myproject/node_modules/yargs/package.json 2000 undefined Project: /dev/null/inferredProject1* WatchType: File location affecting resolution
Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /user/users/projects/myproject/node_modules/@types 1 undefined Project: /dev/null/inferredProject1* WatchType: Type roots
Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/users/projects/myproject/node_modules/@types 1 undefined Project: /dev/null/inferredProject1* WatchType: Type roots
Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /user/users/projects/node_modules/@types 1 undefined Project: /dev/null/inferredProject1* WatchType: Type roots
Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/users/projects/node_modules/@types 1 undefined Project: /dev/null/inferredProject1* WatchType: Type roots
Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /dev/null/inferredProject1* Version: 1 structureChanged: true structureIsReused:: Not Elapsed:: *ms
Info seq [hh:mm:ss:mss] Project '/dev/null/inferredProject1*' (Inferred)
Info seq [hh:mm:ss:mss] Files (4)
/a/lib/lib.d.ts Text-1 "/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }"
/user/users/projects/myproject/node_modules/@types/yargs/callback.d.ts Text-1 "export declare class Yargs { positional(): Yargs; }\n"
/user/users/projects/myproject/node_modules/@types/yargs/index.d.ts Text-1 "\nimport { Yargs } from \"./callback\";\nexport declare function command(command: string, cb: (yargs: Yargs) => void): void;\n"
/user/users/projects/myproject/index.ts SVC-1-0 "import { command } from \"yargs\";\ncommand(\"foo\", yargs => {\n yargs.positional();\n});\n"
../../../../a/lib/lib.d.ts
Default library for target 'es5'
node_modules/@types/yargs/callback.d.ts
Imported via "./callback" from file 'node_modules/@types/yargs/index.d.ts' with packageId '@types/yargs/callback.d.ts@1.0.0'
node_modules/@types/yargs/index.d.ts
Imported via "yargs" from file 'index.ts' with packageId '@types/yargs/index.d.ts@1.0.0'
Entry point for implicit type library 'yargs' with packageId '@types/yargs/index.d.ts@1.0.0'
index.ts
Root file specified for compilation
Info seq [hh:mm:ss:mss] -----------------------------------------------
Info seq [hh:mm:ss:mss] Project '/dev/null/inferredProject1*' (Inferred)
Info seq [hh:mm:ss:mss] Files (4)
Info seq [hh:mm:ss:mss] -----------------------------------------------
Info seq [hh:mm:ss:mss] Open files:
Info seq [hh:mm:ss:mss] FileName: /user/users/projects/myproject/index.ts ProjectRootPath: undefined
Info seq [hh:mm:ss:mss] Projects: /dev/null/inferredProject1*
Info seq [hh:mm:ss:mss] response:
{
"responseRequired": false
}
After request
PolledWatches::
/user/users/projects/myproject/jsconfig.json: *new*
{"pollingInterval":2000}
/user/users/projects/myproject/tsconfig.json: *new*
{"pollingInterval":2000}
/user/users/projects/node_modules/@types: *new*
{"pollingInterval":500}
FsWatches::
/a/lib/lib.d.ts: *new*
{}
/user/users/projects/myproject/node_modules/@types/yargs/package.json: *new*
{}
/user/users/projects/myproject/node_modules/yargs/package.json: *new*
{}
FsWatchesRecursive::
/user/users/projects/myproject/node_modules: *new*
{}
/user/users/projects/myproject/node_modules/@types: *new*
{}
Before request
Info seq [hh:mm:ss:mss] request:
{
"command": "findSourceDefinition",
"arguments": {
"file": "/user/users/projects/myproject/index.ts",
"line": 3,
"offset": 11
},
"seq": 2,
"type": "request"
}
Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /dev/null/auxiliaryProject1*
Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /user/users/projects/myproject/node_modules 1 undefined Project: /dev/null/auxiliaryProject1* WatchType: Failed Lookup Locations
Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/users/projects/myproject/node_modules 1 undefined Project: /dev/null/auxiliaryProject1* WatchType: Failed Lookup Locations
Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /user/users/projects/node_modules 1 undefined Project: /dev/null/auxiliaryProject1* WatchType: Failed Lookup Locations
Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/users/projects/node_modules 1 undefined Project: /dev/null/auxiliaryProject1* WatchType: Failed Lookup Locations
Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /user/users/projects/myproject/node_modules/yargs/package.json 2000 undefined Project: /dev/null/auxiliaryProject1* WatchType: File location affecting resolution
Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /dev/null/auxiliaryProject1* Version: 1 structureChanged: true structureIsReused:: Not Elapsed:: *ms
Info seq [hh:mm:ss:mss] Project '/dev/null/auxiliaryProject1*' (Auxiliary)
Info seq [hh:mm:ss:mss] Files (2)
/user/users/projects/myproject/node_modules/yargs/index.js Text-1 "// Specifically didnt have ./callback import to ensure that resolving module sepcifier adds the file to project at later stage\nexport function command(cmd, cb) { cb(Yargs) }\n"
/user/users/projects/myproject/index.ts SVC-1-0 "import { command } from \"yargs\";\ncommand(\"foo\", yargs => {\n yargs.positional();\n});\n"
node_modules/yargs/index.js
Imported via "yargs" from file 'index.ts' with packageId 'yargs/index.js@1.0.0'
index.ts
Root file specified for compilation
Info seq [hh:mm:ss:mss] -----------------------------------------------
Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /dev/null/auxiliaryProject1*
Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /dev/null/auxiliaryProject1* Version: 2 structureChanged: true structureIsReused:: Not Elapsed:: *ms
Info seq [hh:mm:ss:mss] Project '/dev/null/auxiliaryProject1*' (Auxiliary)
Info seq [hh:mm:ss:mss] Files (3)
/user/users/projects/myproject/node_modules/yargs/index.js Text-1 "// Specifically didnt have ./callback import to ensure that resolving module sepcifier adds the file to project at later stage\nexport function command(cmd, cb) { cb(Yargs) }\n"
/user/users/projects/myproject/index.ts SVC-1-0 "import { command } from \"yargs\";\ncommand(\"foo\", yargs => {\n yargs.positional();\n});\n"
/user/users/projects/myproject/node_modules/yargs/callback.js Text-1 "export class Yargs { positional() { } }\n"
node_modules/yargs/index.js
Imported via "yargs" from file 'index.ts' with packageId 'yargs/index.js@1.0.0'
index.ts
Root file specified for compilation
node_modules/yargs/callback.js
Root file specified for compilation
Info seq [hh:mm:ss:mss] -----------------------------------------------
Info seq [hh:mm:ss:mss] response:
{
"response": [
{
"file": "/user/users/projects/myproject/node_modules/yargs/callback.js",
"start": {
"line": 1,
"offset": 22
},
"end": {
"line": 1,
"offset": 32
},
"contextStart": {
"line": 1,
"offset": 22
},
"contextEnd": {
"line": 1,
"offset": 38
},
"unverified": true
}
],
"responseRequired": true
}
After request
PolledWatches::
/user/users/projects/myproject/jsconfig.json:
{"pollingInterval":2000}
/user/users/projects/myproject/tsconfig.json:
{"pollingInterval":2000}
/user/users/projects/node_modules: *new*
{"pollingInterval":500}
/user/users/projects/node_modules/@types:
{"pollingInterval":500}
FsWatches::
/a/lib/lib.d.ts:
{}
/user/users/projects/myproject/node_modules/@types/yargs/package.json:
{}
/user/users/projects/myproject/node_modules/yargs/package.json:
{}
FsWatchesRecursive::
/user/users/projects/myproject/node_modules:
{}
/user/users/projects/myproject/node_modules/@types:
{}
Before request
Info seq [hh:mm:ss:mss] request:
{
"command": "findSourceDefinition",
"arguments": {
"file": "/user/users/projects/myproject/index.ts",
"line": 3,
"offset": 11
},
"seq": 3,
"type": "request"
}
Info seq [hh:mm:ss:mss] response:
{
"response": [
{
"file": "/user/users/projects/myproject/node_modules/yargs/callback.js",
"start": {
"line": 1,
"offset": 22
},
"end": {
"line": 1,
"offset": 32
},
"contextStart": {
"line": 1,
"offset": 22
},
"contextEnd": {
"line": 1,
"offset": 38
},
"unverified": true
}
],
"responseRequired": true
}
After request
Before request
Info seq [hh:mm:ss:mss] request:
{
"command": "findSourceDefinition",
"arguments": {
"file": "/user/users/projects/myproject/index.ts",
"line": 2,
"offset": 1
},
"seq": 4,
"type": "request"
}
Info seq [hh:mm:ss:mss] response:
{
"response": [
{
"file": "/user/users/projects/myproject/node_modules/yargs/index.js",
"start": {
"line": 2,
"offset": 17
},
"end": {
"line": 2,
"offset": 24
},
"contextStart": {
"line": 2,
"offset": 1
},
"contextEnd": {
"line": 2,
"offset": 47
}
}
],
"responseRequired": true
}
After request

View File

@ -0,0 +1,272 @@
currentDirectory:: / useCaseSensitiveFileNames: false
Info seq [hh:mm:ss:mss] Provided types map file "/a/lib/typesMap.json" doesn't exist
Before request
//// [/user/users/projects/myproject/node_modules/@types/yargs/package.json]
{
"name": "@types/yargs",
"version": "1.0.0",
"types": "./index.d.ts"
}
//// [/user/users/projects/myproject/node_modules/@types/yargs/callback.d.ts]
export declare class Yargs { positional(): Yargs; }
//// [/user/users/projects/myproject/node_modules/@types/yargs/index.d.ts]
import { Yargs } from "./callback";
export declare function command(command: string, cb: (yargs: Yargs) => void): void;
//// [/user/users/projects/myproject/node_modules/yargs/package.json]
{
"name": "yargs",
"version": "1.0.0",
"main": "index.js"
}
//// [/user/users/projects/myproject/node_modules/yargs/callback.js]
export class Yargs { positional() { } }
//// [/user/users/projects/myproject/node_modules/yargs/index.js]
// Specifically didnt have ./callback import to ensure that resolving module sepcifier adds the file to project at later stage
export function command(cmd, cb) { cb(Yargs) }
//// [/user/users/projects/myproject/folder/random.ts]
import { Yargs } from "yargs/callback";
//// [/user/users/projects/myproject/some/index.ts]
import { random } from "../folder/random";
import { command } from "yargs";
command("foo", yargs => {
yargs.positional();
});
//// [/a/lib/lib.d.ts]
/// <reference no-default-lib="true"/>
interface Boolean {}
interface Function {}
interface CallableFunction {}
interface NewableFunction {}
interface IArguments {}
interface Number { toExponential: any; }
interface Object {}
interface RegExp {}
interface String { charAt: any; }
interface Array<T> { length: number; [n: number]: T; }
Info seq [hh:mm:ss:mss] request:
{
"command": "open",
"arguments": {
"file": "/user/users/projects/myproject/some/index.ts"
},
"seq": 1,
"type": "request"
}
Info seq [hh:mm:ss:mss] Search path: /user/users/projects/myproject/some
Info seq [hh:mm:ss:mss] For info: /user/users/projects/myproject/some/index.ts :: No config files found.
Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /user/users/projects/myproject/some/tsconfig.json 2000 undefined WatchType: Config file for the inferred project root
Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /user/users/projects/myproject/some/jsconfig.json 2000 undefined WatchType: Config file for the inferred project root
Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /user/users/projects/myproject/tsconfig.json 2000 undefined WatchType: Config file for the inferred project root
Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /user/users/projects/myproject/jsconfig.json 2000 undefined WatchType: Config file for the inferred project root
Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /dev/null/inferredProject1*
Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /user/users/projects/myproject/folder/random.ts 500 undefined WatchType: Closed Script info
Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /user/users/projects/myproject/node_modules 1 undefined WatchType: node_modules for closed script infos and package.jsons affecting module specifier cache
Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/users/projects/myproject/node_modules 1 undefined WatchType: node_modules for closed script infos and package.jsons affecting module specifier cache
Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /user/users/projects/myproject/node_modules 1 undefined Project: /dev/null/inferredProject1* WatchType: Failed Lookup Locations
Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/users/projects/myproject/node_modules 1 undefined Project: /dev/null/inferredProject1* WatchType: Failed Lookup Locations
Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /user/users/projects/myproject/node_modules/@types/yargs/package.json 2000 undefined Project: /dev/null/inferredProject1* WatchType: File location affecting resolution
Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /user/users/projects/myproject/some/node_modules 1 undefined Project: /dev/null/inferredProject1* WatchType: Failed Lookup Locations
Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/users/projects/myproject/some/node_modules 1 undefined Project: /dev/null/inferredProject1* WatchType: Failed Lookup Locations
Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /a/lib/lib.d.ts 500 undefined WatchType: Closed Script info
Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /user/users/projects/myproject/node_modules/yargs/package.json 2000 undefined Project: /dev/null/inferredProject1* WatchType: File location affecting resolution
Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /user/users/projects/myproject/folder/node_modules 1 undefined Project: /dev/null/inferredProject1* WatchType: Failed Lookup Locations
Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/users/projects/myproject/folder/node_modules 1 undefined Project: /dev/null/inferredProject1* WatchType: Failed Lookup Locations
Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /user/users/projects/myproject/some/node_modules/@types 1 undefined Project: /dev/null/inferredProject1* WatchType: Type roots
Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/users/projects/myproject/some/node_modules/@types 1 undefined Project: /dev/null/inferredProject1* WatchType: Type roots
Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /user/users/projects/myproject/node_modules/@types 1 undefined Project: /dev/null/inferredProject1* WatchType: Type roots
Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/users/projects/myproject/node_modules/@types 1 undefined Project: /dev/null/inferredProject1* WatchType: Type roots
Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /user/users/projects/node_modules/@types 1 undefined Project: /dev/null/inferredProject1* WatchType: Type roots
Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/users/projects/node_modules/@types 1 undefined Project: /dev/null/inferredProject1* WatchType: Type roots
Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /dev/null/inferredProject1* Version: 1 structureChanged: true structureIsReused:: Not Elapsed:: *ms
Info seq [hh:mm:ss:mss] Project '/dev/null/inferredProject1*' (Inferred)
Info seq [hh:mm:ss:mss] Files (5)
/a/lib/lib.d.ts Text-1 "/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }"
/user/users/projects/myproject/node_modules/@types/yargs/callback.d.ts Text-1 "export declare class Yargs { positional(): Yargs; }\n"
/user/users/projects/myproject/folder/random.ts Text-1 "import { Yargs } from \"yargs/callback\";\n"
/user/users/projects/myproject/node_modules/@types/yargs/index.d.ts Text-1 "\nimport { Yargs } from \"./callback\";\nexport declare function command(command: string, cb: (yargs: Yargs) => void): void;\n"
/user/users/projects/myproject/some/index.ts SVC-1-0 "import { random } from \"../folder/random\";\nimport { command } from \"yargs\";\ncommand(\"foo\", yargs => {\n yargs.positional();\n});\n"
../../../../../a/lib/lib.d.ts
Default library for target 'es5'
../node_modules/@types/yargs/callback.d.ts
Imported via "yargs/callback" from file '../folder/random.ts' with packageId '@types/yargs/callback.d.ts@1.0.0'
Imported via "./callback" from file '../node_modules/@types/yargs/index.d.ts' with packageId '@types/yargs/callback.d.ts@1.0.0'
../folder/random.ts
Imported via "../folder/random" from file 'index.ts'
../node_modules/@types/yargs/index.d.ts
Imported via "yargs" from file 'index.ts' with packageId '@types/yargs/index.d.ts@1.0.0'
Entry point for implicit type library 'yargs' with packageId '@types/yargs/index.d.ts@1.0.0'
index.ts
Root file specified for compilation
Info seq [hh:mm:ss:mss] -----------------------------------------------
Info seq [hh:mm:ss:mss] Project '/dev/null/inferredProject1*' (Inferred)
Info seq [hh:mm:ss:mss] Files (5)
Info seq [hh:mm:ss:mss] -----------------------------------------------
Info seq [hh:mm:ss:mss] Open files:
Info seq [hh:mm:ss:mss] FileName: /user/users/projects/myproject/some/index.ts ProjectRootPath: undefined
Info seq [hh:mm:ss:mss] Projects: /dev/null/inferredProject1*
Info seq [hh:mm:ss:mss] response:
{
"responseRequired": false
}
After request
PolledWatches::
/user/users/projects/myproject/folder/node_modules: *new*
{"pollingInterval":500}
/user/users/projects/myproject/jsconfig.json: *new*
{"pollingInterval":2000}
/user/users/projects/myproject/some/jsconfig.json: *new*
{"pollingInterval":2000}
/user/users/projects/myproject/some/node_modules: *new*
{"pollingInterval":500}
/user/users/projects/myproject/some/node_modules/@types: *new*
{"pollingInterval":500}
/user/users/projects/myproject/some/tsconfig.json: *new*
{"pollingInterval":2000}
/user/users/projects/myproject/tsconfig.json: *new*
{"pollingInterval":2000}
/user/users/projects/node_modules/@types: *new*
{"pollingInterval":500}
FsWatches::
/a/lib/lib.d.ts: *new*
{}
/user/users/projects/myproject/folder/random.ts: *new*
{}
/user/users/projects/myproject/node_modules/@types/yargs/package.json: *new*
{}
/user/users/projects/myproject/node_modules/yargs/package.json: *new*
{}
FsWatchesRecursive::
/user/users/projects/myproject/node_modules: *new*
{}
/user/users/projects/myproject/node_modules/@types: *new*
{}
Before request
Info seq [hh:mm:ss:mss] request:
{
"command": "findSourceDefinition",
"arguments": {
"file": "/user/users/projects/myproject/some/index.ts",
"line": 4,
"offset": 11
},
"seq": 2,
"type": "request"
}
Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /dev/null/auxiliaryProject1*
Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /user/users/projects/myproject/some/node_modules 1 undefined Project: /dev/null/auxiliaryProject1* WatchType: Failed Lookup Locations
Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/users/projects/myproject/some/node_modules 1 undefined Project: /dev/null/auxiliaryProject1* WatchType: Failed Lookup Locations
Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /user/users/projects/myproject/node_modules 1 undefined Project: /dev/null/auxiliaryProject1* WatchType: Failed Lookup Locations
Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/users/projects/myproject/node_modules 1 undefined Project: /dev/null/auxiliaryProject1* WatchType: Failed Lookup Locations
Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /user/users/projects/node_modules 1 undefined Project: /dev/null/auxiliaryProject1* WatchType: Failed Lookup Locations
Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/users/projects/node_modules 1 undefined Project: /dev/null/auxiliaryProject1* WatchType: Failed Lookup Locations
Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /user/users/projects/myproject/node_modules/yargs/package.json 2000 undefined Project: /dev/null/auxiliaryProject1* WatchType: File location affecting resolution
Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /user/users/projects/myproject/folder/node_modules 1 undefined Project: /dev/null/auxiliaryProject1* WatchType: Failed Lookup Locations
Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/users/projects/myproject/folder/node_modules 1 undefined Project: /dev/null/auxiliaryProject1* WatchType: Failed Lookup Locations
Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /dev/null/auxiliaryProject1* Version: 1 structureChanged: true structureIsReused:: Not Elapsed:: *ms
Info seq [hh:mm:ss:mss] Project '/dev/null/auxiliaryProject1*' (Auxiliary)
Info seq [hh:mm:ss:mss] Files (4)
/user/users/projects/myproject/node_modules/yargs/callback.js Text-1 "export class Yargs { positional() { } }\n"
/user/users/projects/myproject/folder/random.ts Text-1 "import { Yargs } from \"yargs/callback\";\n"
/user/users/projects/myproject/node_modules/yargs/index.js Text-1 "// Specifically didnt have ./callback import to ensure that resolving module sepcifier adds the file to project at later stage\nexport function command(cmd, cb) { cb(Yargs) }\n"
/user/users/projects/myproject/some/index.ts SVC-1-0 "import { random } from \"../folder/random\";\nimport { command } from \"yargs\";\ncommand(\"foo\", yargs => {\n yargs.positional();\n});\n"
../node_modules/yargs/callback.js
Imported via "yargs/callback" from file '../folder/random.ts' with packageId 'yargs/callback.js@1.0.0'
../folder/random.ts
Imported via "../folder/random" from file 'index.ts'
../node_modules/yargs/index.js
Imported via "yargs" from file 'index.ts' with packageId 'yargs/index.js@1.0.0'
index.ts
Root file specified for compilation
Info seq [hh:mm:ss:mss] -----------------------------------------------
Info seq [hh:mm:ss:mss] response:
{
"response": [
{
"file": "/user/users/projects/myproject/node_modules/yargs/callback.js",
"start": {
"line": 1,
"offset": 22
},
"end": {
"line": 1,
"offset": 32
},
"contextStart": {
"line": 1,
"offset": 22
},
"contextEnd": {
"line": 1,
"offset": 38
},
"unverified": true
}
],
"responseRequired": true
}
After request
PolledWatches::
/user/users/projects/myproject/folder/node_modules:
{"pollingInterval":500}
/user/users/projects/myproject/jsconfig.json:
{"pollingInterval":2000}
/user/users/projects/myproject/some/jsconfig.json:
{"pollingInterval":2000}
/user/users/projects/myproject/some/node_modules:
{"pollingInterval":500}
/user/users/projects/myproject/some/node_modules/@types:
{"pollingInterval":500}
/user/users/projects/myproject/some/tsconfig.json:
{"pollingInterval":2000}
/user/users/projects/myproject/tsconfig.json:
{"pollingInterval":2000}
/user/users/projects/node_modules: *new*
{"pollingInterval":500}
/user/users/projects/node_modules/@types:
{"pollingInterval":500}
FsWatches::
/a/lib/lib.d.ts:
{}
/user/users/projects/myproject/folder/random.ts:
{}
/user/users/projects/myproject/node_modules/@types/yargs/package.json:
{}
/user/users/projects/myproject/node_modules/yargs/package.json:
{}
FsWatchesRecursive::
/user/users/projects/myproject/node_modules:
{}
/user/users/projects/myproject/node_modules/@types:
{}

View File

@ -0,0 +1,41 @@
/// <reference path="../fourslash.ts" />
// @moduleResolution: node
// This is just modified repro to ensure we are resolving module specifier thats not already present in the file
// @Filename: /node_modules/@types/yargs/package.json
//// {
//// "name": "@types/yargs",
//// "version": "1.0.0",
//// "types": "./index.d.ts"
//// }
// @Filename: /node_modules/@types/yargs/callback.d.ts
//// export declare class Yargs { positional(): Yargs; }
// @Filename: /node_modules/@types/yargs/index.d.ts
//// import { Yargs } from "./callback";
//// export declare function command(command: string, cb: (yargs: Yargs) => void): void;
// @Filename: /node_modules/yargs/package.json
//// {
//// "name": "yargs",
//// "version": "1.0.0",
//// "main": "index.js"
//// }
// @Filename: /node_modules/yargs/callback.js
//// export class Yargs { positional() { } }
// @Filename: /node_modules/yargs/index.js
//// import { Yargs } from "./callback";
//// export function command(cmd, cb) { cb(Yargs) }
// @Filename: /index.ts
//// import { command } from "yargs";
//// command("foo", yargs => {
//// yargs.[|/*start*/positional|]();
//// });
verify.baselineGoToSourceDefinition("start");

View File

@ -0,0 +1,42 @@
/// <reference path="../fourslash.ts" />
// @moduleResolution: node
// This is just made up repro where the js file will be added to auxillary project because its not already part of the project
// Where in js file doesnt already have import to the corresponding js file hence will be added to project at later on stage
// @Filename: /node_modules/@types/yargs/package.json
//// {
//// "name": "@types/yargs",
//// "version": "1.0.0",
//// "types": "./index.d.ts"
//// }
// @Filename: /node_modules/@types/yargs/callback.d.ts
//// export declare class Yargs { positional(): Yargs; }
// @Filename: /node_modules/@types/yargs/index.d.ts
//// import { Yargs } from "./callback";
//// export declare function command(command: string, cb: (yargs: Yargs) => void): void;
// @Filename: /node_modules/yargs/package.json
//// {
//// "name": "yargs",
//// "version": "1.0.0",
//// "main": "index.js"
//// }
// @Filename: /node_modules/yargs/callback.js
//// export class Yargs { positional() { } }
// @Filename: /node_modules/yargs/index.js
//// // Specifically didnt have ./callback import to ensure that resolving module sepcifier adds the file to project at later stage
//// export function command(cmd, cb) { cb(Yargs) }
// @Filename: /index.ts
//// import { command } from "yargs";
//// command("foo", yargs => {
//// yargs.[|/*start*/positional|]();
//// });
verify.baselineGoToSourceDefinition("start");

View File

@ -0,0 +1,46 @@
/// <reference path="../fourslash.ts" />
// @moduleResolution: node
// This is just made up repro where the js file will be added to auxillary project because its not already part of the project
// Where in js file doesnt already have import to the corresponding js file hence will be added to project at later on stage
// @Filename: /node_modules/@types/yargs/package.json
//// {
//// "name": "@types/yargs",
//// "version": "1.0.0",
//// "types": "./index.d.ts"
//// }
// @Filename: /node_modules/@types/yargs/callback.d.ts
//// export declare class Yargs { positional(): Yargs; }
// @Filename: /node_modules/@types/yargs/index.d.ts
//// import { Yargs } from "./callback";
//// export declare function command(command: string, cb: (yargs: Yargs) => void): void;
// @Filename: /node_modules/yargs/package.json
//// {
//// "name": "yargs",
//// "version": "1.0.0",
//// "main": "index.js"
//// }
// @Filename: /node_modules/yargs/callback.js
//// export class Yargs { positional() { } }
// @Filename: /node_modules/yargs/index.js
//// // Specifically didnt have ./callback import to ensure that resolving module sepcifier adds the file to project at later stage
//// export function command(cmd, cb) { cb(Yargs) }
// @Filename: /folder/random.ts
//// import { Yargs } from "yargs/callback";
// @Filename: /some/index.ts
//// import { random } from "../folder/random";
//// import { command } from "yargs";
//// command("foo", yargs => {
//// yargs.[|/*start*/positional|]();
//// });
verify.baselineGoToSourceDefinition("start");