switch (this.containingProjects.length) { case 0: return false; case 1: return this.containingProjects[0] === project; case 2: return this.containingProjects[0] === project || this.containingProjects[1] === project; default: return contains(this.containingProjects, project); } } detachFromProject(project) { switch (this.containingProjects.length) { case 0: return; case 1: if (this.containingProjects[0] === project) { project.onFileAddedOrRemoved(this.isSymlink()); this.containingProjects.pop(); } break; case 2: if (this.containingProjects[0] === project) { project.onFileAddedOrRemoved(this.isSymlink()); this.containingProjects[0] = this.containingProjects.pop(); } else if (this.containingProjects[1] === project) { project.onFileAddedOrRemoved(this.isSymlink()); this.containingProjects.pop(); } break; default: if (orderedRemoveItem(this.containingProjects, project)) { project.onFileAddedOrRemoved(this.isSymlink()); } break; } } detachAllProjects() { for (const p of this.containingProjects) { if (isConfiguredProject(p)) { p.getCachedDirectoryStructureHost().addOrDeleteFile(this.fileName, this.path, 2 /* Deleted */); } const existingRoot = p.getRootFilesMap().get(this.path); p.removeFile( this, /*fileExists*/ false, /*detachFromProject*/ false ); p.onFileAddedOrRemoved(this.isSymlink()); if (existingRoot && !isInferredProject(p)) { p.addMissingFileRoot(existingRoot.fileName); } } clear(this.containingProjects); } getDefaultProject() { switch (this.containingProjects.length) { case 0: return Errors.ThrowNoProject(); case 1: return isProjectDeferredClose(this.containingProjects[0]) || isBackgroundProject(this.containingProjects[0]) ? Errors.ThrowNoProject() : this.containingProjects[0]; default: let firstConfiguredProject; let firstInferredProject; let firstNonSourceOfProjectReferenceRedirect; let defaultConfiguredProject; for (let index = 0; index < this.containingProjects.length; index++) { const project = this.containingProjects[index]; if (isConfiguredProject(project)) { if (project.deferredClose) continue; if (!project.isSourceOfProjectReferenceRedirect(this.fileName)) { if (defaultConfiguredProject === void 0 && index !== this.containingProjects.length - 1) { defaultConfiguredProject = project.projectService.findDefaultConfiguredProject(this) || false; } if (defaultConfiguredProject === project) return project; if (!firstNonSourceOfProjectReferenceRedirect) firstNonSourceOfProjectReferenceRedirect = project; } if (!firstConfiguredProject) firstConfiguredProject = project; } else if (isExternalProject(project)) { return project; } else if (!firstInferredProject && isInferredProject(project)) { firstInferredProject = project; } } return (defaultConfiguredProject || firstNonSourceOfProjectReferenceRedirect || firstConfiguredProject || firstInferredProject) ?? Errors.ThrowNoProject(); } } registerFileUpdate() { for (const p of this.containingProjects) { p.registerFileUpdate(this.path); } } setOptions(formatSettings, preferences) { if (formatSettings) { if (!this.formatSettings) { this.formatSettings = getDefaultFormatCodeSettings(this.host.newLine); assign(this.formatSettings, formatSettings); } else { this.formatSettings = { ...this.formatSettings, ...formatSettings }; } } if (preferences) { if (!this.preferences) { this.preferences = emptyOptions; } this.preferences = { ...this.preferences, ...preferences }; } } getLatestVersion() { this.textStorage.getSnapshot(); return this.textStorage.getVersion(); } saveTo(fileName) { this.host.writeFile(fileName, getSnapshotText(this.textStorage.getSnapshot())); } /** @internal */ delayReloadNonMixedContentFile() { Debug.assert(!this.isDynamicOrHasMixedContent()); this.textStorage.delayReloadFromFileIntoText(); this.markContainingProjectsAsDirty(); } reloadFromFile(tempFileName) { if (this.textStorage.reloadWithFileText(tempFileName)) { this.markContainingProjectsAsDirty(); return true; } return false; } editContent(start, end, newText) { this.textStorage.edit(start, end, newText); this.markContainingProjectsAsDirty(); } markContainingProjectsAsDirty() { for (const p of this.containingProjects) { p.markFileAsDirty(this.path); } } isOrphan() { return this.deferredDelete || !forEach(this.containingProjects, (p) => !p.isOrphan()); } /** @internal */ isContainedByBackgroundProject() { return some( this.containingProjects, isBackgroundProject ); } /** * @param line 1 based index */ lineToTextSpan(line) { return this.textStorage.lineToTextSpan(line); } // eslint-disable-line @typescript-eslint/unified-signatures lineOffsetToPosition(line, offset, allowEdits) { return this.textStorage.lineOffsetToPosition(line, offset, allowEdits); } positionToLineOffset(position) { failIfInvalidPosition(position); const location = this.textStorage.positionToLineOffset(position); failIfInvalidLocation(location); return location; } isJavaScript() { return this.scriptKind === 1 /* JS */ || this.scriptKind === 2 /* JSX */; } /** @internal */ closeSourceMapFileWatcher() { if (this.sourceMapFilePath && !isString(this.sourceMapFilePath)) { closeFileWatcherOf(this.sourceMapFilePath); this.sourceMapFilePath = void 0; } } }; function failIfInvalidPosition(position) { Debug.assert(typeof position === "number", `Expected position ${position} to be a number.`); Debug.assert(position >= 0, `Expected position to be non-negative.`); } function failIfInvalidLocation(location) { Debug.assert(typeof location.line === "number", `Expected line ${location.line} to be a number.`); Debug.assert(typeof location.offset === "number", `Expected offset ${location.offset} to be a number.`); Debug.assert(location.line > 0, `Expected line to be non-${location.line === 0 ? "zero" : "negative"}`); Debug.assert(location.offset > 0, `Expected offset to be non-${location.offset === 0 ? "zero" : "negative"}`); } // src/server/typingsCache.ts var nullTypingsInstaller = { isKnownTypesPackageName: returnFalse, // Should never be called because we never provide a types registry. installPackage: notImplemented, enqueueInstallTypingsRequest: noop, attach: noop, onProjectClosed: noop, globalTypingsCacheLocation: void 0 // TODO: GH#18217 }; function setIsEqualTo(arr1, arr2) { if (arr1 === arr2) { return true; } if ((arr1 || emptyArray2).length === 0 && (arr2 || emptyArray2).length === 0) { return true; } const set = /* @__PURE__ */ new Map(); let unique = 0; for (const v of arr1) { if (set.get(v) !== true) { set.set(v, true); unique++; } } for (const v of arr2) { const isSet = set.get(v); if (isSet === void 0) { return false; } if (isSet === true) { set.set(v, false); unique--; } } return unique === 0; } function typeAcquisitionChanged(opt1, opt2) { return opt1.enable !== opt2.enable || !setIsEqualTo(opt1.include, opt2.include) || !setIsEqualTo(opt1.exclude, opt2.exclude); } function compilerOptionsChanged(opt1, opt2) { return getAllowJSCompilerOption(opt1) !== getAllowJSCompilerOption(opt2); } function unresolvedImportsChanged(imports1, imports2) { if (imports1 === imports2) { return false; } return !arrayIsEqualTo(imports1, imports2); } var TypingsCache = class { constructor(installer) { this.installer = installer; this.perProjectCache = /* @__PURE__ */ new Map(); } isKnownTypesPackageName(name) { return this.installer.isKnownTypesPackageName(name); } installPackage(options) { return this.installer.installPackage(options); } enqueueInstallTypingsForProject(project, unresolvedImports, forceRefresh) { const typeAcquisition = project.getTypeAcquisition(); if (!typeAcquisition || !typeAcquisition.enable) { return; } const entry = this.perProjectCache.get(project.getProjectName()); if (forceRefresh || !entry || typeAcquisitionChanged(typeAcquisition, entry.typeAcquisition) || compilerOptionsChanged(project.getCompilationSettings(), entry.compilerOptions) || unresolvedImportsChanged(unresolvedImports, entry.unresolvedImports)) { this.perProjectCache.set(project.getProjectName(), { compilerOptions: project.getCompilationSettings(), typeAcquisition, typings: entry ? entry.typings : emptyArray2, unresolvedImports, poisoned: true }); this.installer.enqueueInstallTypingsRequest(project, typeAcquisition, unresolvedImports); } } updateTypingsForProject(projectName, compilerOptions, typeAcquisition, unresolvedImports, newTypings) { const typings = sort(newTypings); this.perProjectCache.set(projectName, { compilerOptions, typeAcquisition, typings, unresolvedImports, poisoned: false }); return !typeAcquisition || !typeAcquisition.enable ? emptyArray2 : typings; } onProjectClosed(project) { if (this.perProjectCache.delete(project.getProjectName())) { this.installer.onProjectClosed(project); } } }; // src/server/project.ts var ProjectKind = /* @__PURE__ */ ((ProjectKind2) => { ProjectKind2[ProjectKind2["Inferred"] = 0] = "Inferred"; ProjectKind2[ProjectKind2["Configured"] = 1] = "Configured"; ProjectKind2[ProjectKind2["External"] = 2] = "External"; ProjectKind2[ProjectKind2["AutoImportProvider"] = 3] = "AutoImportProvider"; ProjectKind2[ProjectKind2["Auxiliary"] = 4] = "Auxiliary"; return ProjectKind2; })(ProjectKind || {}); function countEachFileTypes(infos, includeSizes = false) { const result = { js: 0, jsSize: 0, jsx: 0, jsxSize: 0, ts: 0, tsSize: 0, tsx: 0, tsxSize: 0, dts: 0, dtsSize: 0, deferred: 0, deferredSize: 0 }; for (const info of infos) { const fileSize = includeSizes ? info.textStorage.getTelemetryFileSize() : 0; switch (info.scriptKind) { case 1 /* JS */: result.js += 1; result.jsSize += fileSize; break; case 2 /* JSX */: result.jsx += 1; result.jsxSize += fileSize; break; case 3 /* TS */: if (isDeclarationFileName(info.fileName)) { result.dts += 1; result.dtsSize += fileSize; } else { result.ts += 1; result.tsSize += fileSize; } break; case 4 /* TSX */: result.tsx += 1; result.tsxSize += fileSize; break; case 7 /* Deferred */: result.deferred += 1; result.deferredSize += fileSize; break; } } return result; } function hasOneOrMoreJsAndNoTsFiles(project) { const counts2 = countEachFileTypes(project.getScriptInfos()); return counts2.js > 0 && counts2.ts === 0 && counts2.tsx === 0; } function allRootFilesAreJsOrDts(project) { const counts2 = countEachFileTypes(project.getRootScriptInfos()); return counts2.ts === 0 && counts2.tsx === 0; } function allFilesAreJsOrDts(project) { const counts2 = countEachFileTypes(project.getScriptInfos()); return counts2.ts === 0 && counts2.tsx === 0; } function hasNoTypeScriptSource(fileNames) { return !fileNames.some((fileName) => fileExtensionIs(fileName, ".ts" /* Ts */) && !isDeclarationFileName(fileName) || fileExtensionIs(fileName, ".tsx" /* Tsx */)); } function isGeneratedFileWatcher(watch) { return watch.generatedFilePath !== void 0; } var Project3 = class _Project { /** @internal */ constructor(projectName, projectKind, projectService, documentRegistry, hasExplicitListOfFiles, lastFileExceededProgramSize, compilerOptions, compileOnSaveEnabled, watchOptions, directoryStructureHost, currentDirectory) { this.projectKind = projectKind; this.projectService = projectService; this.documentRegistry = documentRegistry; this.compilerOptions = compilerOptions; this.compileOnSaveEnabled = compileOnSaveEnabled; this.watchOptions = watchOptions; this.rootFilesMap = /* @__PURE__ */ new Map(); /** @internal */ this.plugins = []; /** * This is map from files to unresolved imports in it * Maop does not contain entries for files that do not have unresolved imports * This helps in containing the set of files to invalidate * * @internal */ this.cachedUnresolvedImportsPerFile = /* @__PURE__ */ new Map(); /** @internal */ this.hasAddedorRemovedFiles = false; /** @internal */ this.hasAddedOrRemovedSymlinks = false; /** * Last version that was reported. */ this.lastReportedVersion = 0; /** * Current project's program version. (incremented everytime new program is created that is not complete reuse from the old one) * This property is changed in 'updateGraph' based on the set of files in program * @internal */ this.projectProgramVersion = 0; /** * Current version of the project state. It is changed when: * - new root file was added/removed * - edit happen in some file that is currently included in the project. * This property is different from projectStructureVersion since in most cases edits don't affect set of files in the project * @internal */ this.projectStateVersion = 0; this.isInitialLoadPending = returnFalse; /** @internal */ this.dirty = false; /** @internal */ this.typingFiles = emptyArray2; /** @internal */ this.moduleSpecifierCache = createModuleSpecifierCache(this); /** @internal */ this.createHash = maybeBind(this.projectService.host, this.projectService.host.createHash); /** @internal */ this.globalCacheResolutionModuleName = ts_JsTyping_exports.nonRelativeModuleNameForTypingCache; /** @internal */ this.updateFromProjectInProgress = false; this.projectName = projectName; this.directoryStructureHost = directoryStructureHost; this.currentDirectory = this.projectService.getNormalizedAbsolutePath(currentDirectory); this.getCanonicalFileName = this.projectService.toCanonicalFileName; this.jsDocParsingMode = this.projectService.jsDocParsingMode; this.cancellationToken = new ThrottledCancellationToken(this.projectService.cancellationToken, this.projectService.throttleWaitMilliseconds); if (!this.compilerOptions) { this.compilerOptions = getDefaultCompilerOptions2(); this.compilerOptions.allowNonTsExtensions = true; this.compilerOptions.allowJs = true; } else if (hasExplicitListOfFiles || getAllowJSCompilerOption(this.compilerOptions) || this.projectService.hasDeferredExtension()) { this.compilerOptions.allowNonTsExtensions = true; } switch (projectService.serverMode) { case 0 /* Semantic */: this.languageServiceEnabled = true; break; case 1 /* PartialSemantic */: this.languageServiceEnabled = true; this.compilerOptions.noResolve = true; this.compilerOptions.types = []; break; case 2 /* Syntactic */: this.languageServiceEnabled = false; this.compilerOptions.noResolve = true; this.compilerOptions.types = []; break; default: Debug.assertNever(projectService.serverMode); } this.setInternalCompilerOptionsForEmittingJsFiles(); const host = this.projectService.host; if (this.projectService.logger.loggingEnabled()) { this.trace = (s) => this.writeLog(s); } else if (host.trace) { this.trace = (s) => host.trace(s); } this.realpath = maybeBind(host, host.realpath); this.resolutionCache = createResolutionCache( this, this.currentDirectory, /*logChangesWhenResolvingModule*/ true ); this.languageService = createLanguageService(this, this.documentRegistry, this.projectService.serverMode); if (lastFileExceededProgramSize) { this.disableLanguageService(lastFileExceededProgramSize); } this.markAsDirty(); if (!isBackgroundProject(this)) { this.projectService.pendingEnsureProjectForOpenFiles = true; } this.projectService.onProjectCreation(this); } /** @internal */ getResolvedProjectReferenceToRedirect(_fileName) { return void 0; } isNonTsProject() { updateProjectIfDirty(this); return allFilesAreJsOrDts(this); } isJsOnlyProject() { updateProjectIfDirty(this); return hasOneOrMoreJsAndNoTsFiles(this); } static resolveModule(moduleName, initialDir, host, log) { return _Project.importServicePluginSync({ name: moduleName }, [initialDir], host, log).resolvedModule; } /** @internal */ static importServicePluginSync(pluginConfigEntry, searchPaths, host, log) { Debug.assertIsDefined(host.require); let errorLogs; let resolvedModule; for (const initialDir of searchPaths) { const resolvedPath = normalizeSlashes(host.resolvePath(combinePaths(initialDir, "node_modules"))); log(`Loading ${pluginConfigEntry.name} from ${initialDir} (resolved to ${resolvedPath})`); const result = host.require(resolvedPath, pluginConfigEntry.name); if (!result.error) { resolvedModule = result.module; break; } const err = result.error.stack || result.error.message || JSON.stringify(result.error); (errorLogs ?? (errorLogs = [])).push(`Failed to load module '${pluginConfigEntry.name}' from ${resolvedPath}: ${err}`); } return { pluginConfigEntry, resolvedModule, errorLogs }; } /** @internal */ static async importServicePluginAsync(pluginConfigEntry, searchPaths, host, log) { Debug.assertIsDefined(host.importPlugin); let errorLogs; let resolvedModule; for (const initialDir of searchPaths) { const resolvedPath = combinePaths(initialDir, "node_modules"); log(`Dynamically importing ${pluginConfigEntry.name} from ${initialDir} (resolved to ${resolvedPath})`); let result; try { result = await host.importPlugin(resolvedPath, pluginConfigEntry.name); } catch (e) { result = { module: void 0, error: e }; } if (!result.error) { resolvedModule = result.module; break; } const err = result.error.stack || result.error.message || JSON.stringify(result.error); (errorLogs ?? (errorLogs = [])).push(`Failed to dynamically import module '${pluginConfigEntry.name}' from ${resolvedPath}: ${err}`); } return { pluginConfigEntry, resolvedModule, errorLogs }; } isKnownTypesPackageName(name) { return this.typingsCache.isKnownTypesPackageName(name); } installPackage(options) { return this.typingsCache.installPackage({ ...options, projectName: this.projectName, projectRootPath: this.toPath(this.currentDirectory) }); } /** @internal */ getGlobalTypingsCacheLocation() { return this.getGlobalCache(); } get typingsCache() { return this.projectService.typingsCache; } /** @internal */ getSymlinkCache() { if (!this.symlinks) { this.symlinks = createSymlinkCache(this.getCurrentDirectory(), this.getCanonicalFileName); } if (this.program && !this.symlinks.hasProcessedResolutions()) { this.symlinks.setSymlinksFromResolutions( this.program.forEachResolvedModule, this.program.forEachResolvedTypeReferenceDirective, this.program.getAutomaticTypeDirectiveResolutions() ); } return this.symlinks; } // Method of LanguageServiceHost getCompilationSettings() { return this.compilerOptions; } // Method to support public API getCompilerOptions() { return this.getCompilationSettings(); } getNewLine() { return this.projectService.host.newLine; } getProjectVersion() { return this.projectStateVersion.toString(); } getProjectReferences() { return void 0; } getScriptFileNames() { if (!this.rootFilesMap.size) { return emptyArray; } let result; this.rootFilesMap.forEach((value) => { if (this.languageServiceEnabled || value.info && value.info.isScriptOpen()) { (result || (result = [])).push(value.fileName); } }); return addRange(result, this.typingFiles) || emptyArray; } getOrCreateScriptInfoAndAttachToProject(fileName) { const scriptInfo = this.projectService.getOrCreateScriptInfoNotOpenedByClient( fileName, this.currentDirectory, this.directoryStructureHost, /*deferredDeleteOk*/ false ); if (scriptInfo) { const existingValue = this.rootFilesMap.get(scriptInfo.path); if (existingValue && existingValue.info !== scriptInfo) { existingValue.info = scriptInfo; } scriptInfo.attachToProject(this); } return scriptInfo; } getScriptKind(fileName) { const info = this.projectService.getScriptInfoForPath(this.toPath(fileName)); return info && info.scriptKind; } getScriptVersion(filename) { const info = this.projectService.getOrCreateScriptInfoNotOpenedByClient( filename, this.currentDirectory, this.directoryStructureHost, /*deferredDeleteOk*/ false ); return info && info.getLatestVersion(); } getScriptSnapshot(filename) { const scriptInfo = this.getOrCreateScriptInfoAndAttachToProject(filename); if (scriptInfo) { return scriptInfo.getSnapshot(); } } getCancellationToken() { return this.cancellationToken; } getCurrentDirectory() { return this.currentDirectory; } getDefaultLibFileName() { const nodeModuleBinDir = getDirectoryPath(normalizePath(this.projectService.getExecutingFilePath())); return combinePaths(nodeModuleBinDir, getDefaultLibFileName(this.compilerOptions)); } useCaseSensitiveFileNames() { return this.projectService.host.useCaseSensitiveFileNames; } readDirectory(path, extensions, exclude, include, depth) { return this.directoryStructureHost.readDirectory(path, extensions, exclude, include, depth); } readFile(fileName) { return this.projectService.host.readFile(fileName); } writeFile(fileName, content) { return this.projectService.host.writeFile(fileName, content); } fileExists(file) { const path = this.toPath(file); return !this.isWatchedMissingFile(path) && this.directoryStructureHost.fileExists(file); } /** @internal */ resolveModuleNameLiterals(moduleLiterals, containingFile, redirectedReference, options, containingSourceFile, reusedNames) { return this.resolutionCache.resolveModuleNameLiterals(moduleLiterals, containingFile, redirectedReference, options, containingSourceFile, reusedNames); } /** @internal */ getModuleResolutionCache() { return this.resolutionCache.getModuleResolutionCache(); } /** @internal */ resolveTypeReferenceDirectiveReferences(typeDirectiveReferences, containingFile, redirectedReference, options, containingSourceFile, reusedNames) { return this.resolutionCache.resolveTypeReferenceDirectiveReferences( typeDirectiveReferences, containingFile, redirectedReference, options, containingSourceFile, reusedNames ); } /** @internal */ resolveLibrary(libraryName, resolveFrom, options, libFileName) { return this.resolutionCache.resolveLibrary(libraryName, resolveFrom, options, libFileName); } directoryExists(path) { return this.directoryStructureHost.directoryExists(path); } getDirectories(path) { return this.directoryStructureHost.getDirectories(path); } /** @internal */ getCachedDirectoryStructureHost() { return void 0; } /** @internal */ toPath(fileName) { return toPath(fileName, this.currentDirectory, this.projectService.toCanonicalFileName); } /** @internal */ watchDirectoryOfFailedLookupLocation(directory, cb, flags) { return this.projectService.watchFactory.watchDirectory( directory, cb, flags, this.projectService.getWatchOptions(this), WatchType.FailedLookupLocations, this ); } /** @internal */ watchAffectingFileLocation(file, cb) { return this.projectService.watchFactory.watchFile( file, cb, 2e3 /* High */, this.projectService.getWatchOptions(this), WatchType.AffectingFileLocation, this ); } /** @internal */ clearInvalidateResolutionOfFailedLookupTimer() { return this.projectService.throttledOperations.cancel(`${this.getProjectName()}FailedLookupInvalidation`); } /** @internal */ scheduleInvalidateResolutionsOfFailedLookupLocations() { this.projectService.throttledOperations.schedule( `${this.getProjectName()}FailedLookupInvalidation`, /*delay*/ 1e3, () => { if (this.resolutionCache.invalidateResolutionsOfFailedLookupLocations()) { this.projectService.delayUpdateProjectGraphAndEnsureProjectStructureForOpenFiles(this); } } ); } /** @internal */ invalidateResolutionsOfFailedLookupLocations() { if (this.clearInvalidateResolutionOfFailedLookupTimer() && this.resolutionCache.invalidateResolutionsOfFailedLookupLocations()) { this.markAsDirty(); this.projectService.delayEnsureProjectForOpenFiles(); } } /** @internal */ onInvalidatedResolution() { this.projectService.delayUpdateProjectGraphAndEnsureProjectStructureForOpenFiles(this); } /** @internal */ watchTypeRootsDirectory(directory, cb, flags) { return this.projectService.watchFactory.watchDirectory( directory, cb, flags, this.projectService.getWatchOptions(this), WatchType.TypeRoots, this ); } /** @internal */ hasChangedAutomaticTypeDirectiveNames() { return this.resolutionCache.hasChangedAutomaticTypeDirectiveNames(); } /** @internal */ onChangedAutomaticTypeDirectiveNames() { this.projectService.delayUpdateProjectGraphAndEnsureProjectStructureForOpenFiles(this); } /** @internal */ getGlobalCache() { return this.getTypeAcquisition().enable ? this.projectService.typingsInstaller.globalTypingsCacheLocation : void 0; } /** @internal */ fileIsOpen(filePath) { return this.projectService.openFiles.has(filePath); } /** @internal */ writeLog(s) { this.projectService.logger.info(s); } log(s) { this.writeLog(s); } error(s) { this.projectService.logger.msg(s, "Err" /* Err */); } setInternalCompilerOptionsForEmittingJsFiles() { if (this.projectKind === 0 /* Inferred */ || this.projectKind === 2 /* External */) { this.compilerOptions.noEmitForJsFiles = true; } } /** * Get the errors that dont have any file name associated */ getGlobalProjectErrors() { return filter(this.projectErrors, (diagnostic) => !diagnostic.file) || emptyArray2; } /** * Get all the project errors */ getAllProjectErrors() { return this.projectErrors || emptyArray2; } setProjectErrors(projectErrors) { this.projectErrors = projectErrors; } getLanguageService(ensureSynchronized = true) { if (ensureSynchronized) { updateProjectIfDirty(this); } return this.languageService; } /** @internal */ getSourceMapper() { return this.getLanguageService().getSourceMapper(); } /** @internal */ clearSourceMapperCache() { this.languageService.clearSourceMapperCache(); } /** @internal */ getDocumentPositionMapper(generatedFileName, sourceFileName) { return this.projectService.getDocumentPositionMapper(this, generatedFileName, sourceFileName); } /** @internal */ getSourceFileLike(fileName) { return this.projectService.getSourceFileLike(fileName, this); } /** @internal */ shouldEmitFile(scriptInfo) { return scriptInfo && !scriptInfo.isDynamicOrHasMixedContent() && !this.program.isSourceOfProjectReferenceRedirect(scriptInfo.path); } getCompileOnSaveAffectedFileList(scriptInfo) { if (!this.languageServiceEnabled) { return []; } updateProjectIfDirty(this); this.builderState = BuilderState.create( this.program, this.builderState, /*disableUseFileVersionAsSignature*/ true ); return mapDefined( BuilderState.getFilesAffectedBy( this.builderState, this.program, scriptInfo.path, this.cancellationToken, this.projectService.host ), (sourceFile) => this.shouldEmitFile(this.projectService.getScriptInfoForPath(sourceFile.path)) ? sourceFile.fileName : void 0 ); } /** * Returns true if emit was conducted */ emitFile(scriptInfo, writeFile2) { if (!this.languageServiceEnabled || !this.shouldEmitFile(scriptInfo)) { return { emitSkipped: true, diagnostics: emptyArray2 }; } const { emitSkipped, diagnostics, outputFiles } = this.getLanguageService().getEmitOutput(scriptInfo.fileName); if (!emitSkipped) { for (const outputFile of outputFiles) { const outputFileAbsoluteFileName = getNormalizedAbsolutePath(outputFile.name, this.currentDirectory); writeFile2(outputFileAbsoluteFileName, outputFile.text, outputFile.writeByteOrderMark); } if (this.builderState && getEmitDeclarations(this.compilerOptions)) { const dtsFiles = outputFiles.filter((f) => isDeclarationFileName(f.name)); if (dtsFiles.length === 1) { const sourceFile = this.program.getSourceFile(scriptInfo.fileName); const signature = this.projectService.host.createHash ? this.projectService.host.createHash(dtsFiles[0].text) : generateDjb2Hash(dtsFiles[0].text); BuilderState.updateSignatureOfFile(this.builderState, signature, sourceFile.resolvedPath); } } } return { emitSkipped, diagnostics }; } enableLanguageService() { if (this.languageServiceEnabled || this.projectService.serverMode === 2 /* Syntactic */) { return; } this.languageServiceEnabled = true; this.lastFileExceededProgramSize = void 0; this.projectService.onUpdateLanguageServiceStateForProject( this, /*languageServiceEnabled*/ true ); } /** @internal */ cleanupProgram() { if (this.program) { for (const f of this.program.getSourceFiles()) { this.detachScriptInfoIfNotRoot(f.fileName); } this.program.forEachResolvedProjectReference((ref) => this.detachScriptInfoFromProject(ref.sourceFile.fileName)); this.program = void 0; } } disableLanguageService(lastFileExceededProgramSize) { if (!this.languageServiceEnabled) { return; } Debug.assert(this.projectService.serverMode !== 2 /* Syntactic */); this.languageService.cleanupSemanticCache(); this.languageServiceEnabled = false; this.cleanupProgram(); this.lastFileExceededProgramSize = lastFileExceededProgramSize; this.builderState = void 0; if (this.autoImportProviderHost) { this.autoImportProviderHost.close(); } this.autoImportProviderHost = void 0; this.resolutionCache.closeTypeRootsWatch(); this.clearGeneratedFileWatch(); this.projectService.verifyDocumentRegistry(); this.projectService.onUpdateLanguageServiceStateForProject( this, /*languageServiceEnabled*/ false ); } getProjectName() { return this.projectName; } removeLocalTypingsFromTypeAcquisition(newTypeAcquisition) { if (!newTypeAcquisition || !newTypeAcquisition.include) { return newTypeAcquisition; } return { ...newTypeAcquisition, include: this.removeExistingTypings(newTypeAcquisition.include) }; } getExternalFiles(updateLevel) { return sort(flatMap(this.plugins, (plugin) => { if (typeof plugin.module.getExternalFiles !== "function") return; try { return plugin.module.getExternalFiles(this, updateLevel || 0 /* Update */); } catch (e) { this.projectService.logger.info(`A plugin threw an exception in getExternalFiles: ${e}`); if (e.stack) { this.projectService.logger.info(e.stack); } } })); } getSourceFile(path) { if (!this.program) { return void 0; } return this.program.getSourceFileByPath(path); } /** @internal */ getSourceFileOrConfigFile(path) { const options = this.program.getCompilerOptions(); return path === options.configFilePath ? options.configFile : this.getSourceFile(path); } close() { var _a; this.projectService.typingsCache.onProjectClosed(this); this.closeWatchingTypingLocations(); this.cleanupProgram(); forEach(this.externalFiles, (externalFile) => this.detachScriptInfoIfNotRoot(externalFile)); this.rootFilesMap.forEach((root) => { var _a2; return (_a2 = root.info) == null ? void 0 : _a2.detachFromProject(this); }); this.projectService.pendingEnsureProjectForOpenFiles = true; this.rootFilesMap = void 0; this.externalFiles = void 0; this.program = void 0; this.builderState = void 0; this.resolutionCache.clear(); this.resolutionCache = void 0; this.cachedUnresolvedImportsPerFile = void 0; (_a = this.packageJsonWatches) == null ? void 0 : _a.forEach((watcher) => { watcher.projects.delete(this); watcher.close(); }); this.packageJsonWatches = void 0; this.moduleSpecifierCache.clear(); this.moduleSpecifierCache = void 0; this.directoryStructureHost = void 0; this.exportMapCache = void 0; this.projectErrors = void 0; this.plugins.length = 0; if (this.missingFilesMap) { clearMap(this.missingFilesMap, closeFileWatcher); this.missingFilesMap = void 0; } this.clearGeneratedFileWatch(); this.clearInvalidateResolutionOfFailedLookupTimer(); if (this.autoImportProviderHost) { this.autoImportProviderHost.close(); } this.autoImportProviderHost = void 0; if (this.noDtsResolutionProject) { this.noDtsResolutionProject.close(); } this.noDtsResolutionProject = void 0; this.languageService.dispose(); this.languageService = void 0; } detachScriptInfoIfNotRoot(uncheckedFilename) { const info = this.projectService.getScriptInfo(uncheckedFilename); if (info && !this.isRoot(info)) { info.detachFromProject(this); } } isClosed() { return this.rootFilesMap === void 0; } hasRoots() { var _a; return !!((_a = this.rootFilesMap) == null ? void 0 : _a.size); } /** @internal */ isOrphan() { return false; } getRootFiles() { return this.rootFilesMap && arrayFrom(mapDefinedIterator(this.rootFilesMap.values(), (value) => { var _a; return (_a = value.info) == null ? void 0 : _a.fileName; })); } /** @internal */ getRootFilesMap() { return this.rootFilesMap; } getRootScriptInfos() { return arrayFrom(mapDefinedIterator(this.rootFilesMap.values(), (value) => value.info)); } getScriptInfos() { if (!this.languageServiceEnabled) { return this.getRootScriptInfos(); } return map(this.program.getSourceFiles(), (sourceFile) => { const scriptInfo = this.projectService.getScriptInfoForPath(sourceFile.resolvedPath); Debug.assert(!!scriptInfo, "getScriptInfo", () => `scriptInfo for a file '${sourceFile.fileName}' Path: '${sourceFile.path}' / '${sourceFile.resolvedPath}' is missing.`); return scriptInfo; }); } getExcludedFiles() { return emptyArray2; } getFileNames(excludeFilesFromExternalLibraries, excludeConfigFiles) { if (!this.program) { return []; } if (!this.languageServiceEnabled) { let rootFiles = this.getRootFiles(); if (this.compilerOptions) { const defaultLibrary = getDefaultLibFilePath(this.compilerOptions); if (defaultLibrary) { (rootFiles || (rootFiles = [])).push(asNormalizedPath(defaultLibrary)); } } return rootFiles; } const result = []; for (const f of this.program.getSourceFiles()) { if (excludeFilesFromExternalLibraries && this.program.isSourceFileFromExternalLibrary(f)) { continue; } result.push(asNormalizedPath(f.fileName)); } if (!excludeConfigFiles) { const configFile = this.program.getCompilerOptions().configFile; if (configFile) { result.push(asNormalizedPath(configFile.fileName)); if (configFile.extendedSourceFiles) { for (const f of configFile.extendedSourceFiles) { result.push(asNormalizedPath(f)); } } } } return result; } /** @internal */ getFileNamesWithRedirectInfo(includeProjectReferenceRedirectInfo) { return this.getFileNames().map((fileName) => ({ fileName, isSourceOfProjectReferenceRedirect: includeProjectReferenceRedirectInfo && this.isSourceOfProjectReferenceRedirect(fileName) })); } hasConfigFile(configFilePath) { if (this.program && this.languageServiceEnabled) { const configFile = this.program.getCompilerOptions().configFile; if (configFile) { if (configFilePath === asNormalizedPath(configFile.fileName)) { return true; } if (configFile.extendedSourceFiles) { for (const f of configFile.extendedSourceFiles) { if (configFilePath === asNormalizedPath(f)) { return true; } } } } } return false; } containsScriptInfo(info) { if (this.isRoot(info)) return true; if (!this.program) return false; const file = this.program.getSourceFileByPath(info.path); return !!file && file.resolvedPath === info.path; } containsFile(filename, requireOpen) { const info = this.projectService.getScriptInfoForNormalizedPath(filename); if (info && (info.isScriptOpen() || !requireOpen)) { return this.containsScriptInfo(info); } return false; } isRoot(info) { var _a, _b; return ((_b = (_a = this.rootFilesMap) == null ? void 0 : _a.get(info.path)) == null ? void 0 : _b.info) === info; } // add a root file to project addRoot(info, fileName) { Debug.assert(!this.isRoot(info)); this.rootFilesMap.set(info.path, { fileName: fileName || info.fileName, info }); info.attachToProject(this); this.markAsDirty(); } // add a root file that doesnt exist on host addMissingFileRoot(fileName) { const path = this.projectService.toPath(fileName); this.rootFilesMap.set(path, { fileName }); this.markAsDirty(); } removeFile(info, fileExists, detachFromProject) { if (this.isRoot(info)) { this.removeRoot(info); } if (fileExists) { this.resolutionCache.removeResolutionsOfFile(info.path); } else { this.resolutionCache.invalidateResolutionOfFile(info.path); } this.cachedUnresolvedImportsPerFile.delete(info.path); if (detachFromProject) { info.detachFromProject(this); } this.markAsDirty(); } registerFileUpdate(fileName) { (this.updatedFileNames || (this.updatedFileNames = /* @__PURE__ */ new Set())).add(fileName); } /** @internal */ markFileAsDirty(changedFile) { this.markAsDirty(); if (this.exportMapCache && !this.exportMapCache.isEmpty()) { (this.changedFilesForExportMapCache || (this.changedFilesForExportMapCache = /* @__PURE__ */ new Set())).add(changedFile); } } /** @internal */ markAsDirty() { if (!this.dirty) { this.projectStateVersion++; this.dirty = true; } } /** @internal */ markAutoImportProviderAsDirty() { var _a; if (!this.autoImportProviderHost) this.autoImportProviderHost = void 0; (_a = this.autoImportProviderHost) == null ? void 0 : _a.markAsDirty(); } /** @internal */ onAutoImportProviderSettingsChanged() { var _a; if (this.autoImportProviderHost === false) { this.autoImportProviderHost = void 0; } else { (_a = this.autoImportProviderHost) == null ? void 0 : _a.markAsDirty(); } } /** @internal */ onPackageJsonChange() { this.moduleSpecifierCache.clear(); if (this.autoImportProviderHost) { this.autoImportProviderHost.markAsDirty(); } } /** @internal */ onFileAddedOrRemoved(isSymlink) { this.hasAddedorRemovedFiles = true; if (isSymlink) { this.hasAddedOrRemovedSymlinks = true; } } /** @internal */ onDiscoveredSymlink() { this.hasAddedOrRemovedSymlinks = true; } /** @internal */ updateFromProject() { updateProjectIfDirty(this); } /** * Updates set of files that contribute to this project * @returns: true if set of files in the project stays the same and false - otherwise. */ updateGraph() { var _a, _b, _c, _d; (_a = tracing) == null ? void 0 : _a.push(tracing.Phase.Session, "updateGraph", { name: this.projectName, kind: ProjectKind[this.projectKind] }); (_b = perfLogger) == null ? void 0 : _b.logStartUpdateGraph(); this.resolutionCache.startRecordingFilesWithChangedResolutions(); const hasNewProgram = this.updateGraphWorker(); const hasAddedorRemovedFiles = this.hasAddedorRemovedFiles; this.hasAddedorRemovedFiles = false; this.hasAddedOrRemovedSymlinks = false; const changedFiles = this.resolutionCache.finishRecordingFilesWithChangedResolutions() || emptyArray2; for (const file of changedFiles) { this.cachedUnresolvedImportsPerFile.delete(file); } if (this.languageServiceEnabled && this.projectService.serverMode === 0 /* Semantic */ && !this.isOrphan()) { if (hasNewProgram || changedFiles.length) { this.lastCachedUnresolvedImportsList = getUnresolvedImports(this.program, this.cachedUnresolvedImportsPerFile); } this.projectService.typingsCache.enqueueInstallTypingsForProject(this, this.lastCachedUnresolvedImportsList, hasAddedorRemovedFiles); } else { this.lastCachedUnresolvedImportsList = void 0; } const isFirstProgramLoad = this.projectProgramVersion === 0 && hasNewProgram; if (hasNewProgram) { this.projectProgramVersion++; } if (hasAddedorRemovedFiles) { this.markAutoImportProviderAsDirty(); } if (isFirstProgramLoad) { this.getPackageJsonAutoImportProvider(); } (_c = perfLogger) == null ? void 0 : _c.logStopUpdateGraph(); (_d = tracing) == null ? void 0 : _d.pop(); return !hasNewProgram; } /** @internal */ updateTypingFiles(typingFiles) { if (enumerateInsertsAndDeletes( typingFiles, this.typingFiles, getStringComparer(!this.useCaseSensitiveFileNames()), /*inserted*/ noop, (removed) => this.detachScriptInfoFromProject(removed) )) { this.typingFiles = typingFiles; this.resolutionCache.setFilesWithInvalidatedNonRelativeUnresolvedImports(this.cachedUnresolvedImportsPerFile); this.projectService.delayUpdateProjectGraphAndEnsureProjectStructureForOpenFiles(this); } } /** @internal */ closeWatchingTypingLocations() { if (this.typingWatchers) clearMap(this.typingWatchers, closeFileWatcher); this.typingWatchers = void 0; } /** @internal */ onTypingInstallerWatchInvoke() { this.typingWatchers.isInvoked = true; this.projectService.updateTypingsForProject({ projectName: this.getProjectName(), kind: ActionInvalidate }); } /** @internal */ watchTypingLocations(files) { if (!files) { this.typingWatchers.isInvoked = false; return; } if (!files.length) { this.closeWatchingTypingLocations(); return; } const toRemove = new Map(this.typingWatchers); if (!this.typingWatchers) this.typingWatchers = /* @__PURE__ */ new Map(); this.typingWatchers.isInvoked = false; const createProjectWatcher = (path, typingsWatcherType) => { const canonicalPath = this.toPath(path); toRemove.delete(canonicalPath); if (!this.typingWatchers.has(canonicalPath)) { this.typingWatchers.set( canonicalPath, typingsWatcherType === "FileWatcher" /* FileWatcher */ ? this.projectService.watchFactory.watchFile( path, () => !this.typingWatchers.isInvoked ? this.onTypingInstallerWatchInvoke() : this.writeLog(`TypingWatchers already invoked`), 2e3 /* High */, this.projectService.getWatchOptions(this), WatchType.TypingInstallerLocationFile, this ) : this.projectService.watchFactory.watchDirectory( path, (f) => { if (this.typingWatchers.isInvoked) return this.writeLog(`TypingWatchers already invoked`); if (!fileExtensionIs(f, ".json" /* Json */)) return this.writeLog(`Ignoring files that are not *.json`); if (comparePaths(f, combinePaths(this.projectService.typingsInstaller.globalTypingsCacheLocation, "package.json"), !this.useCaseSensitiveFileNames())) return this.writeLog(`Ignoring package.json change at global typings location`); this.onTypingInstallerWatchInvoke(); }, 1 /* Recursive */, this.projectService.getWatchOptions(this), WatchType.TypingInstallerLocationDirectory, this ) ); } }; for (const file of files) { const basename = getBaseFileName(file); if (basename === "package.json" || basename === "bower.json") { createProjectWatcher(file, "FileWatcher" /* FileWatcher */); continue; } if (containsPath(this.currentDirectory, file, this.currentDirectory, !this.useCaseSensitiveFileNames())) { const subDirectory = file.indexOf(directorySeparator, this.currentDirectory.length + 1); if (subDirectory !== -1) { createProjectWatcher(file.substr(0, subDirectory), "DirectoryWatcher" /* DirectoryWatcher */); } else { createProjectWatcher(file, "DirectoryWatcher" /* DirectoryWatcher */); } continue; } if (containsPath(this.projectService.typingsInstaller.globalTypingsCacheLocation, file, this.currentDirectory, !this.useCaseSensitiveFileNames())) { createProjectWatcher(this.projectService.typingsInstaller.globalTypingsCacheLocation, "DirectoryWatcher" /* DirectoryWatcher */); continue; } createProjectWatcher(file, "DirectoryWatcher" /* DirectoryWatcher */); } toRemove.forEach((watch, path) => { watch.close(); this.typingWatchers.delete(path); }); } /** @internal */ getCurrentProgram() { return this.program; } removeExistingTypings(include) { const existing = getAutomaticTypeDirectiveNames(this.getCompilerOptions(), this.directoryStructureHost); return include.filter((i) => !existing.includes(i)); } updateGraphWorker() { var _a, _b; const oldProgram = this.languageService.getCurrentProgram(); Debug.assert(oldProgram === this.program); Debug.assert(!this.isClosed(), "Called update graph worker of closed project"); this.writeLog(`Starting updateGraphWorker: Project: ${this.getProjectName()}`); const start = timestamp(); const { hasInvalidatedResolutions, hasInvalidatedLibResolutions } = this.resolutionCache.createHasInvalidatedResolutions(returnFalse, returnFalse); this.hasInvalidatedResolutions = hasInvalidatedResolutions; this.hasInvalidatedLibResolutions = hasInvalidatedLibResolutions; this.resolutionCache.startCachingPerDirectoryResolution(); this.dirty = false; this.updateFromProjectInProgress = true; this.program = this.languageService.getProgram(); this.updateFromProjectInProgress = false; (_a = tracing) == null ? void 0 : _a.push(tracing.Phase.Session, "finishCachingPerDirectoryResolution"); this.resolutionCache.finishCachingPerDirectoryResolution(this.program, oldProgram); (_b = tracing) == null ? void 0 : _b.pop(); Debug.assert(oldProgram === void 0 || this.program !== void 0); let hasNewProgram = false; if (this.program && (!oldProgram || this.program !== oldProgram && this.program.structureIsReused !== 2 /* Completely */)) { hasNewProgram = true; if (oldProgram) { for (const f of oldProgram.getSourceFiles()) { const newFile = this.program.getSourceFileByPath(f.resolvedPath); if (!newFile || f.resolvedPath === f.path && newFile.resolvedPath !== f.path) { this.detachScriptInfoFromProject( f.fileName, !!this.program.getSourceFileByPath(f.path), /*syncDirWatcherRemove*/ true ); } } oldProgram.forEachResolvedProjectReference((resolvedProjectReference) => { if (!this.program.getResolvedProjectReferenceByPath(resolvedProjectReference.sourceFile.path)) { this.detachScriptInfoFromProject( resolvedProjectReference.sourceFile.fileName, /*noRemoveResolution*/ void 0, /*syncDirWatcherRemove*/ true ); } }); } this.rootFilesMap.forEach((value, path) => { var _a2; const file = this.program.getSourceFileByPath(path); const info = value.info; if (!file || ((_a2 = value.info) == null ? void 0 : _a2.path) === file.resolvedPath) return; value.info = this.projectService.getScriptInfo(file.fileName); Debug.assert(value.info.isAttached(this)); info == null ? void 0 : info.detachFromProject(this); }); updateMissingFilePathsWatch( this.program, this.missingFilesMap || (this.missingFilesMap = /* @__PURE__ */ new Map()), // Watch the missing files (missingFilePath, missingFileName) => this.addMissingFileWatcher(missingFilePath, missingFileName) ); if (this.generatedFilesMap) { const outPath = this.compilerOptions.outFile; if (isGeneratedFileWatcher(this.generatedFilesMap)) { if (!outPath || !this.isValidGeneratedFileWatcher( removeFileExtension(outPath) + ".d.ts" /* Dts */, this.generatedFilesMap )) { this.clearGeneratedFileWatch(); } } else { if (outPath) { this.clearGeneratedFileWatch(); } else { this.generatedFilesMap.forEach((watcher, source) => { const sourceFile = this.program.getSourceFileByPath(source); if (!sourceFile || sourceFile.resolvedPath !== source || !this.isValidGeneratedFileWatcher( getDeclarationEmitOutputFilePathWorker(sourceFile.fileName, this.compilerOptions, this.program), watcher )) { closeFileWatcherOf(watcher); this.generatedFilesMap.delete(source); } }); } } } if (this.languageServiceEnabled && this.projectService.serverMode === 0 /* Semantic */) { this.resolutionCache.updateTypeRootsWatch(); } } this.projectService.verifyProgram(this); if (this.exportMapCache && !this.exportMapCache.isEmpty()) { this.exportMapCache.releaseSymbols(); if (this.hasAddedorRemovedFiles || oldProgram && !this.program.structureIsReused) { this.exportMapCache.clear(); } else if (this.changedFilesForExportMapCache && oldProgram && this.program) { forEachKey(this.changedFilesForExportMapCache, (fileName) => { const oldSourceFile = oldProgram.getSourceFileByPath(fileName); const sourceFile = this.program.getSourceFileByPath(fileName); if (!oldSourceFile || !sourceFile) { this.exportMapCache.clear(); return true; } return this.exportMapCache.onFileChanged(oldSourceFile, sourceFile, !!this.getTypeAcquisition().enable); }); } } if (this.changedFilesForExportMapCache) { this.changedFilesForExportMapCache.clear(); } if (this.hasAddedOrRemovedSymlinks || this.program && !this.program.structureIsReused && this.getCompilerOptions().preserveSymlinks) { this.symlinks = void 0; this.moduleSpecifierCache.clear(); } const oldExternalFiles = this.externalFiles || emptyArray2; this.externalFiles = this.getExternalFiles(); enumerateInsertsAndDeletes( this.externalFiles, oldExternalFiles, getStringComparer(!this.useCaseSensitiveFileNames()), // Ensure a ScriptInfo is created for new external files. This is performed indirectly // by the host for files in the program when the program is retrieved above but // the program doesn't contain external files so this must be done explicitly. (inserted) => { const scriptInfo = this.projectService.getOrCreateScriptInfoNotOpenedByClient( inserted, this.currentDirectory, this.directoryStructureHost, /*deferredDeleteOk*/ false ); scriptInfo == null ? void 0 : scriptInfo.attachToProject(this); }, (removed) => this.detachScriptInfoFromProject(removed) ); const elapsed = timestamp() - start; this.sendPerformanceEvent("UpdateGraph", elapsed); this.writeLog(`Finishing updateGraphWorker: Project: ${this.getProjectName()} projectStateVersion: ${this.projectStateVersion} projectProgramVersion: ${this.projectProgramVersion} structureChanged: ${hasNewProgram}${this.program ? ` structureIsReused:: ${StructureIsReused[this.program.structureIsReused]}` : ""} Elapsed: ${elapsed}ms`); if (this.projectService.logger.isTestLogger) { if (this.program !== oldProgram) { this.print( /*writeProjectFileNames*/ true, this.hasAddedorRemovedFiles, /*writeFileVersionAndText*/ true ); } else { this.writeLog(`Same program as before`); } } else if (this.hasAddedorRemovedFiles) { this.print( /*writeProjectFileNames*/ true, /*writeFileExplaination*/ true, /*writeFileVersionAndText*/ false ); } else if (this.program !== oldProgram) { this.writeLog(`Different program with same set of files`); } this.projectService.verifyDocumentRegistry(); return hasNewProgram; } /** @internal */ sendPerformanceEvent(kind, durationMs) { this.projectService.sendPerformanceEvent(kind, durationMs); } detachScriptInfoFromProject(uncheckedFileName, noRemoveResolution, syncDirWatcherRemove) { const scriptInfoToDetach = this.projectService.getScriptInfo(uncheckedFileName); if (scriptInfoToDetach) { scriptInfoToDetach.detachFromProject(this); if (!noRemoveResolution) { this.resolutionCache.removeResolutionsOfFile(scriptInfoToDetach.path, syncDirWatcherRemove); } } } addMissingFileWatcher(missingFilePath, missingFileName) { var _a; if (isConfiguredProject(this)) { const configFileExistenceInfo = this.projectService.configFileExistenceInfoCache.get(missingFilePath); if ((_a = configFileExistenceInfo == null ? void 0 : configFileExistenceInfo.config) == null ? void 0 : _a.projects.has(this.canonicalConfigFilePath)) return noopFileWatcher; } const fileWatcher = this.projectService.watchFactory.watchFile( getNormalizedAbsolutePath(missingFileName, this.currentDirectory), (fileName, eventKind) => { if (isConfiguredProject(this)) { this.getCachedDirectoryStructureHost().addOrDeleteFile(fileName, missingFilePath, eventKind); } if (eventKind === 0 /* Created */ && this.missingFilesMap.has(missingFilePath)) { this.missingFilesMap.delete(missingFilePath); fileWatcher.close(); this.projectService.delayUpdateProjectGraphAndEnsureProjectStructureForOpenFiles(this); } }, 500 /* Medium */, this.projectService.getWatchOptions(this), WatchType.MissingFile, this ); return fileWatcher; } isWatchedMissingFile(path) { return !!this.missingFilesMap && this.missingFilesMap.has(path); } /** @internal */ addGeneratedFileWatch(generatedFile, sourceFile) { if (this.compilerOptions.outFile) { if (!this.generatedFilesMap) { this.generatedFilesMap = this.createGeneratedFileWatcher(generatedFile); } } else { const path = this.toPath(sourceFile); if (this.generatedFilesMap) { if (isGeneratedFileWatcher(this.generatedFilesMap)) { Debug.fail(`${this.projectName} Expected to not have --out watcher for generated file with options: ${JSON.stringify(this.compilerOptions)}`); return; } if (this.generatedFilesMap.has(path)) return; } else { this.generatedFilesMap = /* @__PURE__ */ new Map(); } this.generatedFilesMap.set(path, this.createGeneratedFileWatcher(generatedFile)); } } createGeneratedFileWatcher(generatedFile) { return { generatedFilePath: this.toPath(generatedFile), watcher: this.projectService.watchFactory.watchFile( generatedFile, () => { this.clearSourceMapperCache(); this.projectService.delayUpdateProjectGraphAndEnsureProjectStructureForOpenFiles(this); }, 2e3 /* High */, this.projectService.getWatchOptions(this), WatchType.MissingGeneratedFile, this ) }; } isValidGeneratedFileWatcher(generateFile, watcher) { return this.toPath(generateFile) === watcher.generatedFilePath; } clearGeneratedFileWatch() { if (this.generatedFilesMap) { if (isGeneratedFileWatcher(this.generatedFilesMap)) { closeFileWatcherOf(this.generatedFilesMap); } else { clearMap(this.generatedFilesMap, closeFileWatcherOf); } this.generatedFilesMap = void 0; } } getScriptInfoForNormalizedPath(fileName) { const scriptInfo = this.projectService.getScriptInfoForPath(this.toPath(fileName)); if (scriptInfo && !scriptInfo.isAttached(this)) { return Errors.ThrowProjectDoesNotContainDocument(fileName, this); } return scriptInfo; } getScriptInfo(uncheckedFileName) { return this.projectService.getScriptInfo(uncheckedFileName); } filesToString(writeProjectFileNames) { return this.filesToStringWorker( writeProjectFileNames, /*writeFileExplaination*/ true, /*writeFileVersionAndText*/ false ); } /** @internal */ filesToStringWorker(writeProjectFileNames, writeFileExplaination, writeFileVersionAndText) { if (this.isInitialLoadPending()) return " Files (0) InitialLoadPending\n"; if (!this.program) return " Files (0) NoProgram\n"; const sourceFiles = this.program.getSourceFiles(); let strBuilder = ` Files (${sourceFiles.length}) `; if (writeProjectFileNames) { for (const file of sourceFiles) { strBuilder += ` ${file.fileName}${writeFileVersionAndText ? ` ${file.version} ${JSON.stringify(file.text)}` : ""} `; } if (writeFileExplaination) { strBuilder += "\n\n"; explainFiles(this.program, (s) => strBuilder += ` ${s} `); } } return strBuilder; } /** @internal */ print(writeProjectFileNames, writeFileExplaination, writeFileVersionAndText) { var _a; this.writeLog(`Project '${this.projectName}' (${ProjectKind[this.projectKind]})`); this.writeLog(this.filesToStringWorker( writeProjectFileNames && this.projectService.logger.hasLevel(3 /* verbose */), writeFileExplaination && this.projectService.logger.hasLevel(3 /* verbose */), writeFileVersionAndText && this.projectService.logger.hasLevel(3 /* verbose */) )); this.writeLog("-----------------------------------------------"); if (this.autoImportProviderHost) { this.autoImportProviderHost.print( /*writeProjectFileNames*/ false, /*writeFileExplaination*/ false, /*writeFileVersionAndText*/ false ); } (_a = this.noDtsResolutionProject) == null ? void 0 : _a.print( /*writeProjectFileNames*/ false, /*writeFileExplaination*/ false, /*writeFileVersionAndText*/ false ); } setCompilerOptions(compilerOptions) { var _a; if (compilerOptions) { compilerOptions.allowNonTsExtensions = true; const oldOptions = this.compilerOptions; this.compilerOptions = compilerOptions; this.setInternalCompilerOptionsForEmittingJsFiles(); (_a = this.noDtsResolutionProject) == null ? void 0 : _a.setCompilerOptions(this.getCompilerOptionsForNoDtsResolutionProject()); if (changesAffectModuleResolution(oldOptions, compilerOptions)) { this.cachedUnresolvedImportsPerFile.clear(); this.lastCachedUnresolvedImportsList = void 0; this.resolutionCache.onChangesAffectModuleResolution(); this.moduleSpecifierCache.clear(); } this.markAsDirty(); } } /** @internal */ setWatchOptions(watchOptions) { this.watchOptions = watchOptions; } /** @internal */ getWatchOptions() { return this.watchOptions; } setTypeAcquisition(newTypeAcquisition) { if (newTypeAcquisition) { this.typeAcquisition = this.removeLocalTypingsFromTypeAcquisition(newTypeAcquisition); } } getTypeAcquisition() { return this.typeAcquisition || {}; } /** @internal */ getChangesSinceVersion(lastKnownVersion, includeProjectReferenceRedirectInfo) { var _a, _b; const includeProjectReferenceRedirectInfoIfRequested = includeProjectReferenceRedirectInfo ? (files) => arrayFrom(files.entries(), ([fileName, isSourceOfProjectReferenceRedirect]) => ({ fileName, isSourceOfProjectReferenceRedirect })) : (files) => arrayFrom(files.keys()); if (!this.isInitialLoadPending()) { updateProjectIfDirty(this); } const info = { projectName: this.getProjectName(), version: this.projectProgramVersion, isInferred: isInferredProject(this), options: this.getCompilationSettings(), languageServiceDisabled: !this.languageServiceEnabled, lastFileExceededProgramSize: this.lastFileExceededProgramSize }; const updatedFileNames = this.updatedFileNames; this.updatedFileNames = void 0; if (this.lastReportedFileNames && lastKnownVersion === this.lastReportedVersion) { if (this.projectProgramVersion === this.lastReportedVersion && !updatedFileNames) { return { info, projectErrors: this.getGlobalProjectErrors() }; } const lastReportedFileNames = this.lastReportedFileNames; const externalFiles = ((_a = this.externalFiles) == null ? void 0 : _a.map((f) => ({ fileName: toNormalizedPath(f), isSourceOfProjectReferenceRedirect: false }))) || emptyArray2; const currentFiles = arrayToMap( this.getFileNamesWithRedirectInfo(!!includeProjectReferenceRedirectInfo).concat(externalFiles), (info2) => info2.fileName, (info2) => info2.isSourceOfProjectReferenceRedirect ); const added = /* @__PURE__ */ new Map(); const removed = /* @__PURE__ */ new Map(); const updated = updatedFileNames ? arrayFrom(updatedFileNames.keys()) : []; const updatedRedirects = []; forEachEntry(currentFiles, (isSourceOfProjectReferenceRedirect, fileName) => { if (!lastReportedFileNames.has(fileName)) { added.set(fileName, isSourceOfProjectReferenceRedirect); } else if (includeProjectReferenceRedirectInfo && isSourceOfProjectReferenceRedirect !== lastReportedFileNames.get(fileName)) { updatedRedirects.push({ fileName, isSourceOfProjectReferenceRedirect }); } }); forEachEntry(lastReportedFileNames, (isSourceOfProjectReferenceRedirect, fileName) => { if (!currentFiles.has(fileName)) { removed.set(fileName, isSourceOfProjectReferenceRedirect); } }); this.lastReportedFileNames = currentFiles; this.lastReportedVersion = this.projectProgramVersion; return { info, changes: { added: includeProjectReferenceRedirectInfoIfRequested(added), removed: includeProjectReferenceRedirectInfoIfRequested(removed), updated: includeProjectReferenceRedirectInfo ? updated.map((fileName) => ({ fileName, isSourceOfProjectReferenceRedirect: this.isSourceOfProjectReferenceRedirect(fileName) })) : updated, updatedRedirects: includeProjectReferenceRedirectInfo ? updatedRedirects : void 0 }, projectErrors: this.getGlobalProjectErrors() }; } else { const projectFileNames = this.getFileNamesWithRedirectInfo(!!includeProjectReferenceRedirectInfo); const externalFiles = ((_b = this.externalFiles) == null ? void 0 : _b.map((f) => ({ fileName: toNormalizedPath(f), isSourceOfProjectReferenceRedirect: false }))) || emptyArray2; const allFiles = projectFileNames.concat(externalFiles); this.lastReportedFileNames = arrayToMap( allFiles, (info2) => info2.fileName, (info2) => info2.isSourceOfProjectReferenceRedirect ); this.lastReportedVersion = this.projectProgramVersion; return { info, files: includeProjectReferenceRedirectInfo ? allFiles : allFiles.map((f) => f.fileName), projectErrors: this.getGlobalProjectErrors() }; } } // remove a root file from project removeRoot(info) { this.rootFilesMap.delete(info.path); } /** @internal */ isSourceOfProjectReferenceRedirect(fileName) { return !!this.program && this.program.isSourceOfProjectReferenceRedirect(fileName); } /** @internal */ getGlobalPluginSearchPaths() { return [ ...this.projectService.pluginProbeLocations, // ../../.. to walk from X/node_modules/typescript/lib/tsserver.js to X/node_modules/ combinePaths(this.projectService.getExecutingFilePath(), "../../..") ]; } enableGlobalPlugins(options) { if (!this.projectService.globalPlugins.length) return; const host = this.projectService.host; if (!host.require && !host.importPlugin) { this.projectService.logger.info("Plugins were requested but not running in environment that supports 'require'. Nothing will be loaded"); return; } const searchPaths = this.getGlobalPluginSearchPaths(); for (const globalPluginName of this.projectService.globalPlugins) { if (!globalPluginName) continue; if (options.plugins && options.plugins.some((p) => p.name === globalPluginName)) continue; this.projectService.logger.info(`Loading global plugin ${globalPluginName}`); this.enablePlugin({ name: globalPluginName, global: true }, searchPaths); } } enablePlugin(pluginConfigEntry, searchPaths) { this.projectService.requestEnablePlugin(this, pluginConfigEntry, searchPaths); } /** @internal */ enableProxy(pluginModuleFactory, configEntry) { try { if (typeof pluginModuleFactory !== "function") { this.projectService.logger.info(`Skipped loading plugin ${configEntry.name} because it did not expose a proper factory function`); return; } const info = { config: configEntry, project: this, languageService: this.languageService, languageServiceHost: this, serverHost: this.projectService.host, session: this.projectService.session }; const pluginModule = pluginModuleFactory({ typescript: ts_exports2 }); const newLS = pluginModule.create(info); for (const k of Object.keys(this.languageService)) { if (!(k in newLS)) { this.projectService.logger.info(`Plugin activation warning: Missing proxied method ${k} in created LS. Patching.`); newLS[k] = this.languageService[k]; } } this.projectService.logger.info(`Plugin validation succeeded`); this.languageService = newLS; this.plugins.push({ name: configEntry.name, module: pluginModule }); } catch (e) { this.projectService.logger.info(`Plugin activation failed: ${e}`); } } /** @internal */ onPluginConfigurationChanged(pluginName, configuration) { this.plugins.filter((plugin) => plugin.name === pluginName).forEach((plugin) => { if (plugin.module.onConfigurationChanged) { plugin.module.onConfigurationChanged(configuration); } }); } /** Starts a new check for diagnostics. Call this if some file has updated that would cause diagnostics to be changed. */ refreshDiagnostics() { this.projectService.sendProjectsUpdatedInBackgroundEvent(); } /** @internal */ getPackageJsonsVisibleToFile(fileName, rootDir) { if (this.projectService.serverMode !== 0 /* Semantic */) return emptyArray2; return this.projectService.getPackageJsonsVisibleToFile(fileName, this, rootDir); } /** @internal */ getNearestAncestorDirectoryWithPackageJson(fileName) { return this.projectService.getNearestAncestorDirectoryWithPackageJson(fileName); } /** @internal */ getPackageJsonsForAutoImport(rootDir) { return this.getPackageJsonsVisibleToFile(combinePaths(this.currentDirectory, inferredTypesContainingFile), rootDir); } /** @internal */ getPackageJsonCache() { return this.projectService.packageJsonCache; } /** @internal */ getCachedExportInfoMap() { return this.exportMapCache || (this.exportMapCache = createCacheableExportInfoMap(this)); } /** @internal */ clearCachedExportInfoMap() { var _a; (_a = this.exportMapCache) == null ? void 0 : _a.clear(); } /** @internal */ getModuleSpecifierCache() { return this.moduleSpecifierCache; } /** @internal */ includePackageJsonAutoImports() { if (this.projectService.includePackageJsonAutoImports() === 0 /* Off */ || !this.languageServiceEnabled || isInsideNodeModules(this.currentDirectory) || !this.isDefaultProjectForOpenFiles()) { return 0 /* Off */; } return this.projectService.includePackageJsonAutoImports(); } /** @internal */ getHostForAutoImportProvider() { var _a, _b; if (this.program) { return { fileExists: this.program.fileExists, directoryExists: this.program.directoryExists, realpath: this.program.realpath || ((_a = this.projectService.host.realpath) == null ? void 0 : _a.bind(this.projectService.host)), getCurrentDirectory: this.getCurrentDirectory.bind(this), readFile: this.projectService.host.readFile.bind(this.projectService.host), getDirectories: this.projectService.host.getDirectories.bind(this.projectService.host), trace: (_b = this.projectService.host.trace) == null ? void 0 : _b.bind(this.projectService.host), useCaseSensitiveFileNames: this.program.useCaseSensitiveFileNames(), readDirectory: this.projectService.host.readDirectory.bind(this.projectService.host) }; } return this.projectService.host; } /** @internal */ getPackageJsonAutoImportProvider() { var _a, _b, _c; if (this.autoImportProviderHost === false) { return void 0; } if (this.projectService.serverMode !== 0 /* Semantic */) { this.autoImportProviderHost = false; return void 0; } if (this.autoImportProviderHost) { updateProjectIfDirty(this.autoImportProviderHost); if (this.autoImportProviderHost.isEmpty()) { this.autoImportProviderHost.close(); this.autoImportProviderHost = void 0; return void 0; } return this.autoImportProviderHost.getCurrentProgram(); } const dependencySelection = this.includePackageJsonAutoImports(); if (dependencySelection) { (_a = tracing) == null ? void 0 : _a.push(tracing.Phase.Session, "getPackageJsonAutoImportProvider"); const start = timestamp(); this.autoImportProviderHost = AutoImportProviderProject.create(dependencySelection, this, this.getHostForAutoImportProvider(), this.documentRegistry); if (this.autoImportProviderHost) { updateProjectIfDirty(this.autoImportProviderHost); this.sendPerformanceEvent("CreatePackageJsonAutoImportProvider", timestamp() - start); (_b = tracing) == null ? void 0 : _b.pop(); return this.autoImportProviderHost.getCurrentProgram(); } (_c = tracing) == null ? void 0 : _c.pop(); } } /** @internal */ isDefaultProjectForOpenFiles() { return !!forEachEntry( this.projectService.openFiles, (_projectRootPath, path) => this.projectService.tryGetDefaultProjectForFile(this.projectService.getScriptInfoForPath(path)) === this ); } /** @internal */ watchNodeModulesForPackageJsonChanges(directoryPath) { return this.projectService.watchPackageJsonsInNodeModules(directoryPath, this); } /** @internal */ getIncompleteCompletionsCache() { return this.projectService.getIncompleteCompletionsCache(); } /** @internal */ getNoDtsResolutionProject(rootFile) { Debug.assert(this.projectService.serverMode === 0 /* Semantic */); if (!this.noDtsResolutionProject) { this.noDtsResolutionProject = new AuxiliaryProject(this.projectService, this.documentRegistry, this.getCompilerOptionsForNoDtsResolutionProject(), this.currentDirectory); } if (this.noDtsResolutionProject.rootFile !== rootFile) { this.projectService.setFileNamesOfAutpImportProviderOrAuxillaryProject(this.noDtsResolutionProject, [rootFile]); this.noDtsResolutionProject.rootFile = rootFile; } return this.noDtsResolutionProject; } /** @internal */ runWithTemporaryFileUpdate(rootFile, updatedText, cb) { var _a, _b, _c, _d; const originalProgram = this.program; const rootSourceFile = Debug.checkDefined((_a = this.program) == null ? void 0 : _a.getSourceFile(rootFile), "Expected file to be part of program"); const originalText = Debug.checkDefined(rootSourceFile.getText()); (_b = this.getScriptInfo(rootFile)) == null ? void 0 : _b.editContent(0, originalText.length, updatedText); this.updateGraph(); try { cb(this.program, originalProgram, (_c = this.program) == null ? void 0 : _c.getSourceFile(rootFile)); } finally { (_d = this.getScriptInfo(rootFile)) == null ? void 0 : _d.editContent(0, this.program.getSourceFile(rootFile).getText().length, originalText); } } /** @internal */ getCompilerOptionsForNoDtsResolutionProject() { return { ...this.getCompilerOptions(), noDtsResolution: true, allowJs: true, maxNodeModuleJsDepth: 3, diagnostics: false, skipLibCheck: true, sourceMap: false, types: emptyArray, lib: emptyArray, noLib: true }; } }; function getUnresolvedImports(program, cachedUnresolvedImportsPerFile) { var _a, _b; const sourceFiles = program.getSourceFiles(); (_a = tracing) == null ? void 0 : _a.push(tracing.Phase.Session, "getUnresolvedImports", { count: sourceFiles.length }); const ambientModules = program.getTypeChecker().getAmbientModules().map((mod) => stripQuotes(mod.getName())); const result = sortAndDeduplicate(flatMap(sourceFiles, (sourceFile) => extractUnresolvedImportsFromSourceFile( program, sourceFile, ambientModules, cachedUnresolvedImportsPerFile ))); (_b = tracing) == null ? void 0 : _b.pop(); return result; } function extractUnresolvedImportsFromSourceFile(program, file, ambientModules, cachedUnresolvedImportsPerFile) { return getOrUpdate(cachedUnresolvedImportsPerFile, file.path, () => { let unresolvedImports; program.forEachResolvedModule(({ resolvedModule }, name) => { if ((!resolvedModule || !resolutionExtensionIsTSOrJson(resolvedModule.extension)) && !isExternalModuleNameRelative(name) && !ambientModules.some((m) => m === name)) { unresolvedImports = append(unresolvedImports, parsePackageName(name).packageName); } }, file); return unresolvedImports || emptyArray2; }); } var InferredProject2 = class extends Project3 { /** @internal */ constructor(projectService, documentRegistry, compilerOptions, watchOptions, projectRootPath, currentDirectory, typeAcquisition) { super( projectService.newInferredProjectName(), 0 /* Inferred */, projectService, documentRegistry, // TODO: GH#18217 /*files*/ void 0, /*lastFileExceededProgramSize*/ void 0, compilerOptions, /*compileOnSaveEnabled*/ false, watchOptions, projectService.host, currentDirectory ); this._isJsInferredProject = false; this.typeAcquisition = typeAcquisition; this.projectRootPath = projectRootPath && projectService.toCanonicalFileName(projectRootPath); if (!projectRootPath && !projectService.useSingleInferredProject) { this.canonicalCurrentDirectory = projectService.toCanonicalFileName(this.currentDirectory); } this.enableGlobalPlugins(this.getCompilerOptions()); } toggleJsInferredProject(isJsInferredProject) { if (isJsInferredProject !== this._isJsInferredProject) { this._isJsInferredProject = isJsInferredProject; this.setCompilerOptions(); } } setCompilerOptions(options) { if (!options && !this.getCompilationSettings()) { return; } const newOptions = cloneCompilerOptions(options || this.getCompilationSettings()); if (this._isJsInferredProject && typeof newOptions.maxNodeModuleJsDepth !== "number") { newOptions.maxNodeModuleJsDepth = 2; } else if (!this._isJsInferredProject) { newOptions.maxNodeModuleJsDepth = void 0; } newOptions.allowJs = true; super.setCompilerOptions(newOptions); } addRoot(info) { Debug.assert(info.isScriptOpen()); this.projectService.startWatchingConfigFilesForInferredProjectRoot(info); if (!this._isJsInferredProject && info.isJavaScript()) { this.toggleJsInferredProject( /*isJsInferredProject*/ true ); } else if (this.isOrphan() && this._isJsInferredProject && !info.isJavaScript()) { this.toggleJsInferredProject( /*isJsInferredProject*/ false ); } super.addRoot(info); } removeRoot(info) { this.projectService.stopWatchingConfigFilesForScriptInfo(info); super.removeRoot(info); if (!this.isOrphan() && this._isJsInferredProject && info.isJavaScript()) { if (every(this.getRootScriptInfos(), (rootInfo) => !rootInfo.isJavaScript())) { this.toggleJsInferredProject( /*isJsInferredProject*/ false ); } } } /** @internal */ isOrphan() { return !this.hasRoots(); } isProjectWithSingleRoot() { return !this.projectRootPath && !this.projectService.useSingleInferredProject || this.getRootScriptInfos().length === 1; } close() { forEach(this.getRootScriptInfos(), (info) => this.projectService.stopWatchingConfigFilesForScriptInfo(info)); super.close(); } getTypeAcquisition() { return this.typeAcquisition || { enable: allRootFilesAreJsOrDts(this), include: emptyArray, exclude: emptyArray }; } }; var AuxiliaryProject = class extends Project3 { constructor(projectService, documentRegistry, compilerOptions, currentDirectory) { super( projectService.newAuxiliaryProjectName(), 4 /* Auxiliary */, projectService, documentRegistry, /*hasExplicitListOfFiles*/ false, /*lastFileExceededProgramSize*/ void 0, compilerOptions, /*compileOnSaveEnabled*/ false, /*watchOptions*/ void 0, projectService.host, currentDirectory ); } isOrphan() { return true; } scheduleInvalidateResolutionsOfFailedLookupLocations() { return; } }; var _AutoImportProviderProject = class _AutoImportProviderProject extends Project3 { /** @internal */ constructor(hostProject, initialRootNames, documentRegistry, compilerOptions) { super( hostProject.projectService.newAutoImportProviderProjectName(), 3 /* AutoImportProvider */, hostProject.projectService, documentRegistry, /*hasExplicitListOfFiles*/ false, /*lastFileExceededProgramSize*/ void 0, compilerOptions, /*compileOnSaveEnabled*/ false, hostProject.getWatchOptions(), hostProject.projectService.host, hostProject.currentDirectory ); this.hostProject = hostProject; this.rootFileNames = initialRootNames; this.useSourceOfProjectReferenceRedirect = maybeBind(this.hostProject, this.hostProject.useSourceOfProjectReferenceRedirect); this.getParsedCommandLine = maybeBind(this.hostProject, this.hostProject.getParsedCommandLine); } /** @internal */ static getRootFileNames(dependencySelection, hostProject, host, compilerOptions) { var _a, _b; if (!dependencySelection) { return emptyArray; } const program = hostProject.getCurrentProgram(); if (!program) { return emptyArray; } const start = timestamp(); let dependencyNames; let rootNames; const rootFileName = combinePaths(hostProject.currentDirectory, inferredTypesContainingFile); const packageJsons = hostProject.getPackageJsonsForAutoImport(combinePaths(hostProject.currentDirectory, rootFileName)); for (const packageJson of packageJsons) { (_a = packageJson.dependencies) == null ? void 0 : _a.forEach((_, dependenyName) => addDependency(dependenyName)); (_b = packageJson.peerDependencies) == null ? void 0 : _b.forEach((_, dependencyName) => addDependency(dependencyName)); } let dependenciesAdded = 0; if (dependencyNames) { const symlinkCache = hostProject.getSymlinkCache(); for (const name of arrayFrom(dependencyNames.keys())) { if (dependencySelection === 2 /* Auto */ && dependenciesAdded > this.maxDependencies) { hostProject.log(`AutoImportProviderProject: attempted to add more than ${this.maxDependencies} dependencies. Aborting.`); return emptyArray; } const packageJson = resolvePackageNameToPackageJson( name, hostProject.currentDirectory, compilerOptions, host, program.getModuleResolutionCache() ); if (packageJson) { const entrypoints = getRootNamesFromPackageJson(packageJson, program, symlinkCache); if (entrypoints) { dependenciesAdded += addRootNames(entrypoints); continue; } } const done = forEach([hostProject.currentDirectory, hostProject.getGlobalTypingsCacheLocation()], (directory) => { if (directory) { const typesPackageJson = resolvePackageNameToPackageJson( `@types/${name}`, directory, compilerOptions, host, program.getModuleResolutionCache() ); if (typesPackageJson) { const entrypoints = getRootNamesFromPackageJson(typesPackageJson, program, symlinkCache); dependenciesAdded += addRootNames(entrypoints); return true; } } }); if (done) continue; if (packageJson && compilerOptions.allowJs && compilerOptions.maxNodeModuleJsDepth) { const entrypoints = getRootNamesFromPackageJson( packageJson, program, symlinkCache, /*resolveJs*/ true ); dependenciesAdded += addRootNames(entrypoints); } } } const references = program.getResolvedProjectReferences(); let referencesAddded = 0; if ((references == null ? void 0 : references.length) && hostProject.projectService.getHostPreferences().includeCompletionsForModuleExports) { references.forEach((ref) => { if (ref == null ? void 0 : ref.commandLine.options.outFile) { referencesAddded += addRootNames(filterEntrypoints([ changeExtension(ref.commandLine.options.outFile, ".d.ts") ])); } else if (ref) { const getCommonSourceDirectory2 = memoize( () => getCommonSourceDirectoryOfConfig( ref.commandLine, !hostProject.useCaseSensitiveFileNames() ) ); referencesAddded += addRootNames(filterEntrypoints(mapDefined( ref.commandLine.fileNames, (fileName) => !isDeclarationFileName(fileName) && !fileExtensionIs(fileName, ".json" /* Json */) && !program.getSourceFile(fileName) ? getOutputDeclarationFileName( fileName, ref.commandLine, !hostProject.useCaseSensitiveFileNames(), getCommonSourceDirectory2 ) : void 0 ))); } }); } if (rootNames == null ? void 0 : rootNames.size) { hostProject.log(`AutoImportProviderProject: found ${rootNames.size} root files in ${dependenciesAdded} dependencies ${referencesAddded} referenced projects in ${timestamp() - start} ms`); } return rootNames ? arrayFrom(rootNames.values()) : emptyArray; function addRootNames(entrypoints) { if (!(entrypoints == null ? void 0 : entrypoints.length)) return 0; rootNames ?? (rootNames = /* @__PURE__ */ new Set()); entrypoints.forEach((entry) => rootNames.add(entry)); return 1; } function addDependency(dependency) { if (!startsWith(dependency, "@types/")) { (dependencyNames || (dependencyNames = /* @__PURE__ */ new Set())).add(dependency); } } function getRootNamesFromPackageJson(packageJson, program2, symlinkCache, resolveJs) { var _a2; const entrypoints = getEntrypointsFromPackageJsonInfo( packageJson, compilerOptions, host, program2.getModuleResolutionCache(), resolveJs ); if (entrypoints) { const real = (_a2 = host.realpath) == null ? void 0 : _a2.call(host, packageJson.packageDirectory); const realPath2 = real ? hostProject.toPath(real) : void 0; const isSymlink = realPath2 && realPath2 !== hostProject.toPath(packageJson.packageDirectory); if (isSymlink) { symlinkCache.setSymlinkedDirectory(packageJson.packageDirectory, { real: ensureTrailingDirectorySeparator(real), realPath: ensureTrailingDirectorySeparator(realPath2) }); } return filterEntrypoints(entrypoints, isSymlink ? (entrypoint) => entrypoint.replace(packageJson.packageDirectory, real) : void 0); } } function filterEntrypoints(entrypoints, symlinkName) { return mapDefined(entrypoints, (entrypoint) => { const resolvedFileName = symlinkName ? symlinkName(entrypoint) : entrypoint; if (!program.getSourceFile(resolvedFileName) && !(symlinkName && program.getSourceFile(entrypoint))) { return resolvedFileName; } }); } } /** @internal */ static create(dependencySelection, hostProject, host, documentRegistry) { if (dependencySelection === 0 /* Off */) { return void 0; } const compilerOptions = { ...hostProject.getCompilerOptions(), ...this.compilerOptionsOverrides }; const rootNames = this.getRootFileNames(dependencySelection, hostProject, host, compilerOptions); if (!rootNames.length) { return void 0; } return new _AutoImportProviderProject(hostProject, rootNames, documentRegistry, compilerOptions); } /** @internal */ isEmpty() { return !some(this.rootFileNames); } /** @internal */ isOrphan() { return true; } updateGraph() { let rootFileNames = this.rootFileNames; if (!rootFileNames) { rootFileNames = _AutoImportProviderProject.getRootFileNames( this.hostProject.includePackageJsonAutoImports(), this.hostProject, this.hostProject.getHostForAutoImportProvider(), this.getCompilationSettings() ); } this.projectService.setFileNamesOfAutpImportProviderOrAuxillaryProject(this, rootFileNames); this.rootFileNames = rootFileNames; const oldProgram = this.getCurrentProgram(); const hasSameSetOfFiles = super.updateGraph(); if (oldProgram && oldProgram !== this.getCurrentProgram()) { this.hostProject.clearCachedExportInfoMap(); } return hasSameSetOfFiles; } /** @internal */ scheduleInvalidateResolutionsOfFailedLookupLocations() { return; } hasRoots() { var _a; return !!((_a = this.rootFileNames) == null ? void 0 : _a.length); } /** @internal */ markAsDirty() { this.rootFileNames = void 0; super.markAsDirty(); } getScriptFileNames() { return this.rootFileNames || emptyArray; } getLanguageService() { throw new Error("AutoImportProviderProject language service should never be used. To get the program, use `project.getCurrentProgram()`."); } /** @internal */ onAutoImportProviderSettingsChanged() { throw new Error("AutoImportProviderProject is an auto import provider; use `markAsDirty()` instead."); } /** @internal */ onPackageJsonChange() { throw new Error("package.json changes should be notified on an AutoImportProvider's host project"); } getHostForAutoImportProvider() { throw new Error("AutoImportProviderProject cannot provide its own host; use `hostProject.getModuleResolutionHostForAutomImportProvider()` instead."); } getProjectReferences() { return this.hostProject.getProjectReferences(); } /** @internal */ includePackageJsonAutoImports() { return 0 /* Off */; } /** @internal */ getSymlinkCache() { return this.hostProject.getSymlinkCache(); } /** @internal */ getModuleResolutionCache() { var _a; return (_a = this.hostProject.getCurrentProgram()) == null ? void 0 : _a.getModuleResolutionCache(); } }; /** @internal */ _AutoImportProviderProject.maxDependencies = 10; /** @internal */ _AutoImportProviderProject.compilerOptionsOverrides = { diagnostics: false, skipLibCheck: true, sourceMap: false, types: emptyArray, lib: emptyArray, noLib: true }; var AutoImportProviderProject = _AutoImportProviderProject; var ConfiguredProject2 = class extends Project3 { /** @internal */ constructor(configFileName, canonicalConfigFilePath, projectService, documentRegistry, cachedDirectoryStructureHost, pendingUpdateReason) { super( configFileName, 1 /* Configured */, projectService, documentRegistry, /*hasExplicitListOfFiles*/ false, /*lastFileExceededProgramSize*/ void 0, /*compilerOptions*/ {}, /*compileOnSaveEnabled*/ false, /*watchOptions*/ void 0, cachedDirectoryStructureHost, getDirectoryPath(configFileName) ); this.canonicalConfigFilePath = canonicalConfigFilePath; /** @internal */ this.openFileWatchTriggered = /* @__PURE__ */ new Map(); /** @internal */ this.canConfigFileJsonReportNoInputFiles = false; /** @internal */ this.isInitialLoadPending = returnTrue; /** @internal */ this.sendLoadingProjectFinish = false; this.pendingUpdateLevel = 2 /* Full */; this.pendingUpdateReason = pendingUpdateReason; } /** @internal */ setCompilerHost(host) { this.compilerHost = host; } /** @internal */ getCompilerHost() { return this.compilerHost; } /** @internal */ useSourceOfProjectReferenceRedirect() { return this.languageServiceEnabled; } /** @internal */ getParsedCommandLine(fileName) { const configFileName = asNormalizedPath(normalizePath(fileName)); const canonicalConfigFilePath = asNormalizedPath(this.projectService.toCanonicalFileName(configFileName)); let configFileExistenceInfo = this.projectService.configFileExistenceInfoCache.get(canonicalConfigFilePath); if (!configFileExistenceInfo) { this.projectService.configFileExistenceInfoCache.set(canonicalConfigFilePath, configFileExistenceInfo = { exists: this.projectService.host.fileExists(configFileName) }); } this.projectService.ensureParsedConfigUptoDate(configFileName, canonicalConfigFilePath, configFileExistenceInfo, this); if (this.languageServiceEnabled && this.projectService.serverMode === 0 /* Semantic */) { this.projectService.watchWildcards(configFileName, configFileExistenceInfo, this); } return configFileExistenceInfo.exists ? configFileExistenceInfo.config.parsedCommandLine : void 0; } /** @internal */ onReleaseParsedCommandLine(fileName) { this.releaseParsedConfig(asNormalizedPath(this.projectService.toCanonicalFileName(asNormalizedPath(normalizePath(fileName))))); } /** @internal */ releaseParsedConfig(canonicalConfigFilePath) { this.projectService.stopWatchingWildCards(canonicalConfigFilePath, this); this.projectService.releaseParsedConfig(canonicalConfigFilePath, this); } /** * If the project has reload from disk pending, it reloads (and then updates graph as part of that) instead of just updating the graph * @returns: true if set of files in the project stays the same and false - otherwise. */ updateGraph() { if (this.deferredClose) return false; const isDirty = this.dirty; this.isInitialLoadPending = returnFalse; const updateLevel = this.pendingUpdateLevel; this.pendingUpdateLevel = 0 /* Update */; let result; switch (updateLevel) { case 1 /* RootNamesAndUpdate */: this.openFileWatchTriggered.clear(); result = this.projectService.reloadFileNamesOfConfiguredProject(this); break; case 2 /* Full */: this.openFileWatchTriggered.clear(); const reason = Debug.checkDefined(this.pendingUpdateReason); this.projectService.reloadConfiguredProject(this, reason); result = true; break; default: result = super.updateGraph(); } this.compilerHost = void 0; this.projectService.sendProjectLoadingFinishEvent(this); this.projectService.sendProjectTelemetry(this); if (updateLevel === 2 /* Full */ || // Already sent event through reload result && // Not new program (!isDirty || !this.triggerFileForConfigFileDiag || this.getCurrentProgram().structureIsReused === 2 /* Completely */)) { this.triggerFileForConfigFileDiag = void 0; } else if (!this.triggerFileForConfigFileDiag) { this.projectService.sendConfigFileDiagEvent( this, /*triggerFile*/ void 0, /*force*/ false ); } return result; } /** @internal */ getCachedDirectoryStructureHost() { return this.directoryStructureHost; } getConfigFilePath() { return asNormalizedPath(this.getProjectName()); } getProjectReferences() { return this.projectReferences; } updateReferences(refs) { if (typeof process.versions.pnp !== `undefined`) { const basePath = this.getCurrentDirectory(); const getPnpPath = (path) => { try { const pnpApi = getPnpApi(`${path}/`); if (!pnpApi) { return path; } const targetLocator = pnpApi.findPackageLocator(`${path}/`); const { packageLocation } = pnpApi.getPackageInformation(targetLocator); const request = combinePaths(targetLocator.name, getRelativePathFromDirectory( packageLocation, path, /*ignoreCase*/ false )); return pnpApi.resolveToUnqualified(request, `${basePath}/`); } catch { return path; } }; refs = refs == null ? void 0 : refs.map((r) => ({ ...r, path: getPnpPath(r.path) })); } this.projectReferences = refs; this.potentialProjectReferences = void 0; } /** @internal */ setPotentialProjectReference(canonicalConfigPath) { Debug.assert(this.isInitialLoadPending()); (this.potentialProjectReferences || (this.potentialProjectReferences = /* @__PURE__ */ new Set())).add(canonicalConfigPath); } /** @internal */ getResolvedProjectReferenceToRedirect(fileName) { const program = this.getCurrentProgram(); return program && program.getResolvedProjectReferenceToRedirect(fileName); } /** @internal */ forEachResolvedProjectReference(cb) { var _a; return (_a = this.getCurrentProgram()) == null ? void 0 : _a.forEachResolvedProjectReference(cb); } /** @internal */ enablePluginsWithOptions(options) { var _a; this.plugins.length = 0; if (!((_a = options.plugins) == null ? void 0 : _a.length) && !this.projectService.globalPlugins.length) return; const host = this.projectService.host; if (!host.require && !host.importPlugin) { this.projectService.logger.info("Plugins were requested but not running in environment that supports 'require'. Nothing will be loaded"); return; } const searchPaths = this.getGlobalPluginSearchPaths(); if (this.projectService.allowLocalPluginLoads) { const local = getDirectoryPath(this.canonicalConfigFilePath); this.projectService.logger.info(`Local plugin loading enabled; adding ${local} to search paths`); searchPaths.unshift(local); } if (options.plugins) { for (const pluginConfigEntry of options.plugins) { this.enablePlugin(pluginConfigEntry, searchPaths); } } return this.enableGlobalPlugins(options); } /** * Get the errors that dont have any file name associated */ getGlobalProjectErrors() { return filter(this.projectErrors, (diagnostic) => !diagnostic.file) || emptyArray2; } /** * Get all the project errors */ getAllProjectErrors() { return this.projectErrors || emptyArray2; } setProjectErrors(projectErrors) { this.projectErrors = projectErrors; } close() { this.projectService.configFileExistenceInfoCache.forEach((_configFileExistenceInfo, canonicalConfigFilePath) => this.releaseParsedConfig(canonicalConfigFilePath)); this.projectErrors = void 0; this.openFileWatchTriggered.clear(); this.compilerHost = void 0; super.close(); } /** @internal */ markAsDirty() { if (this.deferredClose) return; super.markAsDirty(); } /** @internal */ isSolution() { return this.getRootFilesMap().size === 0 && !this.canConfigFileJsonReportNoInputFiles; } /** @internal */ isOrphan() { return !!this.deferredClose; } getEffectiveTypeRoots() { return getEffectiveTypeRoots(this.getCompilationSettings(), this) || []; } /** @internal */ updateErrorOnNoInputFiles(fileNames) { updateErrorForNoInputFiles(fileNames, this.getConfigFilePath(), this.getCompilerOptions().configFile.configFileSpecs, this.projectErrors, this.canConfigFileJsonReportNoInputFiles); } }; var ExternalProject = class extends Project3 { /** @internal */ constructor(externalProjectName, projectService, documentRegistry, compilerOptions, lastFileExceededProgramSize, compileOnSaveEnabled, projectFilePath, watchOptions) { super( externalProjectName, 2 /* External */, projectService, documentRegistry, /*hasExplicitListOfFiles*/ true, lastFileExceededProgramSize, compilerOptions, compileOnSaveEnabled, watchOptions, projectService.host, getDirectoryPath(projectFilePath || normalizeSlashes(externalProjectName)) ); this.externalProjectName = externalProjectName; this.compileOnSaveEnabled = compileOnSaveEnabled; this.excludedFiles = []; this.enableGlobalPlugins(this.getCompilerOptions()); } updateGraph() { const result = super.updateGraph(); this.projectService.sendProjectTelemetry(this); return result; } getExcludedFiles() { return this.excludedFiles; } }; function isInferredProject(project) { return project.projectKind === 0 /* Inferred */; } function isConfiguredProject(project) { return project.projectKind === 1 /* Configured */; } function isExternalProject(project) { return project.projectKind === 2 /* External */; } function isBackgroundProject(project) { return project.projectKind === 3 /* AutoImportProvider */ || project.projectKind === 4 /* Auxiliary */; } function isProjectDeferredClose(project) { return isConfiguredProject(project) && !!project.deferredClose; } // src/server/editorServices.ts var maxProgramSizeForNonTsFiles = 20 * 1024 * 1024; var maxFileSize = 4 * 1024 * 1024; var ProjectsUpdatedInBackgroundEvent = "projectsUpdatedInBackground"; var ProjectLoadingStartEvent = "projectLoadingStart"; var ProjectLoadingFinishEvent = "projectLoadingFinish"; var LargeFileReferencedEvent = "largeFileReferenced"; var ConfigFileDiagEvent = "configFileDiag"; var ProjectLanguageServiceStateEvent = "projectLanguageServiceState"; var ProjectInfoTelemetryEvent = "projectInfo"; var OpenFileInfoTelemetryEvent = "openFileInfo"; var CreateFileWatcherEvent = "createFileWatcher"; var CreateDirectoryWatcherEvent = "createDirectoryWatcher"; var CloseFileWatcherEvent = "closeFileWatcher"; var ensureProjectForOpenFileSchedule = "*ensureProjectForOpenFiles*"; function prepareConvertersForEnumLikeCompilerOptions(commandLineOptions) { const map2 = /* @__PURE__ */ new Map(); for (const option of commandLineOptions) { if (typeof option.type === "object") { const optionMap = option.type; optionMap.forEach((value) => { Debug.assert(typeof value === "number"); }); map2.set(option.name, optionMap); } } return map2; } var compilerOptionConverters = prepareConvertersForEnumLikeCompilerOptions(optionDeclarations); var watchOptionsConverters = prepareConvertersForEnumLikeCompilerOptions(optionsForWatch); var indentStyle = new Map(Object.entries({ none: 0 /* None */, block: 1 /* Block */, smart: 2 /* Smart */ })); var defaultTypeSafeList = { "jquery": { // jquery files can have names like "jquery-1.10.2.min.js" (or "jquery.intellisense.js") match: /jquery(-[\d.]+)?(\.intellisense)?(\.min)?\.js$/i, types: ["jquery"] }, "WinJS": { // e.g. c:/temp/UWApp1/lib/winjs-4.0.1/js/base.js match: /^(.*\/winjs-[.\d]+)\/js\/base\.js$/i, // If the winjs/base.js file is found.. exclude: [["^", 1, "/.*"]], // ..then exclude all files under the winjs folder types: ["winjs"] // And fetch the @types package for WinJS }, "Kendo": { // e.g. /Kendo3/wwwroot/lib/kendo/kendo.all.min.js match: /^(.*\/kendo(-ui)?)\/kendo\.all(\.min)?\.js$/i, exclude: [["^", 1, "/.*"]], types: ["kendo-ui"] }, "Office Nuget": { // e.g. /scripts/Office/1/excel-15.debug.js match: /^(.*\/office\/1)\/excel-\d+\.debug\.js$/i, // Office NuGet package is installed under a "1/office" folder exclude: [["^", 1, "/.*"]], // Exclude that whole folder if the file indicated above is found in it types: ["office"] // @types package to fetch instead }, "References": { match: /^(.*\/_references\.js)$/i, exclude: [["^", 1, "$"]] } }; function convertFormatOptions(protocolOptions) { if (isString(protocolOptions.indentStyle)) { protocolOptions.indentStyle = indentStyle.get(protocolOptions.indentStyle.toLowerCase()); Debug.assert(protocolOptions.indentStyle !== void 0); } return protocolOptions; } function convertCompilerOptions(protocolOptions) { compilerOptionConverters.forEach((mappedValues, id) => { const propertyValue = protocolOptions[id]; if (isString(propertyValue)) { protocolOptions[id] = mappedValues.get(propertyValue.toLowerCase()); } }); return protocolOptions; } function convertWatchOptions(protocolOptions, currentDirectory) { let watchOptions; let errors; optionsForWatch.forEach((option) => { const propertyValue = protocolOptions[option.name]; if (propertyValue === void 0) return; const mappedValues = watchOptionsConverters.get(option.name); (watchOptions || (watchOptions = {}))[option.name] = mappedValues ? isString(propertyValue) ? mappedValues.get(propertyValue.toLowerCase()) : propertyValue : convertJsonOption(option, propertyValue, currentDirectory || "", errors || (errors = [])); }); return watchOptions && { watchOptions, errors }; } function convertTypeAcquisition(protocolOptions) { let result; typeAcquisitionDeclarations.forEach((option) => { const propertyValue = protocolOptions[option.name]; if (propertyValue === void 0) return; (result || (result = {}))[option.name] = propertyValue; }); return result; } function tryConvertScriptKindName(scriptKindName) { return isString(scriptKindName) ? convertScriptKindName(scriptKindName) : scriptKindName; } function convertScriptKindName(scriptKindName) { switch (scriptKindName) { case "JS": return 1 /* JS */; case "JSX": return 2 /* JSX */; case "TS": return 3 /* TS */; case "TSX": return 4 /* TSX */; default: return 0 /* Unknown */; } } function convertUserPreferences(preferences) { const { lazyConfiguredProjectsFromExternalProject: _, ...userPreferences } = preferences; return userPreferences; } var fileNamePropertyReader = { getFileName: (x) => x, getScriptKind: (fileName, extraFileExtensions) => { let result; if (extraFileExtensions) { const fileExtension = getAnyExtensionFromPath(fileName); if (fileExtension) { some(extraFileExtensions, (info) => { if (info.extension === fileExtension) { result = info.scriptKind; return true; } return false; }); } } return result; }, hasMixedContent: (fileName, extraFileExtensions) => some(extraFileExtensions, (ext) => ext.isMixedContent && fileExtensionIs(fileName, ext.extension)) }; var externalFilePropertyReader = { getFileName: (x) => x.fileName, getScriptKind: (x) => tryConvertScriptKindName(x.scriptKind), // TODO: GH#18217 hasMixedContent: (x) => !!x.hasMixedContent }; function findProjectByName(projectName, projects) { for (const proj of projects) { if (proj.getProjectName() === projectName) { return proj; } } } var noopConfigFileWatcher = { close: noop }; function getConfigFileNameFromCache(info, cache) { if (!cache || isAncestorConfigFileInfo(info)) return void 0; return cache.get(info.path); } function isOpenScriptInfo(infoOrFileNameOrConfig) { return !!infoOrFileNameOrConfig.containingProjects; } function isAncestorConfigFileInfo(infoOrFileNameOrConfig) { return !!infoOrFileNameOrConfig.configFileInfo; } var ConfiguredProjectLoadKind = /* @__PURE__ */ ((ConfiguredProjectLoadKind2) => { ConfiguredProjectLoadKind2[ConfiguredProjectLoadKind2["Find"] = 0] = "Find"; ConfiguredProjectLoadKind2[ConfiguredProjectLoadKind2["Create"] = 1] = "Create"; ConfiguredProjectLoadKind2[ConfiguredProjectLoadKind2["Reload"] = 2] = "Reload"; return ConfiguredProjectLoadKind2; })(ConfiguredProjectLoadKind || {}); function forEachAncestorProject(info, project, cb, kind, reason, allowDeferredClosed, reloadedProjects, delayReloadedConfiguredProjects) { while (true) { if (!project.isInitialLoadPending() && (!project.getCompilerOptions().composite || project.getCompilerOptions().disableSolutionSearching)) return; const configFileName = project.projectService.getConfigFileNameForFile({ fileName: project.getConfigFilePath(), path: info.path, configFileInfo: true }, kind === 0 /* Find */); if (!configFileName) return; const ancestor = project.projectService.findCreateOrReloadConfiguredProject( configFileName, kind, reason, allowDeferredClosed, /*triggerFile*/ void 0, reloadedProjects, /*delayLoad*/ true, delayReloadedConfiguredProjects ); if (!ancestor) return; if (ancestor.project.isInitialLoadPending() && project.getCompilerOptions().composite) { ancestor.project.setPotentialProjectReference(project.canonicalConfigFilePath); } const result = cb(ancestor.project); if (result) return result; project = ancestor.project; } } function forEachResolvedProjectReferenceProject(project, fileName, cb, kind, reason, allowDeferredClosed, triggerFile, reloadedProjects) { var _a; const resolvedRefs = (_a = project.getCurrentProgram()) == null ? void 0 : _a.getResolvedProjectReferences(); if (!resolvedRefs) return void 0; const possibleDefaultRef = fileName ? project.getResolvedProjectReferenceToRedirect(fileName) : void 0; if (possibleDefaultRef) { const configFileName = toNormalizedPath(possibleDefaultRef.sourceFile.fileName); const child = project.projectService.findConfiguredProjectByProjectName( configFileName, allowDeferredClosed ); if (child) { const result = callbackWithProjectFoundUsingFind(child); if (result) return result; } else if (kind !== 0 /* Find */) { const result = forEachResolvedProjectReferenceProjectWorker( resolvedRefs, project.getCompilerOptions(), (ref, loadKind) => possibleDefaultRef === ref ? callback(ref, loadKind) : void 0, kind, project.projectService ); if (result) return result; } } return forEachResolvedProjectReferenceProjectWorker( resolvedRefs, project.getCompilerOptions(), (ref, loadKind) => possibleDefaultRef !== ref ? callback(ref, loadKind) : void 0, kind, project.projectService ); function callback(ref, loadKind) { const result = project.projectService.findCreateOrReloadConfiguredProject( toNormalizedPath(ref.sourceFile.fileName), loadKind, reason, allowDeferredClosed, triggerFile, reloadedProjects ); return result && (loadKind === kind ? cb(result.project, result.sentConfigFileDiag) : callbackWithProjectFoundUsingFind(result.project)); } function callbackWithProjectFoundUsingFind(child) { let sentConfigFileDiag = false; switch (kind) { case 1 /* Create */: sentConfigFileDiag = updateConfiguredProject(child, triggerFile); break; case 2 /* Reload */: sentConfigFileDiag = child.projectService.reloadConfiguredProjectClearingSemanticCache(child, reason, reloadedProjects); break; case 0 /* Find */: break; default: Debug.assertNever(kind); } const result = cb(child, sentConfigFileDiag); if (result) return result; } } function forEachResolvedProjectReferenceProjectWorker(resolvedProjectReferences, parentOptions, cb, kind, projectService, seenResolvedRefs) { const loadKind = parentOptions.disableReferencedProjectLoad ? 0 /* Find */ : kind; return forEach(resolvedProjectReferences, (ref) => { if (!ref) return void 0; const configFileName = toNormalizedPath(ref.sourceFile.fileName); const canonicalPath = projectService.toCanonicalFileName(configFileName); const seenValue = seenResolvedRefs == null ? void 0 : seenResolvedRefs.get(canonicalPath); if (seenValue !== void 0 && seenValue >= loadKind) { return void 0; } const result = cb(ref, loadKind); if (result) { return result; } (seenResolvedRefs || (seenResolvedRefs = /* @__PURE__ */ new Map())).set(canonicalPath, loadKind); return ref.references && forEachResolvedProjectReferenceProjectWorker(ref.references, ref.commandLine.options, cb, loadKind, projectService, seenResolvedRefs); }); } function forEachPotentialProjectReference(project, cb) { return project.potentialProjectReferences && forEachKey(project.potentialProjectReferences, cb); } function forEachAnyProjectReferenceKind(project, cb, cbProjectRef, cbPotentialProjectRef) { return project.getCurrentProgram() ? project.forEachResolvedProjectReference(cb) : project.isInitialLoadPending() ? forEachPotentialProjectReference(project, cbPotentialProjectRef) : forEach(project.getProjectReferences(), cbProjectRef); } function callbackRefProject(project, cb, refPath) { const refProject = refPath && project.projectService.configuredProjects.get(refPath); return refProject && cb(refProject); } function forEachReferencedProject(project, cb) { return forEachAnyProjectReferenceKind( project, (resolvedRef) => callbackRefProject(project, cb, resolvedRef.sourceFile.path), (projectRef) => callbackRefProject(project, cb, project.toPath(resolveProjectReferencePath(projectRef))), (potentialProjectRef) => callbackRefProject(project, cb, potentialProjectRef) ); } function getDetailWatchInfo(watchType, project) { return `${isString(project) ? `Config: ${project} ` : project ? `Project: ${project.getProjectName()} ` : ""}WatchType: ${watchType}`; } function isScriptInfoWatchedFromNodeModules(info) { return !info.isScriptOpen() && info.mTime !== void 0; } function updateProjectIfDirty(project) { project.invalidateResolutionsOfFailedLookupLocations(); return project.dirty && !project.updateGraph(); } function updateWithTriggerFile(project, triggerFile, isReload) { if (!isReload) { project.invalidateResolutionsOfFailedLookupLocations(); if (!project.dirty) return false; } project.triggerFileForConfigFileDiag = triggerFile; const updateLevel = project.pendingUpdateLevel; project.updateGraph(); if (!project.triggerFileForConfigFileDiag && !isReload) return updateLevel === 2 /* Full */; const sent = project.projectService.sendConfigFileDiagEvent(project, triggerFile, isReload); project.triggerFileForConfigFileDiag = void 0; return sent; } function updateConfiguredProject(project, triggerFile) { if (triggerFile) { if (updateWithTriggerFile( project, triggerFile, /*isReload*/ false )) return true; } else { updateProjectIfDirty(project); } return false; } function fileOpenReason(info) { return `Creating possible configured project for ${info.fileName} to open`; } function reloadReason(reason) { return `User requested reload projects: ${reason}`; } function setProjectOptionsUsed(project) { if (isConfiguredProject(project)) { project.projectOptions = true; } } function createProjectNameFactoryWithCounter(nameFactory) { let nextId = 1; return () => nameFactory(nextId++); } function getHostWatcherMap() { return { idToCallbacks: /* @__PURE__ */ new Map(), pathToId: /* @__PURE__ */ new Map() }; } function createWatchFactoryHostUsingWatchEvents(service, canUseWatchEvents) { if (!canUseWatchEvents || !service.eventHandler || !service.session) return void 0; const watchedFiles = getHostWatcherMap(); const watchedDirectories = getHostWatcherMap(); const watchedDirectoriesRecursive = getHostWatcherMap(); let ids = 1; service.session.addProtocolHandler("watchChange" /* WatchChange */, (req) => { onWatchChange(req.arguments); return { responseRequired: false }; }); return { watchFile: watchFile2, watchDirectory, getCurrentDirectory: () => service.host.getCurrentDirectory(), useCaseSensitiveFileNames: service.host.useCaseSensitiveFileNames }; function watchFile2(path, callback) { return getOrCreateFileWatcher( watchedFiles, path, callback, (id) => ({ eventName: CreateFileWatcherEvent, data: { id, path } }) ); } function watchDirectory(path, callback, recursive) { return getOrCreateFileWatcher( recursive ? watchedDirectoriesRecursive : watchedDirectories, path, callback, (id) => ({ eventName: CreateDirectoryWatcherEvent, data: { id, path, recursive: !!recursive, // Special case node_modules as we watch it for changes to closed script infos as well ignoreUpdate: !path.endsWith("/node_modules") ? true : void 0 } }) ); } function getOrCreateFileWatcher({ pathToId, idToCallbacks }, path, callback, event) { const key = service.toPath(path); let id = pathToId.get(key); if (!id) pathToId.set(key, id = ids++); let callbacks = idToCallbacks.get(id); if (!callbacks) { idToCallbacks.set(id, callbacks = /* @__PURE__ */ new Set()); service.eventHandler(event(id)); } callbacks.add(callback); return { close() { const callbacks2 = idToCallbacks.get(id); if (!(callbacks2 == null ? void 0 : callbacks2.delete(callback))) return; if (callbacks2.size) return; idToCallbacks.delete(id); pathToId.delete(key); service.eventHandler({ eventName: CloseFileWatcherEvent, data: { id } }); } }; } function onWatchChange(args) { if (isArray(args)) args.forEach(onWatchChangeRequestArgs); else onWatchChangeRequestArgs(args); } function onWatchChangeRequestArgs({ id, created, deleted, updated }) { onWatchEventType(id, created, 0 /* Created */); onWatchEventType(id, deleted, 2 /* Deleted */); onWatchEventType(id, updated, 1 /* Changed */); } function onWatchEventType(id, paths, eventKind) { if (!(paths == null ? void 0 : paths.length)) return; forEachCallback(watchedFiles, id, paths, (callback, eventPath) => callback(eventPath, eventKind)); forEachCallback(watchedDirectories, id, paths, (callback, eventPath) => callback(eventPath)); forEachCallback(watchedDirectoriesRecursive, id, paths, (callback, eventPath) => callback(eventPath)); } function forEachCallback(hostWatcherMap, id, eventPaths, cb) { var _a; (_a = hostWatcherMap.idToCallbacks.get(id)) == null ? void 0 : _a.forEach((callback) => { eventPaths.forEach((eventPath) => cb(callback, normalizeSlashes(eventPath))); }); } } var _ProjectService = class _ProjectService { constructor(opts) { /** * Container of all known scripts * * @internal */ this.filenameToScriptInfo = /* @__PURE__ */ new Map(); this.nodeModulesWatchers = /* @__PURE__ */ new Map(); /** * Contains all the deleted script info's version information so that * it does not reset when creating script info again * (and could have potentially collided with version where contents mismatch) */ this.filenameToScriptInfoVersion = /* @__PURE__ */ new Map(); // Set of all '.js' files ever opened. this.allJsFilesForOpenFileTelemetry = /* @__PURE__ */ new Map(); /** * maps external project file name to list of config files that were the part of this project */ this.externalProjectToConfiguredProjectMap = /* @__PURE__ */ new Map(); /** * external projects (configuration and list of root files is not controlled by tsserver) */ this.externalProjects = []; /** * projects built from openFileRoots */ this.inferredProjects = []; /** * projects specified by a tsconfig.json file */ this.configuredProjects = /* @__PURE__ */ new Map(); /** @internal */ this.newInferredProjectName = createProjectNameFactoryWithCounter(makeInferredProjectName); /** @internal */ this.newAutoImportProviderProjectName = createProjectNameFactoryWithCounter(makeAutoImportProviderProjectName); /** @internal */ this.newAuxiliaryProjectName = createProjectNameFactoryWithCounter(makeAuxiliaryProjectName); /** * Open files: with value being project root path, and key being Path of the file that is open */ this.openFiles = /* @__PURE__ */ new Map(); /** Config files looked up and cached config files for open script info */ this.configFileForOpenFiles = /* @__PURE__ */ new Map(); /** Set of open script infos that are root of inferred project */ this.rootOfInferredProjects = /* @__PURE__ */ new Set(); /** * Map of open files that are opened without complete path but have projectRoot as current directory */ this.openFilesWithNonRootedDiskPath = /* @__PURE__ */ new Map(); this.compilerOptionsForInferredProjectsPerProjectRoot = /* @__PURE__ */ new Map(); this.watchOptionsForInferredProjectsPerProjectRoot = /* @__PURE__ */ new Map(); this.typeAcquisitionForInferredProjectsPerProjectRoot = /* @__PURE__ */ new Map(); /** * Project size for configured or external projects */ this.projectToSizeMap = /* @__PURE__ */ new Map(); /** * This is a map of config file paths existence that doesnt need query to disk * - The entry can be present because there is inferred project that needs to watch addition of config file to directory * In this case the exists could be true/false based on config file is present or not * - Or it is present if we have configured project open with config file at that location * In this case the exists property is always true * * @internal */ this.configFileExistenceInfoCache = /* @__PURE__ */ new Map(); this.safelist = defaultTypeSafeList; this.legacySafelist = /* @__PURE__ */ new Map(); this.pendingProjectUpdates = /* @__PURE__ */ new Map(); /** @internal */ this.pendingEnsureProjectForOpenFiles = false; /** Tracks projects that we have already sent telemetry for. */ this.seenProjects = /* @__PURE__ */ new Map(); /** @internal */ this.sharedExtendedConfigFileWatchers = /* @__PURE__ */ new Map(); /** @internal */ this.extendedConfigCache = /* @__PURE__ */ new Map(); /** @internal */ this.baseline = noop; /** @internal */ this.verifyDocumentRegistry = noop; /** @internal */ this.verifyProgram = noop; /** @internal */ this.onProjectCreation = noop; var _a; this.host = opts.host; this.logger = opts.logger; this.cancellationToken = opts.cancellationToken; this.useSingleInferredProject = opts.useSingleInferredProject; this.useInferredProjectPerProjectRoot = opts.useInferredProjectPerProjectRoot; this.typingsInstaller = opts.typingsInstaller || nullTypingsInstaller; this.throttleWaitMilliseconds = opts.throttleWaitMilliseconds; this.eventHandler = opts.eventHandler; this.suppressDiagnosticEvents = opts.suppressDiagnosticEvents; this.globalPlugins = opts.globalPlugins || emptyArray2; this.pluginProbeLocations = opts.pluginProbeLocations || emptyArray2; this.allowLocalPluginLoads = !!opts.allowLocalPluginLoads; this.typesMapLocation = opts.typesMapLocation === void 0 ? combinePaths(getDirectoryPath(this.getExecutingFilePath()), "typesMap.json") : opts.typesMapLocation; this.session = opts.session; this.jsDocParsingMode = opts.jsDocParsingMode; if (opts.serverMode !== void 0) { this.serverMode = opts.serverMode; } else { this.serverMode = 0 /* Semantic */; } if (this.host.realpath) { this.realpathToScriptInfos = createMultiMap(); } this.currentDirectory = toNormalizedPath(this.host.getCurrentDirectory()); this.toCanonicalFileName = createGetCanonicalFileName(this.host.useCaseSensitiveFileNames); this.globalCacheLocationDirectoryPath = this.typingsInstaller.globalTypingsCacheLocation ? ensureTrailingDirectorySeparator(this.toPath(this.typingsInstaller.globalTypingsCacheLocation)) : void 0; this.throttledOperations = new ThrottledOperations(this.host, this.logger); if (this.typesMapLocation) { this.loadTypesMap(); } else { this.logger.info("No types map provided; using the default"); } this.typingsInstaller.attach(this); this.typingsCache = new TypingsCache(this.typingsInstaller); this.hostConfiguration = { formatCodeOptions: getDefaultFormatCodeSettings(this.host.newLine), preferences: emptyOptions, hostInfo: "Unknown host", extraFileExtensions: [] }; this.documentRegistry = createDocumentRegistryInternal(this.host.useCaseSensitiveFileNames, this.currentDirectory, this.jsDocParsingMode, this); const watchLogLevel = this.logger.hasLevel(3 /* verbose */) ? 2 /* Verbose */ : this.logger.loggingEnabled() ? 1 /* TriggerOnly */ : 0 /* None */; const log = watchLogLevel !== 0 /* None */ ? (s) => this.logger.info(s) : noop; this.packageJsonCache = createPackageJsonCache(this); this.watchFactory = this.serverMode !== 0 /* Semantic */ ? { watchFile: returnNoopFileWatcher, watchDirectory: returnNoopFileWatcher } : getWatchFactory( createWatchFactoryHostUsingWatchEvents(this, opts.canUseWatchEvents) || this.host, watchLogLevel, log, getDetailWatchInfo ); this.pnpWatcher = this.watchPnpFile(); (_a = opts.incrementalVerifier) == null ? void 0 : _a.call(opts, this); } toPath(fileName) { return toPath(fileName, this.currentDirectory, this.toCanonicalFileName); } /** @internal */ getExecutingFilePath() { return this.getNormalizedAbsolutePath(this.host.getExecutingFilePath()); } /** @internal */ getNormalizedAbsolutePath(fileName) { return getNormalizedAbsolutePath(fileName, this.host.getCurrentDirectory()); } /** @internal */ setDocument(key, path, sourceFile) { const info = Debug.checkDefined(this.getScriptInfoForPath(path)); info.cacheSourceFile = { key, sourceFile }; } /** @internal */ getDocument(key, path) { const info = this.getScriptInfoForPath(path); return info && info.cacheSourceFile && info.cacheSourceFile.key === key ? info.cacheSourceFile.sourceFile : void 0; } /** @internal */ ensureInferredProjectsUpToDate_TestOnly() { this.ensureProjectStructuresUptoDate(); } /** @internal */ getCompilerOptionsForInferredProjects() { return this.compilerOptionsForInferredProjects; } /** @internal */ onUpdateLanguageServiceStateForProject(project, languageServiceEnabled) { if (!this.eventHandler) { return; } const event = { eventName: ProjectLanguageServiceStateEvent, data: { project, languageServiceEnabled } }; this.eventHandler(event); } loadTypesMap() { try { const fileContent = this.host.readFile(this.typesMapLocation); if (fileContent === void 0) { this.logger.info(`Provided types map file "${this.typesMapLocation}" doesn't exist`); return; } const raw = JSON.parse(fileContent); for (const k of Object.keys(raw.typesMap)) { raw.typesMap[k].match = new RegExp(raw.typesMap[k].match, "i"); } this.safelist = raw.typesMap; for (const key in raw.simpleMap) { if (hasProperty(raw.simpleMap, key)) { this.legacySafelist.set(key, raw.simpleMap[key].toLowerCase()); } } } catch (e) { this.logger.info(`Error loading types map: ${e}`); this.safelist = defaultTypeSafeList; this.legacySafelist.clear(); } } // eslint-disable-line @typescript-eslint/unified-signatures updateTypingsForProject(response) { const project = this.findProject(response.projectName); if (!project) { return; } switch (response.kind) { case ActionSet: project.updateTypingFiles(this.typingsCache.updateTypingsForProject(response.projectName, response.compilerOptions, response.typeAcquisition, response.unresolvedImports, response.typings)); return; case ActionInvalidate: this.typingsCache.enqueueInstallTypingsForProject( project, project.lastCachedUnresolvedImportsList, /*forceRefresh*/ true ); return; } } /** @internal */ watchTypingLocations(response) { var _a; (_a = this.findProject(response.projectName)) == null ? void 0 : _a.watchTypingLocations(response.files); } /** @internal */ delayEnsureProjectForOpenFiles() { if (!this.openFiles.size) return; this.pendingEnsureProjectForOpenFiles = true; this.throttledOperations.schedule( ensureProjectForOpenFileSchedule, /*delay*/ 2500, () => { if (this.pendingProjectUpdates.size !== 0) { this.delayEnsureProjectForOpenFiles(); } else { if (this.pendingEnsureProjectForOpenFiles) { this.ensureProjectForOpenFiles(); this.sendProjectsUpdatedInBackgroundEvent(); } } } ); } delayUpdateProjectGraph(project) { if (isProjectDeferredClose(project)) return; project.markAsDirty(); 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 */ hasPendingProjectUpdate(project) { return this.pendingProjectUpdates.has(project.getProjectName()); } /** @internal */ sendProjectsUpdatedInBackgroundEvent() { if (!this.eventHandler) { return; } const event = { eventName: ProjectsUpdatedInBackgroundEvent, data: { openFiles: arrayFrom(this.openFiles.keys(), (path) => this.getScriptInfoForPath(path).fileName) } }; this.eventHandler(event); } /** @internal */ sendLargeFileReferencedEvent(file, fileSize) { if (!this.eventHandler) { return; } const event = { eventName: LargeFileReferencedEvent, data: { file, fileSize, maxFileSize } }; this.eventHandler(event); } /** @internal */ sendProjectLoadingStartEvent(project, reason) { if (!this.eventHandler) { return; } project.sendLoadingProjectFinish = true; const event = { eventName: ProjectLoadingStartEvent, data: { project, reason } }; this.eventHandler(event); } /** @internal */ sendProjectLoadingFinishEvent(project) { if (!this.eventHandler || !project.sendLoadingProjectFinish) { return; } project.sendLoadingProjectFinish = false; const event = { eventName: ProjectLoadingFinishEvent, data: { project } }; this.eventHandler(event); } /** @internal */ sendPerformanceEvent(kind, durationMs) { if (this.performanceEventHandler) { this.performanceEventHandler({ kind, durationMs }); } } /** @internal */ delayUpdateProjectGraphAndEnsureProjectStructureForOpenFiles(project) { this.delayUpdateProjectGraph(project); this.delayEnsureProjectForOpenFiles(); } delayUpdateProjectGraphs(projects, clearSourceMapperCache) { if (projects.length) { for (const project of projects) { if (clearSourceMapperCache) project.clearSourceMapperCache(); this.delayUpdateProjectGraph(project); } this.delayEnsureProjectForOpenFiles(); } } setCompilerOptionsForInferredProjects(projectCompilerOptions, projectRootPath) { Debug.assert(projectRootPath === void 0 || this.useInferredProjectPerProjectRoot, "Setting compiler options per project root path is only supported when useInferredProjectPerProjectRoot is enabled"); const compilerOptions = convertCompilerOptions(projectCompilerOptions); const watchOptions = convertWatchOptions(projectCompilerOptions, projectRootPath); const typeAcquisition = convertTypeAcquisition(projectCompilerOptions); compilerOptions.allowNonTsExtensions = true; const canonicalProjectRootPath = projectRootPath && this.toCanonicalFileName(projectRootPath); if (canonicalProjectRootPath) { this.compilerOptionsForInferredProjectsPerProjectRoot.set(canonicalProjectRootPath, compilerOptions); this.watchOptionsForInferredProjectsPerProjectRoot.set(canonicalProjectRootPath, watchOptions || false); this.typeAcquisitionForInferredProjectsPerProjectRoot.set(canonicalProjectRootPath, typeAcquisition); } else { this.compilerOptionsForInferredProjects = compilerOptions; this.watchOptionsForInferredProjects = watchOptions; this.typeAcquisitionForInferredProjects = typeAcquisition; } for (const project of this.inferredProjects) { if (canonicalProjectRootPath ? project.projectRootPath === canonicalProjectRootPath : !project.projectRootPath || !this.compilerOptionsForInferredProjectsPerProjectRoot.has(project.projectRootPath)) { project.setCompilerOptions(compilerOptions); project.setTypeAcquisition(typeAcquisition); project.setWatchOptions(watchOptions == null ? void 0 : watchOptions.watchOptions); project.setProjectErrors(watchOptions == null ? void 0 : watchOptions.errors); project.compileOnSaveEnabled = compilerOptions.compileOnSave; project.markAsDirty(); this.delayUpdateProjectGraph(project); } } this.delayEnsureProjectForOpenFiles(); } findProject(projectName) { if (projectName === void 0) { return void 0; } if (isInferredProjectName(projectName)) { return findProjectByName(projectName, this.inferredProjects); } return this.findExternalProjectByProjectName(projectName) || this.findConfiguredProjectByProjectName(toNormalizedPath(projectName)); } /** @internal */ forEachProject(cb) { this.externalProjects.forEach(cb); this.configuredProjects.forEach(cb); this.inferredProjects.forEach(cb); } /** @internal */ forEachEnabledProject(cb) { this.forEachProject((project) => { if (!project.isOrphan() && project.languageServiceEnabled) { cb(project); } }); } getDefaultProjectForFile(fileName, ensureProject) { return ensureProject ? this.ensureDefaultProjectForFile(fileName) : this.tryGetDefaultProjectForFile(fileName); } /** @internal */ tryGetDefaultProjectForFile(fileNameOrScriptInfo) { const scriptInfo = isString(fileNameOrScriptInfo) ? this.getScriptInfoForNormalizedPath(fileNameOrScriptInfo) : fileNameOrScriptInfo; return scriptInfo && !scriptInfo.isOrphan() ? scriptInfo.getDefaultProject() : void 0; } /** * If there is default project calculation pending for this file, * then it completes that calculation so that correct default project is used for the project */ tryGetDefaultProjectForEnsuringConfiguredProjectForFile(fileNameOrScriptInfo) { var _a; const scriptInfo = isString(fileNameOrScriptInfo) ? this.getScriptInfoForNormalizedPath(fileNameOrScriptInfo) : fileNameOrScriptInfo; if (!scriptInfo) return void 0; if ((_a = this.pendingOpenFileProjectUpdates) == null ? void 0 : _a.delete(scriptInfo.path)) { this.tryFindDefaultConfiguredProjectAndLoadAncestorsForOpenScriptInfo( scriptInfo, 1 /* Create */ ); if (scriptInfo.isOrphan()) { this.assignOrphanScriptInfoToInferredProject(scriptInfo, this.openFiles.get(scriptInfo.path)); } } return this.tryGetDefaultProjectForFile(scriptInfo); } /** @internal */ ensureDefaultProjectForFile(fileNameOrScriptInfo) { return this.tryGetDefaultProjectForEnsuringConfiguredProjectForFile(fileNameOrScriptInfo) || this.doEnsureDefaultProjectForFile(fileNameOrScriptInfo); } doEnsureDefaultProjectForFile(fileNameOrScriptInfo) { this.ensureProjectStructuresUptoDate(); const scriptInfo = isString(fileNameOrScriptInfo) ? this.getScriptInfoForNormalizedPath(fileNameOrScriptInfo) : fileNameOrScriptInfo; return scriptInfo ? scriptInfo.getDefaultProject() : (this.logErrorForScriptInfoNotFound(isString(fileNameOrScriptInfo) ? fileNameOrScriptInfo : fileNameOrScriptInfo.fileName), Errors.ThrowNoProject()); } getScriptInfoEnsuringProjectsUptoDate(uncheckedFileName) { this.ensureProjectStructuresUptoDate(); return this.getScriptInfo(uncheckedFileName); } /** * Ensures the project structures are upto date * This means, * - we go through all the projects and update them if they are dirty * - if updates reflect some change in structure or there was pending request to ensure projects for open files * ensure that each open script info has project */ ensureProjectStructuresUptoDate() { let hasChanges = this.pendingEnsureProjectForOpenFiles; this.pendingProjectUpdates.clear(); const updateGraph = (project) => { hasChanges = updateProjectIfDirty(project) || hasChanges; }; this.externalProjects.forEach(updateGraph); this.configuredProjects.forEach(updateGraph); this.inferredProjects.forEach(updateGraph); if (hasChanges) { this.ensureProjectForOpenFiles(); } } getFormatCodeOptions(file) { const info = this.getScriptInfoForNormalizedPath(file); return info && info.getFormatCodeSettings() || this.hostConfiguration.formatCodeOptions; } getPreferences(file) { const info = this.getScriptInfoForNormalizedPath(file); return { ...this.hostConfiguration.preferences, ...info && info.getPreferences() }; } getHostFormatCodeOptions() { return this.hostConfiguration.formatCodeOptions; } getHostPreferences() { return this.hostConfiguration.preferences; } onSourceFileChanged(info, eventKind) { Debug.assert(!info.isScriptOpen()); if (eventKind === 2 /* Deleted */) { this.handleDeletedFile( info, /*deferredDelete*/ true ); } else { if (info.deferredDelete) info.deferredDelete = void 0; info.delayReloadNonMixedContentFile(); this.delayUpdateProjectGraphs( info.containingProjects, /*clearSourceMapperCache*/ false ); this.handleSourceMapProjects(info); } } handleSourceMapProjects(info) { if (info.sourceMapFilePath) { if (isString(info.sourceMapFilePath)) { const sourceMapFileInfo = this.getScriptInfoForPath(info.sourceMapFilePath); this.delayUpdateSourceInfoProjects(sourceMapFileInfo == null ? void 0 : sourceMapFileInfo.sourceInfos); } else { this.delayUpdateSourceInfoProjects(info.sourceMapFilePath.sourceInfos); } } this.delayUpdateSourceInfoProjects(info.sourceInfos); if (info.declarationInfoPath) { this.delayUpdateProjectsOfScriptInfoPath(info.declarationInfoPath); } } delayUpdateSourceInfoProjects(sourceInfos) { if (sourceInfos) { sourceInfos.forEach((_value, path) => this.delayUpdateProjectsOfScriptInfoPath(path)); } } delayUpdateProjectsOfScriptInfoPath(path) { const info = this.getScriptInfoForPath(path); if (info) { this.delayUpdateProjectGraphs( info.containingProjects, /*clearSourceMapperCache*/ true ); } } handleDeletedFile(info, deferredDelete) { Debug.assert(!info.isScriptOpen()); this.delayUpdateProjectGraphs( info.containingProjects, /*clearSourceMapperCache*/ false ); this.handleSourceMapProjects(info); info.detachAllProjects(); if (deferredDelete) { info.delayReloadNonMixedContentFile(); info.deferredDelete = true; } else { this.deleteScriptInfo(info); } } /** * This is to watch whenever files are added or removed to the wildcard directories * * @internal */ watchWildcardDirectory(directory, flags, configFileName, config) { let watcher = this.watchFactory.watchDirectory( directory, (fileOrDirectory) => { const fileOrDirectoryPath = this.toPath(fileOrDirectory); const fsResult = config.cachedDirectoryStructureHost.addOrDeleteFileOrDirectory(fileOrDirectory, fileOrDirectoryPath); if (getBaseFileName(fileOrDirectoryPath) === "package.json" && !isInsideNodeModules(fileOrDirectoryPath) && (fsResult && fsResult.fileExists || !fsResult && this.host.fileExists(fileOrDirectory))) { const file = this.getNormalizedAbsolutePath(fileOrDirectory); this.logger.info(`Config: ${configFileName} Detected new package.json: ${file}`); this.packageJsonCache.addOrUpdate(file, fileOrDirectoryPath); this.watchPackageJsonFile(file, fileOrDirectoryPath, result); } const configuredProjectForConfig = this.findConfiguredProjectByProjectName(configFileName); if (isIgnoredFileFromWildCardWatching({ watchedDirPath: this.toPath(directory), fileOrDirectory, fileOrDirectoryPath, configFileName, extraFileExtensions: this.hostConfiguration.extraFileExtensions, currentDirectory: this.currentDirectory, options: config.parsedCommandLine.options, program: (configuredProjectForConfig == null ? void 0 : configuredProjectForConfig.getCurrentProgram()) || config.parsedCommandLine.fileNames, useCaseSensitiveFileNames: this.host.useCaseSensitiveFileNames, writeLog: (s) => this.logger.info(s), toPath: (s) => this.toPath(s), getScriptKind: configuredProjectForConfig ? (fileName) => configuredProjectForConfig.getScriptKind(fileName) : void 0 })) return; if (config.updateLevel !== 2 /* Full */) config.updateLevel = 1 /* RootNamesAndUpdate */; config.projects.forEach((watchWildcardDirectories, projectCanonicalPath) => { var _a; if (!watchWildcardDirectories) return; const project = this.getConfiguredProjectByCanonicalConfigFilePath(projectCanonicalPath); if (!project) return; if (configuredProjectForConfig !== project && this.getHostPreferences().includeCompletionsForModuleExports) { const path = this.toPath(configFileName); if (find((_a = project.getCurrentProgram()) == null ? void 0 : _a.getResolvedProjectReferences(), (ref) => (ref == null ? void 0 : ref.sourceFile.path) === path)) { project.markAutoImportProviderAsDirty(); } } const updateLevel = configuredProjectForConfig === project ? 1 /* RootNamesAndUpdate */ : 0 /* Update */; if (project.pendingUpdateLevel > updateLevel) return; if (this.openFiles.has(fileOrDirectoryPath)) { const info = Debug.checkDefined(this.getScriptInfoForPath(fileOrDirectoryPath)); if (info.isAttached(project)) { const loadLevelToSet = Math.max(updateLevel, project.openFileWatchTriggered.get(fileOrDirectoryPath) || 0 /* Update */); project.openFileWatchTriggered.set(fileOrDirectoryPath, loadLevelToSet); } else { project.pendingUpdateLevel = updateLevel; this.delayUpdateProjectGraphAndEnsureProjectStructureForOpenFiles(project); } } else { project.pendingUpdateLevel = updateLevel; this.delayUpdateProjectGraphAndEnsureProjectStructureForOpenFiles(project); } }); }, flags, this.getWatchOptionsFromProjectWatchOptions(config.parsedCommandLine.watchOptions, getDirectoryPath(configFileName)), WatchType.WildcardDirectory, configFileName ); const result = { packageJsonWatches: void 0, close() { var _a; if (watcher) { watcher.close(); watcher = void 0; (_a = result.packageJsonWatches) == null ? void 0 : _a.forEach((watcher2) => { watcher2.projects.delete(result); watcher2.close(); }); result.packageJsonWatches = void 0; } } }; return result; } /** @internal */ delayUpdateProjectsFromParsedConfigOnConfigFileChange(canonicalConfigFilePath, loadReason) { const configFileExistenceInfo = this.configFileExistenceInfoCache.get(canonicalConfigFilePath); if (!(configFileExistenceInfo == null ? void 0 : configFileExistenceInfo.config)) return false; let scheduledAnyProjectUpdate = false; configFileExistenceInfo.config.updateLevel = 2 /* Full */; configFileExistenceInfo.config.projects.forEach((_watchWildcardDirectories, projectCanonicalPath) => { var _a; const project = this.getConfiguredProjectByCanonicalConfigFilePath(projectCanonicalPath); if (!project) return; scheduledAnyProjectUpdate = true; if (projectCanonicalPath === canonicalConfigFilePath) { if (project.isInitialLoadPending()) return; project.pendingUpdateLevel = 2 /* Full */; project.pendingUpdateReason = loadReason; this.delayUpdateProjectGraph(project); project.markAutoImportProviderAsDirty(); } else { const path = this.toPath(canonicalConfigFilePath); project.resolutionCache.removeResolutionsFromProjectReferenceRedirects(path); this.delayUpdateProjectGraph(project); if (this.getHostPreferences().includeCompletionsForModuleExports && find((_a = project.getCurrentProgram()) == null ? void 0 : _a.getResolvedProjectReferences(), (ref) => (ref == null ? void 0 : ref.sourceFile.path) === path)) { project.markAutoImportProviderAsDirty(); } } }); return scheduledAnyProjectUpdate; } /** @internal */ onConfigFileChanged(configFileName, canonicalConfigFilePath, eventKind) { const configFileExistenceInfo = this.configFileExistenceInfoCache.get(canonicalConfigFilePath); const project = this.getConfiguredProjectByCanonicalConfigFilePath(canonicalConfigFilePath); const wasDefferedClose = project == null ? void 0 : project.deferredClose; if (eventKind === 2 /* Deleted */) { configFileExistenceInfo.exists = false; if (project) project.deferredClose = true; } else { configFileExistenceInfo.exists = true; if (wasDefferedClose) { project.deferredClose = void 0; project.markAsDirty(); } } this.delayUpdateProjectsFromParsedConfigOnConfigFileChange( canonicalConfigFilePath, "Change in config file detected" ); const updatedProjects = new Set(project ? [project] : void 0); this.openFiles.forEach((_projectRootPath, path) => { var _a, _b; const configFileForOpenFile = this.configFileForOpenFiles.get(path); if (!((_a = configFileExistenceInfo.openFilesImpactedByConfigFile) == null ? void 0 : _a.has(path))) return; this.configFileForOpenFiles.delete(path); const info = this.getScriptInfoForPath(path); const newConfigFileNameForInfo = this.getConfigFileNameForFile( info, /*findFromCacheOnly*/ false ); if (!newConfigFileNameForInfo) return; const projectForInfo = this.findConfiguredProjectByProjectName(newConfigFileNameForInfo) ?? this.createConfiguredProject( newConfigFileNameForInfo, `Change in config file ${configFileName} detected, ${fileOpenReason(info)}` ); if (!((_b = this.pendingOpenFileProjectUpdates) == null ? void 0 : _b.has(path))) { (this.pendingOpenFileProjectUpdates ?? (this.pendingOpenFileProjectUpdates = /* @__PURE__ */ new Map())).set(path, configFileForOpenFile); } if (tryAddToSet(updatedProjects, projectForInfo) && projectForInfo.isInitialLoadPending()) { this.delayUpdateProjectGraph(projectForInfo); } }); this.delayEnsureProjectForOpenFiles(); } removeProject(project) { this.logger.info("`remove Project::"); project.print( /*writeProjectFileNames*/ true, /*writeFileExplaination*/ true, /*writeFileVersionAndText*/ false ); project.close(); if (Debug.shouldAssert(1 /* Normal */)) { this.filenameToScriptInfo.forEach( (info) => Debug.assert( !info.isAttached(project), "Found script Info still attached to project", () => `${project.projectName}: ScriptInfos still attached: ${JSON.stringify( arrayFrom( mapDefinedIterator( this.filenameToScriptInfo.values(), (info2) => info2.isAttached(project) ? { fileName: info2.fileName, projects: info2.containingProjects.map((p) => p.projectName), hasMixedContent: info2.hasMixedContent } : void 0 ) ), /*replacer*/ void 0, " " )}` ) ); } this.pendingProjectUpdates.delete(project.getProjectName()); switch (project.projectKind) { case 2 /* External */: unorderedRemoveItem(this.externalProjects, project); this.projectToSizeMap.delete(project.getProjectName()); break; case 1 /* Configured */: this.configuredProjects.delete(project.canonicalConfigFilePath); this.projectToSizeMap.delete(project.canonicalConfigFilePath); break; case 0 /* Inferred */: unorderedRemoveItem(this.inferredProjects, project); break; } } /** @internal */ assignOrphanScriptInfoToInferredProject(info, projectRootPath) { Debug.assert(info.isOrphan()); const project = this.getOrCreateInferredProjectForProjectRootPathIfEnabled(info, projectRootPath) || this.getOrCreateSingleInferredProjectIfEnabled() || this.getOrCreateSingleInferredWithoutProjectRoot( info.isDynamic ? projectRootPath || this.currentDirectory : getDirectoryPath( isRootedDiskPath(info.fileName) ? info.fileName : getNormalizedAbsolutePath( info.fileName, projectRootPath ? this.getNormalizedAbsolutePath(projectRootPath) : this.currentDirectory ) ) ); project.addRoot(info); if (info.containingProjects[0] !== project) { orderedRemoveItem(info.containingProjects, project); info.containingProjects.unshift(project); } project.updateGraph(); if (!this.useSingleInferredProject && !project.projectRootPath) { for (const inferredProject of this.inferredProjects) { if (inferredProject === project || inferredProject.isOrphan()) { continue; } const roots = inferredProject.getRootScriptInfos(); Debug.assert(roots.length === 1 || !!inferredProject.projectRootPath); if (roots.length === 1 && forEach(roots[0].containingProjects, (p) => p !== roots[0].containingProjects[0] && !p.isOrphan())) { inferredProject.removeFile( roots[0], /*fileExists*/ true, /*detachFromProject*/ true ); } } } return project; } assignOrphanScriptInfosToInferredProject() { this.openFiles.forEach((projectRootPath, path) => { const info = this.getScriptInfoForPath(path); if (info.isOrphan()) { this.assignOrphanScriptInfoToInferredProject(info, projectRootPath); } }); } /** * Remove this file from the set of open, non-configured files. * @param info The file that has been closed or newly configured */ closeOpenFile(info, skipAssignOrphanScriptInfosToInferredProject) { var _a; const fileExists = info.isDynamic ? false : this.host.fileExists(info.fileName); info.close(fileExists); this.stopWatchingConfigFilesForScriptInfo(info); const canonicalFileName = this.toCanonicalFileName(info.fileName); if (this.openFilesWithNonRootedDiskPath.get(canonicalFileName) === info) { this.openFilesWithNonRootedDiskPath.delete(canonicalFileName); } let ensureProjectsForOpenFiles = false; for (const p of info.containingProjects) { if (isConfiguredProject(p)) { if (info.hasMixedContent) { info.registerFileUpdate(); } const updateLevel = p.openFileWatchTriggered.get(info.path); if (updateLevel !== void 0) { p.openFileWatchTriggered.delete(info.path); if (p.pendingUpdateLevel < updateLevel) { p.pendingUpdateLevel = updateLevel; p.markFileAsDirty(info.path); } } } else if (isInferredProject(p) && p.isRoot(info)) { if (p.isProjectWithSingleRoot()) { ensureProjectsForOpenFiles = true; } p.removeFile( info, fileExists, /*detachFromProject*/ true ); } if (!p.languageServiceEnabled) { p.markAsDirty(); } } this.openFiles.delete(info.path); this.configFileForOpenFiles.delete(info.path); (_a = this.pendingOpenFileProjectUpdates) == null ? void 0 : _a.delete(info.path); Debug.assert(!this.rootOfInferredProjects.has(info)); if (!skipAssignOrphanScriptInfosToInferredProject && ensureProjectsForOpenFiles) { this.assignOrphanScriptInfosToInferredProject(); } if (fileExists) { this.watchClosedScriptInfo(info); } else { this.handleDeletedFile( info, /*deferredDelete*/ false ); } return ensureProjectsForOpenFiles; } deleteScriptInfo(info) { Debug.assert(!info.isScriptOpen()); this.filenameToScriptInfo.delete(info.path); this.filenameToScriptInfoVersion.set(info.path, info.textStorage.version); this.stopWatchingScriptInfo(info); const realpath = info.getRealpathIfDifferent(); if (realpath) { this.realpathToScriptInfos.remove(realpath, info); } info.closeSourceMapFileWatcher(); } configFileExists(configFileName, canonicalConfigFilePath, info) { const configFileExistenceInfo = this.configFileExistenceInfoCache.get(canonicalConfigFilePath); let openFilesImpactedByConfigFile; if (this.openFiles.has(info.path) && !isAncestorConfigFileInfo(info)) { if (configFileExistenceInfo) (configFileExistenceInfo.openFilesImpactedByConfigFile ?? (configFileExistenceInfo.openFilesImpactedByConfigFile = /* @__PURE__ */ new Set())).add(info.path); else (openFilesImpactedByConfigFile = /* @__PURE__ */ new Set()).add(info.path); } if (configFileExistenceInfo) return configFileExistenceInfo.exists; const exists = this.host.fileExists(configFileName); this.configFileExistenceInfoCache.set(canonicalConfigFilePath, { exists, openFilesImpactedByConfigFile }); return exists; } /** @internal */ createConfigFileWatcherForParsedConfig(configFileName, canonicalConfigFilePath, forProject) { var _a, _b; const configFileExistenceInfo = this.configFileExistenceInfoCache.get(canonicalConfigFilePath); if (!configFileExistenceInfo.watcher || configFileExistenceInfo.watcher === noopConfigFileWatcher) { configFileExistenceInfo.watcher = this.watchFactory.watchFile( configFileName, (_fileName, eventKind) => this.onConfigFileChanged(configFileName, canonicalConfigFilePath, eventKind), 2e3 /* High */, this.getWatchOptionsFromProjectWatchOptions((_b = (_a = configFileExistenceInfo == null ? void 0 : configFileExistenceInfo.config) == null ? void 0 : _a.parsedCommandLine) == null ? void 0 : _b.watchOptions, getDirectoryPath(configFileName)), WatchType.ConfigFile, forProject ); } const projects = configFileExistenceInfo.config.projects; projects.set(forProject.canonicalConfigFilePath, projects.get(forProject.canonicalConfigFilePath) || false); } /** @internal */ releaseParsedConfig(canonicalConfigFilePath, forProject) { var _a, _b, _c; const configFileExistenceInfo = this.configFileExistenceInfoCache.get(canonicalConfigFilePath); if (!((_a = configFileExistenceInfo.config) == null ? void 0 : _a.projects.delete(forProject.canonicalConfigFilePath))) return; if ((_b = configFileExistenceInfo.config) == null ? void 0 : _b.projects.size) return; configFileExistenceInfo.config = void 0; clearSharedExtendedConfigFileWatcher(canonicalConfigFilePath, this.sharedExtendedConfigFileWatchers); Debug.checkDefined(configFileExistenceInfo.watcher); if ((_c = configFileExistenceInfo.openFilesImpactedByConfigFile) == null ? void 0 : _c.size) { if (configFileExistenceInfo.inferredProjectRoots) { if (!canWatchDirectoryOrFile(getPathComponents(getDirectoryPath(canonicalConfigFilePath)))) { configFileExistenceInfo.watcher.close(); configFileExistenceInfo.watcher = noopConfigFileWatcher; } } else { configFileExistenceInfo.watcher.close(); configFileExistenceInfo.watcher = void 0; } } else { configFileExistenceInfo.watcher.close(); this.configFileExistenceInfoCache.delete(canonicalConfigFilePath); } } /** * This is called on file close or when its removed from inferred project as root, * so that we handle the watches and inferred project root data * @internal */ stopWatchingConfigFilesForScriptInfo(info) { if (this.serverMode !== 0 /* Semantic */) return; const isRootOfInferredProject = this.rootOfInferredProjects.delete(info); const isOpen = info.isScriptOpen(); if (isOpen && !isRootOfInferredProject) return; this.forEachConfigFileLocation(info, (canonicalConfigFilePath) => { var _a, _b, _c; const configFileExistenceInfo = this.configFileExistenceInfoCache.get(canonicalConfigFilePath); if (!configFileExistenceInfo) return; if (isOpen) { if (!((_a = configFileExistenceInfo == null ? void 0 : configFileExistenceInfo.openFilesImpactedByConfigFile) == null ? void 0 : _a.has(info.path))) return; } else { if (!((_b = configFileExistenceInfo.openFilesImpactedByConfigFile) == null ? void 0 : _b.delete(info.path))) return; } if (isRootOfInferredProject) { configFileExistenceInfo.inferredProjectRoots--; if (configFileExistenceInfo.watcher && !configFileExistenceInfo.config && !configFileExistenceInfo.inferredProjectRoots) { configFileExistenceInfo.watcher.close(); configFileExistenceInfo.watcher = void 0; } } if (!((_c = configFileExistenceInfo.openFilesImpactedByConfigFile) == null ? void 0 : _c.size) && !configFileExistenceInfo.config) { Debug.assert(!configFileExistenceInfo.watcher); this.configFileExistenceInfoCache.delete(canonicalConfigFilePath); } }); } /** * This is called by inferred project whenever script info is added as a root * * @internal */ startWatchingConfigFilesForInferredProjectRoot(info) { if (this.serverMode !== 0 /* Semantic */) return; Debug.assert(info.isScriptOpen()); this.rootOfInferredProjects.add(info); this.forEachConfigFileLocation(info, (canonicalConfigFilePath, configFileName) => { let configFileExistenceInfo = this.configFileExistenceInfoCache.get(canonicalConfigFilePath); if (!configFileExistenceInfo) { configFileExistenceInfo = { exists: this.host.fileExists(configFileName), inferredProjectRoots: 1 }; this.configFileExistenceInfoCache.set(canonicalConfigFilePath, configFileExistenceInfo); } else { configFileExistenceInfo.inferredProjectRoots = (configFileExistenceInfo.inferredProjectRoots ?? 0) + 1; } (configFileExistenceInfo.openFilesImpactedByConfigFile ?? (configFileExistenceInfo.openFilesImpactedByConfigFile = /* @__PURE__ */ new Set())).add(info.path); configFileExistenceInfo.watcher || (configFileExistenceInfo.watcher = canWatchDirectoryOrFile(getPathComponents(getDirectoryPath(canonicalConfigFilePath))) ? this.watchFactory.watchFile( configFileName, (_filename, eventKind) => this.onConfigFileChanged(configFileName, canonicalConfigFilePath, eventKind), 2e3 /* High */, this.hostConfiguration.watchOptions, WatchType.ConfigFileForInferredRoot ) : noopConfigFileWatcher); }); } /** * This function tries to search for a tsconfig.json for the given file. * This is different from the method the compiler uses because * the compiler can assume it will always start searching in the * current directory (the directory in which tsc was invoked). * The server must start searching from the directory containing * the newly opened file. */ forEachConfigFileLocation(info, action) { if (this.serverMode !== 0 /* Semantic */) { return void 0; } Debug.assert(!isOpenScriptInfo(info) || this.openFiles.has(info.path)); const projectRootPath = this.openFiles.get(info.path); const scriptInfo = Debug.checkDefined(this.getScriptInfo(info.path)); if (scriptInfo.isDynamic) return void 0; let searchPath = asNormalizedPath(getDirectoryPath(info.fileName)); const isSearchPathInProjectRoot = () => containsPath(projectRootPath, searchPath, this.currentDirectory, !this.host.useCaseSensitiveFileNames); const anySearchPathOk = !projectRootPath || !isSearchPathInProjectRoot(); let searchInDirectory = !isAncestorConfigFileInfo(info); do { if (searchInDirectory) { const canonicalSearchPath = normalizedPathToPath(searchPath, this.currentDirectory, this.toCanonicalFileName); const tsconfigFileName = asNormalizedPath(combinePaths(searchPath, "tsconfig.json")); let result = action(combinePaths(canonicalSearchPath, "tsconfig.json"), tsconfigFileName); if (result) return tsconfigFileName; const jsconfigFileName = asNormalizedPath(combinePaths(searchPath, "jsconfig.json")); result = action(combinePaths(canonicalSearchPath, "jsconfig.json"), jsconfigFileName); if (result) return jsconfigFileName; if (isNodeModulesDirectory(canonicalSearchPath)) { break; } } const parentPath = asNormalizedPath(getDirectoryPath(searchPath)); if (parentPath === searchPath) break; searchPath = parentPath; searchInDirectory = true; } while (anySearchPathOk || isSearchPathInProjectRoot()); return void 0; } /** @internal */ findDefaultConfiguredProject(info) { var _a; return info.isScriptOpen() ? (_a = this.tryFindDefaultConfiguredProjectForOpenScriptInfo( info, 0 /* Find */ )) == null ? void 0 : _a.defaultProject : void 0; } /** Get cached configFileName for scriptInfo or ancestor of open script info */ getConfigFileNameForFileFromCache(info, lookInPendingFilesForValue) { if (lookInPendingFilesForValue) { const result = getConfigFileNameFromCache(info, this.pendingOpenFileProjectUpdates); if (result !== void 0) return result; } return getConfigFileNameFromCache(info, this.configFileForOpenFiles); } /** Caches the configFilename for script info or ancestor of open script info */ setConfigFileNameForFileInCache(info, configFileName) { if (!this.openFiles.has(info.path)) return; if (isAncestorConfigFileInfo(info)) return; this.configFileForOpenFiles.set(info.path, configFileName || false); } /** * This function tries to search for a tsconfig.json for the given file. * This is different from the method the compiler uses because * the compiler can assume it will always start searching in the * current directory (the directory in which tsc was invoked). * The server must start searching from the directory containing * the newly opened file. * If script info is passed in, it is asserted to be open script info * otherwise just file name * when findFromCacheOnly is true only looked up in cache instead of hitting disk to figure things out * @internal */ getConfigFileNameForFile(info, findFromCacheOnly) { const fromCache = this.getConfigFileNameForFileFromCache(info, findFromCacheOnly); if (fromCache !== void 0) return fromCache || void 0; if (findFromCacheOnly) return void 0; const configFileName = this.forEachConfigFileLocation(info, (canonicalConfigFilePath, configFileName2) => this.configFileExists(configFileName2, canonicalConfigFilePath, info)); this.logger.info(`getConfigFileNameForFile:: File: ${info.fileName} ProjectRootPath: ${this.openFiles.get(info.path)}:: Result: ${configFileName}`); this.setConfigFileNameForFileInCache(info, configFileName); return configFileName; } printProjects() { if (!this.logger.hasLevel(1 /* normal */)) { return; } this.logger.startGroup(); this.externalProjects.forEach(printProjectWithoutFileNames); this.configuredProjects.forEach(printProjectWithoutFileNames); this.inferredProjects.forEach(printProjectWithoutFileNames); this.logger.info("Open files: "); this.openFiles.forEach((projectRootPath, path) => { const info = this.getScriptInfoForPath(path); this.logger.info(` FileName: ${info.fileName} ProjectRootPath: ${projectRootPath}`); this.logger.info(` Projects: ${info.containingProjects.map((p) => p.getProjectName())}`); }); this.logger.endGroup(); } /** @internal */ findConfiguredProjectByProjectName(configFileName, allowDeferredClosed) { const canonicalConfigFilePath = asNormalizedPath(this.toCanonicalFileName(configFileName)); const result = this.getConfiguredProjectByCanonicalConfigFilePath(canonicalConfigFilePath); return allowDeferredClosed ? result : !(result == null ? void 0 : result.deferredClose) ? result : void 0; } getConfiguredProjectByCanonicalConfigFilePath(canonicalConfigFilePath) { return this.configuredProjects.get(canonicalConfigFilePath); } findExternalProjectByProjectName(projectFileName) { return findProjectByName(projectFileName, this.externalProjects); } /** Get a filename if the language service exceeds the maximum allowed program size; otherwise returns undefined. */ getFilenameForExceededTotalSizeLimitForNonTsFiles(name, options, fileNames, propertyReader) { if (options && options.disableSizeLimit || !this.host.getFileSize) { return; } let availableSpace = maxProgramSizeForNonTsFiles; this.projectToSizeMap.set(name, 0); this.projectToSizeMap.forEach((val) => availableSpace -= val || 0); let totalNonTsFileSize = 0; for (const f of fileNames) { const fileName = propertyReader.getFileName(f); if (hasTSFileExtension(fileName)) { continue; } totalNonTsFileSize += this.host.getFileSize(fileName); if (totalNonTsFileSize > maxProgramSizeForNonTsFiles || totalNonTsFileSize > availableSpace) { const top5LargestFiles = fileNames.map((f2) => propertyReader.getFileName(f2)).filter((name2) => !hasTSFileExtension(name2)).map((name2) => ({ name: name2, size: this.host.getFileSize(name2) })).sort((a, b) => b.size - a.size).slice(0, 5); this.logger.info(`Non TS file size exceeded limit (${totalNonTsFileSize}). Largest files: ${top5LargestFiles.map((file) => `${file.name}:${file.size}`).join(", ")}`); return fileName; } } this.projectToSizeMap.set(name, totalNonTsFileSize); } createExternalProject(projectFileName, files, options, typeAcquisition, excludedFiles) { const compilerOptions = convertCompilerOptions(options); const watchOptionsAndErrors = convertWatchOptions(options, getDirectoryPath(normalizeSlashes(projectFileName))); const project = new ExternalProject( projectFileName, this, this.documentRegistry, compilerOptions, /*lastFileExceededProgramSize*/ this.getFilenameForExceededTotalSizeLimitForNonTsFiles(projectFileName, compilerOptions, files, externalFilePropertyReader), options.compileOnSave === void 0 ? true : options.compileOnSave, /*projectFilePath*/ void 0, watchOptionsAndErrors == null ? void 0 : watchOptionsAndErrors.watchOptions ); project.setProjectErrors(watchOptionsAndErrors == null ? void 0 : watchOptionsAndErrors.errors); project.excludedFiles = excludedFiles; this.addFilesToNonInferredProject(project, files, externalFilePropertyReader, typeAcquisition); this.externalProjects.push(project); return project; } /** @internal */ sendProjectTelemetry(project) { if (this.seenProjects.has(project.projectName)) { setProjectOptionsUsed(project); return; } this.seenProjects.set(project.projectName, true); if (!this.eventHandler || !this.host.createSHA256Hash) { setProjectOptionsUsed(project); return; } const projectOptions = isConfiguredProject(project) ? project.projectOptions : void 0; setProjectOptionsUsed(project); const data = { projectId: this.host.createSHA256Hash(project.projectName), fileStats: countEachFileTypes( project.getScriptInfos(), /*includeSizes*/ true ), compilerOptions: convertCompilerOptionsForTelemetry(project.getCompilationSettings()), typeAcquisition: convertTypeAcquisition2(project.getTypeAcquisition()), extends: projectOptions && projectOptions.configHasExtendsProperty, files: projectOptions && projectOptions.configHasFilesProperty, include: projectOptions && projectOptions.configHasIncludeProperty, exclude: projectOptions && projectOptions.configHasExcludeProperty, compileOnSave: project.compileOnSaveEnabled, configFileName: configFileName(), projectType: project instanceof ExternalProject ? "external" : "configured", languageServiceEnabled: project.languageServiceEnabled, version }; this.eventHandler({ eventName: ProjectInfoTelemetryEvent, data }); function configFileName() { if (!isConfiguredProject(project)) { return "other"; } return getBaseConfigFileName(project.getConfigFilePath()) || "other"; } function convertTypeAcquisition2({ enable: enable2, include, exclude }) { return { enable: enable2, include: include !== void 0 && include.length !== 0, exclude: exclude !== void 0 && exclude.length !== 0 }; } } addFilesToNonInferredProject(project, files, propertyReader, typeAcquisition) { this.updateNonInferredProjectFiles(project, files, propertyReader); project.setTypeAcquisition(typeAcquisition); project.markAsDirty(); } /** @internal */ createConfiguredProject(configFileName, reason) { var _a; (_a = tracing) == null ? void 0 : _a.instant(tracing.Phase.Session, "createConfiguredProject", { configFilePath: configFileName }); this.logger.info(`Creating configuration project ${configFileName}`); const canonicalConfigFilePath = asNormalizedPath(this.toCanonicalFileName(configFileName)); let configFileExistenceInfo = this.configFileExistenceInfoCache.get(canonicalConfigFilePath); if (!configFileExistenceInfo) { this.configFileExistenceInfoCache.set(canonicalConfigFilePath, configFileExistenceInfo = { exists: true }); } else { configFileExistenceInfo.exists = true; } if (!configFileExistenceInfo.config) { configFileExistenceInfo.config = { cachedDirectoryStructureHost: createCachedDirectoryStructureHost(this.host, this.host.getCurrentDirectory(), this.host.useCaseSensitiveFileNames), projects: /* @__PURE__ */ new Map(), updateLevel: 2 /* Full */ }; } const project = new ConfiguredProject2( configFileName, canonicalConfigFilePath, this, this.documentRegistry, configFileExistenceInfo.config.cachedDirectoryStructureHost, reason ); Debug.assert(!this.configuredProjects.has(canonicalConfigFilePath)); this.configuredProjects.set(canonicalConfigFilePath, project); this.createConfigFileWatcherForParsedConfig(configFileName, canonicalConfigFilePath, project); return project; } /** * Read the config file of the project, and update the project root file names. * * @internal */ loadConfiguredProject(project, reason) { var _a, _b; (_a = tracing) == null ? void 0 : _a.push(tracing.Phase.Session, "loadConfiguredProject", { configFilePath: project.canonicalConfigFilePath }); this.sendProjectLoadingStartEvent(project, reason); const configFilename = asNormalizedPath(normalizePath(project.getConfigFilePath())); const configFileExistenceInfo = this.ensureParsedConfigUptoDate( configFilename, project.canonicalConfigFilePath, this.configFileExistenceInfoCache.get(project.canonicalConfigFilePath), project ); const parsedCommandLine = configFileExistenceInfo.config.parsedCommandLine; Debug.assert(!!parsedCommandLine.fileNames); const compilerOptions = parsedCommandLine.options; if (!project.projectOptions) { project.projectOptions = { configHasExtendsProperty: parsedCommandLine.raw.extends !== void 0, configHasFilesProperty: parsedCommandLine.raw.files !== void 0, configHasIncludeProperty: parsedCommandLine.raw.include !== void 0, configHasExcludeProperty: parsedCommandLine.raw.exclude !== void 0 }; } project.canConfigFileJsonReportNoInputFiles = canJsonReportNoInputFiles(parsedCommandLine.raw); project.setProjectErrors(parsedCommandLine.options.configFile.parseDiagnostics); project.updateReferences(parsedCommandLine.projectReferences); const lastFileExceededProgramSize = this.getFilenameForExceededTotalSizeLimitForNonTsFiles(project.canonicalConfigFilePath, compilerOptions, parsedCommandLine.fileNames, fileNamePropertyReader); if (lastFileExceededProgramSize) { project.disableLanguageService(lastFileExceededProgramSize); this.configFileExistenceInfoCache.forEach((_configFileExistenceInfo, canonicalConfigFilePath) => this.stopWatchingWildCards(canonicalConfigFilePath, project)); } else { project.setCompilerOptions(compilerOptions); project.setWatchOptions(parsedCommandLine.watchOptions); project.enableLanguageService(); this.watchWildcards(configFilename, configFileExistenceInfo, project); } project.enablePluginsWithOptions(compilerOptions); const filesToAdd = parsedCommandLine.fileNames.concat(project.getExternalFiles(2 /* Full */)); this.updateRootAndOptionsOfNonInferredProject(project, filesToAdd, fileNamePropertyReader, compilerOptions, parsedCommandLine.typeAcquisition, parsedCommandLine.compileOnSave, parsedCommandLine.watchOptions); (_b = tracing) == null ? void 0 : _b.pop(); } /** @internal */ ensureParsedConfigUptoDate(configFilename, canonicalConfigFilePath, configFileExistenceInfo, forProject) { var _a, _b, _c; if (configFileExistenceInfo.config) { if (!configFileExistenceInfo.config.updateLevel) return configFileExistenceInfo; if (configFileExistenceInfo.config.updateLevel === 1 /* RootNamesAndUpdate */) { this.reloadFileNamesOfParsedConfig(configFilename, configFileExistenceInfo.config); return configFileExistenceInfo; } } const cachedDirectoryStructureHost = ((_a = configFileExistenceInfo.config) == null ? void 0 : _a.cachedDirectoryStructureHost) || createCachedDirectoryStructureHost(this.host, this.host.getCurrentDirectory(), this.host.useCaseSensitiveFileNames); const configFileContent = tryReadFile(configFilename, (fileName) => this.host.readFile(fileName)); const configFile = parseJsonText(configFilename, isString(configFileContent) ? configFileContent : ""); const configFileErrors = configFile.parseDiagnostics; if (!isString(configFileContent)) configFileErrors.push(configFileContent); const configDir = getDirectoryPath(configFilename); const parsedCommandLine = parseJsonSourceFileConfigFileContent( configFile, cachedDirectoryStructureHost, configDir, /*existingOptions*/ void 0, configFilename, /*resolutionStack*/ void 0, this.hostConfiguration.extraFileExtensions, this.extendedConfigCache ); if (parsedCommandLine.errors.length) { configFileErrors.push(...parsedCommandLine.errors); } this.logger.info(`Config: ${configFilename} : ${JSON.stringify( { rootNames: parsedCommandLine.fileNames, options: parsedCommandLine.options, watchOptions: parsedCommandLine.watchOptions, projectReferences: parsedCommandLine.projectReferences }, /*replacer*/ void 0, " " )}`); const oldCommandLine = (_b = configFileExistenceInfo.config) == null ? void 0 : _b.parsedCommandLine; if (!configFileExistenceInfo.config) { configFileExistenceInfo.config = { parsedCommandLine, cachedDirectoryStructureHost, projects: /* @__PURE__ */ new Map() }; } else { configFileExistenceInfo.config.parsedCommandLine = parsedCommandLine; configFileExistenceInfo.config.watchedDirectoriesStale = true; configFileExistenceInfo.config.updateLevel = void 0; } if (!oldCommandLine && !isJsonEqual( // Old options this.getWatchOptionsFromProjectWatchOptions( /*projectOptions*/ void 0, configDir ), // New options this.getWatchOptionsFromProjectWatchOptions(parsedCommandLine.watchOptions, configDir) )) { (_c = configFileExistenceInfo.watcher) == null ? void 0 : _c.close(); configFileExistenceInfo.watcher = void 0; } this.createConfigFileWatcherForParsedConfig(configFilename, canonicalConfigFilePath, forProject); updateSharedExtendedConfigFileWatcher( canonicalConfigFilePath, parsedCommandLine.options, this.sharedExtendedConfigFileWatchers, (extendedConfigFileName, extendedConfigFilePath) => this.watchFactory.watchFile( extendedConfigFileName, () => { var _a2; cleanExtendedConfigCache(this.extendedConfigCache, extendedConfigFilePath, (fileName) => this.toPath(fileName)); let ensureProjectsForOpenFiles = false; (_a2 = this.sharedExtendedConfigFileWatchers.get(extendedConfigFilePath)) == null ? void 0 : _a2.projects.forEach((canonicalPath) => { ensureProjectsForOpenFiles = this.delayUpdateProjectsFromParsedConfigOnConfigFileChange(canonicalPath, `Change in extended config file ${extendedConfigFileName} detected`) || ensureProjectsForOpenFiles; }); if (ensureProjectsForOpenFiles) this.delayEnsureProjectForOpenFiles(); }, 2e3 /* High */, this.hostConfiguration.watchOptions, WatchType.ExtendedConfigFile, configFilename ), (fileName) => this.toPath(fileName) ); return configFileExistenceInfo; } /** @internal */ watchWildcards(configFileName, { exists, config }, forProject) { config.projects.set(forProject.canonicalConfigFilePath, true); if (exists) { if (config.watchedDirectories && !config.watchedDirectoriesStale) return; config.watchedDirectoriesStale = false; updateWatchingWildcardDirectories( config.watchedDirectories || (config.watchedDirectories = /* @__PURE__ */ new Map()), config.parsedCommandLine.wildcardDirectories, // Create new directory watcher (directory, flags) => this.watchWildcardDirectory(directory, flags, configFileName, config) ); } else { config.watchedDirectoriesStale = false; if (!config.watchedDirectories) return; clearMap(config.watchedDirectories, closeFileWatcherOf); config.watchedDirectories = void 0; } } /** @internal */ stopWatchingWildCards(canonicalConfigFilePath, forProject) { const configFileExistenceInfo = this.configFileExistenceInfoCache.get(canonicalConfigFilePath); if (!configFileExistenceInfo.config || !configFileExistenceInfo.config.projects.get(forProject.canonicalConfigFilePath)) { return; } configFileExistenceInfo.config.projects.set(forProject.canonicalConfigFilePath, false); if (forEachEntry(configFileExistenceInfo.config.projects, identity)) return; if (configFileExistenceInfo.config.watchedDirectories) { clearMap(configFileExistenceInfo.config.watchedDirectories, closeFileWatcherOf); configFileExistenceInfo.config.watchedDirectories = void 0; } configFileExistenceInfo.config.watchedDirectoriesStale = void 0; } updateNonInferredProjectFiles(project, files, propertyReader) { var _a; const projectRootFilesMap = project.getRootFilesMap(); const newRootScriptInfoMap = /* @__PURE__ */ new Map(); for (const f of files) { const newRootFile = propertyReader.getFileName(f); const fileName = toNormalizedPath(newRootFile); const isDynamic = isDynamicFileName(fileName); let path; if (!isDynamic && !project.fileExists(newRootFile)) { path = normalizedPathToPath(fileName, this.currentDirectory, this.toCanonicalFileName); const existingValue = projectRootFilesMap.get(path); if (existingValue) { if (((_a = existingValue.info) == null ? void 0 : _a.path) === path) { project.removeFile( existingValue.info, /*fileExists*/ false, /*detachFromProject*/ true ); existingValue.info = void 0; } existingValue.fileName = fileName; } else { projectRootFilesMap.set(path, { fileName }); } } else { const scriptKind = propertyReader.getScriptKind(f, this.hostConfiguration.extraFileExtensions); const hasMixedContent = propertyReader.hasMixedContent(f, this.hostConfiguration.extraFileExtensions); const scriptInfo = Debug.checkDefined(this.getOrCreateScriptInfoNotOpenedByClientForNormalizedPath( fileName, project.currentDirectory, scriptKind, hasMixedContent, project.directoryStructureHost, /*deferredDeleteOk*/ false )); path = scriptInfo.path; const existingValue = projectRootFilesMap.get(path); if (!existingValue || existingValue.info !== scriptInfo) { project.addRoot(scriptInfo, fileName); if (scriptInfo.isScriptOpen()) { this.removeRootOfInferredProjectIfNowPartOfOtherProject(scriptInfo); } } else { existingValue.fileName = fileName; } } newRootScriptInfoMap.set(path, true); } if (projectRootFilesMap.size > newRootScriptInfoMap.size) { projectRootFilesMap.forEach((value, path) => { if (!newRootScriptInfoMap.has(path)) { if (value.info) { project.removeFile( value.info, project.fileExists(value.info.fileName), /*detachFromProject*/ true ); } else { projectRootFilesMap.delete(path); } } }); } } updateRootAndOptionsOfNonInferredProject(project, newUncheckedFiles, propertyReader, newOptions, newTypeAcquisition, compileOnSave, watchOptions) { project.setCompilerOptions(newOptions); project.setWatchOptions(watchOptions); if (compileOnSave !== void 0) { project.compileOnSaveEnabled = compileOnSave; } this.addFilesToNonInferredProject(project, newUncheckedFiles, propertyReader, newTypeAcquisition); } /** * Reload the file names from config file specs and update the project graph * * @internal */ reloadFileNamesOfConfiguredProject(project) { const fileNames = this.reloadFileNamesOfParsedConfig(project.getConfigFilePath(), this.configFileExistenceInfoCache.get(project.canonicalConfigFilePath).config); project.updateErrorOnNoInputFiles(fileNames); this.updateNonInferredProjectFiles(project, fileNames.concat(project.getExternalFiles(1 /* RootNamesAndUpdate */)), fileNamePropertyReader); project.markAsDirty(); return project.updateGraph(); } /** @internal */ reloadFileNamesOfParsedConfig(configFileName, config) { if (config.updateLevel === void 0) return config.parsedCommandLine.fileNames; Debug.assert(config.updateLevel === 1 /* RootNamesAndUpdate */); const configFileSpecs = config.parsedCommandLine.options.configFile.configFileSpecs; const fileNames = getFileNamesFromConfigSpecs( configFileSpecs, getDirectoryPath(configFileName), config.parsedCommandLine.options, config.cachedDirectoryStructureHost, this.hostConfiguration.extraFileExtensions ); config.parsedCommandLine = { ...config.parsedCommandLine, fileNames }; return fileNames; } /** @internal */ setFileNamesOfAutpImportProviderOrAuxillaryProject(project, fileNames) { this.updateNonInferredProjectFiles(project, fileNames, fileNamePropertyReader); } /** @internal */ reloadConfiguredProjectClearingSemanticCache(project, reason, reloadedProjects) { if (!tryAddToSet(reloadedProjects, project)) return false; this.clearSemanticCache(project); this.reloadConfiguredProject(project, reloadReason(reason)); return true; } /** * Read the config file of the project again by clearing the cache and update the project graph * * @internal */ reloadConfiguredProject(project, reason) { project.isInitialLoadPending = returnFalse; project.pendingUpdateReason = void 0; project.pendingUpdateLevel = 0 /* Update */; const host = project.getCachedDirectoryStructureHost(); host.clearCache(); this.loadConfiguredProject(project, reason); updateWithTriggerFile( project, project.triggerFileForConfigFileDiag ?? project.getConfigFilePath(), /*isReload*/ true ); } /** @internal */ clearSemanticCache(project) { project.originalConfiguredProjects = void 0; project.resolutionCache.clear(); project.getLanguageService( /*ensureSynchronized*/ false ).cleanupSemanticCache(); project.cleanupProgram(); project.markAsDirty(); } /** @internal */ sendConfigFileDiagEvent(project, triggerFile, force) { if (!this.eventHandler || this.suppressDiagnosticEvents) return false; const diagnostics = project.getLanguageService().getCompilerOptionsDiagnostics(); diagnostics.push(...project.getAllProjectErrors()); if (!force && diagnostics.length === (project.configDiagDiagnosticsReported ?? 0)) return false; project.configDiagDiagnosticsReported = diagnostics.length; this.eventHandler( { eventName: ConfigFileDiagEvent, data: { configFileName: project.getConfigFilePath(), diagnostics, triggerFile: triggerFile ?? project.getConfigFilePath() } } ); return true; } getOrCreateInferredProjectForProjectRootPathIfEnabled(info, projectRootPath) { if (!this.useInferredProjectPerProjectRoot || // Its a dynamic info opened without project root info.isDynamic && projectRootPath === void 0) { return void 0; } if (projectRootPath) { const canonicalProjectRootPath = this.toCanonicalFileName(projectRootPath); for (const project of this.inferredProjects) { if (project.projectRootPath === canonicalProjectRootPath) { return project; } } return this.createInferredProject( projectRootPath, /*isSingleInferredProject*/ false, projectRootPath ); } let bestMatch; for (const project of this.inferredProjects) { if (!project.projectRootPath) continue; if (!containsPath(project.projectRootPath, info.path, this.host.getCurrentDirectory(), !this.host.useCaseSensitiveFileNames)) continue; if (bestMatch && bestMatch.projectRootPath.length > project.projectRootPath.length) continue; bestMatch = project; } return bestMatch; } getOrCreateSingleInferredProjectIfEnabled() { if (!this.useSingleInferredProject) { return void 0; } if (this.inferredProjects.length > 0 && this.inferredProjects[0].projectRootPath === void 0) { return this.inferredProjects[0]; } return this.createInferredProject( "", /*isSingleInferredProject*/ true ); } getOrCreateSingleInferredWithoutProjectRoot(currentDirectory) { Debug.assert(!this.useSingleInferredProject); const expectedCurrentDirectory = this.toCanonicalFileName(this.getNormalizedAbsolutePath(currentDirectory)); for (const inferredProject of this.inferredProjects) { if (!inferredProject.projectRootPath && inferredProject.isOrphan() && inferredProject.canonicalCurrentDirectory === expectedCurrentDirectory) { return inferredProject; } } return this.createInferredProject(currentDirectory); } createInferredProject(currentDirectory, isSingleInferredProject, projectRootPath) { const compilerOptions = projectRootPath && this.compilerOptionsForInferredProjectsPerProjectRoot.get(projectRootPath) || this.compilerOptionsForInferredProjects; let watchOptionsAndErrors; let typeAcquisition; if (projectRootPath) { watchOptionsAndErrors = this.watchOptionsForInferredProjectsPerProjectRoot.get(projectRootPath); typeAcquisition = this.typeAcquisitionForInferredProjectsPerProjectRoot.get(projectRootPath); } if (watchOptionsAndErrors === void 0) { watchOptionsAndErrors = this.watchOptionsForInferredProjects; } if (typeAcquisition === void 0) { typeAcquisition = this.typeAcquisitionForInferredProjects; } watchOptionsAndErrors = watchOptionsAndErrors || void 0; const project = new InferredProject2(this, this.documentRegistry, compilerOptions, watchOptionsAndErrors == null ? void 0 : watchOptionsAndErrors.watchOptions, projectRootPath, currentDirectory, typeAcquisition); project.setProjectErrors(watchOptionsAndErrors == null ? void 0 : watchOptionsAndErrors.errors); if (isSingleInferredProject) { this.inferredProjects.unshift(project); } else { this.inferredProjects.push(project); } return project; } /** @internal */ getOrCreateScriptInfoNotOpenedByClient(uncheckedFileName, currentDirectory, hostToQueryFileExistsOn, deferredDeleteOk) { return this.getOrCreateScriptInfoNotOpenedByClientForNormalizedPath( toNormalizedPath(uncheckedFileName), currentDirectory, /*scriptKind*/ void 0, /*hasMixedContent*/ void 0, hostToQueryFileExistsOn, deferredDeleteOk ); } getScriptInfo(uncheckedFileName) { return this.getScriptInfoForNormalizedPath(toNormalizedPath(uncheckedFileName)); } /** @internal */ getScriptInfoOrConfig(uncheckedFileName) { const path = toNormalizedPath(uncheckedFileName); const info = this.getScriptInfoForNormalizedPath(path); if (info) return info; const configProject = this.configuredProjects.get(this.toPath(uncheckedFileName)); return configProject && configProject.getCompilerOptions().configFile; } /** @internal */ logErrorForScriptInfoNotFound(fileName) { const names = arrayFrom( mapDefinedIterator( this.filenameToScriptInfo.entries(), (entry) => entry[1].deferredDelete ? void 0 : entry ), ([path, scriptInfo]) => ({ path, fileName: scriptInfo.fileName }) ); this.logger.msg(`Could not find file ${JSON.stringify(fileName)}. All files are: ${JSON.stringify(names)}`, "Err" /* Err */); } /** * Returns the projects that contain script info through SymLink * Note that this does not return projects in info.containingProjects * * @internal */ getSymlinkedProjects(info) { let projects; if (this.realpathToScriptInfos) { const realpath = info.getRealpathIfDifferent(); if (realpath) { forEach(this.realpathToScriptInfos.get(realpath), combineProjects); } forEach(this.realpathToScriptInfos.get(info.path), combineProjects); } return projects; function combineProjects(toAddInfo) { if (toAddInfo !== info) { for (const project of toAddInfo.containingProjects) { if (project.languageServiceEnabled && !project.isOrphan() && !project.getCompilerOptions().preserveSymlinks && !info.isAttached(project)) { if (!projects) { projects = createMultiMap(); projects.add(toAddInfo.path, project); } else if (!forEachEntry(projects, (projs, path) => path === toAddInfo.path ? false : contains(projs, project))) { projects.add(toAddInfo.path, project); } } } } } } watchClosedScriptInfo(info) { Debug.assert(!info.fileWatcher); if (!info.isDynamicOrHasMixedContent() && (!this.globalCacheLocationDirectoryPath || !startsWith(info.path, this.globalCacheLocationDirectoryPath))) { const indexOfNodeModules = info.fileName.indexOf("/node_modules/"); if (!this.host.getModifiedTime || indexOfNodeModules === -1) { info.fileWatcher = this.watchFactory.watchFile( info.fileName, (_fileName, eventKind) => this.onSourceFileChanged(info, eventKind), 500 /* Medium */, this.hostConfiguration.watchOptions, WatchType.ClosedScriptInfo ); } else { info.mTime = this.getModifiedTime(info); info.fileWatcher = this.watchClosedScriptInfoInNodeModules(info.fileName.substring(0, indexOfNodeModules)); } } } createNodeModulesWatcher(dir, dirPath) { let watcher = this.watchFactory.watchDirectory( dir, (fileOrDirectory) => { var _a; const fileOrDirectoryPath = removeIgnoredPath(this.toPath(fileOrDirectory)); if (!fileOrDirectoryPath) return; const basename = getBaseFileName(fileOrDirectoryPath); if (((_a = result.affectedModuleSpecifierCacheProjects) == null ? void 0 : _a.size) && (basename === "package.json" || basename === "node_modules")) { result.affectedModuleSpecifierCacheProjects.forEach((project) => { var _a2; (_a2 = project.getModuleSpecifierCache()) == null ? void 0 : _a2.clear(); }); } if (result.refreshScriptInfoRefCount) { if (dirPath === fileOrDirectoryPath) { this.refreshScriptInfosInDirectory(dirPath); } else { const info = this.filenameToScriptInfo.get(fileOrDirectoryPath); if (info) { if (isScriptInfoWatchedFromNodeModules(info)) { this.refreshScriptInfo(info); } } else if (!hasExtension(fileOrDirectoryPath)) { this.refreshScriptInfosInDirectory(fileOrDirectoryPath); } } } }, 1 /* Recursive */, this.hostConfiguration.watchOptions, WatchType.NodeModules ); const result = { refreshScriptInfoRefCount: 0, affectedModuleSpecifierCacheProjects: void 0, close: () => { var _a; if (watcher && !result.refreshScriptInfoRefCount && !((_a = result.affectedModuleSpecifierCacheProjects) == null ? void 0 : _a.size)) { watcher.close(); watcher = void 0; this.nodeModulesWatchers.delete(dirPath); } } }; this.nodeModulesWatchers.set(dirPath, result); return result; } /** @internal */ watchPackageJsonsInNodeModules(dir, project) { var _a; const dirPath = this.toPath(dir); const watcher = this.nodeModulesWatchers.get(dirPath) || this.createNodeModulesWatcher(dir, dirPath); Debug.assert(!((_a = watcher.affectedModuleSpecifierCacheProjects) == null ? void 0 : _a.has(project))); (watcher.affectedModuleSpecifierCacheProjects || (watcher.affectedModuleSpecifierCacheProjects = /* @__PURE__ */ new Set())).add(project); return { close: () => { var _a2; (_a2 = watcher.affectedModuleSpecifierCacheProjects) == null ? void 0 : _a2.delete(project); watcher.close(); } }; } watchClosedScriptInfoInNodeModules(dir) { const watchDir = dir + "/node_modules"; const watchDirPath = this.toPath(watchDir); const watcher = this.nodeModulesWatchers.get(watchDirPath) || this.createNodeModulesWatcher(watchDir, watchDirPath); watcher.refreshScriptInfoRefCount++; return { close: () => { watcher.refreshScriptInfoRefCount--; watcher.close(); } }; } getModifiedTime(info) { return (this.host.getModifiedTime(info.fileName) || missingFileModifiedTime).getTime(); } refreshScriptInfo(info) { const mTime = this.getModifiedTime(info); if (mTime !== info.mTime) { const eventKind = getFileWatcherEventKind(info.mTime, mTime); info.mTime = mTime; this.onSourceFileChanged(info, eventKind); } } refreshScriptInfosInDirectory(dir) { dir = dir + directorySeparator; this.filenameToScriptInfo.forEach((info) => { if (isScriptInfoWatchedFromNodeModules(info) && startsWith(info.path, dir)) { this.refreshScriptInfo(info); } }); } stopWatchingScriptInfo(info) { if (info.fileWatcher) { info.fileWatcher.close(); info.fileWatcher = void 0; } } getOrCreateScriptInfoNotOpenedByClientForNormalizedPath(fileName, currentDirectory, scriptKind, hasMixedContent, hostToQueryFileExistsOn, deferredDeleteOk) { if (isRootedDiskPath(fileName) || isDynamicFileName(fileName)) { return this.getOrCreateScriptInfoWorker( fileName, currentDirectory, /*openedByClient*/ false, /*fileContent*/ void 0, scriptKind, !!hasMixedContent, hostToQueryFileExistsOn, deferredDeleteOk ); } const info = this.openFilesWithNonRootedDiskPath.get(this.toCanonicalFileName(fileName)); if (info) { return info; } return void 0; } getOrCreateScriptInfoForNormalizedPath(fileName, openedByClient, fileContent, scriptKind, hasMixedContent, hostToQueryFileExistsOn) { return this.getOrCreateScriptInfoWorker( fileName, this.currentDirectory, openedByClient, fileContent, scriptKind, !!hasMixedContent, hostToQueryFileExistsOn, /*deferredDeleteOk*/ false ); } getOrCreateScriptInfoWorker(fileName, currentDirectory, openedByClient, fileContent, scriptKind, hasMixedContent, hostToQueryFileExistsOn, deferredDeleteOk) { Debug.assert(fileContent === void 0 || openedByClient, "ScriptInfo needs to be opened by client to be able to set its user defined content"); const path = normalizedPathToPath(fileName, currentDirectory, this.toCanonicalFileName); let info = this.filenameToScriptInfo.get(path); if (!info) { const isDynamic = isDynamicFileName(fileName); Debug.assert(isRootedDiskPath(fileName) || isDynamic || openedByClient, "", () => `${JSON.stringify({ fileName, currentDirectory, hostCurrentDirectory: this.currentDirectory, openKeys: arrayFrom(this.openFilesWithNonRootedDiskPath.keys()) })} Script info with non-dynamic relative file name can only be open script info or in context of host currentDirectory`); Debug.assert(!isRootedDiskPath(fileName) || this.currentDirectory === currentDirectory || !this.openFilesWithNonRootedDiskPath.has(this.toCanonicalFileName(fileName)), "", () => `${JSON.stringify({ fileName, currentDirectory, hostCurrentDirectory: this.currentDirectory, openKeys: arrayFrom(this.openFilesWithNonRootedDiskPath.keys()) })} Open script files with non rooted disk path opened with current directory context cannot have same canonical names`); Debug.assert(!isDynamic || this.currentDirectory === currentDirectory || this.useInferredProjectPerProjectRoot, "", () => `${JSON.stringify({ fileName, currentDirectory, hostCurrentDirectory: this.currentDirectory, openKeys: arrayFrom(this.openFilesWithNonRootedDiskPath.keys()) })} Dynamic files must always be opened with service's current directory or service should support inferred project per projectRootPath.`); if (!openedByClient && !isDynamic && !(hostToQueryFileExistsOn || this.host).fileExists(fileName)) { return; } info = new ScriptInfo(this.host, fileName, scriptKind, hasMixedContent, path, this.filenameToScriptInfoVersion.get(path)); this.filenameToScriptInfo.set(info.path, info); this.filenameToScriptInfoVersion.delete(info.path); if (!openedByClient) { this.watchClosedScriptInfo(info); } else if (!isRootedDiskPath(fileName) && (!isDynamic || this.currentDirectory !== currentDirectory)) { this.openFilesWithNonRootedDiskPath.set(this.toCanonicalFileName(fileName), info); } } else if (info.deferredDelete) { Debug.assert(!info.isDynamic); if (!openedByClient && !(hostToQueryFileExistsOn || this.host).fileExists(fileName)) { return deferredDeleteOk ? info : void 0; } info.deferredDelete = void 0; } if (openedByClient) { this.stopWatchingScriptInfo(info); info.open(fileContent); if (hasMixedContent) { info.registerFileUpdate(); } } return info; } /** * This gets the script info for the normalized path. If the path is not rooted disk path then the open script info with project root context is preferred */ getScriptInfoForNormalizedPath(fileName) { return !isRootedDiskPath(fileName) && this.openFilesWithNonRootedDiskPath.get(this.toCanonicalFileName(fileName)) || this.getScriptInfoForPath(normalizedPathToPath(fileName, this.currentDirectory, this.toCanonicalFileName)); } getScriptInfoForPath(fileName) { const info = this.filenameToScriptInfo.get(fileName); return !info || !info.deferredDelete ? info : void 0; } /** @internal */ getDocumentPositionMapper(project, generatedFileName, sourceFileName) { const declarationInfo = this.getOrCreateScriptInfoNotOpenedByClient( generatedFileName, project.currentDirectory, this.host, /*deferredDeleteOk*/ false ); if (!declarationInfo) { if (sourceFileName) { project.addGeneratedFileWatch(generatedFileName, sourceFileName); } return void 0; } declarationInfo.getSnapshot(); if (isString(declarationInfo.sourceMapFilePath)) { const sourceMapFileInfo2 = this.getScriptInfoForPath(declarationInfo.sourceMapFilePath); if (sourceMapFileInfo2) { sourceMapFileInfo2.getSnapshot(); if (sourceMapFileInfo2.documentPositionMapper !== void 0) { sourceMapFileInfo2.sourceInfos = this.addSourceInfoToSourceMap(sourceFileName, project, sourceMapFileInfo2.sourceInfos); return sourceMapFileInfo2.documentPositionMapper ? sourceMapFileInfo2.documentPositionMapper : void 0; } } declarationInfo.sourceMapFilePath = void 0; } else if (declarationInfo.sourceMapFilePath) { declarationInfo.sourceMapFilePath.sourceInfos = this.addSourceInfoToSourceMap(sourceFileName, project, declarationInfo.sourceMapFilePath.sourceInfos); return void 0; } else if (declarationInfo.sourceMapFilePath !== void 0) { return void 0; } let sourceMapFileInfo; let readMapFile = (mapFileName, mapFileNameFromDts) => { const mapInfo = this.getOrCreateScriptInfoNotOpenedByClient( mapFileName, project.currentDirectory, this.host, /*deferredDeleteOk*/ true ); sourceMapFileInfo = mapInfo || mapFileNameFromDts; if (!mapInfo || mapInfo.deferredDelete) return void 0; const snap = mapInfo.getSnapshot(); if (mapInfo.documentPositionMapper !== void 0) return mapInfo.documentPositionMapper; return getSnapshotText(snap); }; const projectName = project.projectName; const documentPositionMapper = getDocumentPositionMapper( { getCanonicalFileName: this.toCanonicalFileName, log: (s) => this.logger.info(s), getSourceFileLike: (f) => this.getSourceFileLike(f, projectName, declarationInfo) }, declarationInfo.fileName, declarationInfo.textStorage.getLineInfo(), readMapFile ); readMapFile = void 0; if (sourceMapFileInfo) { if (!isString(sourceMapFileInfo)) { declarationInfo.sourceMapFilePath = sourceMapFileInfo.path; sourceMapFileInfo.declarationInfoPath = declarationInfo.path; if (!sourceMapFileInfo.deferredDelete) sourceMapFileInfo.documentPositionMapper = documentPositionMapper || false; sourceMapFileInfo.sourceInfos = this.addSourceInfoToSourceMap(sourceFileName, project, sourceMapFileInfo.sourceInfos); } else { declarationInfo.sourceMapFilePath = { watcher: this.addMissingSourceMapFile( project.currentDirectory === this.currentDirectory ? sourceMapFileInfo : getNormalizedAbsolutePath(sourceMapFileInfo, project.currentDirectory), declarationInfo.path ), sourceInfos: this.addSourceInfoToSourceMap(sourceFileName, project) }; } } else { declarationInfo.sourceMapFilePath = false; } return documentPositionMapper; } addSourceInfoToSourceMap(sourceFileName, project, sourceInfos) { if (sourceFileName) { const sourceInfo = this.getOrCreateScriptInfoNotOpenedByClient( sourceFileName, project.currentDirectory, project.directoryStructureHost, /*deferredDeleteOk*/ false ); (sourceInfos || (sourceInfos = /* @__PURE__ */ new Set())).add(sourceInfo.path); } return sourceInfos; } addMissingSourceMapFile(mapFileName, declarationInfoPath) { const fileWatcher = this.watchFactory.watchFile( mapFileName, () => { const declarationInfo = this.getScriptInfoForPath(declarationInfoPath); if (declarationInfo && declarationInfo.sourceMapFilePath && !isString(declarationInfo.sourceMapFilePath)) { this.delayUpdateProjectGraphs( declarationInfo.containingProjects, /*clearSourceMapperCache*/ true ); this.delayUpdateSourceInfoProjects(declarationInfo.sourceMapFilePath.sourceInfos); declarationInfo.closeSourceMapFileWatcher(); } }, 2e3 /* High */, this.hostConfiguration.watchOptions, WatchType.MissingSourceMapFile ); return fileWatcher; } /** @internal */ getSourceFileLike(fileName, projectNameOrProject, declarationInfo) { const project = projectNameOrProject.projectName ? projectNameOrProject : this.findProject(projectNameOrProject); if (project) { const path = project.toPath(fileName); const sourceFile = project.getSourceFile(path); if (sourceFile && sourceFile.resolvedPath === path) return sourceFile; } const info = this.getOrCreateScriptInfoNotOpenedByClient( fileName, (project || this).currentDirectory, project ? project.directoryStructureHost : this.host, /*deferredDeleteOk*/ false ); if (!info) return void 0; if (declarationInfo && isString(declarationInfo.sourceMapFilePath) && info !== declarationInfo) { const sourceMapInfo = this.getScriptInfoForPath(declarationInfo.sourceMapFilePath); if (sourceMapInfo) { (sourceMapInfo.sourceInfos ?? (sourceMapInfo.sourceInfos = /* @__PURE__ */ new Set())).add(info.path); } } if (info.cacheSourceFile) return info.cacheSourceFile.sourceFile; if (!info.sourceFileLike) { info.sourceFileLike = { get text() { Debug.fail("shouldnt need text"); return ""; }, getLineAndCharacterOfPosition: (pos) => { const lineOffset = info.positionToLineOffset(pos); return { line: lineOffset.line - 1, character: lineOffset.offset - 1 }; }, getPositionOfLineAndCharacter: (line, character, allowEdits) => info.lineOffsetToPosition(line + 1, character + 1, allowEdits) }; } return info.sourceFileLike; } /** @internal */ setPerformanceEventHandler(performanceEventHandler) { this.performanceEventHandler = performanceEventHandler; } setHostConfiguration(args) { var _a, _b; if (args.file) { const info = this.getScriptInfoForNormalizedPath(toNormalizedPath(args.file)); if (info) { info.setOptions(convertFormatOptions(args.formatOptions), args.preferences); this.logger.info(`Host configuration update for file ${args.file}`); } } else { if (args.hostInfo !== void 0) { this.hostConfiguration.hostInfo = args.hostInfo; this.logger.info(`Host information ${args.hostInfo}`); } if (args.formatOptions) { this.hostConfiguration.formatCodeOptions = { ...this.hostConfiguration.formatCodeOptions, ...convertFormatOptions(args.formatOptions) }; this.logger.info("Format host information updated"); } if (args.preferences) { const { lazyConfiguredProjectsFromExternalProject, includePackageJsonAutoImports, includeCompletionsForModuleExports } = this.hostConfiguration.preferences; this.hostConfiguration.preferences = { ...this.hostConfiguration.preferences, ...args.preferences }; if (lazyConfiguredProjectsFromExternalProject && !this.hostConfiguration.preferences.lazyConfiguredProjectsFromExternalProject) { this.externalProjectToConfiguredProjectMap.forEach( (projects) => projects.forEach((project) => { if (!project.deferredClose && !project.isClosed() && project.pendingUpdateLevel === 2 /* Full */ && !this.hasPendingProjectUpdate(project)) { project.updateGraph(); } }) ); } if (includePackageJsonAutoImports !== args.preferences.includePackageJsonAutoImports || !!includeCompletionsForModuleExports !== !!args.preferences.includeCompletionsForModuleExports) { this.forEachProject((project) => { project.onAutoImportProviderSettingsChanged(); }); } } if (args.extraFileExtensions) { this.hostConfiguration.extraFileExtensions = args.extraFileExtensions; this.reloadProjects(); this.logger.info("Host file extension mappings updated"); } if (args.watchOptions) { const watchOptions = (_a = convertWatchOptions(args.watchOptions)) == null ? void 0 : _a.watchOptions; const substitution = handleWatchOptionsConfigDirTemplateSubstitution(watchOptions, this.currentDirectory); this.hostConfiguration.watchOptions = substitution; this.hostConfiguration.beforeSubstitution = substitution === watchOptions ? void 0 : watchOptions; this.logger.info(`Host watch options changed to ${JSON.stringify(this.hostConfiguration.watchOptions)}, it will be take effect for next watches.`); (_b = this.pnpWatcher) == null ? void 0 : _b.close(); this.watchPnpFile(); } } } /** @internal */ getWatchOptions(project) { return this.getWatchOptionsFromProjectWatchOptions(project.getWatchOptions(), project.getCurrentDirectory()); } /** @internal */ getWatchOptionsFromProjectWatchOptions(projectOptions, basePath) { const hostWatchOptions = !this.hostConfiguration.beforeSubstitution ? this.hostConfiguration.watchOptions : handleWatchOptionsConfigDirTemplateSubstitution( this.hostConfiguration.beforeSubstitution, basePath ); return projectOptions && hostWatchOptions ? { ...hostWatchOptions, ...projectOptions } : projectOptions || hostWatchOptions; } closeLog() { this.logger.close(); } /** * This function rebuilds the project for every file opened by the client * This does not reload contents of open files from disk. But we could do that if needed */ reloadProjects() { this.logger.info("reload projects."); this.filenameToScriptInfo.forEach((info) => { if (this.openFiles.has(info.path)) return; if (!info.fileWatcher) return; this.onSourceFileChanged( info, this.host.fileExists(info.fileName) ? info.deferredDelete ? 0 /* Created */ : 1 /* Changed */ : 2 /* Deleted */ ); }); this.pendingProjectUpdates.forEach((_project, projectName) => { this.throttledOperations.cancel(projectName); this.pendingProjectUpdates.delete(projectName); }); this.throttledOperations.cancel(ensureProjectForOpenFileSchedule); this.pendingOpenFileProjectUpdates = void 0; this.pendingEnsureProjectForOpenFiles = false; this.configFileExistenceInfoCache.forEach((info) => { if (info.config) info.config.updateLevel = 2 /* Full */; }); this.configFileForOpenFiles.clear(); this.externalProjects.forEach((project) => { this.clearSemanticCache(project); project.updateGraph(); }); const reloadedConfiguredProjects = /* @__PURE__ */ new Set(); const delayReloadedConfiguredProjects = /* @__PURE__ */ new Set(); this.externalProjectToConfiguredProjectMap.forEach((projects, externalProjectName) => { const reason = `Reloading configured project in external project: ${externalProjectName}`; projects.forEach((project) => { if (this.getHostPreferences().lazyConfiguredProjectsFromExternalProject) { if (!project.isInitialLoadPending()) { this.clearSemanticCache(project); project.pendingUpdateLevel = 2 /* Full */; project.pendingUpdateReason = reloadReason(reason); } delayReloadedConfiguredProjects.add(project); } else { this.reloadConfiguredProjectClearingSemanticCache( project, reason, reloadedConfiguredProjects ); } }); }); this.openFiles.forEach((_projectRootPath, path) => { const info = this.getScriptInfoForPath(path); if (find(info.containingProjects, isExternalProject)) return; this.tryFindDefaultConfiguredProjectAndLoadAncestorsForOpenScriptInfo( info, 2 /* Reload */, reloadedConfiguredProjects, delayReloadedConfiguredProjects ); }); delayReloadedConfiguredProjects.forEach((p) => reloadedConfiguredProjects.add(p)); this.inferredProjects.forEach((project) => this.clearSemanticCache(project)); this.ensureProjectForOpenFiles(); this.cleanupProjectsAndScriptInfos( reloadedConfiguredProjects, new Set(this.openFiles.keys()), new Set(this.externalProjectToConfiguredProjectMap.keys()) ); this.logger.info("After reloading projects.."); this.printProjects(); } /** * Remove the root of inferred project if script info is part of another project */ removeRootOfInferredProjectIfNowPartOfOtherProject(info) { Debug.assert(info.containingProjects.length > 0); const firstProject = info.containingProjects[0]; if (!firstProject.isOrphan() && isInferredProject(firstProject) && firstProject.isRoot(info) && forEach(info.containingProjects, (p) => p !== firstProject && !p.isOrphan())) { firstProject.removeFile( info, /*fileExists*/ true, /*detachFromProject*/ true ); } } /** * This function is to update the project structure for every inferred project. * It is called on the premise that all the configured projects are * up to date. * This will go through open files and assign them to inferred project if open file is not part of any other project * After that all the inferred project graphs are updated */ ensureProjectForOpenFiles() { this.logger.info("Before ensureProjectForOpenFiles:"); this.printProjects(); const pendingOpenFileProjectUpdates = this.pendingOpenFileProjectUpdates; this.pendingOpenFileProjectUpdates = void 0; pendingOpenFileProjectUpdates == null ? void 0 : pendingOpenFileProjectUpdates.forEach( (_config, path) => this.tryFindDefaultConfiguredProjectAndLoadAncestorsForOpenScriptInfo( this.getScriptInfoForPath(path), 1 /* Create */ ) ); this.openFiles.forEach((projectRootPath, path) => { const info = this.getScriptInfoForPath(path); if (info.isOrphan()) { this.assignOrphanScriptInfoToInferredProject(info, projectRootPath); } else { this.removeRootOfInferredProjectIfNowPartOfOtherProject(info); } }); this.pendingEnsureProjectForOpenFiles = false; this.inferredProjects.forEach(updateProjectIfDirty); this.logger.info("After ensureProjectForOpenFiles:"); this.printProjects(); } /** * Open file whose contents is managed by the client * @param filename is absolute pathname * @param fileContent is a known version of the file content that is more up to date than the one on disk */ openClientFile(fileName, fileContent, scriptKind, projectRootPath) { return this.openClientFileWithNormalizedPath( toNormalizedPath(fileName), fileContent, scriptKind, /*hasMixedContent*/ false, projectRootPath ? toNormalizedPath(projectRootPath) : void 0 ); } /** @internal */ getOriginalLocationEnsuringConfiguredProject(project, location) { const isSourceOfProjectReferenceRedirect = project.isSourceOfProjectReferenceRedirect(location.fileName); const originalLocation = isSourceOfProjectReferenceRedirect ? location : project.getSourceMapper().tryGetSourcePosition(location); if (!originalLocation) return void 0; const { fileName } = originalLocation; const scriptInfo = this.getScriptInfo(fileName); if (!scriptInfo && !this.host.fileExists(fileName)) return void 0; const originalFileInfo = { fileName: toNormalizedPath(fileName), path: this.toPath(fileName) }; const configFileName = this.getConfigFileNameForFile( originalFileInfo, /*findFromCacheOnly*/ false ); if (!configFileName) return void 0; let configuredProject = this.findConfiguredProjectByProjectName(configFileName); if (!configuredProject) { if (project.getCompilerOptions().disableReferencedProjectLoad) { if (isSourceOfProjectReferenceRedirect) { return location; } return (scriptInfo == null ? void 0 : scriptInfo.containingProjects.length) ? originalLocation : location; } configuredProject = this.createConfiguredProject(configFileName, `Creating project for original file: ${originalFileInfo.fileName}${location !== originalLocation ? " for location: " + location.fileName : ""}`); } updateProjectIfDirty(configuredProject); const projectContainsOriginalInfo = (project2) => { const info = this.getScriptInfo(fileName); return info && project2.containsScriptInfo(info) && !project2.isSourceOfProjectReferenceRedirect(info.path); }; if (configuredProject.isSolution() || !projectContainsOriginalInfo(configuredProject)) { configuredProject = forEachResolvedProjectReferenceProject( configuredProject, fileName, (child) => projectContainsOriginalInfo(child) ? child : void 0, 1 /* Create */, `Creating project referenced in solution ${configuredProject.projectName} to find possible configured project for original file: ${originalFileInfo.fileName}${location !== originalLocation ? " for location: " + location.fileName : ""}` ); if (!configuredProject) return void 0; if (configuredProject === project) return originalLocation; } addOriginalConfiguredProject(configuredProject); const originalScriptInfo = this.getScriptInfo(fileName); if (!originalScriptInfo || !originalScriptInfo.containingProjects.length) return void 0; originalScriptInfo.containingProjects.forEach((project2) => { if (isConfiguredProject(project2)) { addOriginalConfiguredProject(project2); } }); return originalLocation; function addOriginalConfiguredProject(originalProject) { (project.originalConfiguredProjects ?? (project.originalConfiguredProjects = /* @__PURE__ */ new Set())).add(originalProject.canonicalConfigFilePath); } } /** @internal */ fileExists(fileName) { return !!this.getScriptInfoForNormalizedPath(fileName) || this.host.fileExists(fileName); } findExternalProjectContainingOpenScriptInfo(info) { return find(this.externalProjects, (proj) => { updateProjectIfDirty(proj); return proj.containsScriptInfo(info); }); } getOrCreateOpenScriptInfo(fileName, fileContent, scriptKind, hasMixedContent, projectRootPath) { const info = this.getOrCreateScriptInfoWorker( fileName, projectRootPath ? this.getNormalizedAbsolutePath(projectRootPath) : this.currentDirectory, /*openedByClient*/ true, fileContent, scriptKind, !!hasMixedContent, /*hostToQueryFileExistsOn*/ void 0, /*deferredDeleteOk*/ true ); this.openFiles.set(info.path, projectRootPath); return info; } assignProjectToOpenedScriptInfo(info) { let configFileName; let configFileErrors; const project = this.findExternalProjectContainingOpenScriptInfo(info); let retainProjects; let sentConfigDiag; if (!project && this.serverMode === 0 /* Semantic */) { const result = this.tryFindDefaultConfiguredProjectAndLoadAncestorsForOpenScriptInfo( info, 1 /* Create */ ); if (result) { retainProjects = result.seenProjects; sentConfigDiag = result.sentConfigDiag; if (result.defaultProject) { configFileName = result.defaultProject.getConfigFilePath(); configFileErrors = result.defaultProject.getAllProjectErrors(); } } } info.containingProjects.forEach(updateProjectIfDirty); if (info.isOrphan()) { retainProjects == null ? void 0 : retainProjects.forEach((project2) => { if (!sentConfigDiag.has(project2)) this.sendConfigFileDiagEvent( project2, info.fileName, /*force*/ true ); }); Debug.assert(this.openFiles.has(info.path)); this.assignOrphanScriptInfoToInferredProject(info, this.openFiles.get(info.path)); } Debug.assert(!info.isOrphan()); return { configFileName, configFileErrors, retainProjects }; } /** * Depending on kind * - Find the configuedProject and return it - if allowDeferredClosed is set it will find the deferredClosed project as well * - Create - if the project doesnt exist, it creates one as well. If not delayLoad, the project is updated (with triggerFile if passed) * - Reload - if the project doesnt exist, it creates one. If not delayLoad, the project is reloaded clearing semantic cache * @internal */ findCreateOrReloadConfiguredProject(configFileName, kind, reason, allowDeferredClosed, triggerFile, reloadedProjects, delayLoad, delayReloadedConfiguredProjects) { let project = this.findConfiguredProjectByProjectName(configFileName, allowDeferredClosed); let sentConfigFileDiag = false; switch (kind) { case 0 /* Find */: if (!project) return; break; case 1 /* Create */: project ?? (project = this.createConfiguredProject(configFileName, reason)); sentConfigFileDiag = !delayLoad && updateConfiguredProject(project, triggerFile); break; case 2 /* Reload */: project ?? (project = this.createConfiguredProject(configFileName, reloadReason(reason))); sentConfigFileDiag = !delayReloadedConfiguredProjects && this.reloadConfiguredProjectClearingSemanticCache(project, reason, reloadedProjects); if (delayReloadedConfiguredProjects && !delayReloadedConfiguredProjects.has(project) && !reloadedProjects.has(project)) { project.pendingUpdateLevel = 2 /* Full */; project.pendingUpdateReason = reloadReason(reason); delayReloadedConfiguredProjects.add(project); } break; default: Debug.assertNever(kind); } return { project, sentConfigFileDiag }; } /** * Finds the default configured project for given info * For any tsconfig found, it looks into that project, if not then all its references, * The search happens for all tsconfigs till projectRootPath */ tryFindDefaultConfiguredProjectForOpenScriptInfo(info, kind, allowDeferredClosed, reloadedProjects) { const configFileName = this.getConfigFileNameForFile(info, kind === 0 /* Find */); if (!configFileName) return; const result = this.findCreateOrReloadConfiguredProject( configFileName, kind, fileOpenReason(info), allowDeferredClosed, info.fileName, reloadedProjects ); if (!result) return; const seenProjects = /* @__PURE__ */ new Set(); const sentConfigDiag = new Set(result.sentConfigFileDiag ? [result.project] : void 0); let defaultProject; let possiblyDefault; tryFindDefaultConfiguredProject(result.project); return { defaultProject: defaultProject ?? possiblyDefault, sentConfigDiag, seenProjects }; function tryFindDefaultConfiguredProject(project) { return isDefaultProject(project) ? defaultProject : tryFindDefaultConfiguredProjectFromReferences(project); } function isDefaultProject(project) { if (!tryAddToSet(seenProjects, project)) return; const projectWithInfo = project.containsScriptInfo(info); if (projectWithInfo && !project.isSourceOfProjectReferenceRedirect(info.path)) return defaultProject = project; possiblyDefault ?? (possiblyDefault = projectWithInfo ? project : void 0); } function tryFindDefaultConfiguredProjectFromReferences(project) { return forEachResolvedProjectReferenceProject( project, info.path, (child, sentConfigFileDiag) => { if (sentConfigFileDiag) sentConfigDiag.add(child); return isDefaultProject(child); }, kind, `Creating project referenced in solution ${project.projectName} to find possible configured project for ${info.fileName} to open`, allowDeferredClosed, info.fileName, reloadedProjects ); } } tryFindDefaultConfiguredProjectAndLoadAncestorsForOpenScriptInfo(info, kind, reloadedProjects, delayReloadedConfiguredProjects) { const allowDeferredClosed = kind === 0 /* Find */; const result = this.tryFindDefaultConfiguredProjectForOpenScriptInfo( info, kind, allowDeferredClosed, reloadedProjects ); if (!result) return; const { defaultProject, seenProjects } = result; if (defaultProject) { forEachAncestorProject( info, defaultProject, (ancestor) => { seenProjects.add(ancestor); }, kind, `Creating project possibly referencing default composite project ${defaultProject.getProjectName()} of open file ${info.fileName}`, allowDeferredClosed, reloadedProjects, delayReloadedConfiguredProjects ); } return result; } /** @internal */ loadAncestorProjectTree(forProjects) { forProjects = forProjects || mapDefinedEntries( this.configuredProjects, (key, project) => !project.isInitialLoadPending() ? [key, true] : void 0 ); const seenProjects = /* @__PURE__ */ new Set(); for (const project of arrayFrom(this.configuredProjects.values())) { if (forEachPotentialProjectReference(project, (potentialRefPath) => forProjects.has(potentialRefPath))) { updateProjectIfDirty(project); } this.ensureProjectChildren(project, forProjects, seenProjects); } } ensureProjectChildren(project, forProjects, seenProjects) { var _a; if (!tryAddToSet(seenProjects, project.canonicalConfigFilePath)) return; if (project.getCompilerOptions().disableReferencedProjectLoad) return; const children = (_a = project.getCurrentProgram()) == null ? void 0 : _a.getResolvedProjectReferences(); if (!children) return; for (const child of children) { if (!child) continue; const referencedProject = forEachResolvedProjectReference(child.references, (ref) => forProjects.has(ref.sourceFile.path) ? ref : void 0); if (!referencedProject) continue; const configFileName = toNormalizedPath(child.sourceFile.fileName); const childProject = this.findConfiguredProjectByProjectName(configFileName) ?? this.createConfiguredProject( configFileName, `Creating project referenced by : ${project.projectName} as it references project ${referencedProject.sourceFile.fileName}` ); updateProjectIfDirty(childProject); this.ensureProjectChildren(childProject, forProjects, seenProjects); } } cleanupConfiguredProjects(toRetainConfiguredProjects, externalProjectsRetainingConfiguredProjects, openFilesWithRetainedConfiguredProject) { this.getOrphanConfiguredProjects( toRetainConfiguredProjects, openFilesWithRetainedConfiguredProject, externalProjectsRetainingConfiguredProjects ).forEach((project) => this.removeProject(project)); } cleanupProjectsAndScriptInfos(toRetainConfiguredProjects, openFilesWithRetainedConfiguredProject, externalProjectsRetainingConfiguredProjects) { this.cleanupConfiguredProjects( toRetainConfiguredProjects, externalProjectsRetainingConfiguredProjects, openFilesWithRetainedConfiguredProject ); for (const inferredProject of this.inferredProjects.slice()) { if (inferredProject.isOrphan()) { this.removeProject(inferredProject); } } this.removeOrphanScriptInfos(); } openClientFileWithNormalizedPath(fileName, fileContent, scriptKind, hasMixedContent, projectRootPath) { const info = this.getOrCreateOpenScriptInfo(fileName, fileContent, scriptKind, hasMixedContent, projectRootPath); const { retainProjects, ...result } = this.assignProjectToOpenedScriptInfo(info); this.cleanupProjectsAndScriptInfos( retainProjects, /* @__PURE__ */ new Set([info.path]), /*externalProjectsRetainingConfiguredProjects*/ void 0 ); this.telemetryOnOpenFile(info); this.printProjects(); return result; } /** @internal */ getOrphanConfiguredProjects(toRetainConfiguredProjects, openFilesWithRetainedConfiguredProject, externalProjectsRetainingConfiguredProjects) { const toRemoveConfiguredProjects = new Set(this.configuredProjects.values()); const markOriginalProjectsAsUsed = (project) => { if (project.originalConfiguredProjects && (isConfiguredProject(project) || !project.isOrphan())) { project.originalConfiguredProjects.forEach( (_value, configuredProjectPath) => { const project2 = this.getConfiguredProjectByCanonicalConfigFilePath(configuredProjectPath); return project2 && retainConfiguredProject(project2); } ); } }; toRetainConfiguredProjects == null ? void 0 : toRetainConfiguredProjects.forEach(retainConfiguredProject); this.inferredProjects.forEach(markOriginalProjectsAsUsed); this.externalProjects.forEach(markOriginalProjectsAsUsed); this.externalProjectToConfiguredProjectMap.forEach((projects, externalProjectName) => { if (!(externalProjectsRetainingConfiguredProjects == null ? void 0 : externalProjectsRetainingConfiguredProjects.has(externalProjectName))) { projects.forEach(retainConfiguredProject); } }); this.openFiles.forEach((_projectRootPath, path) => { if (openFilesWithRetainedConfiguredProject == null ? void 0 : openFilesWithRetainedConfiguredProject.has(path)) return; const info = this.getScriptInfoForPath(path); if (find(info.containingProjects, isExternalProject)) return; const result = this.tryFindDefaultConfiguredProjectAndLoadAncestorsForOpenScriptInfo( info, 0 /* Find */ ); if (result == null ? void 0 : result.defaultProject) { result == null ? void 0 : result.seenProjects.forEach(retainConfiguredProject); } }); this.configuredProjects.forEach((project) => { if (toRemoveConfiguredProjects.has(project)) { if (isPendingUpdate(project) || forEachReferencedProject(project, isRetained)) { retainConfiguredProject(project); } } }); return toRemoveConfiguredProjects; function isRetained(project) { return !toRemoveConfiguredProjects.has(project) || isPendingUpdate(project); } function isPendingUpdate(project) { var _a, _b; return (project.deferredClose || project.projectService.hasPendingProjectUpdate(project)) && !!((_b = (_a = project.projectService.configFileExistenceInfoCache.get(project.canonicalConfigFilePath)) == null ? void 0 : _a.openFilesImpactedByConfigFile) == null ? void 0 : _b.size); } function retainConfiguredProject(project) { if (!toRemoveConfiguredProjects.delete(project)) return; markOriginalProjectsAsUsed(project); forEachReferencedProject(project, retainConfiguredProject); } } removeOrphanScriptInfos() { const toRemoveScriptInfos = new Map(this.filenameToScriptInfo); this.filenameToScriptInfo.forEach((info) => { if (info.deferredDelete) return; if (!info.isScriptOpen() && info.isOrphan() && !info.isContainedByBackgroundProject()) { if (!info.sourceMapFilePath) return; let sourceInfos; if (isString(info.sourceMapFilePath)) { const sourceMapInfo = this.filenameToScriptInfo.get(info.sourceMapFilePath); sourceInfos = sourceMapInfo == null ? void 0 : sourceMapInfo.sourceInfos; } else { sourceInfos = info.sourceMapFilePath.sourceInfos; } if (!sourceInfos) return; if (!forEachKey(sourceInfos, (path) => { const info2 = this.getScriptInfoForPath(path); return !!info2 && (info2.isScriptOpen() || !info2.isOrphan()); })) { return; } } toRemoveScriptInfos.delete(info.path); if (info.sourceMapFilePath) { let sourceInfos; if (isString(info.sourceMapFilePath)) { const sourceMapInfo = this.filenameToScriptInfo.get(info.sourceMapFilePath); if (sourceMapInfo == null ? void 0 : sourceMapInfo.deferredDelete) { info.sourceMapFilePath = { watcher: this.addMissingSourceMapFile(sourceMapInfo.fileName, info.path), sourceInfos: sourceMapInfo.sourceInfos }; } else { toRemoveScriptInfos.delete(info.sourceMapFilePath); } sourceInfos = sourceMapInfo == null ? void 0 : sourceMapInfo.sourceInfos; } else { sourceInfos = info.sourceMapFilePath.sourceInfos; } if (sourceInfos) { sourceInfos.forEach((_value, path) => toRemoveScriptInfos.delete(path)); } } }); toRemoveScriptInfos.forEach((info) => this.deleteScriptInfo(info)); } telemetryOnOpenFile(scriptInfo) { if (this.serverMode !== 0 /* Semantic */ || !this.eventHandler || !scriptInfo.isJavaScript() || !addToSeen(this.allJsFilesForOpenFileTelemetry, scriptInfo.path)) { return; } const project = this.ensureDefaultProjectForFile(scriptInfo); if (!project.languageServiceEnabled) { return; } const sourceFile = project.getSourceFile(scriptInfo.path); const checkJs = !!sourceFile && !!sourceFile.checkJsDirective; this.eventHandler({ eventName: OpenFileInfoTelemetryEvent, data: { info: { checkJs } } }); } closeClientFile(uncheckedFileName, skipAssignOrphanScriptInfosToInferredProject) { const info = this.getScriptInfoForNormalizedPath(toNormalizedPath(uncheckedFileName)); const result = info ? this.closeOpenFile(info, skipAssignOrphanScriptInfosToInferredProject) : false; if (!skipAssignOrphanScriptInfosToInferredProject) { this.printProjects(); } return result; } collectChanges(lastKnownProjectVersions, currentProjects, includeProjectReferenceRedirectInfo, result) { for (const proj of currentProjects) { const knownProject = find(lastKnownProjectVersions, (p) => p.projectName === proj.getProjectName()); result.push(proj.getChangesSinceVersion(knownProject && knownProject.version, includeProjectReferenceRedirectInfo)); } } /** @internal */ synchronizeProjectList(knownProjects, includeProjectReferenceRedirectInfo) { const files = []; this.collectChanges(knownProjects, this.externalProjects, includeProjectReferenceRedirectInfo, files); this.collectChanges(knownProjects, mapDefinedIterator(this.configuredProjects.values(), (p) => p.deferredClose ? void 0 : p), includeProjectReferenceRedirectInfo, files); this.collectChanges(knownProjects, this.inferredProjects, includeProjectReferenceRedirectInfo, files); return files; } /** @internal */ applyChangesInOpenFiles(openFiles, changedFiles, closedFiles) { let openScriptInfos; let assignOrphanScriptInfosToInferredProject = false; if (openFiles) { for (const file of openFiles) { const info = this.getOrCreateOpenScriptInfo( toNormalizedPath(file.fileName), file.content, tryConvertScriptKindName(file.scriptKind), file.hasMixedContent, file.projectRootPath ? toNormalizedPath(file.projectRootPath) : void 0 ); (openScriptInfos || (openScriptInfos = [])).push(info); } } if (changedFiles) { for (const file of changedFiles) { const scriptInfo = this.getScriptInfo(file.fileName); Debug.assert(!!scriptInfo); this.applyChangesToFile(scriptInfo, file.changes); } } if (closedFiles) { for (const file of closedFiles) { assignOrphanScriptInfosToInferredProject = this.closeClientFile( file, /*skipAssignOrphanScriptInfosToInferredProject*/ true ) || assignOrphanScriptInfosToInferredProject; } } let retainProjects; openScriptInfos == null ? void 0 : openScriptInfos.forEach((info) => { var _a; return (_a = this.assignProjectToOpenedScriptInfo(info).retainProjects) == null ? void 0 : _a.forEach((p) => (retainProjects ?? (retainProjects = /* @__PURE__ */ new Set())).add(p)); }); if (assignOrphanScriptInfosToInferredProject) { this.assignOrphanScriptInfosToInferredProject(); } if (openScriptInfos) { this.cleanupProjectsAndScriptInfos( retainProjects, new Set(openScriptInfos.map((info) => info.path)), /*externalProjectsRetainingConfiguredProjects*/ void 0 ); openScriptInfos.forEach((info) => this.telemetryOnOpenFile(info)); this.printProjects(); } else if (length(closedFiles)) { this.printProjects(); } } /** @internal */ applyChangesToFile(scriptInfo, changes) { for (const change of changes) { scriptInfo.editContent(change.span.start, change.span.start + change.span.length, change.newText); } } // eslint-disable-line @typescript-eslint/unified-signatures closeExternalProject(uncheckedFileName, cleanupAfter) { const fileName = toNormalizedPath(uncheckedFileName); const projects = this.externalProjectToConfiguredProjectMap.get(fileName); if (projects) { this.externalProjectToConfiguredProjectMap.delete(fileName); } else { const externalProject = this.findExternalProjectByProjectName(uncheckedFileName); if (externalProject) { this.removeProject(externalProject); } } if (cleanupAfter) { this.cleanupConfiguredProjects(); this.printProjects(); } } openExternalProjects(projects) { const projectsToClose = new Set(this.externalProjects.map((p) => p.getProjectName())); this.externalProjectToConfiguredProjectMap.forEach((_, externalProjectName) => projectsToClose.add(externalProjectName)); for (const externalProject of projects) { this.openExternalProject( externalProject, /*cleanupAfter*/ false ); projectsToClose.delete(externalProject.projectFileName); } projectsToClose.forEach((externalProjectName) => this.closeExternalProject( externalProjectName, /*cleanupAfter*/ false )); this.cleanupConfiguredProjects(); this.printProjects(); } static escapeFilenameForRegex(filename) { return filename.replace(this.filenameEscapeRegexp, "\\$&"); } resetSafeList() { this.safelist = defaultTypeSafeList; } applySafeList(proj) { const typeAcquisition = proj.typeAcquisition; Debug.assert(!!typeAcquisition, "proj.typeAcquisition should be set by now"); const result = this.applySafeListWorker(proj, proj.rootFiles, typeAcquisition); return (result == null ? void 0 : result.excludedFiles) ?? []; } applySafeListWorker(proj, rootFiles, typeAcquisition) { if (typeAcquisition.enable === false || typeAcquisition.disableFilenameBasedTypeAcquisition) { return void 0; } const typeAcqInclude = typeAcquisition.include || (typeAcquisition.include = []); const excludeRules = []; const normalizedNames = rootFiles.map((f) => normalizeSlashes(f.fileName)); for (const name of Object.keys(this.safelist)) { const rule2 = this.safelist[name]; for (const root of normalizedNames) { if (rule2.match.test(root)) { this.logger.info(`Excluding files based on rule ${name} matching file '${root}'`); if (rule2.types) { for (const type of rule2.types) { if (!typeAcqInclude.includes(type)) { typeAcqInclude.push(type); } } } if (rule2.exclude) { for (const exclude of rule2.exclude) { const processedRule = root.replace(rule2.match, (...groups) => { return exclude.map((groupNumberOrString) => { if (typeof groupNumberOrString === "number") { if (!isString(groups[groupNumberOrString])) { this.logger.info(`Incorrect RegExp specification in safelist rule ${name} - not enough groups`); return "\\*"; } return _ProjectService.escapeFilenameForRegex(groups[groupNumberOrString]); } return groupNumberOrString; }).join(""); }); if (!excludeRules.includes(processedRule)) { excludeRules.push(processedRule); } } } else { const escaped = _ProjectService.escapeFilenameForRegex(root); if (!excludeRules.includes(escaped)) { excludeRules.push(escaped); } } } } } const excludeRegexes = excludeRules.map((e) => new RegExp(e, "i")); let filesToKeep; let excludedFiles; for (let i = 0; i < rootFiles.length; i++) { if (excludeRegexes.some((re) => re.test(normalizedNames[i]))) { addExcludedFile(i); } else { if (typeAcquisition.enable) { const baseName = getBaseFileName(toFileNameLowerCase(normalizedNames[i])); if (fileExtensionIs(baseName, "js")) { const inferredTypingName = removeFileExtension(baseName); const cleanedTypingName = removeMinAndVersionNumbers(inferredTypingName); const typeName = this.legacySafelist.get(cleanedTypingName); if (typeName !== void 0) { this.logger.info(`Excluded '${normalizedNames[i]}' because it matched ${cleanedTypingName} from the legacy safelist`); addExcludedFile(i); if (!typeAcqInclude.includes(typeName)) { typeAcqInclude.push(typeName); } continue; } } } if (/^.+[.-]min\.js$/.test(normalizedNames[i])) { addExcludedFile(i); } else { filesToKeep == null ? void 0 : filesToKeep.push(rootFiles[i]); } } } return excludedFiles ? { rootFiles: filesToKeep, excludedFiles } : void 0; function addExcludedFile(index) { if (!excludedFiles) { Debug.assert(!filesToKeep); filesToKeep = rootFiles.slice(0, index); excludedFiles = []; } excludedFiles.push(normalizedNames[index]); } } // eslint-disable-line @typescript-eslint/unified-signatures openExternalProject(proj, cleanupAfter) { const existingExternalProject = this.findExternalProjectByProjectName(proj.projectFileName); let configuredProjects; let rootFiles = []; for (const file of proj.rootFiles) { const normalized = toNormalizedPath(file.fileName); if (getBaseConfigFileName(normalized)) { if (this.serverMode === 0 /* Semantic */ && this.host.fileExists(normalized)) { let project = this.findConfiguredProjectByProjectName(normalized); if (!project) { project = this.createConfiguredProject(normalized, `Creating configured project in external project: ${proj.projectFileName}`); if (!this.getHostPreferences().lazyConfiguredProjectsFromExternalProject) project.updateGraph(); } (configuredProjects ?? (configuredProjects = /* @__PURE__ */ new Set())).add(project); Debug.assert(!project.isClosed()); } } else { rootFiles.push(file); } } if (configuredProjects) { this.externalProjectToConfiguredProjectMap.set(proj.projectFileName, configuredProjects); if (existingExternalProject) this.removeProject(existingExternalProject); } else { this.externalProjectToConfiguredProjectMap.delete(proj.projectFileName); const typeAcquisition = proj.typeAcquisition || {}; typeAcquisition.include = typeAcquisition.include || []; typeAcquisition.exclude = typeAcquisition.exclude || []; if (typeAcquisition.enable === void 0) { typeAcquisition.enable = hasNoTypeScriptSource(rootFiles.map((f) => f.fileName)); } const excludeResult = this.applySafeListWorker(proj, rootFiles, typeAcquisition); const excludedFiles = (excludeResult == null ? void 0 : excludeResult.excludedFiles) ?? []; rootFiles = (excludeResult == null ? void 0 : excludeResult.rootFiles) ?? rootFiles; if (existingExternalProject) { existingExternalProject.excludedFiles = excludedFiles; const compilerOptions = convertCompilerOptions(proj.options); const watchOptionsAndErrors = convertWatchOptions(proj.options, existingExternalProject.getCurrentDirectory()); const lastFileExceededProgramSize = this.getFilenameForExceededTotalSizeLimitForNonTsFiles(proj.projectFileName, compilerOptions, rootFiles, externalFilePropertyReader); if (lastFileExceededProgramSize) { existingExternalProject.disableLanguageService(lastFileExceededProgramSize); } else { existingExternalProject.enableLanguageService(); } existingExternalProject.setProjectErrors(watchOptionsAndErrors == null ? void 0 : watchOptionsAndErrors.errors); this.updateRootAndOptionsOfNonInferredProject(existingExternalProject, rootFiles, externalFilePropertyReader, compilerOptions, typeAcquisition, proj.options.compileOnSave, watchOptionsAndErrors == null ? void 0 : watchOptionsAndErrors.watchOptions); existingExternalProject.updateGraph(); } else { const project = this.createExternalProject(proj.projectFileName, rootFiles, proj.options, typeAcquisition, excludedFiles); project.updateGraph(); } } if (cleanupAfter) { this.cleanupConfiguredProjects( configuredProjects, new Set(proj.projectFileName) ); this.printProjects(); } } hasDeferredExtension() { for (const extension of this.hostConfiguration.extraFileExtensions) { if (extension.scriptKind === 7 /* Deferred */) { return true; } } return false; } /** * Performs the initial steps of enabling a plugin by finding and instantiating the module for a plugin either asynchronously or synchronously * @internal */ requestEnablePlugin(project, pluginConfigEntry, searchPaths) { if (!this.host.importPlugin && !this.host.require) { this.logger.info("Plugins were requested but not running in environment that supports 'require'. Nothing will be loaded"); return; } this.logger.info(`Enabling plugin ${pluginConfigEntry.name} from candidate paths: ${searchPaths.join(",")}`); if (!pluginConfigEntry.name || isExternalModuleNameRelative(pluginConfigEntry.name) || /[\\/]\.\.?($|[\\/])/.test(pluginConfigEntry.name)) { this.logger.info(`Skipped loading plugin ${pluginConfigEntry.name || JSON.stringify(pluginConfigEntry)} because only package name is allowed plugin name`); return; } if (this.host.importPlugin) { const importPromise = Project3.importServicePluginAsync( pluginConfigEntry, searchPaths, this.host, (s) => this.logger.info(s) ); this.pendingPluginEnablements ?? (this.pendingPluginEnablements = /* @__PURE__ */ new Map()); let promises = this.pendingPluginEnablements.get(project); if (!promises) this.pendingPluginEnablements.set(project, promises = []); promises.push(importPromise); return; } this.endEnablePlugin( project, Project3.importServicePluginSync( pluginConfigEntry, searchPaths, this.host, (s) => this.logger.info(s) ) ); } /** * Performs the remaining steps of enabling a plugin after its module has been instantiated. * @internal */ endEnablePlugin(project, { pluginConfigEntry, resolvedModule, errorLogs }) { var _a; if (resolvedModule) { const configurationOverride = (_a = this.currentPluginConfigOverrides) == null ? void 0 : _a.get(pluginConfigEntry.name); if (configurationOverride) { const pluginName = pluginConfigEntry.name; pluginConfigEntry = configurationOverride; pluginConfigEntry.name = pluginName; } project.enableProxy(resolvedModule, pluginConfigEntry); } else { forEach(errorLogs, (message) => this.logger.info(message)); this.logger.info(`Couldn't find ${pluginConfigEntry.name}`); } } /** @internal */ hasNewPluginEnablementRequests() { return !!this.pendingPluginEnablements; } /** @internal */ hasPendingPluginEnablements() { return !!this.currentPluginEnablementPromise; } /** * Waits for any ongoing plugin enablement requests to complete. * * @internal */ async waitForPendingPlugins() { while (this.currentPluginEnablementPromise) { await this.currentPluginEnablementPromise; } } /** * Starts enabling any requested plugins without waiting for the result. * * @internal */ enableRequestedPlugins() { if (this.pendingPluginEnablements) { void this.enableRequestedPluginsAsync(); } } async enableRequestedPluginsAsync() { if (this.currentPluginEnablementPromise) { await this.waitForPendingPlugins(); } if (!this.pendingPluginEnablements) { return; } const entries = arrayFrom(this.pendingPluginEnablements.entries()); this.pendingPluginEnablements = void 0; this.currentPluginEnablementPromise = this.enableRequestedPluginsWorker(entries); await this.currentPluginEnablementPromise; } async enableRequestedPluginsWorker(pendingPlugins) { Debug.assert(this.currentPluginEnablementPromise === void 0); let sendProjectsUpdatedInBackgroundEvent = false; await Promise.all(map(pendingPlugins, async ([project, promises]) => { const results = await Promise.all(promises); if (project.isClosed() || isProjectDeferredClose(project)) { this.logger.info(`Cancelling plugin enabling for ${project.getProjectName()} as it is ${project.isClosed() ? "closed" : "deferred close"}`); return; } sendProjectsUpdatedInBackgroundEvent = true; for (const result of results) { this.endEnablePlugin(project, result); } this.delayUpdateProjectGraph(project); })); this.currentPluginEnablementPromise = void 0; if (sendProjectsUpdatedInBackgroundEvent) this.sendProjectsUpdatedInBackgroundEvent(); } configurePlugin(args) { this.forEachEnabledProject((project) => project.onPluginConfigurationChanged(args.pluginName, args.configuration)); this.currentPluginConfigOverrides = this.currentPluginConfigOverrides || /* @__PURE__ */ new Map(); this.currentPluginConfigOverrides.set(args.pluginName, args.configuration); } /** @internal */ getPackageJsonsVisibleToFile(fileName, project, rootDir) { const packageJsonCache = this.packageJsonCache; const rootPath = rootDir && this.toPath(rootDir); const result = []; const processDirectory = (directory) => { switch (packageJsonCache.directoryHasPackageJson(directory)) { case 3 /* Maybe */: packageJsonCache.searchDirectoryAndAncestors(directory); return processDirectory(directory); case -1 /* True */: const packageJsonFileName = combinePaths(directory, "package.json"); this.watchPackageJsonFile(packageJsonFileName, this.toPath(packageJsonFileName), project); const info = packageJsonCache.getInDirectory(directory); if (info) result.push(info); } if (rootPath && rootPath === directory) { return true; } }; forEachAncestorDirectory(getDirectoryPath(fileName), processDirectory); return result; } /** @internal */ getNearestAncestorDirectoryWithPackageJson(fileName) { return forEachAncestorDirectory(fileName, (directory) => { switch (this.packageJsonCache.directoryHasPackageJson(directory)) { case -1 /* True */: return directory; case 0 /* False */: return void 0; case 3 /* Maybe */: return this.host.fileExists(combinePaths(directory, "package.json")) ? directory : void 0; } }); } /** @internal */ watchPnpFile() { const pnpApiPath = getPnpApiPath(__filename); if (!pnpApiPath) { return; } return this.watchFactory.watchFile( pnpApiPath, () => { this.forEachProject((project) => { for (const info of project.getScriptInfos()) { project.resolutionCache.invalidateResolutionOfFile(info.path); } project.markAsDirty(); updateProjectIfDirty(project); }); this.delayEnsureProjectForOpenFiles(); }, 250 /* Low */, this.hostConfiguration.watchOptions, WatchType.ConfigFile ); } /** @internal */ watchPackageJsonFile(file, path, project) { Debug.assert(project !== void 0); let result = (this.packageJsonFilesMap ?? (this.packageJsonFilesMap = /* @__PURE__ */ new Map())).get(path); if (!result) { let watcher = this.watchFactory.watchFile( file, (fileName, eventKind) => { switch (eventKind) { case 0 /* Created */: case 1 /* Changed */: this.packageJsonCache.addOrUpdate(fileName, path); this.onPackageJsonChange(result); break; case 2 /* Deleted */: this.packageJsonCache.delete(path); this.onPackageJsonChange(result); result.projects.clear(); result.close(); } }, 250 /* Low */, this.hostConfiguration.watchOptions, WatchType.PackageJson ); result = { projects: /* @__PURE__ */ new Set(), close: () => { var _a; if (result.projects.size || !watcher) return; watcher.close(); watcher = void 0; (_a = this.packageJsonFilesMap) == null ? void 0 : _a.delete(path); this.packageJsonCache.invalidate(path); } }; this.packageJsonFilesMap.set(path, result); } result.projects.add(project); (project.packageJsonWatches ?? (project.packageJsonWatches = /* @__PURE__ */ new Set())).add(result); } /** @internal */ onPackageJsonChange(result) { result.projects.forEach((project) => { var _a; return (_a = project.onPackageJsonChange) == null ? void 0 : _a.call(project); }); } /** @internal */ includePackageJsonAutoImports() { switch (this.hostConfiguration.preferences.includePackageJsonAutoImports) { case "on": return 1 /* On */; case "off": return 0 /* Off */; default: return 2 /* Auto */; } } /** @internal */ getIncompleteCompletionsCache() { return this.incompleteCompletionsCache || (this.incompleteCompletionsCache = createIncompleteCompletionsCache()); } }; /** Makes a filename safe to insert in a RegExp */ _ProjectService.filenameEscapeRegexp = /[-/\\^$*+?.()|[\]{}]/g; var ProjectService3 = _ProjectService; function createIncompleteCompletionsCache() { let info; return { get() { return info; }, set(newInfo) { info = newInfo; }, clear() { info = void 0; } }; } function isConfigFile(config) { return config.kind !== void 0; } function printProjectWithoutFileNames(project) { project.print( /*writeProjectFileNames*/ false, /*writeFileExplaination*/ false, /*writeFileVersionAndText*/ false ); } // src/server/moduleSpecifierCache.ts function createModuleSpecifierCache(host) { let containedNodeModulesWatchers; let cache; let currentKey; const result = { get(fromFileName, toFileName2, preferences, options) { if (!cache || currentKey !== key(fromFileName, preferences, options)) return void 0; return cache.get(toFileName2); }, set(fromFileName, toFileName2, preferences, options, kind, modulePaths, moduleSpecifiers) { ensureCache(fromFileName, preferences, options).set(toFileName2, createInfo( kind, modulePaths, moduleSpecifiers, /*isBlockedByPackageJsonDependencies*/ false )); if (moduleSpecifiers) { for (const p of modulePaths) { if (p.isInNodeModules) { const nodeModulesPath = p.path.substring(0, p.path.indexOf(nodeModulesPathPart) + nodeModulesPathPart.length - 1); const key2 = host.toPath(nodeModulesPath); if (!(containedNodeModulesWatchers == null ? void 0 : containedNodeModulesWatchers.has(key2))) { (containedNodeModulesWatchers || (containedNodeModulesWatchers = /* @__PURE__ */ new Map())).set( key2, host.watchNodeModulesForPackageJsonChanges(nodeModulesPath) ); } } } } }, setModulePaths(fromFileName, toFileName2, preferences, options, modulePaths) { const cache2 = ensureCache(fromFileName, preferences, options); const info = cache2.get(toFileName2); if (info) { info.modulePaths = modulePaths; } else { cache2.set(toFileName2, createInfo( /*kind*/ void 0, modulePaths, /*moduleSpecifiers*/ void 0, /*isBlockedByPackageJsonDependencies*/ void 0 )); } }, setBlockedByPackageJsonDependencies(fromFileName, toFileName2, preferences, options, isBlockedByPackageJsonDependencies) { const cache2 = ensureCache(fromFileName, preferences, options); const info = cache2.get(toFileName2); if (info) { info.isBlockedByPackageJsonDependencies = isBlockedByPackageJsonDependencies; } else { cache2.set(toFileName2, createInfo( /*kind*/ void 0, /*modulePaths*/ void 0, /*moduleSpecifiers*/ void 0, isBlockedByPackageJsonDependencies )); } }, clear() { containedNodeModulesWatchers == null ? void 0 : containedNodeModulesWatchers.forEach(closeFileWatcher); cache == null ? void 0 : cache.clear(); containedNodeModulesWatchers == null ? void 0 : containedNodeModulesWatchers.clear(); currentKey = void 0; }, count() { return cache ? cache.size : 0; } }; if (Debug.isDebugging) { Object.defineProperty(result, "__cache", { get: () => cache }); } return result; function ensureCache(fromFileName, preferences, options) { const newKey = key(fromFileName, preferences, options); if (cache && currentKey !== newKey) { result.clear(); } currentKey = newKey; return cache || (cache = /* @__PURE__ */ new Map()); } function key(fromFileName, preferences, options) { return `${fromFileName},${preferences.importModuleSpecifierEnding},${preferences.importModuleSpecifierPreference},${options.overrideImportMode}`; } function createInfo(kind, modulePaths, moduleSpecifiers, isBlockedByPackageJsonDependencies) { return { kind, modulePaths, moduleSpecifiers, isBlockedByPackageJsonDependencies }; } } // src/server/packageJsonCache.ts function createPackageJsonCache(host) { const packageJsons = /* @__PURE__ */ new Map(); const directoriesWithoutPackageJson = /* @__PURE__ */ new Map(); return { addOrUpdate, invalidate, delete: (fileName) => { packageJsons.delete(fileName); directoriesWithoutPackageJson.set(getDirectoryPath(fileName), true); }, getInDirectory: (directory) => { return packageJsons.get(host.toPath(combinePaths(directory, "package.json"))) || void 0; }, directoryHasPackageJson: (directory) => directoryHasPackageJson(host.toPath(directory)), searchDirectoryAndAncestors: (directory) => { forEachAncestorDirectory(directory, (ancestor) => { const ancestorPath = host.toPath(ancestor); if (directoryHasPackageJson(ancestorPath) !== 3 /* Maybe */) { return true; } const packageJsonFileName = combinePaths(ancestor, "package.json"); if (tryFileExists(host, packageJsonFileName)) { addOrUpdate(packageJsonFileName, combinePaths(ancestorPath, "package.json")); } else { directoriesWithoutPackageJson.set(ancestorPath, true); } }); } }; function addOrUpdate(fileName, path) { const packageJsonInfo = Debug.checkDefined(createPackageJsonInfo(fileName, host.host)); packageJsons.set(path, packageJsonInfo); directoriesWithoutPackageJson.delete(getDirectoryPath(path)); } function invalidate(path) { packageJsons.delete(path); directoriesWithoutPackageJson.delete(getDirectoryPath(path)); } function directoryHasPackageJson(directory) { return packageJsons.has(combinePaths(directory, "package.json")) ? -1 /* True */ : directoriesWithoutPackageJson.has(directory) ? 0 /* False */ : 3 /* Maybe */; } } // src/server/session.ts var nullCancellationToken = { isCancellationRequested: () => false, setRequest: () => void 0, resetRequest: () => void 0 }; function hrTimeToMilliseconds(time) { const seconds = time[0]; const nanoseconds = time[1]; return (1e9 * seconds + nanoseconds) / 1e6; } function isDeclarationFileInJSOnlyNonConfiguredProject(project, file) { if ((isInferredProject(project) || isExternalProject(project)) && project.isJsOnlyProject()) { const scriptInfo = project.getScriptInfoForNormalizedPath(file); return scriptInfo && !scriptInfo.isJavaScript(); } return false; } function dtsChangeCanAffectEmit(compilationSettings) { return getEmitDeclarations(compilationSettings) || !!compilationSettings.emitDecoratorMetadata; } function formatDiag(fileName, project, diag2) { const scriptInfo = project.getScriptInfoForNormalizedPath(fileName); return { start: scriptInfo.positionToLineOffset(diag2.start), end: scriptInfo.positionToLineOffset(diag2.start + diag2.length), // TODO: GH#18217 text: flattenDiagnosticMessageText(diag2.messageText, "\n"), code: diag2.code, category: diagnosticCategoryName(diag2), reportsUnnecessary: diag2.reportsUnnecessary, reportsDeprecated: diag2.reportsDeprecated, source: diag2.source, relatedInformation: map(diag2.relatedInformation, formatRelatedInformation) }; } function formatRelatedInformation(info) { if (!info.file) { return { message: flattenDiagnosticMessageText(info.messageText, "\n"), category: diagnosticCategoryName(info), code: info.code }; } return { span: { start: convertToLocation(getLineAndCharacterOfPosition(info.file, info.start)), end: convertToLocation(getLineAndCharacterOfPosition(info.file, info.start + info.length)), // TODO: GH#18217 file: info.file.fileName }, message: flattenDiagnosticMessageText(info.messageText, "\n"), category: diagnosticCategoryName(info), code: info.code }; } function convertToLocation(lineAndCharacter) { return { line: lineAndCharacter.line + 1, offset: lineAndCharacter.character + 1 }; } function formatDiagnosticToProtocol(diag2, includeFileName) { const start = diag2.file && convertToLocation(getLineAndCharacterOfPosition(diag2.file, diag2.start)); const end = diag2.file && convertToLocation(getLineAndCharacterOfPosition(diag2.file, diag2.start + diag2.length)); const text = flattenDiagnosticMessageText(diag2.messageText, "\n"); const { code, source } = diag2; const category = diagnosticCategoryName(diag2); const common = { start, end, text, code, category, reportsUnnecessary: diag2.reportsUnnecessary, reportsDeprecated: diag2.reportsDeprecated, source, relatedInformation: map(diag2.relatedInformation, formatRelatedInformation) }; return includeFileName ? { ...common, fileName: diag2.file && diag2.file.fileName } : common; } function allEditsBeforePos(edits, pos) { return edits.every((edit) => textSpanEnd(edit.span) < pos); } var CommandNames = CommandTypes; function formatMessage2(msg, logger, byteLength, newLine) { const verboseLogging = logger.hasLevel(3 /* verbose */); const json = JSON.stringify(msg); if (verboseLogging) { logger.info(`${msg.type}:${stringifyIndented(msg)}`); } const len = byteLength(json, "utf8"); return `Content-Length: ${1 + len}\r \r ${json}${newLine}`; } var MultistepOperation = class { constructor(operationHost) { this.operationHost = operationHost; } startNew(action) { this.complete(); this.requestId = this.operationHost.getCurrentRequestId(); this.executeAction(action); } complete() { if (this.requestId !== void 0) { this.operationHost.sendRequestCompletedEvent(this.requestId); this.requestId = void 0; } this.setTimerHandle(void 0); this.setImmediateId(void 0); } immediate(actionType, action) { const requestId = this.requestId; Debug.assert(requestId === this.operationHost.getCurrentRequestId(), "immediate: incorrect request id"); this.setImmediateId( this.operationHost.getServerHost().setImmediate(() => { this.immediateId = void 0; this.operationHost.executeWithRequestId(requestId, () => this.executeAction(action)); }, actionType) ); } delay(actionType, ms, action) { const requestId = this.requestId; Debug.assert(requestId === this.operationHost.getCurrentRequestId(), "delay: incorrect request id"); this.setTimerHandle( this.operationHost.getServerHost().setTimeout( () => { this.timerHandle = void 0; this.operationHost.executeWithRequestId(requestId, () => this.executeAction(action)); }, ms, actionType ) ); } executeAction(action) { var _a, _b, _c, _d, _e, _f; let stop = false; try { if (this.operationHost.isCancellationRequested()) { stop = true; (_a = tracing) == null ? void 0 : _a.instant(tracing.Phase.Session, "stepCanceled", { seq: this.requestId, early: true }); } else { (_b = tracing) == null ? void 0 : _b.push(tracing.Phase.Session, "stepAction", { seq: this.requestId }); action(this); (_c = tracing) == null ? void 0 : _c.pop(); } } catch (e) { (_d = tracing) == null ? void 0 : _d.popAll(); stop = true; if (e instanceof OperationCanceledException) { (_e = tracing) == null ? void 0 : _e.instant(tracing.Phase.Session, "stepCanceled", { seq: this.requestId }); } else { (_f = tracing) == null ? void 0 : _f.instant(tracing.Phase.Session, "stepError", { seq: this.requestId, message: e.message }); this.operationHost.logError(e, `delayed processing of request ${this.requestId}`); } } if (stop || !this.hasPendingWork()) { this.complete(); } } setTimerHandle(timerHandle) { if (this.timerHandle !== void 0) { this.operationHost.getServerHost().clearTimeout(this.timerHandle); } this.timerHandle = timerHandle; } setImmediateId(immediateId) { if (this.immediateId !== void 0) { this.operationHost.getServerHost().clearImmediate(this.immediateId); } this.immediateId = immediateId; } hasPendingWork() { return !!this.timerHandle || !!this.immediateId; } }; function toEvent(eventName, body) { return { seq: 0, type: "event", event: eventName, body }; } function combineProjectOutput(defaultValue, getValue, projects, action) { const outputs = flatMapToMutable(isArray(projects) ? projects : projects.projects, (project) => action(project, defaultValue)); if (!isArray(projects) && projects.symLinkedProjects) { projects.symLinkedProjects.forEach((projects2, path) => { const value = getValue(path); outputs.push(...flatMap(projects2, (project) => action(project, value))); }); } return deduplicate(outputs, equateValues); } function createDocumentSpanSet(useCaseSensitiveFileNames2) { return createSet(({ textSpan }) => textSpan.start + 100003 * textSpan.length, getDocumentSpansEqualityComparer(useCaseSensitiveFileNames2)); } function getRenameLocationsWorker(projects, defaultProject, initialLocation, findInStrings, findInComments, preferences, useCaseSensitiveFileNames2) { const perProjectResults = getPerProjectReferences( projects, defaultProject, initialLocation, /*isForRename*/ true, (project, position) => project.getLanguageService().findRenameLocations(position.fileName, position.pos, findInStrings, findInComments, preferences), (renameLocation, cb) => cb(documentSpanLocation(renameLocation)) ); if (isArray(perProjectResults)) { return perProjectResults; } const results = []; const seen = createDocumentSpanSet(useCaseSensitiveFileNames2); perProjectResults.forEach((projectResults, project) => { for (const result of projectResults) { if (!seen.has(result) && !getMappedLocationForProject(documentSpanLocation(result), project)) { results.push(result); seen.add(result); } } }); return results; } function getDefinitionLocation(defaultProject, initialLocation, isForRename) { const infos = defaultProject.getLanguageService().getDefinitionAtPosition( initialLocation.fileName, initialLocation.pos, /*searchOtherFilesOnly*/ false, /*stopAtAlias*/ isForRename ); const info = infos && firstOrUndefined(infos); return info && !info.isLocal ? { fileName: info.fileName, pos: info.textSpan.start } : void 0; } function getReferencesWorker(projects, defaultProject, initialLocation, useCaseSensitiveFileNames2, logger) { var _a, _b; const perProjectResults = getPerProjectReferences( projects, defaultProject, initialLocation, /*isForRename*/ false, (project, position) => { logger.info(`Finding references to ${position.fileName} position ${position.pos} in project ${project.getProjectName()}`); return project.getLanguageService().findReferences(position.fileName, position.pos); }, (referencedSymbol, cb) => { cb(documentSpanLocation(referencedSymbol.definition)); for (const ref of referencedSymbol.references) { cb(documentSpanLocation(ref)); } } ); if (isArray(perProjectResults)) { return perProjectResults; } const defaultProjectResults = perProjectResults.get(defaultProject); if (((_b = (_a = defaultProjectResults == null ? void 0 : defaultProjectResults[0]) == null ? void 0 : _a.references[0]) == null ? void 0 : _b.isDefinition) === void 0) { perProjectResults.forEach((projectResults) => { for (const referencedSymbol of projectResults) { for (const ref of referencedSymbol.references) { delete ref.isDefinition; } } }); } else { const knownSymbolSpans = createDocumentSpanSet(useCaseSensitiveFileNames2); for (const referencedSymbol of defaultProjectResults) { for (const ref of referencedSymbol.references) { if (ref.isDefinition) { knownSymbolSpans.add(ref); break; } } } const updatedProjects = /* @__PURE__ */ new Set(); while (true) { let progress = false; perProjectResults.forEach((referencedSymbols, project) => { if (updatedProjects.has(project)) return; const updated = project.getLanguageService().updateIsDefinitionOfReferencedSymbols(referencedSymbols, knownSymbolSpans); if (updated) { updatedProjects.add(project); progress = true; } }); if (!progress) break; } perProjectResults.forEach((referencedSymbols, project) => { if (updatedProjects.has(project)) return; for (const referencedSymbol of referencedSymbols) { for (const ref of referencedSymbol.references) { ref.isDefinition = false; } } }); } const results = []; const seenRefs = createDocumentSpanSet(useCaseSensitiveFileNames2); perProjectResults.forEach((projectResults, project) => { for (const referencedSymbol of projectResults) { const mappedDefinitionFile = getMappedLocationForProject(documentSpanLocation(referencedSymbol.definition), project); const definition = mappedDefinitionFile === void 0 ? referencedSymbol.definition : { ...referencedSymbol.definition, textSpan: createTextSpan(mappedDefinitionFile.pos, referencedSymbol.definition.textSpan.length), // Why would the length be the same in the original? fileName: mappedDefinitionFile.fileName, contextSpan: getMappedContextSpanForProject(referencedSymbol.definition, project) }; let symbolToAddTo = find(results, (o) => documentSpansEqual(o.definition, definition, useCaseSensitiveFileNames2)); if (!symbolToAddTo) { symbolToAddTo = { definition, references: [] }; results.push(symbolToAddTo); } for (const ref of referencedSymbol.references) { if (!seenRefs.has(ref) && !getMappedLocationForProject(documentSpanLocation(ref), project)) { seenRefs.add(ref); symbolToAddTo.references.push(ref); } } } }); return results.filter((o) => o.references.length !== 0); } function forEachProjectInProjects(projects, path, cb) { for (const project of isArray(projects) ? projects : projects.projects) { cb(project, path); } if (!isArray(projects) && projects.symLinkedProjects) { projects.symLinkedProjects.forEach((symlinkedProjects, symlinkedPath) => { for (const project of symlinkedProjects) { cb(project, symlinkedPath); } }); } } function getPerProjectReferences(projects, defaultProject, initialLocation, isForRename, getResultsForPosition, forPositionInResult) { const resultsMap = /* @__PURE__ */ new Map(); const queue = createQueue(); queue.enqueue({ project: defaultProject, location: initialLocation }); forEachProjectInProjects(projects, initialLocation.fileName, (project, path) => { const location = { fileName: path, pos: initialLocation.pos }; queue.enqueue({ project, location }); }); const projectService = defaultProject.projectService; const cancellationToken = defaultProject.getCancellationToken(); const defaultDefinition = getDefinitionLocation(defaultProject, initialLocation, isForRename); const getGeneratedDefinition = memoize( () => defaultProject.isSourceOfProjectReferenceRedirect(defaultDefinition.fileName) ? defaultDefinition : defaultProject.getLanguageService().getSourceMapper().tryGetGeneratedPosition(defaultDefinition) ); const getSourceDefinition = memoize( () => defaultProject.isSourceOfProjectReferenceRedirect(defaultDefinition.fileName) ? defaultDefinition : defaultProject.getLanguageService().getSourceMapper().tryGetSourcePosition(defaultDefinition) ); const searchedProjectKeys = /* @__PURE__ */ new Set(); onCancellation: while (!queue.isEmpty()) { while (!queue.isEmpty()) { if (cancellationToken.isCancellationRequested()) break onCancellation; const { project, location } = queue.dequeue(); if (resultsMap.has(project)) continue; if (isLocationProjectReferenceRedirect(project, location)) continue; updateProjectIfDirty(project); if (!project.containsFile(toNormalizedPath(location.fileName))) { continue; } const projectResults = searchPosition(project, location); resultsMap.set(project, projectResults ?? emptyArray2); searchedProjectKeys.add(getProjectKey(project)); } if (defaultDefinition) { projectService.loadAncestorProjectTree(searchedProjectKeys); projectService.forEachEnabledProject((project) => { if (cancellationToken.isCancellationRequested()) return; if (resultsMap.has(project)) return; const location = mapDefinitionInProject(defaultDefinition, project, getGeneratedDefinition, getSourceDefinition); if (location) { queue.enqueue({ project, location }); } }); } } if (resultsMap.size === 1) { return firstIterator(resultsMap.values()); } return resultsMap; function searchPosition(project, location) { const projectResults = getResultsForPosition(project, location); if (!projectResults) return void 0; for (const result of projectResults) { forPositionInResult(result, (position) => { const originalLocation = projectService.getOriginalLocationEnsuringConfiguredProject(project, position); if (!originalLocation) return; const originalScriptInfo = projectService.getScriptInfo(originalLocation.fileName); for (const project2 of originalScriptInfo.containingProjects) { if (!project2.isOrphan() && !resultsMap.has(project2)) { queue.enqueue({ project: project2, location: originalLocation }); } } const symlinkedProjectsMap = projectService.getSymlinkedProjects(originalScriptInfo); if (symlinkedProjectsMap) { symlinkedProjectsMap.forEach((symlinkedProjects, symlinkedPath) => { for (const symlinkedProject of symlinkedProjects) { if (!symlinkedProject.isOrphan() && !resultsMap.has(symlinkedProject)) { queue.enqueue({ project: symlinkedProject, location: { fileName: symlinkedPath, pos: originalLocation.pos } }); } } }); } }); } return projectResults; } } function mapDefinitionInProject(definition, project, getGeneratedDefinition, getSourceDefinition) { if (project.containsFile(toNormalizedPath(definition.fileName)) && !isLocationProjectReferenceRedirect(project, definition)) { return definition; } const generatedDefinition = getGeneratedDefinition(); if (generatedDefinition && project.containsFile(toNormalizedPath(generatedDefinition.fileName))) return generatedDefinition; const sourceDefinition = getSourceDefinition(); return sourceDefinition && project.containsFile(toNormalizedPath(sourceDefinition.fileName)) ? sourceDefinition : void 0; } function isLocationProjectReferenceRedirect(project, location) { if (!location) return false; const program = project.getLanguageService().getProgram(); if (!program) return false; const sourceFile = program.getSourceFile(location.fileName); return !!sourceFile && sourceFile.resolvedPath !== sourceFile.path && sourceFile.resolvedPath !== project.toPath(location.fileName); } function getProjectKey(project) { return isConfiguredProject(project) ? project.canonicalConfigFilePath : project.getProjectName(); } function documentSpanLocation({ fileName, textSpan }) { return { fileName, pos: textSpan.start }; } function getMappedLocationForProject(location, project) { return getMappedLocation(location, project.getSourceMapper(), (p) => project.projectService.fileExists(p)); } function getMappedDocumentSpanForProject(documentSpan, project) { return getMappedDocumentSpan(documentSpan, project.getSourceMapper(), (p) => project.projectService.fileExists(p)); } function getMappedContextSpanForProject(documentSpan, project) { return getMappedContextSpan(documentSpan, project.getSourceMapper(), (p) => project.projectService.fileExists(p)); } var invalidPartialSemanticModeCommands = [ "openExternalProject" /* OpenExternalProject */, "openExternalProjects" /* OpenExternalProjects */, "closeExternalProject" /* CloseExternalProject */, "synchronizeProjectList" /* SynchronizeProjectList */, "emit-output" /* EmitOutput */, "compileOnSaveAffectedFileList" /* CompileOnSaveAffectedFileList */, "compileOnSaveEmitFile" /* CompileOnSaveEmitFile */, "compilerOptionsDiagnostics-full" /* CompilerOptionsDiagnosticsFull */, "encodedSemanticClassifications-full" /* EncodedSemanticClassificationsFull */, "semanticDiagnosticsSync" /* SemanticDiagnosticsSync */, "suggestionDiagnosticsSync" /* SuggestionDiagnosticsSync */, "geterrForProject" /* GeterrForProject */, "reload" /* Reload */, "reloadProjects" /* ReloadProjects */, "getCodeFixes" /* GetCodeFixes */, "getCodeFixes-full" /* GetCodeFixesFull */, "getCombinedCodeFix" /* GetCombinedCodeFix */, "getCombinedCodeFix-full" /* GetCombinedCodeFixFull */, "applyCodeActionCommand" /* ApplyCodeActionCommand */, "getSupportedCodeFixes" /* GetSupportedCodeFixes */, "getApplicableRefactors" /* GetApplicableRefactors */, "getMoveToRefactoringFileSuggestions" /* GetMoveToRefactoringFileSuggestions */, "getEditsForRefactor" /* GetEditsForRefactor */, "getEditsForRefactor-full" /* GetEditsForRefactorFull */, "organizeImports" /* OrganizeImports */, "organizeImports-full" /* OrganizeImportsFull */, "getEditsForFileRename" /* GetEditsForFileRename */, "getEditsForFileRename-full" /* GetEditsForFileRenameFull */, "prepareCallHierarchy" /* PrepareCallHierarchy */, "provideCallHierarchyIncomingCalls" /* ProvideCallHierarchyIncomingCalls */, "provideCallHierarchyOutgoingCalls" /* ProvideCallHierarchyOutgoingCalls */, "getPasteEdits" /* GetPasteEdits */ ]; var invalidSyntacticModeCommands = [ ...invalidPartialSemanticModeCommands, "definition" /* Definition */, "definition-full" /* DefinitionFull */, "definitionAndBoundSpan" /* DefinitionAndBoundSpan */, "definitionAndBoundSpan-full" /* DefinitionAndBoundSpanFull */, "typeDefinition" /* TypeDefinition */, "implementation" /* Implementation */, "implementation-full" /* ImplementationFull */, "references" /* References */, "references-full" /* ReferencesFull */, "rename" /* Rename */, "renameLocations-full" /* RenameLocationsFull */, "rename-full" /* RenameInfoFull */, "quickinfo" /* Quickinfo */, "quickinfo-full" /* QuickinfoFull */, "completionInfo" /* CompletionInfo */, "completions" /* Completions */, "completions-full" /* CompletionsFull */, "completionEntryDetails" /* CompletionDetails */, "completionEntryDetails-full" /* CompletionDetailsFull */, "signatureHelp" /* SignatureHelp */, "signatureHelp-full" /* SignatureHelpFull */, "navto" /* Navto */, "navto-full" /* NavtoFull */, "documentHighlights" /* DocumentHighlights */, "documentHighlights-full" /* DocumentHighlightsFull */ ]; var Session3 = class _Session { constructor(opts) { this.changeSeq = 0; this.handlers = new Map(Object.entries({ // TODO(jakebailey): correctly type the handlers ["status" /* Status */]: () => { const response = { version }; return this.requiredResponse(response); }, ["openExternalProject" /* OpenExternalProject */]: (request) => { this.projectService.openExternalProject( request.arguments, /*cleanupAfter*/ true ); return this.requiredResponse( /*response*/ true ); }, ["openExternalProjects" /* OpenExternalProjects */]: (request) => { this.projectService.openExternalProjects(request.arguments.projects); return this.requiredResponse( /*response*/ true ); }, ["closeExternalProject" /* CloseExternalProject */]: (request) => { this.projectService.closeExternalProject( request.arguments.projectFileName, /*cleanupAfter*/ true ); return this.requiredResponse( /*response*/ true ); }, ["synchronizeProjectList" /* SynchronizeProjectList */]: (request) => { const result = this.projectService.synchronizeProjectList(request.arguments.knownProjects, request.arguments.includeProjectReferenceRedirectInfo); if (!result.some((p) => p.projectErrors && p.projectErrors.length !== 0)) { return this.requiredResponse(result); } const converted = map(result, (p) => { if (!p.projectErrors || p.projectErrors.length === 0) { return p; } return { info: p.info, changes: p.changes, files: p.files, projectErrors: this.convertToDiagnosticsWithLinePosition( p.projectErrors, /*scriptInfo*/ void 0 ) }; }); return this.requiredResponse(converted); }, ["updateOpen" /* UpdateOpen */]: (request) => { this.changeSeq++; this.projectService.applyChangesInOpenFiles( request.arguments.openFiles && mapIterator(request.arguments.openFiles, (file) => ({ fileName: file.file, content: file.fileContent, scriptKind: file.scriptKindName, projectRootPath: file.projectRootPath })), request.arguments.changedFiles && mapIterator(request.arguments.changedFiles, (file) => ({ fileName: file.fileName, changes: mapDefinedIterator(arrayReverseIterator(file.textChanges), (change) => { const scriptInfo = Debug.checkDefined(this.projectService.getScriptInfo(file.fileName)); const start = scriptInfo.lineOffsetToPosition(change.start.line, change.start.offset); const end = scriptInfo.lineOffsetToPosition(change.end.line, change.end.offset); return start >= 0 ? { span: { start, length: end - start }, newText: change.newText } : void 0; }) })), request.arguments.closedFiles ); return this.requiredResponse( /*response*/ true ); }, ["applyChangedToOpenFiles" /* ApplyChangedToOpenFiles */]: (request) => { this.changeSeq++; this.projectService.applyChangesInOpenFiles( request.arguments.openFiles, request.arguments.changedFiles && mapIterator(request.arguments.changedFiles, (file) => ({ fileName: file.fileName, // apply changes in reverse order changes: arrayReverseIterator(file.changes) })), request.arguments.closedFiles ); return this.requiredResponse( /*response*/ true ); }, ["exit" /* Exit */]: () => { this.exit(); return this.notRequired(); }, ["definition" /* Definition */]: (request) => { return this.requiredResponse(this.getDefinition( request.arguments, /*simplifiedResult*/ true )); }, ["definition-full" /* DefinitionFull */]: (request) => { return this.requiredResponse(this.getDefinition( request.arguments, /*simplifiedResult*/ false )); }, ["definitionAndBoundSpan" /* DefinitionAndBoundSpan */]: (request) => { return this.requiredResponse(this.getDefinitionAndBoundSpan( request.arguments, /*simplifiedResult*/ true )); }, ["definitionAndBoundSpan-full" /* DefinitionAndBoundSpanFull */]: (request) => { return this.requiredResponse(this.getDefinitionAndBoundSpan( request.arguments, /*simplifiedResult*/ false )); }, ["findSourceDefinition" /* FindSourceDefinition */]: (request) => { return this.requiredResponse(this.findSourceDefinition(request.arguments)); }, ["emit-output" /* EmitOutput */]: (request) => { return this.requiredResponse(this.getEmitOutput(request.arguments)); }, ["typeDefinition" /* TypeDefinition */]: (request) => { return this.requiredResponse(this.getTypeDefinition(request.arguments)); }, ["implementation" /* Implementation */]: (request) => { return this.requiredResponse(this.getImplementation( request.arguments, /*simplifiedResult*/ true )); }, ["implementation-full" /* ImplementationFull */]: (request) => { return this.requiredResponse(this.getImplementation( request.arguments, /*simplifiedResult*/ false )); }, ["references" /* References */]: (request) => { return this.requiredResponse(this.getReferences( request.arguments, /*simplifiedResult*/ true )); }, ["references-full" /* ReferencesFull */]: (request) => { return this.requiredResponse(this.getReferences( request.arguments, /*simplifiedResult*/ false )); }, ["rename" /* Rename */]: (request) => { return this.requiredResponse(this.getRenameLocations( request.arguments, /*simplifiedResult*/ true )); }, ["renameLocations-full" /* RenameLocationsFull */]: (request) => { return this.requiredResponse(this.getRenameLocations( request.arguments, /*simplifiedResult*/ false )); }, ["rename-full" /* RenameInfoFull */]: (request) => { return this.requiredResponse(this.getRenameInfo(request.arguments)); }, ["open" /* Open */]: (request) => { this.openClientFile( toNormalizedPath(request.arguments.file), request.arguments.fileContent, convertScriptKindName(request.arguments.scriptKindName), // TODO: GH#18217 request.arguments.projectRootPath ? toNormalizedPath(request.arguments.projectRootPath) : void 0 ); return this.notRequired(); }, ["quickinfo" /* Quickinfo */]: (request) => { return this.requiredResponse(this.getQuickInfoWorker( request.arguments, /*simplifiedResult*/ true )); }, ["quickinfo-full" /* QuickinfoFull */]: (request) => { return this.requiredResponse(this.getQuickInfoWorker( request.arguments, /*simplifiedResult*/ false )); }, ["getOutliningSpans" /* GetOutliningSpans */]: (request) => { return this.requiredResponse(this.getOutliningSpans( request.arguments, /*simplifiedResult*/ true )); }, ["outliningSpans" /* GetOutliningSpansFull */]: (request) => { return this.requiredResponse(this.getOutliningSpans( request.arguments, /*simplifiedResult*/ false )); }, ["todoComments" /* TodoComments */]: (request) => { return this.requiredResponse(this.getTodoComments(request.arguments)); }, ["indentation" /* Indentation */]: (request) => { return this.requiredResponse(this.getIndentation(request.arguments)); }, ["nameOrDottedNameSpan" /* NameOrDottedNameSpan */]: (request) => { return this.requiredResponse(this.getNameOrDottedNameSpan(request.arguments)); }, ["breakpointStatement" /* BreakpointStatement */]: (request) => { return this.requiredResponse(this.getBreakpointStatement(request.arguments)); }, ["braceCompletion" /* BraceCompletion */]: (request) => { return this.requiredResponse(this.isValidBraceCompletion(request.arguments)); }, ["docCommentTemplate" /* DocCommentTemplate */]: (request) => { return this.requiredResponse(this.getDocCommentTemplate(request.arguments)); }, ["getSpanOfEnclosingComment" /* GetSpanOfEnclosingComment */]: (request) => { return this.requiredResponse(this.getSpanOfEnclosingComment(request.arguments)); }, ["fileReferences" /* FileReferences */]: (request) => { return this.requiredResponse(this.getFileReferences( request.arguments, /*simplifiedResult*/ true )); }, ["fileReferences-full" /* FileReferencesFull */]: (request) => { return this.requiredResponse(this.getFileReferences( request.arguments, /*simplifiedResult*/ false )); }, ["format" /* Format */]: (request) => { return this.requiredResponse(this.getFormattingEditsForRange(request.arguments)); }, ["formatonkey" /* Formatonkey */]: (request) => { return this.requiredResponse(this.getFormattingEditsAfterKeystroke(request.arguments)); }, ["format-full" /* FormatFull */]: (request) => { return this.requiredResponse(this.getFormattingEditsForDocumentFull(request.arguments)); }, ["formatonkey-full" /* FormatonkeyFull */]: (request) => { return this.requiredResponse(this.getFormattingEditsAfterKeystrokeFull(request.arguments)); }, ["formatRange-full" /* FormatRangeFull */]: (request) => { return this.requiredResponse(this.getFormattingEditsForRangeFull(request.arguments)); }, ["completionInfo" /* CompletionInfo */]: (request) => { return this.requiredResponse(this.getCompletions(request.arguments, "completionInfo" /* CompletionInfo */)); }, ["completions" /* Completions */]: (request) => { return this.requiredResponse(this.getCompletions(request.arguments, "completions" /* Completions */)); }, ["completions-full" /* CompletionsFull */]: (request) => { return this.requiredResponse(this.getCompletions(request.arguments, "completions-full" /* CompletionsFull */)); }, ["completionEntryDetails" /* CompletionDetails */]: (request) => { return this.requiredResponse(this.getCompletionEntryDetails( request.arguments, /*fullResult*/ false )); }, ["completionEntryDetails-full" /* CompletionDetailsFull */]: (request) => { return this.requiredResponse(this.getCompletionEntryDetails( request.arguments, /*fullResult*/ true )); }, ["compileOnSaveAffectedFileList" /* CompileOnSaveAffectedFileList */]: (request) => { return this.requiredResponse(this.getCompileOnSaveAffectedFileList(request.arguments)); }, ["compileOnSaveEmitFile" /* CompileOnSaveEmitFile */]: (request) => { return this.requiredResponse(this.emitFile(request.arguments)); }, ["signatureHelp" /* SignatureHelp */]: (request) => { return this.requiredResponse(this.getSignatureHelpItems( request.arguments, /*simplifiedResult*/ true )); }, ["signatureHelp-full" /* SignatureHelpFull */]: (request) => { return this.requiredResponse(this.getSignatureHelpItems( request.arguments, /*simplifiedResult*/ false )); }, ["compilerOptionsDiagnostics-full" /* CompilerOptionsDiagnosticsFull */]: (request) => { return this.requiredResponse(this.getCompilerOptionsDiagnostics(request.arguments)); }, ["encodedSyntacticClassifications-full" /* EncodedSyntacticClassificationsFull */]: (request) => { return this.requiredResponse(this.getEncodedSyntacticClassifications(request.arguments)); }, ["encodedSemanticClassifications-full" /* EncodedSemanticClassificationsFull */]: (request) => { return this.requiredResponse(this.getEncodedSemanticClassifications(request.arguments)); }, ["cleanup" /* Cleanup */]: () => { this.cleanup(); return this.requiredResponse( /*response*/ true ); }, ["semanticDiagnosticsSync" /* SemanticDiagnosticsSync */]: (request) => { return this.requiredResponse(this.getSemanticDiagnosticsSync(request.arguments)); }, ["syntacticDiagnosticsSync" /* SyntacticDiagnosticsSync */]: (request) => { return this.requiredResponse(this.getSyntacticDiagnosticsSync(request.arguments)); }, ["suggestionDiagnosticsSync" /* SuggestionDiagnosticsSync */]: (request) => { return this.requiredResponse(this.getSuggestionDiagnosticsSync(request.arguments)); }, ["geterr" /* Geterr */]: (request) => { this.errorCheck.startNew((next) => this.getDiagnostics(next, request.arguments.delay, request.arguments.files)); return this.notRequired(); }, ["geterrForProject" /* GeterrForProject */]: (request) => { this.errorCheck.startNew((next) => this.getDiagnosticsForProject(next, request.arguments.delay, request.arguments.file)); return this.notRequired(); }, ["change" /* Change */]: (request) => { this.change(request.arguments); return this.notRequired(); }, ["configure" /* Configure */]: (request) => { this.projectService.setHostConfiguration(request.arguments); this.doOutput( /*info*/ void 0, "configure" /* Configure */, request.seq, /*success*/ true ); return this.notRequired(); }, ["reload" /* Reload */]: (request) => { this.reload(request.arguments, request.seq); return this.requiredResponse({ reloadFinished: true }); }, ["saveto" /* Saveto */]: (request) => { const savetoArgs = request.arguments; this.saveToTmp(savetoArgs.file, savetoArgs.tmpfile); return this.notRequired(); }, ["close" /* Close */]: (request) => { const closeArgs = request.arguments; this.closeClientFile(closeArgs.file); return this.notRequired(); }, ["navto" /* Navto */]: (request) => { return this.requiredResponse(this.getNavigateToItems( request.arguments, /*simplifiedResult*/ true )); }, ["navto-full" /* NavtoFull */]: (request) => { return this.requiredResponse(this.getNavigateToItems( request.arguments, /*simplifiedResult*/ false )); }, ["brace" /* Brace */]: (request) => { return this.requiredResponse(this.getBraceMatching( request.arguments, /*simplifiedResult*/ true )); }, ["brace-full" /* BraceFull */]: (request) => { return this.requiredResponse(this.getBraceMatching( request.arguments, /*simplifiedResult*/ false )); }, ["navbar" /* NavBar */]: (request) => { return this.requiredResponse(this.getNavigationBarItems( request.arguments, /*simplifiedResult*/ true )); }, ["navbar-full" /* NavBarFull */]: (request) => { return this.requiredResponse(this.getNavigationBarItems( request.arguments, /*simplifiedResult*/ false )); }, ["navtree" /* NavTree */]: (request) => { return this.requiredResponse(this.getNavigationTree( request.arguments, /*simplifiedResult*/ true )); }, ["navtree-full" /* NavTreeFull */]: (request) => { return this.requiredResponse(this.getNavigationTree( request.arguments, /*simplifiedResult*/ false )); }, ["documentHighlights" /* DocumentHighlights */]: (request) => { return this.requiredResponse(this.getDocumentHighlights( request.arguments, /*simplifiedResult*/ true )); }, ["documentHighlights-full" /* DocumentHighlightsFull */]: (request) => { return this.requiredResponse(this.getDocumentHighlights( request.arguments, /*simplifiedResult*/ false )); }, ["compilerOptionsForInferredProjects" /* CompilerOptionsForInferredProjects */]: (request) => { this.setCompilerOptionsForInferredProjects(request.arguments); return this.requiredResponse( /*response*/ true ); }, ["projectInfo" /* ProjectInfo */]: (request) => { return this.requiredResponse(this.getProjectInfo(request.arguments)); }, ["reloadProjects" /* ReloadProjects */]: () => { this.projectService.reloadProjects(); return this.notRequired(); }, ["jsxClosingTag" /* JsxClosingTag */]: (request) => { return this.requiredResponse(this.getJsxClosingTag(request.arguments)); }, ["linkedEditingRange" /* LinkedEditingRange */]: (request) => { return this.requiredResponse(this.getLinkedEditingRange(request.arguments)); }, ["getCodeFixes" /* GetCodeFixes */]: (request) => { return this.requiredResponse(this.getCodeFixes( request.arguments, /*simplifiedResult*/ true )); }, ["getCodeFixes-full" /* GetCodeFixesFull */]: (request) => { return this.requiredResponse(this.getCodeFixes( request.arguments, /*simplifiedResult*/ false )); }, ["getCombinedCodeFix" /* GetCombinedCodeFix */]: (request) => { return this.requiredResponse(this.getCombinedCodeFix( request.arguments, /*simplifiedResult*/ true )); }, ["getCombinedCodeFix-full" /* GetCombinedCodeFixFull */]: (request) => { return this.requiredResponse(this.getCombinedCodeFix( request.arguments, /*simplifiedResult*/ false )); }, ["applyCodeActionCommand" /* ApplyCodeActionCommand */]: (request) => { return this.requiredResponse(this.applyCodeActionCommand(request.arguments)); }, ["getSupportedCodeFixes" /* GetSupportedCodeFixes */]: (request) => { return this.requiredResponse(this.getSupportedCodeFixes(request.arguments)); }, ["getApplicableRefactors" /* GetApplicableRefactors */]: (request) => { return this.requiredResponse(this.getApplicableRefactors(request.arguments)); }, ["getEditsForRefactor" /* GetEditsForRefactor */]: (request) => { return this.requiredResponse(this.getEditsForRefactor( request.arguments, /*simplifiedResult*/ true )); }, ["getMoveToRefactoringFileSuggestions" /* GetMoveToRefactoringFileSuggestions */]: (request) => { return this.requiredResponse(this.getMoveToRefactoringFileSuggestions(request.arguments)); }, ["getPasteEdits" /* GetPasteEdits */]: (request) => { return this.requiredResponse(this.getPasteEdits(request.arguments)); }, ["getEditsForRefactor-full" /* GetEditsForRefactorFull */]: (request) => { return this.requiredResponse(this.getEditsForRefactor( request.arguments, /*simplifiedResult*/ false )); }, ["organizeImports" /* OrganizeImports */]: (request) => { return this.requiredResponse(this.organizeImports( request.arguments, /*simplifiedResult*/ true )); }, ["organizeImports-full" /* OrganizeImportsFull */]: (request) => { return this.requiredResponse(this.organizeImports( request.arguments, /*simplifiedResult*/ false )); }, ["getEditsForFileRename" /* GetEditsForFileRename */]: (request) => { return this.requiredResponse(this.getEditsForFileRename( request.arguments, /*simplifiedResult*/ true )); }, ["getEditsForFileRename-full" /* GetEditsForFileRenameFull */]: (request) => { return this.requiredResponse(this.getEditsForFileRename( request.arguments, /*simplifiedResult*/ false )); }, ["configurePlugin" /* ConfigurePlugin */]: (request) => { this.configurePlugin(request.arguments); this.doOutput( /*info*/ void 0, "configurePlugin" /* ConfigurePlugin */, request.seq, /*success*/ true ); return this.notRequired(); }, ["selectionRange" /* SelectionRange */]: (request) => { return this.requiredResponse(this.getSmartSelectionRange( request.arguments, /*simplifiedResult*/ true )); }, ["selectionRange-full" /* SelectionRangeFull */]: (request) => { return this.requiredResponse(this.getSmartSelectionRange( request.arguments, /*simplifiedResult*/ false )); }, ["prepareCallHierarchy" /* PrepareCallHierarchy */]: (request) => { return this.requiredResponse(this.prepareCallHierarchy(request.arguments)); }, ["provideCallHierarchyIncomingCalls" /* ProvideCallHierarchyIncomingCalls */]: (request) => { return this.requiredResponse(this.provideCallHierarchyIncomingCalls(request.arguments)); }, ["provideCallHierarchyOutgoingCalls" /* ProvideCallHierarchyOutgoingCalls */]: (request) => { return this.requiredResponse(this.provideCallHierarchyOutgoingCalls(request.arguments)); }, ["toggleLineComment" /* ToggleLineComment */]: (request) => { return this.requiredResponse(this.toggleLineComment( request.arguments, /*simplifiedResult*/ true )); }, ["toggleLineComment-full" /* ToggleLineCommentFull */]: (request) => { return this.requiredResponse(this.toggleLineComment( request.arguments, /*simplifiedResult*/ false )); }, ["toggleMultilineComment" /* ToggleMultilineComment */]: (request) => { return this.requiredResponse(this.toggleMultilineComment( request.arguments, /*simplifiedResult*/ true )); }, ["toggleMultilineComment-full" /* ToggleMultilineCommentFull */]: (request) => { return this.requiredResponse(this.toggleMultilineComment( request.arguments, /*simplifiedResult*/ false )); }, ["commentSelection" /* CommentSelection */]: (request) => { return this.requiredResponse(this.commentSelection( request.arguments, /*simplifiedResult*/ true )); }, ["commentSelection-full" /* CommentSelectionFull */]: (request) => { return this.requiredResponse(this.commentSelection( request.arguments, /*simplifiedResult*/ false )); }, ["uncommentSelection" /* UncommentSelection */]: (request) => { return this.requiredResponse(this.uncommentSelection( request.arguments, /*simplifiedResult*/ true )); }, ["uncommentSelection-full" /* UncommentSelectionFull */]: (request) => { return this.requiredResponse(this.uncommentSelection( request.arguments, /*simplifiedResult*/ false )); }, ["provideInlayHints" /* ProvideInlayHints */]: (request) => { return this.requiredResponse(this.provideInlayHints(request.arguments)); }, ["mapCode" /* MapCode */]: (request) => { return this.requiredResponse(this.mapCode(request.arguments)); } })); this.host = opts.host; this.cancellationToken = opts.cancellationToken; this.typingsInstaller = opts.typingsInstaller || nullTypingsInstaller; this.byteLength = opts.byteLength; this.hrtime = opts.hrtime; this.logger = opts.logger; this.canUseEvents = opts.canUseEvents; this.suppressDiagnosticEvents = opts.suppressDiagnosticEvents; this.noGetErrOnBackgroundUpdate = opts.noGetErrOnBackgroundUpdate; const { throttleWaitMilliseconds } = opts; this.eventHandler = this.canUseEvents ? opts.eventHandler || ((event) => this.defaultEventHandler(event)) : void 0; const multistepOperationHost = { executeWithRequestId: (requestId, action) => this.executeWithRequestId(requestId, action), getCurrentRequestId: () => this.currentRequestId, getServerHost: () => this.host, logError: (err, cmd) => this.logError(err, cmd), sendRequestCompletedEvent: (requestId) => this.sendRequestCompletedEvent(requestId), isCancellationRequested: () => this.cancellationToken.isCancellationRequested() }; this.errorCheck = new MultistepOperation(multistepOperationHost); const settings = { host: this.host, logger: this.logger, cancellationToken: this.cancellationToken, useSingleInferredProject: opts.useSingleInferredProject, useInferredProjectPerProjectRoot: opts.useInferredProjectPerProjectRoot, typingsInstaller: this.typingsInstaller, throttleWaitMilliseconds, eventHandler: this.eventHandler, suppressDiagnosticEvents: this.suppressDiagnosticEvents, globalPlugins: opts.globalPlugins, pluginProbeLocations: opts.pluginProbeLocations, allowLocalPluginLoads: opts.allowLocalPluginLoads, typesMapLocation: opts.typesMapLocation, serverMode: opts.serverMode, session: this, canUseWatchEvents: opts.canUseWatchEvents, incrementalVerifier: opts.incrementalVerifier }; this.projectService = new ProjectService3(settings); this.projectService.setPerformanceEventHandler(this.performanceEventHandler.bind(this)); this.gcTimer = new GcTimer( this.host, /*delay*/ 7e3, this.logger ); switch (this.projectService.serverMode) { case 0 /* Semantic */: break; case 1 /* PartialSemantic */: invalidPartialSemanticModeCommands.forEach( (commandName) => this.handlers.set(commandName, (request) => { throw new Error(`Request: ${request.command} not allowed in LanguageServiceMode.PartialSemantic`); }) ); break; case 2 /* Syntactic */: invalidSyntacticModeCommands.forEach( (commandName) => this.handlers.set(commandName, (request) => { throw new Error(`Request: ${request.command} not allowed in LanguageServiceMode.Syntactic`); }) ); break; default: Debug.assertNever(this.projectService.serverMode); } } sendRequestCompletedEvent(requestId) { this.event({ request_seq: requestId }, "requestCompleted"); } addPerformanceData(key, value) { if (!this.performanceData) { this.performanceData = {}; } this.performanceData[key] = (this.performanceData[key] ?? 0) + value; } performanceEventHandler(event) { switch (event.kind) { case "UpdateGraph": this.addPerformanceData("updateGraphDurationMs", event.durationMs); break; case "CreatePackageJsonAutoImportProvider": this.addPerformanceData("createAutoImportProviderProgramDurationMs", event.durationMs); break; } } defaultEventHandler(event) { switch (event.eventName) { case ProjectsUpdatedInBackgroundEvent: this.projectsUpdatedInBackgroundEvent(event.data.openFiles); break; case ProjectLoadingStartEvent: this.event({ projectName: event.data.project.getProjectName(), reason: event.data.reason }, event.eventName); break; case ProjectLoadingFinishEvent: this.event({ projectName: event.data.project.getProjectName() }, event.eventName); break; case LargeFileReferencedEvent: case CreateFileWatcherEvent: case CreateDirectoryWatcherEvent: case CloseFileWatcherEvent: this.event(event.data, event.eventName); break; case ConfigFileDiagEvent: this.event({ triggerFile: event.data.triggerFile, configFile: event.data.configFileName, diagnostics: map(event.data.diagnostics, (diagnostic) => formatDiagnosticToProtocol( diagnostic, /*includeFileName*/ true )) }, event.eventName); break; case ProjectLanguageServiceStateEvent: { this.event({ projectName: event.data.project.getProjectName(), languageServiceEnabled: event.data.languageServiceEnabled }, event.eventName); break; } case ProjectInfoTelemetryEvent: { const eventName = "telemetry"; this.event({ telemetryEventName: event.eventName, payload: event.data }, eventName); break; } } } projectsUpdatedInBackgroundEvent(openFiles) { this.projectService.logger.info(`got projects updated in background ${openFiles}`); if (openFiles.length) { if (!this.suppressDiagnosticEvents && !this.noGetErrOnBackgroundUpdate) { this.projectService.logger.info(`Queueing diagnostics update for ${openFiles}`); this.errorCheck.startNew((next) => this.updateErrorCheck( next, openFiles, 100, /*requireOpen*/ true )); } this.event({ openFiles }, ProjectsUpdatedInBackgroundEvent); } } logError(err, cmd) { this.logErrorWorker(err, cmd); } logErrorWorker(err, cmd, fileRequest) { let msg = "Exception on executing command " + cmd; if (err.message) { msg += ":\n" + indent2(err.message); if (err.stack) { msg += "\n" + indent2(err.stack); } } if (this.logger.hasLevel(3 /* verbose */)) { if (fileRequest) { try { const { file, project } = this.getFileAndProject(fileRequest); const scriptInfo = project.getScriptInfoForNormalizedPath(file); if (scriptInfo) { const text = getSnapshotText(scriptInfo.getSnapshot()); msg += ` File text of ${fileRequest.file}:${indent2(text)} `; } } catch { } } if (err.ProgramFiles) { msg += ` Program files: ${JSON.stringify(err.ProgramFiles)} `; msg += ` Projects:: `; let counter = 0; const addProjectInfo = (project) => { msg += ` Project '${project.projectName}' (${ProjectKind[project.projectKind]}) ${counter} `; msg += project.filesToString( /*writeProjectFileNames*/ true ); msg += "\n-----------------------------------------------\n"; counter++; }; this.projectService.externalProjects.forEach(addProjectInfo); this.projectService.configuredProjects.forEach(addProjectInfo); this.projectService.inferredProjects.forEach(addProjectInfo); } } this.logger.msg(msg, "Err" /* Err */); } send(msg) { if (msg.type === "event" && !this.canUseEvents) { if (this.logger.hasLevel(3 /* verbose */)) { this.logger.info(`Session does not support events: ignored event: ${stringifyIndented(msg)}`); } return; } this.writeMessage(msg); } writeMessage(msg) { var _a; const msgText = formatMessage2(msg, this.logger, this.byteLength, this.host.newLine); (_a = perfLogger) == null ? void 0 : _a.logEvent(`Response message size: ${msgText.length}`); this.host.write(msgText); } event(body, eventName) { this.send(toEvent(eventName, body)); } /** @internal */ doOutput(info, cmdName, reqSeq, success, message) { const res = { seq: 0, type: "response", command: cmdName, request_seq: reqSeq, success, performanceData: this.performanceData }; if (success) { let metadata; if (isArray(info)) { res.body = info; metadata = info.metadata; delete info.metadata; } else if (typeof info === "object") { if (info.metadata) { const { metadata: infoMetadata, ...body } = info; res.body = body; metadata = infoMetadata; } else { res.body = info; } } else { res.body = info; } if (metadata) res.metadata = metadata; } else { Debug.assert(info === void 0); } if (message) { res.message = message; } this.send(res); } semanticCheck(file, project) { var _a, _b; (_a = tracing) == null ? void 0 : _a.push(tracing.Phase.Session, "semanticCheck", { file, configFilePath: project.canonicalConfigFilePath }); const diags = isDeclarationFileInJSOnlyNonConfiguredProject(project, file) ? emptyArray2 : project.getLanguageService().getSemanticDiagnostics(file).filter((d) => !!d.file); this.sendDiagnosticsEvent(file, project, diags, "semanticDiag"); (_b = tracing) == null ? void 0 : _b.pop(); } syntacticCheck(file, project) { var _a, _b; (_a = tracing) == null ? void 0 : _a.push(tracing.Phase.Session, "syntacticCheck", { file, configFilePath: project.canonicalConfigFilePath }); this.sendDiagnosticsEvent(file, project, project.getLanguageService().getSyntacticDiagnostics(file), "syntaxDiag"); (_b = tracing) == null ? void 0 : _b.pop(); } suggestionCheck(file, project) { var _a, _b; (_a = tracing) == null ? void 0 : _a.push(tracing.Phase.Session, "suggestionCheck", { file, configFilePath: project.canonicalConfigFilePath }); this.sendDiagnosticsEvent(file, project, project.getLanguageService().getSuggestionDiagnostics(file), "suggestionDiag"); (_b = tracing) == null ? void 0 : _b.pop(); } sendDiagnosticsEvent(file, project, diagnostics, kind) { try { this.event({ file, diagnostics: diagnostics.map((diag2) => formatDiag(file, project, diag2)) }, kind); } catch (err) { this.logError(err, kind); } } /** It is the caller's responsibility to verify that `!this.suppressDiagnosticEvents`. */ updateErrorCheck(next, checkList, ms, requireOpen = true) { Debug.assert(!this.suppressDiagnosticEvents); const seq = this.changeSeq; const followMs = Math.min(ms, 200); let index = 0; const goNext = () => { index++; if (checkList.length > index) { next.delay("checkOne", followMs, checkOne); } }; const checkOne = () => { if (this.changeSeq !== seq) { return; } let item = checkList[index]; if (isString(item)) { item = this.toPendingErrorCheck(item); if (!item) { goNext(); return; } } const { fileName, project } = item; updateProjectIfDirty(project); if (!project.containsFile(fileName, requireOpen)) { return; } this.syntacticCheck(fileName, project); if (this.changeSeq !== seq) { return; } if (project.projectService.serverMode !== 0 /* Semantic */) { goNext(); return; } next.immediate("semanticCheck", () => { this.semanticCheck(fileName, project); if (this.changeSeq !== seq) { return; } if (this.getPreferences(fileName).disableSuggestions) { goNext(); return; } next.immediate("suggestionCheck", () => { this.suggestionCheck(fileName, project); goNext(); }); }); }; if (checkList.length > index && this.changeSeq === seq) { next.delay("checkOne", ms, checkOne); } } cleanProjects(caption, projects) { if (!projects) { return; } this.logger.info(`cleaning ${caption}`); for (const p of projects) { p.getLanguageService( /*ensureSynchronized*/ false ).cleanupSemanticCache(); p.cleanupProgram(); } } cleanup() { this.cleanProjects("inferred projects", this.projectService.inferredProjects); this.cleanProjects("configured projects", arrayFrom(this.projectService.configuredProjects.values())); this.cleanProjects("external projects", this.projectService.externalProjects); if (this.host.gc) { this.logger.info(`host.gc()`); this.host.gc(); } } getEncodedSyntacticClassifications(args) { const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args); return languageService.getEncodedSyntacticClassifications(file, args); } getEncodedSemanticClassifications(args) { const { file, project } = this.getFileAndProject(args); const format = args.format === "2020" ? "2020" /* TwentyTwenty */ : "original" /* Original */; return project.getLanguageService().getEncodedSemanticClassifications(file, args, format); } getProject(projectFileName) { return projectFileName === void 0 ? void 0 : this.projectService.findProject(projectFileName); } getConfigFileAndProject(args) { const project = this.getProject(args.projectFileName); const file = toNormalizedPath(args.file); return { configFile: project && project.hasConfigFile(file) ? file : void 0, project }; } getConfigFileDiagnostics(configFile, project, includeLinePosition) { const projectErrors = project.getAllProjectErrors(); const optionsErrors = project.getLanguageService().getCompilerOptionsDiagnostics(); const diagnosticsForConfigFile = filter( concatenate(projectErrors, optionsErrors), (diagnostic) => !!diagnostic.file && diagnostic.file.fileName === configFile ); return includeLinePosition ? this.convertToDiagnosticsWithLinePositionFromDiagnosticFile(diagnosticsForConfigFile) : map( diagnosticsForConfigFile, (diagnostic) => formatDiagnosticToProtocol( diagnostic, /*includeFileName*/ false ) ); } convertToDiagnosticsWithLinePositionFromDiagnosticFile(diagnostics) { return diagnostics.map((d) => ({ message: flattenDiagnosticMessageText(d.messageText, this.host.newLine), start: d.start, // TODO: GH#18217 length: d.length, // TODO: GH#18217 category: diagnosticCategoryName(d), code: d.code, source: d.source, startLocation: d.file && convertToLocation(getLineAndCharacterOfPosition(d.file, d.start)), // TODO: GH#18217 endLocation: d.file && convertToLocation(getLineAndCharacterOfPosition(d.file, d.start + d.length)), // TODO: GH#18217 reportsUnnecessary: d.reportsUnnecessary, reportsDeprecated: d.reportsDeprecated, relatedInformation: map(d.relatedInformation, formatRelatedInformation) })); } getCompilerOptionsDiagnostics(args) { const project = this.getProject(args.projectFileName); return this.convertToDiagnosticsWithLinePosition( filter( project.getLanguageService().getCompilerOptionsDiagnostics(), (diagnostic) => !diagnostic.file ), /*scriptInfo*/ void 0 ); } convertToDiagnosticsWithLinePosition(diagnostics, scriptInfo) { return diagnostics.map( (d) => ({ message: flattenDiagnosticMessageText(d.messageText, this.host.newLine), start: d.start, length: d.length, category: diagnosticCategoryName(d), code: d.code, source: d.source, startLocation: scriptInfo && scriptInfo.positionToLineOffset(d.start), // TODO: GH#18217 endLocation: scriptInfo && scriptInfo.positionToLineOffset(d.start + d.length), reportsUnnecessary: d.reportsUnnecessary, reportsDeprecated: d.reportsDeprecated, relatedInformation: map(d.relatedInformation, formatRelatedInformation) }) ); } getDiagnosticsWorker(args, isSemantic, selector, includeLinePosition) { const { project, file } = this.getFileAndProject(args); if (isSemantic && isDeclarationFileInJSOnlyNonConfiguredProject(project, file)) { return emptyArray2; } const scriptInfo = project.getScriptInfoForNormalizedPath(file); const diagnostics = selector(project, file); return includeLinePosition ? this.convertToDiagnosticsWithLinePosition(diagnostics, scriptInfo) : diagnostics.map((d) => formatDiag(file, project, d)); } getDefinition(args, simplifiedResult) { const { file, project } = this.getFileAndProject(args); const position = this.getPositionInFile(args, file); const definitions = this.mapDefinitionInfoLocations(project.getLanguageService().getDefinitionAtPosition(file, position) || emptyArray2, project); return simplifiedResult ? this.mapDefinitionInfo(definitions, project) : definitions.map(_Session.mapToOriginalLocation); } mapDefinitionInfoLocations(definitions, project) { return definitions.map((info) => { const newDocumentSpan = getMappedDocumentSpanForProject(info, project); return !newDocumentSpan ? info : { ...newDocumentSpan, containerKind: info.containerKind, containerName: info.containerName, kind: info.kind, name: info.name, failedAliasResolution: info.failedAliasResolution, ...info.unverified && { unverified: info.unverified } }; }); } getDefinitionAndBoundSpan(args, simplifiedResult) { const { file, project } = this.getFileAndProject(args); const position = this.getPositionInFile(args, file); const scriptInfo = Debug.checkDefined(project.getScriptInfo(file)); const unmappedDefinitionAndBoundSpan = project.getLanguageService().getDefinitionAndBoundSpan(file, position); if (!unmappedDefinitionAndBoundSpan || !unmappedDefinitionAndBoundSpan.definitions) { return { definitions: emptyArray2, textSpan: void 0 // TODO: GH#18217 }; } const definitions = this.mapDefinitionInfoLocations(unmappedDefinitionAndBoundSpan.definitions, project); const { textSpan } = unmappedDefinitionAndBoundSpan; if (simplifiedResult) { return { definitions: this.mapDefinitionInfo(definitions, project), textSpan: toProtocolTextSpan(textSpan, scriptInfo) }; } return { definitions: definitions.map(_Session.mapToOriginalLocation), textSpan }; } findSourceDefinition(args) { var _a; const { file, project } = this.getFileAndProject(args); const position = this.getPositionInFile(args, file); const unmappedDefinitions = project.getLanguageService().getDefinitionAtPosition(file, position); let definitions = this.mapDefinitionInfoLocations(unmappedDefinitions || emptyArray2, project).slice(); const needsJsResolution = this.projectService.serverMode === 0 /* Semantic */ && (!some(definitions, (d) => toNormalizedPath(d.fileName) !== file && !d.isAmbient) || some(definitions, (d) => !!d.failedAliasResolution)); if (needsJsResolution) { const definitionSet = createSet( (d) => d.textSpan.start, getDocumentSpansEqualityComparer(this.host.useCaseSensitiveFileNames) ); definitions == null ? void 0 : definitions.forEach((d) => definitionSet.add(d)); const noDtsProject = project.getNoDtsResolutionProject(file); const ls = noDtsProject.getLanguageService(); const jsDefinitions = (_a = ls.getDefinitionAtPosition( file, position, /*searchOtherFilesOnly*/ true, /*stopAtAlias*/ false )) == null ? void 0 : _a.filter((d) => toNormalizedPath(d.fileName) !== file); if (some(jsDefinitions)) { for (const jsDefinition of jsDefinitions) { if (jsDefinition.unverified) { const refined = tryRefineDefinition(jsDefinition, project.getLanguageService().getProgram(), ls.getProgram()); if (some(refined)) { for (const def of refined) { definitionSet.add(def); } continue; } } definitionSet.add(jsDefinition); } } else { 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) continue; const info = this.projectService.getOrCreateScriptInfoNotOpenedByClient( fileNameToSearch, noDtsProject.currentDirectory, noDtsProject.directoryStructureHost, /*deferredDeleteOk*/ false ); if (!info) continue; if (!noDtsProject.containsScriptInfo(info)) { noDtsProject.addRoot(info); noDtsProject.updateGraph(); } const noDtsProgram = ls.getProgram(); const fileToSearch = Debug.checkDefined(noDtsProgram.getSourceFile(fileNameToSearch)); for (const match of searchForDeclaration(candidate.name, fileToSearch, noDtsProgram)) { definitionSet.add(match); } } } definitions = arrayFrom(definitionSet.values()); } definitions = definitions.filter((d) => !d.isAmbient && !d.failedAliasResolution); return this.mapDefinitionInfo(definitions, project); function findImplementationFileFromDtsFileName(fileName, resolveFromFile, auxiliaryProject) { var _a2, _b, _c; const nodeModulesPathParts = getNodeModulePathParts(fileName); if (nodeModulesPathParts && fileName.lastIndexOf(nodeModulesPathPart) === nodeModulesPathParts.topLevelNodeModulesIndex) { const packageDirectory = fileName.substring(0, nodeModulesPathParts.packageRootIndex); const packageJsonCache = (_a2 = project.getModuleResolutionCache()) == null ? void 0 : _a2.getPackageJsonInfoCache(); const compilerOptions = project.getCompilationSettings(); const packageJson = getPackageScopeForPath(getNormalizedAbsolutePath(packageDirectory + "/package.json", project.getCurrentDirectory()), getTemporaryModuleResolutionState(packageJsonCache, project, compilerOptions)); if (!packageJson) return void 0; const entrypoints = getEntrypointsFromPackageJsonInfo( packageJson, { moduleResolution: 2 /* Node10 */ }, project, project.getModuleResolutionCache() ); const packageNamePathPart = fileName.substring( nodeModulesPathParts.topLevelPackageNameIndex + 1, nodeModulesPathParts.packageRootIndex ); const packageName = getPackageNameFromTypesPackageName(unmangleScopedPackageName(packageNamePathPart)); const path = project.toPath(fileName); if (entrypoints && some(entrypoints, (e) => project.toPath(e) === path)) { return (_b = auxiliaryProject.resolutionCache.resolveSingleModuleNameWithoutWatching(packageName, resolveFromFile).resolvedModule) == null ? void 0 : _b.resolvedFileName; } else { const pathToFileInPackage = fileName.substring(nodeModulesPathParts.packageRootIndex + 1); const specifier = `${packageName}/${removeFileExtension(pathToFileInPackage)}`; return (_c = auxiliaryProject.resolutionCache.resolveSingleModuleNameWithoutWatching(specifier, resolveFromFile).resolvedModule) == null ? void 0 : _c.resolvedFileName; } } return void 0; } function getAmbientCandidatesByClimbingAccessChain() { const ls = project.getLanguageService(); const program = ls.getProgram(); const initialNode = getTouchingPropertyName(program.getSourceFile(file), position); if ((isStringLiteralLike(initialNode) || isIdentifier(initialNode)) && isAccessExpression(initialNode.parent)) { return forEachNameInAccessChainWalkingLeft(initialNode, (nameInChain) => { var _a2; if (nameInChain === initialNode) return void 0; const candidates = (_a2 = ls.getDefinitionAtPosition( file, nameInChain.getStart(), /*searchOtherFilesOnly*/ true, /*stopAtAlias*/ false )) == null ? void 0 : _a2.filter((d) => toNormalizedPath(d.fileName) !== file && d.isAmbient).map((d) => ({ fileName: d.fileName, name: getTextOfIdentifierOrLiteral(initialNode) })); if (some(candidates)) { return candidates; } }) || emptyArray2; } return emptyArray2; } function tryRefineDefinition(definition, program, noDtsProgram) { var _a2; const fileToSearch = noDtsProgram.getSourceFile(definition.fileName); if (!fileToSearch) { return void 0; } const initialNode = getTouchingPropertyName(program.getSourceFile(file), position); const symbol = program.getTypeChecker().getSymbolAtLocation(initialNode); const importSpecifier = symbol && getDeclarationOfKind(symbol, 276 /* ImportSpecifier */); if (!importSpecifier) return void 0; const nameToSearch = ((_a2 = importSpecifier.propertyName) == null ? void 0 : _a2.text) || importSpecifier.name.text; return searchForDeclaration(nameToSearch, fileToSearch, noDtsProgram); } function searchForDeclaration(declarationName, fileToSearch, noDtsProgram) { const matches = ts_FindAllReferences_exports.Core.getTopMostDeclarationNamesInFile(declarationName, fileToSearch); return mapDefined(matches, (match) => { const symbol = noDtsProgram.getTypeChecker().getSymbolAtLocation(match); const decl = getDeclarationFromName(match); if (symbol && decl) { return ts_GoToDefinition_exports.createDefinitionInfo( decl, noDtsProgram.getTypeChecker(), symbol, decl, /*unverified*/ true ); } }); } } getEmitOutput(args) { const { file, project } = this.getFileAndProject(args); if (!project.shouldEmitFile(project.getScriptInfo(file))) { return { emitSkipped: true, outputFiles: [], diagnostics: [] }; } const result = project.getLanguageService().getEmitOutput(file); return args.richResponse ? { ...result, diagnostics: args.includeLinePosition ? this.convertToDiagnosticsWithLinePositionFromDiagnosticFile(result.diagnostics) : result.diagnostics.map((d) => formatDiagnosticToProtocol( d, /*includeFileName*/ true )) } : result; } mapJSDocTagInfo(tags, project, richResponse) { return tags ? tags.map((tag) => { var _a; return { ...tag, text: richResponse ? this.mapDisplayParts(tag.text, project) : (_a = tag.text) == null ? void 0 : _a.map((part) => part.text).join("") }; }) : []; } mapDisplayParts(parts, project) { if (!parts) { return []; } return parts.map( (part) => part.kind !== "linkName" ? part : { ...part, target: this.toFileSpan(part.target.fileName, part.target.textSpan, project) } ); } mapSignatureHelpItems(items, project, richResponse) { return items.map((item) => ({ ...item, documentation: this.mapDisplayParts(item.documentation, project), parameters: item.parameters.map((p) => ({ ...p, documentation: this.mapDisplayParts(p.documentation, project) })), tags: this.mapJSDocTagInfo(item.tags, project, richResponse) })); } mapDefinitionInfo(definitions, project) { return definitions.map((def) => ({ ...this.toFileSpanWithContext(def.fileName, def.textSpan, def.contextSpan, project), ...def.unverified && { unverified: def.unverified } })); } /* * When we map a .d.ts location to .ts, Visual Studio gets confused because there's no associated Roslyn Document in * the same project which corresponds to the file. VS Code has no problem with this, and luckily we have two protocols. * This retains the existing behavior for the "simplified" (VS Code) protocol but stores the .d.ts location in a * set of additional fields, and does the reverse for VS (store the .d.ts location where * it used to be and stores the .ts location in the additional fields). */ static mapToOriginalLocation(def) { if (def.originalFileName) { Debug.assert(def.originalTextSpan !== void 0, "originalTextSpan should be present if originalFileName is"); return { ...def, fileName: def.originalFileName, textSpan: def.originalTextSpan, targetFileName: def.fileName, targetTextSpan: def.textSpan, contextSpan: def.originalContextSpan, targetContextSpan: def.contextSpan }; } return def; } toFileSpan(fileName, textSpan, project) { const ls = project.getLanguageService(); const start = ls.toLineColumnOffset(fileName, textSpan.start); const end = ls.toLineColumnOffset(fileName, textSpanEnd(textSpan)); return { file: fileName, start: { line: start.line + 1, offset: start.character + 1 }, end: { line: end.line + 1, offset: end.character + 1 } }; } toFileSpanWithContext(fileName, textSpan, contextSpan, project) { const fileSpan = this.toFileSpan(fileName, textSpan, project); const context = contextSpan && this.toFileSpan(fileName, contextSpan, project); return context ? { ...fileSpan, contextStart: context.start, contextEnd: context.end } : fileSpan; } getTypeDefinition(args) { const { file, project } = this.getFileAndProject(args); const position = this.getPositionInFile(args, file); const definitions = this.mapDefinitionInfoLocations(project.getLanguageService().getTypeDefinitionAtPosition(file, position) || emptyArray2, project); return this.mapDefinitionInfo(definitions, project); } mapImplementationLocations(implementations, project) { return implementations.map((info) => { const newDocumentSpan = getMappedDocumentSpanForProject(info, project); return !newDocumentSpan ? info : { ...newDocumentSpan, kind: info.kind, displayParts: info.displayParts }; }); } getImplementation(args, simplifiedResult) { const { file, project } = this.getFileAndProject(args); const position = this.getPositionInFile(args, file); const implementations = this.mapImplementationLocations(project.getLanguageService().getImplementationAtPosition(file, position) || emptyArray2, project); return simplifiedResult ? implementations.map(({ fileName, textSpan, contextSpan }) => this.toFileSpanWithContext(fileName, textSpan, contextSpan, project)) : implementations.map(_Session.mapToOriginalLocation); } getSyntacticDiagnosticsSync(args) { const { configFile } = this.getConfigFileAndProject(args); if (configFile) { return emptyArray2; } return this.getDiagnosticsWorker( args, /*isSemantic*/ false, (project, file) => project.getLanguageService().getSyntacticDiagnostics(file), !!args.includeLinePosition ); } getSemanticDiagnosticsSync(args) { const { configFile, project } = this.getConfigFileAndProject(args); if (configFile) { return this.getConfigFileDiagnostics(configFile, project, !!args.includeLinePosition); } return this.getDiagnosticsWorker( args, /*isSemantic*/ true, (project2, file) => project2.getLanguageService().getSemanticDiagnostics(file).filter((d) => !!d.file), !!args.includeLinePosition ); } getSuggestionDiagnosticsSync(args) { const { configFile } = this.getConfigFileAndProject(args); if (configFile) { return emptyArray2; } return this.getDiagnosticsWorker( args, /*isSemantic*/ true, (project, file) => project.getLanguageService().getSuggestionDiagnostics(file), !!args.includeLinePosition ); } getJsxClosingTag(args) { const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args); const position = this.getPositionInFile(args, file); const tag = languageService.getJsxClosingTagAtPosition(file, position); return tag === void 0 ? void 0 : { newText: tag.newText, caretOffset: 0 }; } getLinkedEditingRange(args) { const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args); const position = this.getPositionInFile(args, file); const linkedEditInfo = languageService.getLinkedEditingRangeAtPosition(file, position); const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file); if (scriptInfo === void 0 || linkedEditInfo === void 0) return void 0; return convertLinkedEditInfoToRanges(linkedEditInfo, scriptInfo); } getDocumentHighlights(args, simplifiedResult) { const { file, project } = this.getFileAndProject(args); const position = this.getPositionInFile(args, file); const documentHighlights = project.getLanguageService().getDocumentHighlights(file, position, args.filesToSearch); if (!documentHighlights) return emptyArray2; if (!simplifiedResult) return documentHighlights; return documentHighlights.map(({ fileName, highlightSpans }) => { const scriptInfo = project.getScriptInfo(fileName); return { file: fileName, highlightSpans: highlightSpans.map(({ textSpan, kind, contextSpan }) => ({ ...toProtocolTextSpanWithContext(textSpan, contextSpan, scriptInfo), kind })) }; }); } provideInlayHints(args) { const { file, project } = this.getFileAndProject(args); const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file); const hints = project.getLanguageService().provideInlayHints(file, args, this.getPreferences(file)); return hints.map((hint) => { const { position, displayParts } = hint; return { ...hint, position: scriptInfo.positionToLineOffset(position), displayParts: displayParts == null ? void 0 : displayParts.map(({ text, span, file: file2 }) => { if (span) { Debug.assertIsDefined(file2, "Target file should be defined together with its span."); const scriptInfo2 = this.projectService.getScriptInfo(file2); return { text, span: { start: scriptInfo2.positionToLineOffset(span.start), end: scriptInfo2.positionToLineOffset(span.start + span.length), file: file2 } }; } else { return { text }; } }) }; }); } mapCode(args) { var _a; const formatOptions = this.getHostFormatOptions(); const preferences = this.getHostPreferences(); const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args); const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file); const focusLocations = (_a = args.mapping.focusLocations) == null ? void 0 : _a.map((spans) => { return spans.map((loc) => { const start = scriptInfo.lineOffsetToPosition(loc.start.line, loc.start.offset); const end = scriptInfo.lineOffsetToPosition(loc.end.line, loc.end.offset); return { start, length: end - start }; }); }); const changes = languageService.mapCode(file, args.mapping.contents, focusLocations, formatOptions, preferences); return this.mapTextChangesToCodeEdits(changes); } setCompilerOptionsForInferredProjects(args) { this.projectService.setCompilerOptionsForInferredProjects(args.options, args.projectRootPath); } getProjectInfo(args) { return this.getProjectInfoWorker( args.file, args.projectFileName, args.needFileNameList, /*excludeConfigFiles*/ false ); } getProjectInfoWorker(uncheckedFileName, projectFileName, needFileNameList, excludeConfigFiles) { const { project } = this.getFileAndProjectWorker(uncheckedFileName, projectFileName); updateProjectIfDirty(project); const projectInfo = { configFileName: project.getProjectName(), languageServiceDisabled: !project.languageServiceEnabled, fileNames: needFileNameList ? project.getFileNames( /*excludeFilesFromExternalLibraries*/ false, excludeConfigFiles ) : void 0 }; return projectInfo; } getRenameInfo(args) { const { file, project } = this.getFileAndProject(args); const position = this.getPositionInFile(args, file); const preferences = this.getPreferences(file); return project.getLanguageService().getRenameInfo(file, position, preferences); } getProjects(args, getScriptInfoEnsuringProjectsUptoDate, ignoreNoProjectError) { let projects; let symLinkedProjects; if (args.projectFileName) { const project = this.getProject(args.projectFileName); if (project) { projects = [project]; } } else { const scriptInfo = getScriptInfoEnsuringProjectsUptoDate ? this.projectService.getScriptInfoEnsuringProjectsUptoDate(args.file) : this.projectService.getScriptInfo(args.file); if (!scriptInfo) { if (ignoreNoProjectError) return emptyArray2; this.projectService.logErrorForScriptInfoNotFound(args.file); return Errors.ThrowNoProject(); } else if (!getScriptInfoEnsuringProjectsUptoDate) { this.projectService.ensureDefaultProjectForFile(scriptInfo); } projects = scriptInfo.containingProjects; symLinkedProjects = this.projectService.getSymlinkedProjects(scriptInfo); } projects = filter(projects, (p) => p.languageServiceEnabled && !p.isOrphan()); if (!ignoreNoProjectError && (!projects || !projects.length) && !symLinkedProjects) { this.projectService.logErrorForScriptInfoNotFound(args.file ?? args.projectFileName); return Errors.ThrowNoProject(); } return symLinkedProjects ? { projects, symLinkedProjects } : projects; } getDefaultProject(args) { if (args.projectFileName) { const project = this.getProject(args.projectFileName); if (project) { return project; } if (!args.file) { return Errors.ThrowNoProject(); } } const info = this.projectService.getScriptInfo(args.file); return info.getDefaultProject(); } getRenameLocations(args, simplifiedResult) { const file = toNormalizedPath(args.file); const position = this.getPositionInFile(args, file); const projects = this.getProjects(args); const defaultProject = this.getDefaultProject(args); const preferences = this.getPreferences(file); const renameInfo = this.mapRenameInfo( defaultProject.getLanguageService().getRenameInfo(file, position, preferences), Debug.checkDefined(this.projectService.getScriptInfo(file)) ); if (!renameInfo.canRename) return simplifiedResult ? { info: renameInfo, locs: [] } : []; const locations = getRenameLocationsWorker( projects, defaultProject, { fileName: args.file, pos: position }, !!args.findInStrings, !!args.findInComments, preferences, this.host.useCaseSensitiveFileNames ); if (!simplifiedResult) return locations; return { info: renameInfo, locs: this.toSpanGroups(locations) }; } mapRenameInfo(info, scriptInfo) { if (info.canRename) { const { canRename, fileToRename, displayName, fullDisplayName, kind, kindModifiers, triggerSpan } = info; return identity( { canRename, fileToRename, displayName, fullDisplayName, kind, kindModifiers, triggerSpan: toProtocolTextSpan(triggerSpan, scriptInfo) } ); } else { return info; } } toSpanGroups(locations) { const map2 = /* @__PURE__ */ new Map(); for (const { fileName, textSpan, contextSpan, originalContextSpan: _2, originalTextSpan: _, originalFileName: _1, ...prefixSuffixText } of locations) { let group2 = map2.get(fileName); if (!group2) map2.set(fileName, group2 = { file: fileName, locs: [] }); const scriptInfo = Debug.checkDefined(this.projectService.getScriptInfo(fileName)); group2.locs.push({ ...toProtocolTextSpanWithContext(textSpan, contextSpan, scriptInfo), ...prefixSuffixText }); } return arrayFrom(map2.values()); } getReferences(args, simplifiedResult) { const file = toNormalizedPath(args.file); const projects = this.getProjects(args); const position = this.getPositionInFile(args, file); const references = getReferencesWorker( projects, this.getDefaultProject(args), { fileName: args.file, pos: position }, this.host.useCaseSensitiveFileNames, this.logger ); if (!simplifiedResult) return references; const preferences = this.getPreferences(file); const defaultProject = this.getDefaultProject(args); const scriptInfo = defaultProject.getScriptInfoForNormalizedPath(file); const nameInfo = defaultProject.getLanguageService().getQuickInfoAtPosition(file, position); const symbolDisplayString = nameInfo ? displayPartsToString(nameInfo.displayParts) : ""; const nameSpan = nameInfo && nameInfo.textSpan; const symbolStartOffset = nameSpan ? scriptInfo.positionToLineOffset(nameSpan.start).offset : 0; const symbolName2 = nameSpan ? scriptInfo.getSnapshot().getText(nameSpan.start, textSpanEnd(nameSpan)) : ""; const refs = flatMap(references, (referencedSymbol) => { return referencedSymbol.references.map((entry) => referenceEntryToReferencesResponseItem(this.projectService, entry, preferences)); }); return { refs, symbolName: symbolName2, symbolStartOffset, symbolDisplayString }; } getFileReferences(args, simplifiedResult) { const projects = this.getProjects(args); const fileName = args.file; const preferences = this.getPreferences(toNormalizedPath(fileName)); const references = []; const seen = createDocumentSpanSet(this.host.useCaseSensitiveFileNames); forEachProjectInProjects( projects, /*path*/ void 0, (project) => { if (project.getCancellationToken().isCancellationRequested()) return; const projectOutputs = project.getLanguageService().getFileReferences(fileName); if (projectOutputs) { for (const referenceEntry of projectOutputs) { if (!seen.has(referenceEntry)) { references.push(referenceEntry); seen.add(referenceEntry); } } } } ); if (!simplifiedResult) return references; const refs = references.map((entry) => referenceEntryToReferencesResponseItem(this.projectService, entry, preferences)); return { refs, symbolName: `"${args.file}"` }; } /** * @param fileName is the name of the file to be opened * @param fileContent is a version of the file content that is known to be more up to date than the one on disk */ openClientFile(fileName, fileContent, scriptKind, projectRootPath) { this.projectService.openClientFileWithNormalizedPath( fileName, fileContent, scriptKind, /*hasMixedContent*/ false, projectRootPath ); } getPosition(args, scriptInfo) { return args.position !== void 0 ? args.position : scriptInfo.lineOffsetToPosition(args.line, args.offset); } getPositionInFile(args, file) { const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file); return this.getPosition(args, scriptInfo); } getFileAndProject(args) { return this.getFileAndProjectWorker(args.file, args.projectFileName); } getFileAndLanguageServiceForSyntacticOperation(args) { const { file, project } = this.getFileAndProject(args); return { file, languageService: project.getLanguageService( /*ensureSynchronized*/ false ) }; } getFileAndProjectWorker(uncheckedFileName, projectFileName) { const file = toNormalizedPath(uncheckedFileName); const project = this.getProject(projectFileName) || this.projectService.ensureDefaultProjectForFile(file); return { file, project }; } getOutliningSpans(args, simplifiedResult) { const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args); const spans = languageService.getOutliningSpans(file); if (simplifiedResult) { const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file); return spans.map((s) => ({ textSpan: toProtocolTextSpan(s.textSpan, scriptInfo), hintSpan: toProtocolTextSpan(s.hintSpan, scriptInfo), bannerText: s.bannerText, autoCollapse: s.autoCollapse, kind: s.kind })); } else { return spans; } } getTodoComments(args) { const { file, project } = this.getFileAndProject(args); return project.getLanguageService().getTodoComments(file, args.descriptors); } getDocCommentTemplate(args) { const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args); const position = this.getPositionInFile(args, file); return languageService.getDocCommentTemplateAtPosition(file, position, this.getPreferences(file), this.getFormatOptions(file)); } getSpanOfEnclosingComment(args) { const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args); const onlyMultiLine = args.onlyMultiLine; const position = this.getPositionInFile(args, file); return languageService.getSpanOfEnclosingComment(file, position, onlyMultiLine); } getIndentation(args) { const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args); const position = this.getPositionInFile(args, file); const options = args.options ? convertFormatOptions(args.options) : this.getFormatOptions(file); const indentation = languageService.getIndentationAtPosition(file, position, options); return { position, indentation }; } getBreakpointStatement(args) { const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args); const position = this.getPositionInFile(args, file); return languageService.getBreakpointStatementAtPosition(file, position); } getNameOrDottedNameSpan(args) { const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args); const position = this.getPositionInFile(args, file); return languageService.getNameOrDottedNameSpan(file, position, position); } isValidBraceCompletion(args) { const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args); const position = this.getPositionInFile(args, file); return languageService.isValidBraceCompletionAtPosition(file, position, args.openingBrace.charCodeAt(0)); } getQuickInfoWorker(args, simplifiedResult) { const { file, project } = this.getFileAndProject(args); const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file); const quickInfo = project.getLanguageService().getQuickInfoAtPosition(file, this.getPosition(args, scriptInfo)); if (!quickInfo) { return void 0; } const useDisplayParts = !!this.getPreferences(file).displayPartsForJSDoc; if (simplifiedResult) { const displayString = displayPartsToString(quickInfo.displayParts); return { kind: quickInfo.kind, kindModifiers: quickInfo.kindModifiers, start: scriptInfo.positionToLineOffset(quickInfo.textSpan.start), end: scriptInfo.positionToLineOffset(textSpanEnd(quickInfo.textSpan)), displayString, documentation: useDisplayParts ? this.mapDisplayParts(quickInfo.documentation, project) : displayPartsToString(quickInfo.documentation), tags: this.mapJSDocTagInfo(quickInfo.tags, project, useDisplayParts) }; } else { return useDisplayParts ? quickInfo : { ...quickInfo, tags: this.mapJSDocTagInfo( quickInfo.tags, project, /*richResponse*/ false ) }; } } getFormattingEditsForRange(args) { const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args); const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file); const startPosition = scriptInfo.lineOffsetToPosition(args.line, args.offset); const endPosition = scriptInfo.lineOffsetToPosition(args.endLine, args.endOffset); const edits = languageService.getFormattingEditsForRange(file, startPosition, endPosition, this.getFormatOptions(file)); if (!edits) { return void 0; } return edits.map((edit) => this.convertTextChangeToCodeEdit(edit, scriptInfo)); } getFormattingEditsForRangeFull(args) { const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args); const options = args.options ? convertFormatOptions(args.options) : this.getFormatOptions(file); return languageService.getFormattingEditsForRange(file, args.position, args.endPosition, options); } getFormattingEditsForDocumentFull(args) { const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args); const options = args.options ? convertFormatOptions(args.options) : this.getFormatOptions(file); return languageService.getFormattingEditsForDocument(file, options); } getFormattingEditsAfterKeystrokeFull(args) { const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args); const options = args.options ? convertFormatOptions(args.options) : this.getFormatOptions(file); return languageService.getFormattingEditsAfterKeystroke(file, args.position, args.key, options); } getFormattingEditsAfterKeystroke(args) { const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args); const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file); const position = scriptInfo.lineOffsetToPosition(args.line, args.offset); const formatOptions = this.getFormatOptions(file); const edits = languageService.getFormattingEditsAfterKeystroke(file, position, args.key, formatOptions); if (args.key === "\n" && (!edits || edits.length === 0 || allEditsBeforePos(edits, position))) { const { lineText, absolutePosition } = scriptInfo.textStorage.getAbsolutePositionAndLineText(args.line); if (lineText && lineText.search("\\S") < 0) { const preferredIndent = languageService.getIndentationAtPosition(file, position, formatOptions); let hasIndent = 0; let i, len; for (i = 0, len = lineText.length; i < len; i++) { if (lineText.charAt(i) === " ") { hasIndent++; } else if (lineText.charAt(i) === " ") { hasIndent += formatOptions.tabSize; } else { break; } } if (preferredIndent !== hasIndent) { const firstNoWhiteSpacePosition = absolutePosition + i; edits.push({ span: createTextSpanFromBounds(absolutePosition, firstNoWhiteSpacePosition), newText: ts_formatting_exports.getIndentationString(preferredIndent, formatOptions) }); } } } if (!edits) { return void 0; } return edits.map((edit) => { return { start: scriptInfo.positionToLineOffset(edit.span.start), end: scriptInfo.positionToLineOffset(textSpanEnd(edit.span)), newText: edit.newText ? edit.newText : "" }; }); } getCompletions(args, kind) { const { file, project } = this.getFileAndProject(args); const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file); const position = this.getPosition(args, scriptInfo); const completions = project.getLanguageService().getCompletionsAtPosition( file, position, { ...convertUserPreferences(this.getPreferences(file)), triggerCharacter: args.triggerCharacter, triggerKind: args.triggerKind, includeExternalModuleExports: args.includeExternalModuleExports, includeInsertTextCompletions: args.includeInsertTextCompletions }, project.projectService.getFormatCodeOptions(file) ); if (completions === void 0) return void 0; if (kind === "completions-full" /* CompletionsFull */) return completions; const prefix = args.prefix || ""; const entries = mapDefined(completions.entries, (entry) => { if (completions.isMemberCompletion || startsWith(entry.name.toLowerCase(), prefix.toLowerCase())) { const { name, kind: kind2, kindModifiers, sortText, insertText, filterText, replacementSpan, hasAction, source, sourceDisplay, labelDetails, isSnippet, isRecommended, isPackageJsonImport, isImportStatementCompletion, data } = entry; const convertedSpan = replacementSpan ? toProtocolTextSpan(replacementSpan, scriptInfo) : void 0; return { name, kind: kind2, kindModifiers, sortText, insertText, filterText, replacementSpan: convertedSpan, isSnippet, hasAction: hasAction || void 0, source, sourceDisplay, labelDetails, isRecommended, isPackageJsonImport, isImportStatementCompletion, data }; } }); if (kind === "completions" /* Completions */) { if (completions.metadata) entries.metadata = completions.metadata; return entries; } const res = { ...completions, optionalReplacementSpan: completions.optionalReplacementSpan && toProtocolTextSpan(completions.optionalReplacementSpan, scriptInfo), entries }; return res; } getCompletionEntryDetails(args, fullResult) { const { file, project } = this.getFileAndProject(args); const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file); const position = this.getPosition(args, scriptInfo); const formattingOptions = project.projectService.getFormatCodeOptions(file); const useDisplayParts = !!this.getPreferences(file).displayPartsForJSDoc; const result = mapDefined(args.entryNames, (entryName) => { const { name, source, data } = typeof entryName === "string" ? { name: entryName, source: void 0, data: void 0 } : entryName; return project.getLanguageService().getCompletionEntryDetails(file, position, name, formattingOptions, source, this.getPreferences(file), data ? cast(data, isCompletionEntryData) : void 0); }); return fullResult ? useDisplayParts ? result : result.map((details) => ({ ...details, tags: this.mapJSDocTagInfo( details.tags, project, /*richResponse*/ false ) })) : result.map((details) => ({ ...details, codeActions: map(details.codeActions, (action) => this.mapCodeAction(action)), documentation: this.mapDisplayParts(details.documentation, project), tags: this.mapJSDocTagInfo(details.tags, project, useDisplayParts) })); } getCompileOnSaveAffectedFileList(args) { const projects = this.getProjects( args, /*getScriptInfoEnsuringProjectsUptoDate*/ true, /*ignoreNoProjectError*/ true ); const info = this.projectService.getScriptInfo(args.file); if (!info) { return emptyArray2; } return combineProjectOutput( info, (path) => this.projectService.getScriptInfoForPath(path), projects, (project, info2) => { if (!project.compileOnSaveEnabled || !project.languageServiceEnabled || project.isOrphan()) { return void 0; } const compilationSettings = project.getCompilationSettings(); if (!!compilationSettings.noEmit || isDeclarationFileName(info2.fileName) && !dtsChangeCanAffectEmit(compilationSettings)) { return void 0; } return { projectFileName: project.getProjectName(), fileNames: project.getCompileOnSaveAffectedFileList(info2), projectUsesOutFile: !!compilationSettings.outFile }; } ); } emitFile(args) { const { file, project } = this.getFileAndProject(args); if (!project) { Errors.ThrowNoProject(); } if (!project.languageServiceEnabled) { return args.richResponse ? { emitSkipped: true, diagnostics: [] } : false; } const scriptInfo = project.getScriptInfo(file); const { emitSkipped, diagnostics } = project.emitFile(scriptInfo, (path, data, writeByteOrderMark) => this.host.writeFile(path, data, writeByteOrderMark)); return args.richResponse ? { emitSkipped, diagnostics: args.includeLinePosition ? this.convertToDiagnosticsWithLinePositionFromDiagnosticFile(diagnostics) : diagnostics.map((d) => formatDiagnosticToProtocol( d, /*includeFileName*/ true )) } : !emitSkipped; } getSignatureHelpItems(args, simplifiedResult) { const { file, project } = this.getFileAndProject(args); const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file); const position = this.getPosition(args, scriptInfo); const helpItems = project.getLanguageService().getSignatureHelpItems(file, position, args); const useDisplayParts = !!this.getPreferences(file).displayPartsForJSDoc; if (helpItems && simplifiedResult) { const span = helpItems.applicableSpan; return { ...helpItems, applicableSpan: { start: scriptInfo.positionToLineOffset(span.start), end: scriptInfo.positionToLineOffset(span.start + span.length) }, items: this.mapSignatureHelpItems(helpItems.items, project, useDisplayParts) }; } else if (useDisplayParts || !helpItems) { return helpItems; } else { return { ...helpItems, items: helpItems.items.map((item) => ({ ...item, tags: this.mapJSDocTagInfo( item.tags, project, /*richResponse*/ false ) })) }; } } toPendingErrorCheck(uncheckedFileName) { const fileName = toNormalizedPath(uncheckedFileName); const project = this.projectService.tryGetDefaultProjectForFile(fileName); return project && { fileName, project }; } getDiagnostics(next, delay, fileNames) { if (this.suppressDiagnosticEvents) { return; } if (fileNames.length > 0) { this.updateErrorCheck(next, fileNames, delay); } } change(args) { const scriptInfo = this.projectService.getScriptInfo(args.file); Debug.assert(!!scriptInfo); scriptInfo.textStorage.switchToScriptVersionCache(); const start = scriptInfo.lineOffsetToPosition(args.line, args.offset); const end = scriptInfo.lineOffsetToPosition(args.endLine, args.endOffset); if (start >= 0) { this.changeSeq++; this.projectService.applyChangesToFile( scriptInfo, singleIterator({ span: { start, length: end - start }, newText: args.insertString // TODO: GH#18217 }) ); } } reload(args, reqSeq) { const file = toNormalizedPath(args.file); const tempFileName = args.tmpfile === void 0 ? void 0 : toNormalizedPath(args.tmpfile); const info = this.projectService.getScriptInfoForNormalizedPath(file); if (info) { this.changeSeq++; if (info.reloadFromFile(tempFileName)) { this.doOutput( /*info*/ void 0, "reload" /* Reload */, reqSeq, /*success*/ true ); } } } saveToTmp(fileName, tempFileName) { const scriptInfo = this.projectService.getScriptInfo(fileName); if (scriptInfo) { scriptInfo.saveTo(tempFileName); } } closeClientFile(fileName) { if (!fileName) { return; } const file = normalizePath(fileName); this.projectService.closeClientFile(file); } mapLocationNavigationBarItems(items, scriptInfo) { return map(items, (item) => ({ text: item.text, kind: item.kind, kindModifiers: item.kindModifiers, spans: item.spans.map((span) => toProtocolTextSpan(span, scriptInfo)), childItems: this.mapLocationNavigationBarItems(item.childItems, scriptInfo), indent: item.indent })); } getNavigationBarItems(args, simplifiedResult) { const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args); const items = languageService.getNavigationBarItems(file); return !items ? void 0 : simplifiedResult ? this.mapLocationNavigationBarItems(items, this.projectService.getScriptInfoForNormalizedPath(file)) : items; } toLocationNavigationTree(tree, scriptInfo) { return { text: tree.text, kind: tree.kind, kindModifiers: tree.kindModifiers, spans: tree.spans.map((span) => toProtocolTextSpan(span, scriptInfo)), nameSpan: tree.nameSpan && toProtocolTextSpan(tree.nameSpan, scriptInfo), childItems: map(tree.childItems, (item) => this.toLocationNavigationTree(item, scriptInfo)) }; } getNavigationTree(args, simplifiedResult) { const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args); const tree = languageService.getNavigationTree(file); return !tree ? void 0 : simplifiedResult ? this.toLocationNavigationTree(tree, this.projectService.getScriptInfoForNormalizedPath(file)) : tree; } getNavigateToItems(args, simplifiedResult) { const full = this.getFullNavigateToItems(args); return !simplifiedResult ? flatMap(full, ({ navigateToItems }) => navigateToItems) : flatMap( full, ({ project, navigateToItems }) => navigateToItems.map((navItem) => { const scriptInfo = project.getScriptInfo(navItem.fileName); const bakedItem = { name: navItem.name, kind: navItem.kind, kindModifiers: navItem.kindModifiers, isCaseSensitive: navItem.isCaseSensitive, matchKind: navItem.matchKind, file: navItem.fileName, start: scriptInfo.positionToLineOffset(navItem.textSpan.start), end: scriptInfo.positionToLineOffset(textSpanEnd(navItem.textSpan)) }; if (navItem.kindModifiers && navItem.kindModifiers !== "") { bakedItem.kindModifiers = navItem.kindModifiers; } if (navItem.containerName && navItem.containerName.length > 0) { bakedItem.containerName = navItem.containerName; } if (navItem.containerKind && navItem.containerKind.length > 0) { bakedItem.containerKind = navItem.containerKind; } return bakedItem; }) ); } getFullNavigateToItems(args) { const { currentFileOnly, searchValue, maxResultCount, projectFileName } = args; if (currentFileOnly) { Debug.assertIsDefined(args.file); const { file, project } = this.getFileAndProject(args); return [{ project, navigateToItems: project.getLanguageService().getNavigateToItems(searchValue, maxResultCount, file) }]; } const preferences = this.getHostPreferences(); const outputs = []; const seenItems = /* @__PURE__ */ new Map(); if (!args.file && !projectFileName) { this.projectService.loadAncestorProjectTree(); this.projectService.forEachEnabledProject((project) => addItemsForProject(project)); } else { const projects = this.getProjects(args); forEachProjectInProjects( projects, /*path*/ void 0, (project) => addItemsForProject(project) ); } return outputs; function addItemsForProject(project) { const projectItems = project.getLanguageService().getNavigateToItems( searchValue, maxResultCount, /*fileName*/ void 0, /*excludeDts*/ project.isNonTsProject(), /*excludeLibFiles*/ preferences.excludeLibrarySymbolsInNavTo ); const unseenItems = filter(projectItems, (item) => tryAddSeenItem(item) && !getMappedLocationForProject(documentSpanLocation(item), project)); if (unseenItems.length) { outputs.push({ project, navigateToItems: unseenItems }); } } function tryAddSeenItem(item) { const name = item.name; if (!seenItems.has(name)) { seenItems.set(name, [item]); return true; } const seen = seenItems.get(name); for (const seenItem of seen) { if (navigateToItemIsEqualTo(seenItem, item)) { return false; } } seen.push(item); return true; } function navigateToItemIsEqualTo(a, b) { if (a === b) { return true; } if (!a || !b) { return false; } return a.containerKind === b.containerKind && a.containerName === b.containerName && a.fileName === b.fileName && a.isCaseSensitive === b.isCaseSensitive && a.kind === b.kind && a.kindModifiers === b.kindModifiers && a.matchKind === b.matchKind && a.name === b.name && a.textSpan.start === b.textSpan.start && a.textSpan.length === b.textSpan.length; } } getSupportedCodeFixes(args) { if (!args) return getSupportedCodeFixes(); if (args.file) { const { file, project: project2 } = this.getFileAndProject(args); return project2.getLanguageService().getSupportedCodeFixes(file); } const project = this.getProject(args.projectFileName); if (!project) Errors.ThrowNoProject(); return project.getLanguageService().getSupportedCodeFixes(); } isLocation(locationOrSpan) { return locationOrSpan.line !== void 0; } extractPositionOrRange(args, scriptInfo) { let position; let textRange; if (this.isLocation(args)) { position = getPosition(args); } else { textRange = this.getRange(args, scriptInfo); } return Debug.checkDefined(position === void 0 ? textRange : position); function getPosition(loc) { return loc.position !== void 0 ? loc.position : scriptInfo.lineOffsetToPosition(loc.line, loc.offset); } } getRange(args, scriptInfo) { const { startPosition, endPosition } = this.getStartAndEndPosition(args, scriptInfo); return { pos: startPosition, end: endPosition }; } getApplicableRefactors(args) { const { file, project } = this.getFileAndProject(args); const scriptInfo = project.getScriptInfoForNormalizedPath(file); const result = project.getLanguageService().getApplicableRefactors(file, this.extractPositionOrRange(args, scriptInfo), this.getPreferences(file), args.triggerReason, args.kind, args.includeInteractiveActions); return result.map((result2) => ({ ...result2, actions: result2.actions.map((action) => ({ ...action, range: action.range ? { start: convertToLocation({ line: action.range.start.line, character: action.range.start.offset }), end: convertToLocation({ line: action.range.end.line, character: action.range.end.offset }) } : void 0 })) })); } getEditsForRefactor(args, simplifiedResult) { const { file, project } = this.getFileAndProject(args); const scriptInfo = project.getScriptInfoForNormalizedPath(file); const result = project.getLanguageService().getEditsForRefactor( file, this.getFormatOptions(file), this.extractPositionOrRange(args, scriptInfo), args.refactor, args.action, this.getPreferences(file), args.interactiveRefactorArguments ); if (result === void 0) { return { edits: [] }; } if (simplifiedResult) { const { renameFilename, renameLocation, edits } = result; let mappedRenameLocation; if (renameFilename !== void 0 && renameLocation !== void 0) { const renameScriptInfo = project.getScriptInfoForNormalizedPath(toNormalizedPath(renameFilename)); mappedRenameLocation = getLocationInNewDocument(getSnapshotText(renameScriptInfo.getSnapshot()), renameFilename, renameLocation, edits); } return { renameLocation: mappedRenameLocation, renameFilename, edits: this.mapTextChangesToCodeEdits(edits), notApplicableReason: result.notApplicableReason }; } return result; } getMoveToRefactoringFileSuggestions(args) { const { file, project } = this.getFileAndProject(args); const scriptInfo = project.getScriptInfoForNormalizedPath(file); return project.getLanguageService().getMoveToRefactoringFileSuggestions(file, this.extractPositionOrRange(args, scriptInfo), this.getPreferences(file)); } getPasteEdits(args) { const { file, project } = this.getFileAndProject(args); const copiedFrom = args.copiedFrom ? { file: args.copiedFrom.file, range: args.copiedFrom.spans.map((copies) => this.getRange({ file: args.copiedFrom.file, startLine: copies.start.line, startOffset: copies.start.offset, endLine: copies.end.line, endOffset: copies.end.offset }, project.getScriptInfoForNormalizedPath(toNormalizedPath(args.copiedFrom.file)))) } : void 0; const result = project.getLanguageService().getPasteEdits( { targetFile: file, pastedText: args.pastedText, pasteLocations: args.pasteLocations.map((paste) => this.getRange({ file, startLine: paste.start.line, startOffset: paste.start.offset, endLine: paste.end.line, endOffset: paste.end.offset }, project.getScriptInfoForNormalizedPath(file))), copiedFrom, preferences: this.getPreferences(file) }, this.getFormatOptions(file) ); return result && this.mapPasteEditsAction(result); } organizeImports(args, simplifiedResult) { Debug.assert(args.scope.type === "file"); const { file, project } = this.getFileAndProject(args.scope.args); const changes = project.getLanguageService().organizeImports( { fileName: file, mode: args.mode ?? (args.skipDestructiveCodeActions ? "SortAndCombine" /* SortAndCombine */ : void 0), type: "file" }, this.getFormatOptions(file), this.getPreferences(file) ); if (simplifiedResult) { return this.mapTextChangesToCodeEdits(changes); } else { return changes; } } getEditsForFileRename(args, simplifiedResult) { const oldPath = toNormalizedPath(args.oldFilePath); const newPath = toNormalizedPath(args.newFilePath); const formatOptions = this.getHostFormatOptions(); const preferences = this.getHostPreferences(); const seenFiles = /* @__PURE__ */ new Set(); const textChanges2 = []; this.projectService.loadAncestorProjectTree(); this.projectService.forEachEnabledProject((project) => { const projectTextChanges = project.getLanguageService().getEditsForFileRename(oldPath, newPath, formatOptions, preferences); const projectFiles = []; for (const textChange of projectTextChanges) { if (!seenFiles.has(textChange.fileName)) { textChanges2.push(textChange); projectFiles.push(textChange.fileName); } } for (const file of projectFiles) { seenFiles.add(file); } }); return simplifiedResult ? textChanges2.map((c) => this.mapTextChangeToCodeEdit(c)) : textChanges2; } getCodeFixes(args, simplifiedResult) { const { file, project } = this.getFileAndProject(args); const scriptInfo = project.getScriptInfoForNormalizedPath(file); const { startPosition, endPosition } = this.getStartAndEndPosition(args, scriptInfo); let codeActions; try { codeActions = project.getLanguageService().getCodeFixesAtPosition(file, startPosition, endPosition, args.errorCodes, this.getFormatOptions(file), this.getPreferences(file)); } catch (e) { const ls = project.getLanguageService(); const existingDiagCodes = [ ...ls.getSyntacticDiagnostics(file), ...ls.getSemanticDiagnostics(file), ...ls.getSuggestionDiagnostics(file) ].map( (d) => decodedTextSpanIntersectsWith(startPosition, endPosition - startPosition, d.start, d.length) && d.code ); const badCode = args.errorCodes.find((c) => !existingDiagCodes.includes(c)); if (badCode !== void 0) { e.message = `BADCLIENT: Bad error code, ${badCode} not found in range ${startPosition}..${endPosition} (found: ${existingDiagCodes.join(", ")}); could have caused this error: ${e.message}`; } throw e; } return simplifiedResult ? codeActions.map((codeAction) => this.mapCodeFixAction(codeAction)) : codeActions; } getCombinedCodeFix({ scope, fixId: fixId55 }, simplifiedResult) { Debug.assert(scope.type === "file"); const { file, project } = this.getFileAndProject(scope.args); const res = project.getLanguageService().getCombinedCodeFix({ type: "file", fileName: file }, fixId55, this.getFormatOptions(file), this.getPreferences(file)); if (simplifiedResult) { return { changes: this.mapTextChangesToCodeEdits(res.changes), commands: res.commands }; } else { return res; } } applyCodeActionCommand(args) { const commands = args.command; for (const command of toArray(commands)) { const { file, project } = this.getFileAndProject(command); project.getLanguageService().applyCodeActionCommand(command, this.getFormatOptions(file)).then( (_result) => { }, (_error) => { } ); } return {}; } getStartAndEndPosition(args, scriptInfo) { let startPosition, endPosition; if (args.startPosition !== void 0) { startPosition = args.startPosition; } else { startPosition = scriptInfo.lineOffsetToPosition(args.startLine, args.startOffset); args.startPosition = startPosition; } if (args.endPosition !== void 0) { endPosition = args.endPosition; } else { endPosition = scriptInfo.lineOffsetToPosition(args.endLine, args.endOffset); args.endPosition = endPosition; } return { startPosition, endPosition }; } mapCodeAction({ description: description3, changes, commands }) { return { description: description3, changes: this.mapTextChangesToCodeEdits(changes), commands }; } mapCodeFixAction({ fixName: fixName8, description: description3, changes, commands, fixId: fixId55, fixAllDescription }) { return { fixName: fixName8, description: description3, changes: this.mapTextChangesToCodeEdits(changes), commands, fixId: fixId55, fixAllDescription }; } mapPasteEditsAction({ edits, fixId: fixId55 }) { return { edits: this.mapTextChangesToCodeEdits(edits), fixId: fixId55 }; } mapTextChangesToCodeEdits(textChanges2) { return textChanges2.map((change) => this.mapTextChangeToCodeEdit(change)); } mapTextChangeToCodeEdit(textChanges2) { const scriptInfo = this.projectService.getScriptInfoOrConfig(textChanges2.fileName); if (!!textChanges2.isNewFile === !!scriptInfo) { if (!scriptInfo) { this.projectService.logErrorForScriptInfoNotFound(textChanges2.fileName); } Debug.fail("Expected isNewFile for (only) new files. " + JSON.stringify({ isNewFile: !!textChanges2.isNewFile, hasScriptInfo: !!scriptInfo })); } return scriptInfo ? { fileName: textChanges2.fileName, textChanges: textChanges2.textChanges.map((textChange) => convertTextChangeToCodeEdit(textChange, scriptInfo)) } : convertNewFileTextChangeToCodeEdit(textChanges2); } convertTextChangeToCodeEdit(change, scriptInfo) { return { start: scriptInfo.positionToLineOffset(change.span.start), end: scriptInfo.positionToLineOffset(change.span.start + change.span.length), newText: change.newText ? change.newText : "" }; } getBraceMatching(args, simplifiedResult) { const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args); const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file); const position = this.getPosition(args, scriptInfo); const spans = languageService.getBraceMatchingAtPosition(file, position); return !spans ? void 0 : simplifiedResult ? spans.map((span) => toProtocolTextSpan(span, scriptInfo)) : spans; } getDiagnosticsForProject(next, delay, fileName) { if (this.suppressDiagnosticEvents) { return; } const { fileNames, languageServiceDisabled } = this.getProjectInfoWorker( fileName, /*projectFileName*/ void 0, /*needFileNameList*/ true, /*excludeConfigFiles*/ true ); if (languageServiceDisabled) { return; } const fileNamesInProject = fileNames.filter((value) => !value.includes("lib.d.ts")); if (fileNamesInProject.length === 0) { return; } const highPriorityFiles = []; const mediumPriorityFiles = []; const lowPriorityFiles = []; const veryLowPriorityFiles = []; const normalizedFileName = toNormalizedPath(fileName); const project = this.projectService.ensureDefaultProjectForFile(normalizedFileName); for (const fileNameInProject of fileNamesInProject) { if (this.getCanonicalFileName(fileNameInProject) === this.getCanonicalFileName(fileName)) { highPriorityFiles.push(fileNameInProject); } else { const info = this.projectService.getScriptInfo(fileNameInProject); if (!info.isScriptOpen()) { if (isDeclarationFileName(fileNameInProject)) { veryLowPriorityFiles.push(fileNameInProject); } else { lowPriorityFiles.push(fileNameInProject); } } else { mediumPriorityFiles.push(fileNameInProject); } } } const sortedFiles = [...highPriorityFiles, ...mediumPriorityFiles, ...lowPriorityFiles, ...veryLowPriorityFiles]; const checkList = sortedFiles.map((fileName2) => ({ fileName: fileName2, project })); this.updateErrorCheck( next, checkList, delay, /*requireOpen*/ false ); } configurePlugin(args) { this.projectService.configurePlugin(args); } getSmartSelectionRange(args, simplifiedResult) { const { locations } = args; const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args); const scriptInfo = Debug.checkDefined(this.projectService.getScriptInfo(file)); return map(locations, (location) => { const pos = this.getPosition(location, scriptInfo); const selectionRange = languageService.getSmartSelectionRange(file, pos); return simplifiedResult ? this.mapSelectionRange(selectionRange, scriptInfo) : selectionRange; }); } toggleLineComment(args, simplifiedResult) { const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args); const scriptInfo = this.projectService.getScriptInfo(file); const textRange = this.getRange(args, scriptInfo); const textChanges2 = languageService.toggleLineComment(file, textRange); if (simplifiedResult) { const scriptInfo2 = this.projectService.getScriptInfoForNormalizedPath(file); return textChanges2.map((textChange) => this.convertTextChangeToCodeEdit(textChange, scriptInfo2)); } return textChanges2; } toggleMultilineComment(args, simplifiedResult) { const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args); const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file); const textRange = this.getRange(args, scriptInfo); const textChanges2 = languageService.toggleMultilineComment(file, textRange); if (simplifiedResult) { const scriptInfo2 = this.projectService.getScriptInfoForNormalizedPath(file); return textChanges2.map((textChange) => this.convertTextChangeToCodeEdit(textChange, scriptInfo2)); } return textChanges2; } commentSelection(args, simplifiedResult) { const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args); const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file); const textRange = this.getRange(args, scriptInfo); const textChanges2 = languageService.commentSelection(file, textRange); if (simplifiedResult) { const scriptInfo2 = this.projectService.getScriptInfoForNormalizedPath(file); return textChanges2.map((textChange) => this.convertTextChangeToCodeEdit(textChange, scriptInfo2)); } return textChanges2; } uncommentSelection(args, simplifiedResult) { const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args); const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file); const textRange = this.getRange(args, scriptInfo); const textChanges2 = languageService.uncommentSelection(file, textRange); if (simplifiedResult) { const scriptInfo2 = this.projectService.getScriptInfoForNormalizedPath(file); return textChanges2.map((textChange) => this.convertTextChangeToCodeEdit(textChange, scriptInfo2)); } return textChanges2; } mapSelectionRange(selectionRange, scriptInfo) { const result = { textSpan: toProtocolTextSpan(selectionRange.textSpan, scriptInfo) }; if (selectionRange.parent) { result.parent = this.mapSelectionRange(selectionRange.parent, scriptInfo); } return result; } getScriptInfoFromProjectService(file) { const normalizedFile = toNormalizedPath(file); const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(normalizedFile); if (!scriptInfo) { this.projectService.logErrorForScriptInfoNotFound(normalizedFile); return Errors.ThrowNoProject(); } return scriptInfo; } toProtocolCallHierarchyItem(item) { const scriptInfo = this.getScriptInfoFromProjectService(item.file); return { name: item.name, kind: item.kind, kindModifiers: item.kindModifiers, file: item.file, containerName: item.containerName, span: toProtocolTextSpan(item.span, scriptInfo), selectionSpan: toProtocolTextSpan(item.selectionSpan, scriptInfo) }; } toProtocolCallHierarchyIncomingCall(incomingCall) { const scriptInfo = this.getScriptInfoFromProjectService(incomingCall.from.file); return { from: this.toProtocolCallHierarchyItem(incomingCall.from), fromSpans: incomingCall.fromSpans.map((fromSpan) => toProtocolTextSpan(fromSpan, scriptInfo)) }; } toProtocolCallHierarchyOutgoingCall(outgoingCall, scriptInfo) { return { to: this.toProtocolCallHierarchyItem(outgoingCall.to), fromSpans: outgoingCall.fromSpans.map((fromSpan) => toProtocolTextSpan(fromSpan, scriptInfo)) }; } prepareCallHierarchy(args) { const { file, project } = this.getFileAndProject(args); const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file); if (scriptInfo) { const position = this.getPosition(args, scriptInfo); const result = project.getLanguageService().prepareCallHierarchy(file, position); return result && mapOneOrMany(result, (item) => this.toProtocolCallHierarchyItem(item)); } return void 0; } provideCallHierarchyIncomingCalls(args) { const { file, project } = this.getFileAndProject(args); const scriptInfo = this.getScriptInfoFromProjectService(file); const incomingCalls = project.getLanguageService().provideCallHierarchyIncomingCalls(file, this.getPosition(args, scriptInfo)); return incomingCalls.map((call) => this.toProtocolCallHierarchyIncomingCall(call)); } provideCallHierarchyOutgoingCalls(args) { const { file, project } = this.getFileAndProject(args); const scriptInfo = this.getScriptInfoFromProjectService(file); const outgoingCalls = project.getLanguageService().provideCallHierarchyOutgoingCalls(file, this.getPosition(args, scriptInfo)); return outgoingCalls.map((call) => this.toProtocolCallHierarchyOutgoingCall(call, scriptInfo)); } getCanonicalFileName(fileName) { const name = this.host.useCaseSensitiveFileNames ? fileName : toFileNameLowerCase(fileName); return normalizePath(name); } exit() { } notRequired() { return { responseRequired: false }; } requiredResponse(response) { return { response, responseRequired: true }; } addProtocolHandler(command, handler) { if (this.handlers.has(command)) { throw new Error(`Protocol handler already exists for command "${command}"`); } this.handlers.set(command, handler); } setCurrentRequest(requestId) { Debug.assert(this.currentRequestId === void 0); this.currentRequestId = requestId; this.cancellationToken.setRequest(requestId); } resetCurrentRequest(requestId) { Debug.assert(this.currentRequestId === requestId); this.currentRequestId = void 0; this.cancellationToken.resetRequest(requestId); } executeWithRequestId(requestId, f) { try { this.setCurrentRequest(requestId); return f(); } finally { this.resetCurrentRequest(requestId); } } executeCommand(request) { const handler = this.handlers.get(request.command); if (handler) { const response = this.executeWithRequestId(request.seq, () => handler(request)); this.projectService.enableRequestedPlugins(); return response; } else { this.logger.msg(`Unrecognized JSON command:${stringifyIndented(request)}`, "Err" /* Err */); this.doOutput( /*info*/ void 0, "unknown" /* Unknown */, request.seq, /*success*/ false, `Unrecognized JSON command: ${request.command}` ); return { responseRequired: false }; } } onMessage(message) { var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k; this.gcTimer.scheduleCollect(); this.performanceData = void 0; let start; if (this.logger.hasLevel(2 /* requestTime */)) { start = this.hrtime(); if (this.logger.hasLevel(3 /* verbose */)) { this.logger.info(`request:${indent2(this.toStringMessage(message))}`); } } let request; let relevantFile; try { request = this.parseMessage(message); relevantFile = request.arguments && request.arguments.file ? request.arguments : void 0; (_a = tracing) == null ? void 0 : _a.instant(tracing.Phase.Session, "request", { seq: request.seq, command: request.command }); (_b = perfLogger) == null ? void 0 : _b.logStartCommand("" + request.command, this.toStringMessage(message).substring(0, 100)); (_c = tracing) == null ? void 0 : _c.push( tracing.Phase.Session, "executeCommand", { seq: request.seq, command: request.command }, /*separateBeginAndEnd*/ true ); const { response, responseRequired } = this.executeCommand(request); (_d = tracing) == null ? void 0 : _d.pop(); if (this.logger.hasLevel(2 /* requestTime */)) { const elapsedTime = hrTimeToMilliseconds(this.hrtime(start)).toFixed(4); if (responseRequired) { this.logger.perftrc(`${request.seq}::${request.command}: elapsed time (in milliseconds) ${elapsedTime}`); } else { this.logger.perftrc(`${request.seq}::${request.command}: async elapsed time (in milliseconds) ${elapsedTime}`); } } (_e = perfLogger) == null ? void 0 : _e.logStopCommand("" + request.command, "Success"); (_f = tracing) == null ? void 0 : _f.instant(tracing.Phase.Session, "response", { seq: request.seq, command: request.command, success: !!response }); if (response) { this.doOutput( response, request.command, request.seq, /*success*/ true ); } else if (responseRequired) { this.doOutput( /*info*/ void 0, request.command, request.seq, /*success*/ false, "No content available." ); } } catch (err) { (_g = tracing) == null ? void 0 : _g.popAll(); if (err instanceof OperationCanceledException) { (_h = perfLogger) == null ? void 0 : _h.logStopCommand("" + (request && request.command), "Canceled: " + err); (_i = tracing) == null ? void 0 : _i.instant(tracing.Phase.Session, "commandCanceled", { seq: request == null ? void 0 : request.seq, command: request == null ? void 0 : request.command }); this.doOutput( { canceled: true }, request.command, request.seq, /*success*/ true ); return; } this.logErrorWorker(err, this.toStringMessage(message), relevantFile); (_j = perfLogger) == null ? void 0 : _j.logStopCommand("" + (request && request.command), "Error: " + err); (_k = tracing) == null ? void 0 : _k.instant(tracing.Phase.Session, "commandError", { seq: request == null ? void 0 : request.seq, command: request == null ? void 0 : request.command, message: err.message }); this.doOutput( /*info*/ void 0, request ? request.command : "unknown" /* Unknown */, request ? request.seq : 0, /*success*/ false, "Error processing request. " + err.message + "\n" + err.stack ); } } parseMessage(message) { return JSON.parse(message); } toStringMessage(message) { return message; } getFormatOptions(file) { return this.projectService.getFormatCodeOptions(file); } getPreferences(file) { return this.projectService.getPreferences(file); } getHostFormatOptions() { return this.projectService.getHostFormatCodeOptions(); } getHostPreferences() { return this.projectService.getHostPreferences(); } }; function toProtocolTextSpan(textSpan, scriptInfo) { return { start: scriptInfo.positionToLineOffset(textSpan.start), end: scriptInfo.positionToLineOffset(textSpanEnd(textSpan)) }; } function toProtocolTextSpanWithContext(span, contextSpan, scriptInfo) { const textSpan = toProtocolTextSpan(span, scriptInfo); const contextTextSpan = contextSpan && toProtocolTextSpan(contextSpan, scriptInfo); return contextTextSpan ? { ...textSpan, contextStart: contextTextSpan.start, contextEnd: contextTextSpan.end } : textSpan; } function convertTextChangeToCodeEdit(change, scriptInfo) { return { start: positionToLineOffset(scriptInfo, change.span.start), end: positionToLineOffset(scriptInfo, textSpanEnd(change.span)), newText: change.newText }; } function positionToLineOffset(info, position) { return isConfigFile(info) ? locationFromLineAndCharacter(info.getLineAndCharacterOfPosition(position)) : info.positionToLineOffset(position); } function convertLinkedEditInfoToRanges(linkedEdit, scriptInfo) { const ranges = linkedEdit.ranges.map( (r) => { return { start: scriptInfo.positionToLineOffset(r.start), end: scriptInfo.positionToLineOffset(r.start + r.length) }; } ); if (!linkedEdit.wordPattern) return { ranges }; return { ranges, wordPattern: linkedEdit.wordPattern }; } function locationFromLineAndCharacter(lc) { return { line: lc.line + 1, offset: lc.character + 1 }; } function convertNewFileTextChangeToCodeEdit(textChanges2) { Debug.assert(textChanges2.textChanges.length === 1); const change = first(textChanges2.textChanges); Debug.assert(change.span.start === 0 && change.span.length === 0); return { fileName: textChanges2.fileName, textChanges: [{ start: { line: 0, offset: 0 }, end: { line: 0, offset: 0 }, newText: change.newText }] }; } function getLocationInNewDocument(oldText, renameFilename, renameLocation, edits) { const newText = applyEdits(oldText, renameFilename, edits); const { line, character } = computeLineAndCharacterOfPosition(computeLineStarts(newText), renameLocation); return { line: line + 1, offset: character + 1 }; } function applyEdits(text, textFilename, edits) { for (const { fileName, textChanges: textChanges2 } of edits) { if (fileName !== textFilename) { continue; } for (let i = textChanges2.length - 1; i >= 0; i--) { const { newText, span: { start, length: length2 } } = textChanges2[i]; text = text.slice(0, start) + newText + text.slice(start + length2); } } return text; } function referenceEntryToReferencesResponseItem(projectService, { fileName, textSpan, contextSpan, isWriteAccess: isWriteAccess2, isDefinition }, { disableLineTextInReferences }) { const scriptInfo = Debug.checkDefined(projectService.getScriptInfo(fileName)); const span = toProtocolTextSpanWithContext(textSpan, contextSpan, scriptInfo); const lineText = disableLineTextInReferences ? void 0 : getLineText(scriptInfo, span); return { file: fileName, ...span, lineText, isWriteAccess: isWriteAccess2, isDefinition }; } function getLineText(scriptInfo, span) { const lineSpan = scriptInfo.lineToTextSpan(span.start.line - 1); return scriptInfo.getSnapshot().getText(lineSpan.start, textSpanEnd(lineSpan)).replace(/\r|\n/g, ""); } function isCompletionEntryData(data) { return data === void 0 || data && typeof data === "object" && typeof data.exportName === "string" && (data.fileName === void 0 || typeof data.fileName === "string") && (data.ambientModuleName === void 0 || typeof data.ambientModuleName === "string" && (data.isPackageJsonImport === void 0 || typeof data.isPackageJsonImport === "boolean")); } // src/server/scriptVersionCache.ts var lineCollectionCapacity = 4; var CharRangeSection = /* @__PURE__ */ ((CharRangeSection2) => { CharRangeSection2[CharRangeSection2["PreStart"] = 0] = "PreStart"; CharRangeSection2[CharRangeSection2["Start"] = 1] = "Start"; CharRangeSection2[CharRangeSection2["Entire"] = 2] = "Entire"; CharRangeSection2[CharRangeSection2["Mid"] = 3] = "Mid"; CharRangeSection2[CharRangeSection2["End"] = 4] = "End"; CharRangeSection2[CharRangeSection2["PostEnd"] = 5] = "PostEnd"; return CharRangeSection2; })(CharRangeSection || {}); var EditWalker = class { constructor() { this.goSubtree = true; this.lineIndex = new LineIndex(); this.endBranch = []; this.state = 2 /* Entire */; this.initialText = ""; this.trailingText = ""; this.lineIndex.root = new LineNode(); this.startPath = [this.lineIndex.root]; this.stack = [this.lineIndex.root]; } get done() { return false; } insertLines(insertedText, suppressTrailingText) { if (suppressTrailingText) { this.trailingText = ""; } if (insertedText) { insertedText = this.initialText + insertedText + this.trailingText; } else { insertedText = this.initialText + this.trailingText; } const lm = LineIndex.linesFromText(insertedText); const lines = lm.lines; if (lines.length > 1 && lines[lines.length - 1] === "") { lines.pop(); } let branchParent; let lastZeroCount; for (let k = this.endBranch.length - 1; k >= 0; k--) { this.endBranch[k].updateCounts(); if (this.endBranch[k].charCount() === 0) { lastZeroCount = this.endBranch[k]; if (k > 0) { branchParent = this.endBranch[k - 1]; } else { branchParent = this.branchNode; } } } if (lastZeroCount) { branchParent.remove(lastZeroCount); } const leafNode = this.startPath[this.startPath.length - 1]; if (lines.length > 0) { leafNode.text = lines[0]; if (lines.length > 1) { let insertedNodes = new Array(lines.length - 1); let startNode2 = leafNode; for (let i = 1; i < lines.length; i++) { insertedNodes[i - 1] = new LineLeaf(lines[i]); } let pathIndex = this.startPath.length - 2; while (pathIndex >= 0) { const insertionNode = this.startPath[pathIndex]; insertedNodes = insertionNode.insertAt(startNode2, insertedNodes); pathIndex--; startNode2 = insertionNode; } let insertedNodesLen = insertedNodes.length; while (insertedNodesLen > 0) { const newRoot = new LineNode(); newRoot.add(this.lineIndex.root); insertedNodes = newRoot.insertAt(this.lineIndex.root, insertedNodes); insertedNodesLen = insertedNodes.length; this.lineIndex.root = newRoot; } this.lineIndex.root.updateCounts(); } else { for (let j = this.startPath.length - 2; j >= 0; j--) { this.startPath[j].updateCounts(); } } } else { const insertionNode = this.startPath[this.startPath.length - 2]; insertionNode.remove(leafNode); for (let j = this.startPath.length - 2; j >= 0; j--) { this.startPath[j].updateCounts(); } } return this.lineIndex; } post(_relativeStart, _relativeLength, lineCollection) { if (lineCollection === this.lineCollectionAtBranch) { this.state = 4 /* End */; } this.stack.pop(); } pre(_relativeStart, _relativeLength, lineCollection, _parent, nodeType) { const currentNode = this.stack[this.stack.length - 1]; if (this.state === 2 /* Entire */ && nodeType === 1 /* Start */) { this.state = 1 /* Start */; this.branchNode = currentNode; this.lineCollectionAtBranch = lineCollection; } let child; function fresh(node) { if (node.isLeaf()) { return new LineLeaf(""); } else return new LineNode(); } switch (nodeType) { case 0 /* PreStart */: this.goSubtree = false; if (this.state !== 4 /* End */) { currentNode.add(lineCollection); } break; case 1 /* Start */: if (this.state === 4 /* End */) { this.goSubtree = false; } else { child = fresh(lineCollection); currentNode.add(child); this.startPath.push(child); } break; case 2 /* Entire */: if (this.state !== 4 /* End */) { child = fresh(lineCollection); currentNode.add(child); this.startPath.push(child); } else { if (!lineCollection.isLeaf()) { child = fresh(lineCollection); currentNode.add(child); this.endBranch.push(child); } } break; case 3 /* Mid */: this.goSubtree = false; break; case 4 /* End */: if (this.state !== 4 /* End */) { this.goSubtree = false; } else { if (!lineCollection.isLeaf()) { child = fresh(lineCollection); currentNode.add(child); this.endBranch.push(child); } } break; case 5 /* PostEnd */: this.goSubtree = false; if (this.state !== 1 /* Start */) { currentNode.add(lineCollection); } break; } if (this.goSubtree) { this.stack.push(child); } } // just gather text from the leaves leaf(relativeStart, relativeLength, ll) { if (this.state === 1 /* Start */) { this.initialText = ll.text.substring(0, relativeStart); } else if (this.state === 2 /* Entire */) { this.initialText = ll.text.substring(0, relativeStart); this.trailingText = ll.text.substring(relativeStart + relativeLength); } else { this.trailingText = ll.text.substring(relativeStart + relativeLength); } } }; var TextChange9 = class { constructor(pos, deleteLen, insertedText) { this.pos = pos; this.deleteLen = deleteLen; this.insertedText = insertedText; } getTextChangeRange() { return createTextChangeRange(createTextSpan(this.pos, this.deleteLen), this.insertedText ? this.insertedText.length : 0); } }; var _ScriptVersionCache = class _ScriptVersionCache { constructor() { this.changes = []; this.versions = new Array(_ScriptVersionCache.maxVersions); this.minVersion = 0; // no versions earlier than min version will maintain change history this.currentVersion = 0; } versionToIndex(version2) { if (version2 < this.minVersion || version2 > this.currentVersion) { return void 0; } return version2 % _ScriptVersionCache.maxVersions; } currentVersionToIndex() { return this.currentVersion % _ScriptVersionCache.maxVersions; } // REVIEW: can optimize by coalescing simple edits edit(pos, deleteLen, insertedText) { this.changes.push(new TextChange9(pos, deleteLen, insertedText)); if (this.changes.length > _ScriptVersionCache.changeNumberThreshold || deleteLen > _ScriptVersionCache.changeLengthThreshold || insertedText && insertedText.length > _ScriptVersionCache.changeLengthThreshold) { this.getSnapshot(); } } getSnapshot() { return this._getSnapshot(); } _getSnapshot() { let snap = this.versions[this.currentVersionToIndex()]; if (this.changes.length > 0) { let snapIndex = snap.index; for (const change of this.changes) { snapIndex = snapIndex.edit(change.pos, change.deleteLen, change.insertedText); } snap = new LineIndexSnapshot(this.currentVersion + 1, this, snapIndex, this.changes); this.currentVersion = snap.version; this.versions[this.currentVersionToIndex()] = snap; this.changes = []; if (this.currentVersion - this.minVersion >= _ScriptVersionCache.maxVersions) { this.minVersion = this.currentVersion - _ScriptVersionCache.maxVersions + 1; } } return snap; } getSnapshotVersion() { return this._getSnapshot().version; } getAbsolutePositionAndLineText(oneBasedLine) { return this._getSnapshot().index.lineNumberToInfo(oneBasedLine); } lineOffsetToPosition(line, column) { return this._getSnapshot().index.absolutePositionOfStartOfLine(line) + (column - 1); } positionToLineOffset(position) { return this._getSnapshot().index.positionToLineOffset(position); } lineToTextSpan(line) { const index = this._getSnapshot().index; const { lineText, absolutePosition } = index.lineNumberToInfo(line + 1); const len = lineText !== void 0 ? lineText.length : index.absolutePositionOfStartOfLine(line + 2) - absolutePosition; return createTextSpan(absolutePosition, len); } getTextChangesBetweenVersions(oldVersion, newVersion) { if (oldVersion < newVersion) { if (oldVersion >= this.minVersion) { const textChangeRanges = []; for (let i = oldVersion + 1; i <= newVersion; i++) { const snap = this.versions[this.versionToIndex(i)]; for (const textChange of snap.changesSincePreviousVersion) { textChangeRanges.push(textChange.getTextChangeRange()); } } return collapseTextChangeRangesAcrossMultipleVersions(textChangeRanges); } else { return void 0; } } else { return unchangedTextChangeRange; } } getLineCount() { return this._getSnapshot().index.getLineCount(); } static fromString(script) { const svc = new _ScriptVersionCache(); const snap = new LineIndexSnapshot(0, svc, new LineIndex()); svc.versions[svc.currentVersion] = snap; const lm = LineIndex.linesFromText(script); snap.index.load(lm.lines); return svc; } }; _ScriptVersionCache.changeNumberThreshold = 8; _ScriptVersionCache.changeLengthThreshold = 256; _ScriptVersionCache.maxVersions = 8; var ScriptVersionCache = _ScriptVersionCache; var LineIndexSnapshot = class _LineIndexSnapshot { constructor(version2, cache, index, changesSincePreviousVersion = emptyArray2) { this.version = version2; this.cache = cache; this.index = index; this.changesSincePreviousVersion = changesSincePreviousVersion; } getText(rangeStart, rangeEnd) { return this.index.getText(rangeStart, rangeEnd - rangeStart); } getLength() { return this.index.getLength(); } getChangeRange(oldSnapshot) { if (oldSnapshot instanceof _LineIndexSnapshot && this.cache === oldSnapshot.cache) { if (this.version <= oldSnapshot.version) { return unchangedTextChangeRange; } else { return this.cache.getTextChangesBetweenVersions(oldSnapshot.version, this.version); } } } }; var LineIndex = class _LineIndex { constructor() { // set this to true to check each edit for accuracy this.checkEdits = false; } absolutePositionOfStartOfLine(oneBasedLine) { return this.lineNumberToInfo(oneBasedLine).absolutePosition; } positionToLineOffset(position) { const { oneBasedLine, zeroBasedColumn } = this.root.charOffsetToLineInfo(1, position); return { line: oneBasedLine, offset: zeroBasedColumn + 1 }; } positionToColumnAndLineText(position) { return this.root.charOffsetToLineInfo(1, position); } getLineCount() { return this.root.lineCount(); } lineNumberToInfo(oneBasedLine) { const lineCount = this.getLineCount(); if (oneBasedLine <= lineCount) { const { position, leaf } = this.root.lineNumberToInfo(oneBasedLine, 0); return { absolutePosition: position, lineText: leaf && leaf.text }; } else { return { absolutePosition: this.root.charCount(), lineText: void 0 }; } } load(lines) { if (lines.length > 0) { const leaves = []; for (let i = 0; i < lines.length; i++) { leaves[i] = new LineLeaf(lines[i]); } this.root = _LineIndex.buildTreeFromBottom(leaves); } else { this.root = new LineNode(); } } walk(rangeStart, rangeLength, walkFns) { this.root.walk(rangeStart, rangeLength, walkFns); } getText(rangeStart, rangeLength) { let accum = ""; if (rangeLength > 0 && rangeStart < this.root.charCount()) { this.walk(rangeStart, rangeLength, { goSubtree: true, done: false, leaf: (relativeStart, relativeLength, ll) => { accum = accum.concat(ll.text.substring(relativeStart, relativeStart + relativeLength)); } }); } return accum; } getLength() { return this.root.charCount(); } every(f, rangeStart, rangeEnd) { if (!rangeEnd) { rangeEnd = this.root.charCount(); } const walkFns = { goSubtree: true, done: false, leaf(relativeStart, relativeLength, ll) { if (!f(ll, relativeStart, relativeLength)) { this.done = true; } } }; this.walk(rangeStart, rangeEnd - rangeStart, walkFns); return !walkFns.done; } edit(pos, deleteLength, newText) { if (this.root.charCount() === 0) { Debug.assert(deleteLength === 0); if (newText !== void 0) { this.load(_LineIndex.linesFromText(newText).lines); return this; } return void 0; } else { let checkText; if (this.checkEdits) { const source = this.getText(0, this.root.charCount()); checkText = source.slice(0, pos) + newText + source.slice(pos + deleteLength); } const walker = new EditWalker(); let suppressTrailingText = false; if (pos >= this.root.charCount()) { pos = this.root.charCount() - 1; const endString = this.getText(pos, 1); if (newText) { newText = endString + newText; } else { newText = endString; } deleteLength = 0; suppressTrailingText = true; } else if (deleteLength > 0) { const e = pos + deleteLength; const { zeroBasedColumn, lineText } = this.positionToColumnAndLineText(e); if (zeroBasedColumn === 0) { deleteLength += lineText.length; newText = newText ? newText + lineText : lineText; } } this.root.walk(pos, deleteLength, walker); walker.insertLines(newText, suppressTrailingText); if (this.checkEdits) { const updatedText = walker.lineIndex.getText(0, walker.lineIndex.getLength()); Debug.assert(checkText === updatedText, "buffer edit mismatch"); } return walker.lineIndex; } } static buildTreeFromBottom(nodes) { if (nodes.length < lineCollectionCapacity) { return new LineNode(nodes); } const interiorNodes = new Array(Math.ceil(nodes.length / lineCollectionCapacity)); let nodeIndex = 0; for (let i = 0; i < interiorNodes.length; i++) { const end = Math.min(nodeIndex + lineCollectionCapacity, nodes.length); interiorNodes[i] = new LineNode(nodes.slice(nodeIndex, end)); nodeIndex = end; } return this.buildTreeFromBottom(interiorNodes); } static linesFromText(text) { const lineMap = computeLineStarts(text); if (lineMap.length === 0) { return { lines: [], lineMap }; } const lines = new Array(lineMap.length); const lc = lineMap.length - 1; for (let lmi = 0; lmi < lc; lmi++) { lines[lmi] = text.substring(lineMap[lmi], lineMap[lmi + 1]); } const endText = text.substring(lineMap[lc]); if (endText.length > 0) { lines[lc] = endText; } else { lines.pop(); } return { lines, lineMap }; } }; var LineNode = class _LineNode { constructor(children = []) { this.children = children; this.totalChars = 0; this.totalLines = 0; if (children.length) this.updateCounts(); } isLeaf() { return false; } updateCounts() { this.totalChars = 0; this.totalLines = 0; for (const child of this.children) { this.totalChars += child.charCount(); this.totalLines += child.lineCount(); } } execWalk(rangeStart, rangeLength, walkFns, childIndex, nodeType) { if (walkFns.pre) { walkFns.pre(rangeStart, rangeLength, this.children[childIndex], this, nodeType); } if (walkFns.goSubtree) { this.children[childIndex].walk(rangeStart, rangeLength, walkFns); if (walkFns.post) { walkFns.post(rangeStart, rangeLength, this.children[childIndex], this, nodeType); } } else { walkFns.goSubtree = true; } return walkFns.done; } skipChild(relativeStart, relativeLength, childIndex, walkFns, nodeType) { if (walkFns.pre && !walkFns.done) { walkFns.pre(relativeStart, relativeLength, this.children[childIndex], this, nodeType); walkFns.goSubtree = true; } } walk(rangeStart, rangeLength, walkFns) { let childIndex = 0; let childCharCount = this.children[childIndex].charCount(); let adjustedStart = rangeStart; while (adjustedStart >= childCharCount) { this.skipChild(adjustedStart, rangeLength, childIndex, walkFns, 0 /* PreStart */); adjustedStart -= childCharCount; childIndex++; childCharCount = this.children[childIndex].charCount(); } if (adjustedStart + rangeLength <= childCharCount) { if (this.execWalk(adjustedStart, rangeLength, walkFns, childIndex, 2 /* Entire */)) { return; } } else { if (this.execWalk(adjustedStart, childCharCount - adjustedStart, walkFns, childIndex, 1 /* Start */)) { return; } let adjustedLength = rangeLength - (childCharCount - adjustedStart); childIndex++; const child = this.children[childIndex]; childCharCount = child.charCount(); while (adjustedLength > childCharCount) { if (this.execWalk(0, childCharCount, walkFns, childIndex, 3 /* Mid */)) { return; } adjustedLength -= childCharCount; childIndex++; childCharCount = this.children[childIndex].charCount(); } if (adjustedLength > 0) { if (this.execWalk(0, adjustedLength, walkFns, childIndex, 4 /* End */)) { return; } } } if (walkFns.pre) { const clen = this.children.length; if (childIndex < clen - 1) { for (let ej = childIndex + 1; ej < clen; ej++) { this.skipChild(0, 0, ej, walkFns, 5 /* PostEnd */); } } } } // Input position is relative to the start of this node. // Output line number is absolute. charOffsetToLineInfo(lineNumberAccumulator, relativePosition) { if (this.children.length === 0) { return { oneBasedLine: lineNumberAccumulator, zeroBasedColumn: relativePosition, lineText: void 0 }; } for (const child of this.children) { if (child.charCount() > relativePosition) { if (child.isLeaf()) { return { oneBasedLine: lineNumberAccumulator, zeroBasedColumn: relativePosition, lineText: child.text }; } else { return child.charOffsetToLineInfo(lineNumberAccumulator, relativePosition); } } else { relativePosition -= child.charCount(); lineNumberAccumulator += child.lineCount(); } } const lineCount = this.lineCount(); if (lineCount === 0) { return { oneBasedLine: 1, zeroBasedColumn: 0, lineText: void 0 }; } const leaf = Debug.checkDefined(this.lineNumberToInfo(lineCount, 0).leaf); return { oneBasedLine: lineCount, zeroBasedColumn: leaf.charCount(), lineText: void 0 }; } /** * Input line number is relative to the start of this node. * Output line number is relative to the child. * positionAccumulator will be an absolute position once relativeLineNumber reaches 0. */ lineNumberToInfo(relativeOneBasedLine, positionAccumulator) { for (const child of this.children) { const childLineCount = child.lineCount(); if (childLineCount >= relativeOneBasedLine) { return child.isLeaf() ? { position: positionAccumulator, leaf: child } : child.lineNumberToInfo(relativeOneBasedLine, positionAccumulator); } else { relativeOneBasedLine -= childLineCount; positionAccumulator += child.charCount(); } } return { position: positionAccumulator, leaf: void 0 }; } splitAfter(childIndex) { let splitNode; const clen = this.children.length; childIndex++; const endLength = childIndex; if (childIndex < clen) { splitNode = new _LineNode(); while (childIndex < clen) { splitNode.add(this.children[childIndex]); childIndex++; } splitNode.updateCounts(); } this.children.length = endLength; return splitNode; } remove(child) { const childIndex = this.findChildIndex(child); const clen = this.children.length; if (childIndex < clen - 1) { for (let i = childIndex; i < clen - 1; i++) { this.children[i] = this.children[i + 1]; } } this.children.pop(); } findChildIndex(child) { const childIndex = this.children.indexOf(child); Debug.assert(childIndex !== -1); return childIndex; } insertAt(child, nodes) { let childIndex = this.findChildIndex(child); const clen = this.children.length; const nodeCount = nodes.length; if (clen < lineCollectionCapacity && childIndex === clen - 1 && nodeCount === 1) { this.add(nodes[0]); this.updateCounts(); return []; } else { const shiftNode = this.splitAfter(childIndex); let nodeIndex = 0; childIndex++; while (childIndex < lineCollectionCapacity && nodeIndex < nodeCount) { this.children[childIndex] = nodes[nodeIndex]; childIndex++; nodeIndex++; } let splitNodes = []; let splitNodeCount = 0; if (nodeIndex < nodeCount) { splitNodeCount = Math.ceil((nodeCount - nodeIndex) / lineCollectionCapacity); splitNodes = new Array(splitNodeCount); let splitNodeIndex = 0; for (let i = 0; i < splitNodeCount; i++) { splitNodes[i] = new _LineNode(); } let splitNode = splitNodes[0]; while (nodeIndex < nodeCount) { splitNode.add(nodes[nodeIndex]); nodeIndex++; if (splitNode.children.length === lineCollectionCapacity) { splitNodeIndex++; splitNode = splitNodes[splitNodeIndex]; } } for (let i = splitNodes.length - 1; i >= 0; i--) { if (splitNodes[i].children.length === 0) { splitNodes.pop(); } } } if (shiftNode) { splitNodes.push(shiftNode); } this.updateCounts(); for (let i = 0; i < splitNodeCount; i++) { splitNodes[i].updateCounts(); } return splitNodes; } } // assume there is room for the item; return true if more room add(collection) { this.children.push(collection); Debug.assert(this.children.length <= lineCollectionCapacity); } charCount() { return this.totalChars; } lineCount() { return this.totalLines; } }; var LineLeaf = class { constructor(text) { this.text = text; } isLeaf() { return true; } walk(rangeStart, rangeLength, walkFns) { walkFns.leaf(rangeStart, rangeLength, this); } charCount() { return this.text.length; } lineCount() { return 1; } }; // src/server/typingInstallerAdapter.ts var _TypingsInstallerAdapter = class _TypingsInstallerAdapter { constructor(telemetryEnabled, logger, host, globalTypingsCacheLocation, event, maxActiveRequestCount) { this.telemetryEnabled = telemetryEnabled; this.logger = logger; this.host = host; this.globalTypingsCacheLocation = globalTypingsCacheLocation; this.event = event; this.maxActiveRequestCount = maxActiveRequestCount; this.activeRequestCount = 0; this.requestQueue = createQueue(); this.requestMap = /* @__PURE__ */ new Map(); // Maps project name to newest requestQueue entry for that project /** We will lazily request the types registry on the first call to `isKnownTypesPackageName` and store it in `typesRegistryCache`. */ this.requestedRegistry = false; this.packageInstallId = 0; } isKnownTypesPackageName(name) { var _a; const validationResult = ts_JsTyping_exports.validatePackageName(name); if (validationResult !== ts_JsTyping_exports.NameValidationResult.Ok) { return false; } if (!this.requestedRegistry) { this.requestedRegistry = true; this.installer.send({ kind: "typesRegistry" }); } return !!((_a = this.typesRegistryCache) == null ? void 0 : _a.has(name)); } installPackage(options) { this.packageInstallId++; const request = { kind: "installPackage", ...options, id: this.packageInstallId }; const promise = new Promise((resolve, reject) => { (this.packageInstalledPromise ?? (this.packageInstalledPromise = /* @__PURE__ */ new Map())).set(this.packageInstallId, { resolve, reject }); }); this.installer.send(request); return promise; } attach(projectService) { this.projectService = projectService; this.installer = this.createInstallerProcess(); } onProjectClosed(p) { this.installer.send({ projectName: p.getProjectName(), kind: "closeProject" }); } enqueueInstallTypingsRequest(project, typeAcquisition, unresolvedImports) { const request = createInstallTypingsRequest(project, typeAcquisition, unresolvedImports); if (this.logger.hasLevel(3 /* verbose */)) { this.logger.info(`TIAdapter:: Scheduling throttled operation:${stringifyIndented(request)}`); } if (this.activeRequestCount < this.maxActiveRequestCount) { this.scheduleRequest(request); } else { if (this.logger.hasLevel(3 /* verbose */)) { this.logger.info(`TIAdapter:: Deferring request for: ${request.projectName}`); } this.requestQueue.enqueue(request); this.requestMap.set(request.projectName, request); } } handleMessage(response) { var _a, _b; if (this.logger.hasLevel(3 /* verbose */)) { this.logger.info(`TIAdapter:: Received response:${stringifyIndented(response)}`); } switch (response.kind) { case EventTypesRegistry: this.typesRegistryCache = new Map(Object.entries(response.typesRegistry)); break; case ActionPackageInstalled: { const promise = (_a = this.packageInstalledPromise) == null ? void 0 : _a.get(response.id); Debug.assertIsDefined(promise, "Should find the promise for package install"); (_b = this.packageInstalledPromise) == null ? void 0 : _b.delete(response.id); if (response.success) { promise.resolve({ successMessage: response.message }); } else { promise.reject(response.message); } this.projectService.updateTypingsForProject(response); this.event(response, "setTypings"); break; } case EventInitializationFailed: { const body = { message: response.message }; const eventName = "typesInstallerInitializationFailed"; this.event(body, eventName); break; } case EventBeginInstallTypes: { const body = { eventId: response.eventId, packages: response.packagesToInstall }; const eventName = "beginInstallTypes"; this.event(body, eventName); break; } case EventEndInstallTypes: { if (this.telemetryEnabled) { const body2 = { telemetryEventName: "typingsInstalled", payload: { installedPackages: response.packagesToInstall.join(","), installSuccess: response.installSuccess, typingsInstallerVersion: response.typingsInstallerVersion } }; const eventName2 = "telemetry"; this.event(body2, eventName2); } const body = { eventId: response.eventId, packages: response.packagesToInstall, success: response.installSuccess }; const eventName = "endInstallTypes"; this.event(body, eventName); break; } case ActionInvalidate: { this.projectService.updateTypingsForProject(response); break; } case ActionSet: { if (this.activeRequestCount > 0) { this.activeRequestCount--; } else { Debug.fail("TIAdapter:: Received too many responses"); } while (!this.requestQueue.isEmpty()) { const queuedRequest = this.requestQueue.dequeue(); if (this.requestMap.get(queuedRequest.projectName) === queuedRequest) { this.requestMap.delete(queuedRequest.projectName); this.scheduleRequest(queuedRequest); break; } if (this.logger.hasLevel(3 /* verbose */)) { this.logger.info(`TIAdapter:: Skipping defunct request for: ${queuedRequest.projectName}`); } } this.projectService.updateTypingsForProject(response); this.event(response, "setTypings"); break; } case ActionWatchTypingLocations: this.projectService.watchTypingLocations(response); break; default: assertType(response); } } scheduleRequest(request) { if (this.logger.hasLevel(3 /* verbose */)) { this.logger.info(`TIAdapter:: Scheduling request for: ${request.projectName}`); } this.activeRequestCount++; this.host.setTimeout( () => { if (this.logger.hasLevel(3 /* verbose */)) { this.logger.info(`TIAdapter:: Sending request:${stringifyIndented(request)}`); } this.installer.send(request); }, _TypingsInstallerAdapter.requestDelayMillis, `${request.projectName}::${request.kind}` ); } }; // This number is essentially arbitrary. Processing more than one typings request // at a time makes sense, but having too many in the pipe results in a hang // (see https://github.com/nodejs/node/issues/7657). // It would be preferable to base our limit on the amount of space left in the // buffer, but we have yet to find a way to retrieve that value. _TypingsInstallerAdapter.requestDelayMillis = 100; var TypingsInstallerAdapter = _TypingsInstallerAdapter; // src/typescript/_namespaces/ts.server.ts var ts_server_exports4 = {}; __export(ts_server_exports4, { ActionInvalidate: () => ActionInvalidate, ActionPackageInstalled: () => ActionPackageInstalled, ActionSet: () => ActionSet, ActionWatchTypingLocations: () => ActionWatchTypingLocations, Arguments: () => Arguments, AutoImportProviderProject: () => AutoImportProviderProject, AuxiliaryProject: () => AuxiliaryProject, CharRangeSection: () => CharRangeSection, CloseFileWatcherEvent: () => CloseFileWatcherEvent, CommandNames: () => CommandNames, ConfigFileDiagEvent: () => ConfigFileDiagEvent, ConfiguredProject: () => ConfiguredProject2, ConfiguredProjectLoadKind: () => ConfiguredProjectLoadKind, CreateDirectoryWatcherEvent: () => CreateDirectoryWatcherEvent, CreateFileWatcherEvent: () => CreateFileWatcherEvent, Errors: () => Errors, EventBeginInstallTypes: () => EventBeginInstallTypes, EventEndInstallTypes: () => EventEndInstallTypes, EventInitializationFailed: () => EventInitializationFailed, EventTypesRegistry: () => EventTypesRegistry, ExternalProject: () => ExternalProject, GcTimer: () => GcTimer, InferredProject: () => InferredProject2, LargeFileReferencedEvent: () => LargeFileReferencedEvent, LineIndex: () => LineIndex, LineLeaf: () => LineLeaf, LineNode: () => LineNode, LogLevel: () => LogLevel2, Msg: () => Msg, OpenFileInfoTelemetryEvent: () => OpenFileInfoTelemetryEvent, Project: () => Project3, ProjectInfoTelemetryEvent: () => ProjectInfoTelemetryEvent, ProjectKind: () => ProjectKind, ProjectLanguageServiceStateEvent: () => ProjectLanguageServiceStateEvent, ProjectLoadingFinishEvent: () => ProjectLoadingFinishEvent, ProjectLoadingStartEvent: () => ProjectLoadingStartEvent, ProjectService: () => ProjectService3, ProjectsUpdatedInBackgroundEvent: () => ProjectsUpdatedInBackgroundEvent, ScriptInfo: () => ScriptInfo, ScriptVersionCache: () => ScriptVersionCache, Session: () => Session3, TextStorage: () => TextStorage, ThrottledOperations: () => ThrottledOperations, TypingsCache: () => TypingsCache, TypingsInstallerAdapter: () => TypingsInstallerAdapter, allFilesAreJsOrDts: () => allFilesAreJsOrDts, allRootFilesAreJsOrDts: () => allRootFilesAreJsOrDts, asNormalizedPath: () => asNormalizedPath, convertCompilerOptions: () => convertCompilerOptions, convertFormatOptions: () => convertFormatOptions, convertScriptKindName: () => convertScriptKindName, convertTypeAcquisition: () => convertTypeAcquisition, convertUserPreferences: () => convertUserPreferences, convertWatchOptions: () => convertWatchOptions, countEachFileTypes: () => countEachFileTypes, createInstallTypingsRequest: () => createInstallTypingsRequest, createModuleSpecifierCache: () => createModuleSpecifierCache, createNormalizedPathMap: () => createNormalizedPathMap, createPackageJsonCache: () => createPackageJsonCache, createSortedArray: () => createSortedArray2, emptyArray: () => emptyArray2, findArgument: () => findArgument, forEachResolvedProjectReferenceProject: () => forEachResolvedProjectReferenceProject, formatDiagnosticToProtocol: () => formatDiagnosticToProtocol, formatMessage: () => formatMessage2, getBaseConfigFileName: () => getBaseConfigFileName, getLocationInNewDocument: () => getLocationInNewDocument, hasArgument: () => hasArgument, hasNoTypeScriptSource: () => hasNoTypeScriptSource, indent: () => indent2, isBackgroundProject: () => isBackgroundProject, isConfigFile: () => isConfigFile, isConfiguredProject: () => isConfiguredProject, isDynamicFileName: () => isDynamicFileName, isExternalProject: () => isExternalProject, isInferredProject: () => isInferredProject, isInferredProjectName: () => isInferredProjectName, isProjectDeferredClose: () => isProjectDeferredClose, makeAutoImportProviderProjectName: () => makeAutoImportProviderProjectName, makeAuxiliaryProjectName: () => makeAuxiliaryProjectName, makeInferredProjectName: () => makeInferredProjectName, maxFileSize: () => maxFileSize, maxProgramSizeForNonTsFiles: () => maxProgramSizeForNonTsFiles, normalizedPathToPath: () => normalizedPathToPath, nowString: () => nowString, nullCancellationToken: () => nullCancellationToken, nullTypingsInstaller: () => nullTypingsInstaller, protocol: () => ts_server_protocol_exports, removeSorted: () => removeSorted, stringifyIndented: () => stringifyIndented, toEvent: () => toEvent, toNormalizedPath: () => toNormalizedPath, tryConvertScriptKindName: () => tryConvertScriptKindName, typingsInstaller: () => ts_server_typingsInstaller_exports, updateProjectIfDirty: () => updateProjectIfDirty }); // src/typescript/typescript.ts if (typeof console !== "undefined") { Debug.loggingHost = { log(level, s) { switch (level) { case 1 /* Error */: return console.error(s); case 2 /* Warning */: return console.warn(s); case 3 /* Info */: return console.log(s); case 4 /* Verbose */: return console.log(s); } } }; } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { ANONYMOUS, AccessFlags, AssertionLevel, AssignmentDeclarationKind, AssignmentKind, Associativity, BreakpointResolver, BuilderFileEmit, BuilderProgramKind, BuilderState, CallHierarchy, CharacterCodes, CheckFlags, CheckMode, ClassificationType, ClassificationTypeNames, CommentDirectiveType, Comparison, CompletionInfoFlags, CompletionTriggerKind, Completions, ContainerFlags, ContextFlags, Debug, DiagnosticCategory, Diagnostics, DocumentHighlights, ElementFlags, EmitFlags, EmitHint, EmitOnly, EndOfLineState, ExitStatus, ExportKind, Extension, ExternalEmitHelpers, FileIncludeKind, FilePreprocessingDiagnosticsKind, FileSystemEntryKind, FileWatcherEventKind, FindAllReferences, FlattenLevel, FlowFlags, ForegroundColorEscapeSequences, FunctionFlags, GeneratedIdentifierFlags, GetLiteralTextFlags, GoToDefinition, HighlightSpanKind, IdentifierNameMap, IdentifierNameMultiMap, ImportKind, ImportsNotUsedAsValues, IndentStyle, IndexFlags, IndexKind, InferenceFlags, InferencePriority, InlayHintKind, InlayHints, InternalEmitFlags, InternalSymbolName, IntersectionFlags, InvalidatedProjectKind, JSDocParsingMode, JsDoc, JsTyping, JsxEmit, JsxFlags, JsxReferenceKind, LanguageFeatureMinimumTarget, LanguageServiceMode, LanguageVariant, LexicalEnvironmentFlags, ListFormat, LogLevel, MapCode, MemberOverrideStatus, ModifierFlags, ModuleDetectionKind, ModuleInstanceState, ModuleKind, ModuleResolutionKind, ModuleSpecifierEnding, NavigateTo, NavigationBar, NewLineKind, NodeBuilderFlags, NodeCheckFlags, NodeFactoryFlags, NodeFlags, NodeResolutionFeatures, ObjectFlags, OperationCanceledException, OperatorPrecedence, OrganizeImports, OrganizeImportsMode, OuterExpressionKinds, OutliningElementsCollector, OutliningSpanKind, OutputFileType, PackageJsonAutoImportPreference, PackageJsonDependencyGroup, PatternMatchKind, PollingInterval, PollingWatchKind, PragmaKindFlags, PrivateIdentifierKind, ProcessLevel, ProgramUpdateLevel, QuotePreference, RegularExpressionFlags, RelationComparisonResult, Rename, ScriptElementKind, ScriptElementKindModifier, ScriptKind, ScriptSnapshot, ScriptTarget, SemanticClassificationFormat, SemanticMeaning, SemicolonPreference, SignatureCheckMode, SignatureFlags, SignatureHelp, SignatureInfo, SignatureKind, SmartSelectionRange, SnippetKind, StatisticType, StructureIsReused, SymbolAccessibility, SymbolDisplay, SymbolDisplayPartKind, SymbolFlags, SymbolFormatFlags, SyntaxKind, SyntheticSymbolKind, Ternary, ThrottledCancellationToken, TokenClass, TokenFlags, TransformFlags, TypeFacts, TypeFlags, TypeFormatFlags, TypeMapKind, TypePredicateKind, TypeReferenceSerializationKind, UnionReduction, UpToDateStatusType, VarianceFlags, Version, VersionRange, WatchDirectoryFlags, WatchDirectoryKind, WatchFileKind, WatchLogLevel, WatchType, accessPrivateIdentifier, addDisposableResourceHelper, addEmitFlags, addEmitHelper, addEmitHelpers, addInternalEmitFlags, addNodeFactoryPatcher, addObjectAllocatorPatcher, addRange, addRelatedInfo, addSyntheticLeadingComment, addSyntheticTrailingComment, addToSeen, advancedAsyncSuperHelper, affectsDeclarationPathOptionDeclarations, affectsEmitOptionDeclarations, allKeysStartWithDot, altDirectorySeparator, and, append, appendIfUnique, arrayFrom, arrayIsEqualTo, arrayIsHomogeneous, arrayIsSorted, arrayOf, arrayReverseIterator, arrayToMap, arrayToMultiMap, arrayToNumericMap, arraysEqual, assertType, assign, assignHelper, asyncDelegator, asyncGeneratorHelper, asyncSuperHelper, asyncValues, attachFileToDiagnostics, awaitHelper, awaiterHelper, base64decode, base64encode, binarySearch, binarySearchKey, bindSourceFile, breakIntoCharacterSpans, breakIntoWordSpans, buildLinkParts, buildOpts, buildOverload, bundlerModuleNameResolver, canBeConvertedToAsync, canHaveDecorators, canHaveExportModifier, canHaveFlowNode, canHaveIllegalDecorators, canHaveIllegalModifiers, canHaveIllegalType, canHaveIllegalTypeParameters, canHaveJSDoc, canHaveLocals, canHaveModifiers, canHaveSymbol, canIncludeBindAndCheckDiagnsotics, canJsonReportNoInputFiles, canProduceDiagnostics, canUsePropertyAccess, canWatchAffectingLocation, canWatchAtTypes, canWatchDirectoryOrFile, cartesianProduct, cast, chainBundle, chainDiagnosticMessages, changeAnyExtension, changeCompilerHostLikeToUseCache, changeExtension, changeFullExtension, changesAffectModuleResolution, changesAffectingProgramStructure, characterToRegularExpressionFlag, childIsDecorated, classElementOrClassElementParameterIsDecorated, classHasClassThisAssignment, classHasDeclaredOrExplicitlyAssignedName, classHasExplicitlyAssignedName, classOrConstructorParameterIsDecorated, classPrivateFieldGetHelper, classPrivateFieldInHelper, classPrivateFieldSetHelper, classicNameResolver, classifier, cleanExtendedConfigCache, clear, clearMap, clearSharedExtendedConfigFileWatcher, climbPastPropertyAccess, climbPastPropertyOrElementAccess, clone, cloneCompilerOptions, closeFileWatcher, closeFileWatcherOf, codefix, collapseTextChangeRangesAcrossMultipleVersions, collectExternalModuleInfo, combine, combinePaths, commandLineOptionOfCustomType, commentPragmas, commonOptionsWithBuild, commonPackageFolders, compact, compareBooleans, compareDataObjects, compareDiagnostics, compareDiagnosticsSkipRelatedInformation, compareEmitHelpers, compareNumberOfDirectorySeparators, comparePaths, comparePathsCaseInsensitive, comparePathsCaseSensitive, comparePatternKeys, compareProperties, compareStringsCaseInsensitive, compareStringsCaseInsensitiveEslintCompatible, compareStringsCaseSensitive, compareStringsCaseSensitiveUI, compareTextSpans, compareValues, compileOnSaveCommandLineOption, compilerOptionsAffectDeclarationPath, compilerOptionsAffectEmit, compilerOptionsAffectSemanticDiagnostics, compilerOptionsDidYouMeanDiagnostics, compilerOptionsIndicateEsModules, compose, computeCommonSourceDirectoryOfFilenames, computeLineAndCharacterOfPosition, computeLineOfPosition, computeLineStarts, computePositionOfLineAndCharacter, computeSignature, computeSignatureWithDiagnostics, computeSuggestionDiagnostics, computedOptions, concatenate, concatenateDiagnosticMessageChains, configDirTemplateSubstitutionOptions, configDirTemplateSubstitutionWatchOptions, consumesNodeCoreModules, contains, containsIgnoredPath, containsObjectRestOrSpread, containsParseError, containsPath, convertCompilerOptionsForTelemetry, convertCompilerOptionsFromJson, convertJsonOption, convertToBase64, convertToJson, convertToObject, convertToOptionsWithAbsolutePaths, convertToRelativePath, convertToTSConfig, convertTypeAcquisitionFromJson, copyComments, copyEntries, copyLeadingComments, copyProperties, copyTrailingAsLeadingComments, copyTrailingComments, couldStartTrivia, countWhere, createAbstractBuilder, createAccessorPropertyBackingField, createAccessorPropertyGetRedirector, createAccessorPropertySetRedirector, createBaseNodeFactory, createBinaryExpressionTrampoline, createBindingHelper, createBuildInfo, createBuilderProgram, createBuilderProgramUsingProgramBuildInfo, createBuilderStatusReporter, createCacheWithRedirects, createCacheableExportInfoMap, createCachedDirectoryStructureHost, createClassNamedEvaluationHelperBlock, createClassThisAssignmentBlock, createClassifier, createCommentDirectivesMap, createCompilerDiagnostic, createCompilerDiagnosticForInvalidCustomType, createCompilerDiagnosticFromMessageChain, createCompilerHost, createCompilerHostFromProgramHost, createCompilerHostWorker, createDetachedDiagnostic, createDiagnosticCollection, createDiagnosticForFileFromMessageChain, createDiagnosticForNode, createDiagnosticForNodeArray, createDiagnosticForNodeArrayFromMessageChain, createDiagnosticForNodeFromMessageChain, createDiagnosticForNodeInSourceFile, createDiagnosticForRange, createDiagnosticMessageChainFromDiagnostic, createDiagnosticReporter, createDocumentPositionMapper, createDocumentRegistry, createDocumentRegistryInternal, createEmitAndSemanticDiagnosticsBuilderProgram, createEmitHelperFactory, createEmptyExports, createEvaluator, createExpressionForJsxElement, createExpressionForJsxFragment, createExpressionForObjectLiteralElementLike, createExpressionForPropertyName, createExpressionFromEntityName, createExternalHelpersImportDeclarationIfNeeded, createFileDiagnostic, createFileDiagnosticFromMessageChain, createFlowNode, createForOfBindingStatement, createFutureSourceFile, createGetCanonicalFileName, createGetIsolatedDeclarationErrors, createGetSourceFile, createGetSymbolAccessibilityDiagnosticForNode, createGetSymbolAccessibilityDiagnosticForNodeName, createGetSymbolWalker, createIncrementalCompilerHost, createIncrementalProgram, createJsxFactoryExpression, createLanguageService, createLanguageServiceSourceFile, createMemberAccessForPropertyName, createModeAwareCache, createModeAwareCacheKey, createModuleNotFoundChain, createModuleResolutionCache, createModuleResolutionLoader, createModuleResolutionLoaderUsingGlobalCache, createModuleSpecifierResolutionHost, createMultiMap, createNameResolver, createNodeConverters, createNodeFactory, createOptionNameMap, createOverload, createPackageJsonImportFilter, createPackageJsonInfo, createParenthesizerRules, createPatternMatcher, createPrinter, createPrinterWithDefaults, createPrinterWithRemoveComments, createPrinterWithRemoveCommentsNeverAsciiEscape, createPrinterWithRemoveCommentsOmitTrailingSemicolon, createProgram, createProgramHost, createPropertyNameNodeForIdentifierOrLiteral, createQueue, createRange, createRedirectedBuilderProgram, createResolutionCache, createRuntimeTypeSerializer, createScanner, createSemanticDiagnosticsBuilderProgram, createSet, createSolutionBuilder, createSolutionBuilderHost, createSolutionBuilderWithWatch, createSolutionBuilderWithWatchHost, createSortedArray, createSourceFile, createSourceMapGenerator, createSourceMapSource, createSuperAccessVariableStatement, createSymbolTable, createSymlinkCache, createSyntacticTypeNodeBuilder, createSystemWatchFunctions, createTextChange, createTextChangeFromStartLength, createTextChangeRange, createTextRangeFromNode, createTextRangeFromSpan, createTextSpan, createTextSpanFromBounds, createTextSpanFromNode, createTextSpanFromRange, createTextSpanFromStringLiteralLikeContent, createTextWriter, createTokenRange, createTypeChecker, createTypeReferenceDirectiveResolutionCache, createTypeReferenceResolutionLoader, createWatchCompilerHost, createWatchCompilerHostOfConfigFile, createWatchCompilerHostOfFilesAndCompilerOptions, createWatchFactory, createWatchHost, createWatchProgram, createWatchStatusReporter, createWriteFileMeasuringIO, declarationNameToString, decodeMappings, decodedTextSpanIntersectsWith, decorateHelper, deduplicate, defaultIncludeSpec, defaultInitCompilerOptions, defaultMaximumTruncationLength, diagnosticCategoryName, diagnosticToString, diagnosticsEqualityComparer, directoryProbablyExists, directorySeparator, displayPart, displayPartsToString, disposeEmitNodes, disposeResourcesHelper, documentSpansEqual, dumpTracingLegend, elementAt, elideNodes, emitComments, emitDetachedComments, emitFiles, emitFilesAndReportErrors, emitFilesAndReportErrorsAndGetExitStatus, emitModuleKindIsNonNodeESM, emitNewLineBeforeLeadingCommentOfPosition, emitNewLineBeforeLeadingComments, emitNewLineBeforeLeadingCommentsOfPosition, emitResolverSkipsTypeChecking, emitSkippedWithNoDiagnostics, emptyArray, emptyFileSystemEntries, emptyMap, emptyOptions, emptySet, endsWith, ensurePathIsNonModuleName, ensureScriptKind, ensureTrailingDirectorySeparator, entityNameToString, enumerateInsertsAndDeletes, equalOwnProperties, equateStringsCaseInsensitive, equateStringsCaseSensitive, equateValues, esDecorateHelper, escapeJsxAttributeString, escapeLeadingUnderscores, escapeNonAsciiString, escapeSnippetText, escapeString, escapeTemplateSubstitution, evaluatorResult, every, executeCommandLine, expandPreOrPostfixIncrementOrDecrementExpression, explainFiles, explainIfFileIsRedirectAndImpliedFormat, exportAssignmentIsAlias, exportStarHelper, expressionResultIsUnused, extend, extendsHelper, extensionFromPath, extensionIsTS, extensionsNotSupportingExtensionlessResolution, externalHelpersModuleNameText, factory, fileExtensionIs, fileExtensionIsOneOf, fileIncludeReasonToDiagnostics, fileShouldUseJavaScriptRequire, filter, filterMutate, filterSemanticDiagnostics, find, findAncestor, findBestPatternMatch, findChildOfKind, findComputedPropertyNameCacheAssignment, findConfigFile, findConstructorDeclaration, findContainingList, findDiagnosticForNode, findFirstNonJsxWhitespaceToken, findIndex, findLast, findLastIndex, findListItemInfo, findMap, findModifier, findNextToken, findPackageJson, findPackageJsons, findPrecedingMatchingToken, findPrecedingToken, findSuperStatementIndexPath, findTokenOnLeftOfPosition, findUseStrictPrologue, first, firstDefined, firstDefinedIterator, firstIterator, firstOrOnly, firstOrUndefined, firstOrUndefinedIterator, fixupCompilerOptions, flatMap, flatMapIterator, flatMapToMutable, flatten, flattenCommaList, flattenDestructuringAssignment, flattenDestructuringBinding, flattenDiagnosticMessageText, forEach, forEachAncestor, forEachAncestorDirectory, forEachChild, forEachChildRecursively, forEachEmittedFile, forEachEnclosingBlockScopeContainer, forEachEntry, forEachExternalModuleToImportFrom, forEachImportClauseDeclaration, forEachKey, forEachLeadingCommentRange, forEachNameInAccessChainWalkingLeft, forEachNameOfDefaultExport, forEachPropertyAssignment, forEachResolvedProjectReference, forEachReturnStatement, forEachRight, forEachTrailingCommentRange, forEachTsConfigPropArray, forEachUnique, forEachYieldExpression, forSomeAncestorDirectory, formatColorAndReset, formatDiagnostic, formatDiagnostics, formatDiagnosticsWithColorAndContext, formatGeneratedName, formatGeneratedNamePart, formatLocation, formatMessage, formatStringFromArgs, formatting, fullTripleSlashAMDReferencePathRegEx, fullTripleSlashReferencePathRegEx, generateDjb2Hash, generateTSConfig, generatorHelper, getAdjustedReferenceLocation, getAdjustedRenameLocation, getAliasDeclarationFromName, getAllAccessorDeclarations, getAllDecoratorsOfClass, getAllDecoratorsOfClassElement, getAllJSDocTags, getAllJSDocTagsOfKind, getAllKeys, getAllProjectOutputs, getAllSuperTypeNodes, getAllowJSCompilerOption, getAllowSyntheticDefaultImports, getAncestor, getAnyExtensionFromPath, getAreDeclarationMapsEnabled, getAssignedExpandoInitializer, getAssignedName, getAssignedNameOfIdentifier, getAssignmentDeclarationKind, getAssignmentDeclarationPropertyAccessKind, getAssignmentTargetKind, getAutomaticTypeDirectiveNames, getBaseFileName, getBinaryOperatorPrecedence, getBuildInfo, getBuildInfoFileVersionMap, getBuildInfoText, getBuildOrderFromAnyBuildOrder, getBuilderCreationParameters, getBuilderFileEmit, getCanonicalDiagnostic, getCheckFlags, getClassExtendsHeritageElement, getClassLikeDeclarationOfSymbol, getCombinedLocalAndExportSymbolFlags, getCombinedModifierFlags, getCombinedNodeFlags, getCombinedNodeFlagsAlwaysIncludeJSDoc, getCommentRange, getCommonSourceDirectory, getCommonSourceDirectoryOfConfig, getCompilerOptionValue, getCompilerOptionsDiffValue, getConditions, getConfigFileParsingDiagnostics, getConstantValue, getContainerFlags, getContainerNode, getContainingClass, getContainingClassExcludingClassDecorators, getContainingClassStaticBlock, getContainingFunction, getContainingFunctionDeclaration, getContainingFunctionOrClassStaticBlock, getContainingNodeArray, getContainingObjectLiteralElement, getContextualTypeFromParent, getContextualTypeFromParentOrAncestorTypeNode, getCurrentTime, getDeclarationDiagnostics, getDeclarationEmitExtensionForPath, getDeclarationEmitOutputFilePath, getDeclarationEmitOutputFilePathWorker, getDeclarationFileExtension, getDeclarationFromName, getDeclarationModifierFlagsFromSymbol, getDeclarationOfKind, getDeclarationsOfKind, getDeclaredExpandoInitializer, getDecorators, getDefaultCompilerOptions, getDefaultFormatCodeSettings, getDefaultLibFileName, getDefaultLibFilePath, getDefaultLikeExportInfo, getDefaultLikeExportNameFromDeclaration, getDiagnosticText, getDiagnosticsWithinSpan, getDirectoryPath, getDirectoryToWatchFailedLookupLocation, getDirectoryToWatchFailedLookupLocationFromTypeRoot, getDocumentPositionMapper, getDocumentSpansEqualityComparer, getESModuleInterop, getEditsForFileRename, getEffectiveBaseTypeNode, getEffectiveConstraintOfTypeParameter, getEffectiveContainerForJSDocTemplateTag, getEffectiveImplementsTypeNodes, getEffectiveInitializer, getEffectiveJSDocHost, getEffectiveModifierFlags, getEffectiveModifierFlagsAlwaysIncludeJSDoc, getEffectiveModifierFlagsNoCache, getEffectiveReturnTypeNode, getEffectiveSetAccessorTypeAnnotationNode, getEffectiveTypeAnnotationNode, getEffectiveTypeParameterDeclarations, getEffectiveTypeRoots, getElementOrPropertyAccessArgumentExpressionOrName, getElementOrPropertyAccessName, getElementsOfBindingOrAssignmentPattern, getEmitDeclarations, getEmitFlags, getEmitHelpers, getEmitModuleDetectionKind, getEmitModuleKind, getEmitModuleResolutionKind, getEmitScriptTarget, getEmitStandardClassFields, getEnclosingBlockScopeContainer, getEnclosingContainer, getEncodedSemanticClassifications, getEncodedSyntacticClassifications, getEndLinePosition, getEntityNameFromTypeNode, getEntrypointsFromPackageJsonInfo, getErrorCountForSummary, getErrorSpanForNode, getErrorSummaryText, getEscapedTextOfIdentifierOrLiteral, getEscapedTextOfJsxAttributeName, getEscapedTextOfJsxNamespacedName, getExpandoInitializer, getExportAssignmentExpression, getExportInfoMap, getExportNeedsImportStarHelper, getExpressionAssociativity, getExpressionPrecedence, getExternalHelpersModuleName, getExternalModuleImportEqualsDeclarationExpression, getExternalModuleName, getExternalModuleNameFromDeclaration, getExternalModuleNameFromPath, getExternalModuleNameLiteral, getExternalModuleRequireArgument, getFallbackOptions, getFileEmitOutput, getFileMatcherPatterns, getFileNamesFromConfigSpecs, getFileWatcherEventKind, getFilesInErrorForSummary, getFirstConstructorWithBody, getFirstIdentifier, getFirstNonSpaceCharacterPosition, getFirstProjectOutput, getFixableErrorSpanExpression, getFormatCodeSettingsForWriting, getFullWidth, getFunctionFlags, getHeritageClause, getHostSignatureFromJSDoc, getIdentifierAutoGenerate, getIdentifierGeneratedImportReference, getIdentifierTypeArguments, getImmediatelyInvokedFunctionExpression, getImpliedNodeFormatForFile, getImpliedNodeFormatForFileWorker, getImportNeedsImportDefaultHelper, getImportNeedsImportStarHelper, getIndentSize, getIndentString, getInferredLibraryNameResolveFrom, getInitializedVariables, getInitializerOfBinaryExpression, getInitializerOfBindingOrAssignmentElement, getInterfaceBaseTypeNodes, getInternalEmitFlags, getInvokedExpression, getIsolatedModules, getJSDocAugmentsTag, getJSDocClassTag, getJSDocCommentRanges, getJSDocCommentsAndTags, getJSDocDeprecatedTag, getJSDocDeprecatedTagNoCache, getJSDocEnumTag, getJSDocHost, getJSDocImplementsTags, getJSDocOverloadTags, getJSDocOverrideTagNoCache, getJSDocParameterTags, getJSDocParameterTagsNoCache, getJSDocPrivateTag, getJSDocPrivateTagNoCache, getJSDocProtectedTag, getJSDocProtectedTagNoCache, getJSDocPublicTag, getJSDocPublicTagNoCache, getJSDocReadonlyTag, getJSDocReadonlyTagNoCache, getJSDocReturnTag, getJSDocReturnType, getJSDocRoot, getJSDocSatisfiesExpressionType, getJSDocSatisfiesTag, getJSDocTags, getJSDocTagsNoCache, getJSDocTemplateTag, getJSDocThisTag, getJSDocType, getJSDocTypeAliasName, getJSDocTypeAssertionType, getJSDocTypeParameterDeclarations, getJSDocTypeParameterTags, getJSDocTypeParameterTagsNoCache, getJSDocTypeTag, getJSXImplicitImportBase, getJSXRuntimeImport, getJSXTransformEnabled, getKeyForCompilerOptions, getLanguageVariant, getLastChild, getLeadingCommentRanges, getLeadingCommentRangesOfNode, getLeftmostAccessExpression, getLeftmostExpression, getLibraryNameFromLibFileName, getLineAndCharacterOfPosition, getLineInfo, getLineOfLocalPosition, getLineOfLocalPositionFromLineMap, getLineStartPositionForPosition, getLineStarts, getLinesBetweenPositionAndNextNonWhitespaceCharacter, getLinesBetweenPositionAndPrecedingNonWhitespaceCharacter, getLinesBetweenPositions, getLinesBetweenRangeEndAndRangeStart, getLinesBetweenRangeEndPositions, getLiteralText, getLocalNameForExternalImport, getLocalSymbolForExportDefault, getLocaleSpecificMessage, getLocaleTimeString, getMappedContextSpan, getMappedDocumentSpan, getMappedLocation, getMatchedFileSpec, getMatchedIncludeSpec, getMeaningFromDeclaration, getMeaningFromLocation, getMembersOfDeclaration, getModeForFileReference, getModeForResolutionAtIndex, getModeForUsageLocation, getModifiedTime, getModifiers, getModuleInstanceState, getModuleNameStringLiteralAt, getModuleSpecifierEndingPreference, getModuleSpecifierResolverHost, getNameForExportedSymbol, getNameFromImportAttribute, getNameFromIndexInfo, getNameFromPropertyName, getNameOfAccessExpression, getNameOfCompilerOptionValue, getNameOfDeclaration, getNameOfExpando, getNameOfJSDocTypedef, getNameOfScriptTarget, getNameOrArgument, getNameTable, getNamesForExportedSymbol, getNamespaceDeclarationNode, getNewLineCharacter, getNewLineKind, getNewLineOrDefaultFromHost, getNewTargetContainer, getNextJSDocCommentLocation, getNodeChildren, getNodeForGeneratedName, getNodeId, getNodeKind, getNodeModifiers, getNodeModulePathParts, getNonAssignedNameOfDeclaration, getNonAssignmentOperatorForCompoundAssignment, getNonAugmentationDeclaration, getNonDecoratorTokenPosOfNode, getNormalizedAbsolutePath, getNormalizedAbsolutePathWithoutRoot, getNormalizedPathComponents, getObjectFlags, getOperator, getOperatorAssociativity, getOperatorPrecedence, getOptionFromName, getOptionsForLibraryResolution, getOptionsNameMap, getOrCreateEmitNode, getOrCreateExternalHelpersModuleNameIfNeeded, getOrUpdate, getOriginalNode, getOriginalNodeId, getOriginalSourceFile, getOutputDeclarationFileName, getOutputDeclarationFileNameWorker, getOutputExtension, getOutputFileNames, getOutputJSFileNameWorker, getOutputPathsFor, getOutputPathsForBundle, getOwnEmitOutputFilePath, getOwnKeys, getOwnValues, getPackageJsonInfo, getPackageJsonTypesVersionsPaths, getPackageJsonsVisibleToFile, getPackageNameFromTypesPackageName, getPackageScopeForPath, getParameterSymbolFromJSDoc, getParameterTypeNode, getParentNodeInSpan, getParseTreeNode, getParsedCommandLineOfConfigFile, getPathComponents, getPathComponentsRelativeTo, getPathFromPathComponents, getPathUpdater, getPathsBasePath, getPatternFromSpec, getPendingEmitKind, getPositionOfLineAndCharacter, getPossibleGenericSignatures, getPossibleOriginalInputExtensionForExtension, getPossibleTypeArgumentsInfo, getPreEmitDiagnostics, getPrecedingNonSpaceCharacterPosition, getPrivateIdentifier, getProperties, getProperty, getPropertyArrayElementValue, getPropertyAssignmentAliasLikeExpression, getPropertyNameForPropertyNameNode, getPropertyNameForUniqueESSymbol, getPropertyNameFromType, getPropertyNameOfBindingOrAssignmentElement, getPropertySymbolFromBindingElement, getPropertySymbolsFromContextualType, getQuoteFromPreference, getQuotePreference, getRangesWhere, getRefactorContextSpan, getReferencedFileLocation, getRegexFromPattern, getRegularExpressionForWildcard, getRegularExpressionsForWildcards, getRelativePathFromDirectory, getRelativePathFromFile, getRelativePathToDirectoryOrUrl, getRenameLocation, getReplacementSpanForContextToken, getResolutionDiagnostic, getResolutionModeOverride, getResolveJsonModule, getResolvePackageJsonExports, getResolvePackageJsonImports, getResolvedExternalModuleName, getRestIndicatorOfBindingOrAssignmentElement, getRestParameterElementType, getRightMostAssignedExpression, getRootDeclaration, getRootDirectoryOfResolutionCache, getRootLength, getRootPathSplitLength, getScriptKind, getScriptKindFromFileName, getScriptTargetFeatures, getSelectedEffectiveModifierFlags, getSelectedSyntacticModifierFlags, getSemanticClassifications, getSemanticJsxChildren, getSetAccessorTypeAnnotationNode, getSetAccessorValueParameter, getSetExternalModuleIndicator, getShebang, getSingleInitializerOfVariableStatementOrPropertyDeclaration, getSingleVariableOfVariableStatement, getSnapshotText, getSnippetElement, getSourceFileOfModule, getSourceFileOfNode, getSourceFilePathInNewDir, getSourceFilePathInNewDirWorker, getSourceFileVersionAsHashFromText, getSourceFilesToEmit, getSourceMapRange, getSourceMapper, getSourceTextOfNodeFromSourceFile, getSpanOfTokenAtPosition, getSpellingSuggestion, getStartPositionOfLine, getStartPositionOfRange, getStartsOnNewLine, getStaticPropertiesAndClassStaticBlock, getStrictOptionValue, getStringComparer, getSubPatternFromSpec, getSuperCallFromStatement, getSuperContainer, getSupportedCodeFixes, getSupportedExtensions, getSupportedExtensionsWithJsonIfResolveJsonModule, getSwitchedType, getSymbolId, getSymbolNameForPrivateIdentifier, getSymbolParentOrFail, getSymbolTarget, getSyntacticClassifications, getSyntacticModifierFlags, getSyntacticModifierFlagsNoCache, getSynthesizedDeepClone, getSynthesizedDeepCloneWithReplacements, getSynthesizedDeepClones, getSynthesizedDeepClonesWithReplacements, getSyntheticLeadingComments, getSyntheticTrailingComments, getTargetLabel, getTargetOfBindingOrAssignmentElement, getTemporaryModuleResolutionState, getTextOfConstantValue, getTextOfIdentifierOrLiteral, getTextOfJSDocComment, getTextOfJsxAttributeName, getTextOfJsxNamespacedName, getTextOfNode, getTextOfNodeFromSourceText, getTextOfPropertyName, getThisContainer, getThisParameter, getTokenAtPosition, getTokenPosOfNode, getTokenSourceMapRange, getTouchingPropertyName, getTouchingToken, getTrailingCommentRanges, getTrailingSemicolonDeferringWriter, getTransformFlagsSubtreeExclusions, getTransformers, getTsBuildInfoEmitOutputFilePath, getTsConfigObjectLiteralExpression, getTsConfigPropArrayElementValue, getTypeAnnotationNode, getTypeArgumentOrTypeParameterList, getTypeKeywordOfTypeOnlyImport, getTypeNode, getTypeNodeIfAccessible, getTypeParameterFromJsDoc, getTypeParameterOwner, getTypesPackageName, getUILocale, getUniqueName, getUniqueSymbolId, getUseDefineForClassFields, getWatchErrorSummaryDiagnosticMessage, getWatchFactory, group, groupBy, guessIndentation, handleNoEmitOptions, handleWatchOptionsConfigDirTemplateSubstitution, hasAbstractModifier, hasAccessorModifier, hasAmbientModifier, hasChangesInResolutions, hasChildOfKind, hasContextSensitiveParameters, hasDecorators, hasDocComment, hasDynamicName, hasEffectiveModifier, hasEffectiveModifiers, hasEffectiveReadonlyModifier, hasExtension, hasIndexSignature, hasInferredType, hasInitializer, hasInvalidEscape, hasJSDocNodes, hasJSDocParameterTags, hasJSFileExtension, hasJsonModuleEmitEnabled, hasOnlyExpressionInitializer, hasOverrideModifier, hasPossibleExternalModuleReference, hasProperty, hasPropertyAccessExpressionWithName, hasQuestionToken, hasRecordedExternalHelpers, hasResolutionModeOverride, hasRestParameter, hasScopeMarker, hasStaticModifier, hasSyntacticModifier, hasSyntacticModifiers, hasTSFileExtension, hasTabstop, hasTrailingDirectorySeparator, hasType, hasTypeArguments, hasZeroOrOneAsteriskCharacter, helperString, hostGetCanonicalFileName, hostUsesCaseSensitiveFileNames, idText, identifierIsThisKeyword, identifierToKeywordKind, identity, identitySourceMapConsumer, ignoreSourceNewlines, ignoredPaths, importDefaultHelper, importFromModuleSpecifier, importStarHelper, indexOfAnyCharCode, indexOfNode, indicesOf, inferredTypesContainingFile, injectClassNamedEvaluationHelperBlockIfMissing, injectClassThisAssignmentIfMissing, insertImports, insertLeadingStatement, insertSorted, insertStatementAfterCustomPrologue, insertStatementAfterStandardPrologue, insertStatementsAfterCustomPrologue, insertStatementsAfterStandardPrologue, intersperse, intrinsicTagNameToString, introducesArgumentsExoticObject, inverseJsxOptionMap, isAbstractConstructorSymbol, isAbstractModifier, isAccessExpression, isAccessibilityModifier, isAccessor, isAccessorModifier, isAliasSymbolDeclaration, isAliasableExpression, isAmbientModule, isAmbientPropertyDeclaration, isAnonymousFunctionDefinition, isAnyDirectorySeparator, isAnyImportOrBareOrAccessedRequire, isAnyImportOrReExport, isAnyImportOrRequireStatement, isAnyImportSyntax, isAnySupportedFileExtension, isApplicableVersionedTypesKey, isArgumentExpressionOfElementAccess, isArray, isArrayBindingElement, isArrayBindingOrAssignmentElement, isArrayBindingOrAssignmentPattern, isArrayBindingPattern, isArrayLiteralExpression, isArrayLiteralOrObjectLiteralDestructuringPattern, isArrayTypeNode, isArrowFunction, isAsExpression, isAssertClause, isAssertEntry, isAssertionExpression, isAssertsKeyword, isAssignmentDeclaration, isAssignmentExpression, isAssignmentOperator, isAssignmentPattern, isAssignmentTarget, isAsteriskToken, isAsyncFunction, isAsyncModifier, isAutoAccessorPropertyDeclaration, isAwaitExpression, isAwaitKeyword, isBigIntLiteral, isBinaryExpression, isBinaryOperatorToken, isBindableObjectDefinePropertyCall, isBindableStaticAccessExpression, isBindableStaticElementAccessExpression, isBindableStaticNameExpression, isBindingElement, isBindingElementOfBareOrAccessedRequire, isBindingName, isBindingOrAssignmentElement, isBindingOrAssignmentPattern, isBindingPattern, isBlock, isBlockLike, isBlockOrCatchScoped, isBlockScope, isBlockScopedContainerTopLevel, isBooleanLiteral, isBreakOrContinueStatement, isBreakStatement, isBuild, isBuildInfoFile, isBuilderProgram, isBundle, isCallChain, isCallExpression, isCallExpressionTarget, isCallLikeExpression, isCallLikeOrFunctionLikeExpression, isCallOrNewExpression, isCallOrNewExpressionTarget, isCallSignatureDeclaration, isCallToHelper, isCaseBlock, isCaseClause, isCaseKeyword, isCaseOrDefaultClause, isCatchClause, isCatchClauseVariableDeclaration, isCatchClauseVariableDeclarationOrBindingElement, isCheckJsEnabledForFile, isChildOfNodeWithKind, isCircularBuildOrder, isClassDeclaration, isClassElement, isClassExpression, isClassInstanceProperty, isClassLike, isClassMemberModifier, isClassNamedEvaluationHelperBlock, isClassOrTypeElement, isClassStaticBlockDeclaration, isClassThisAssignmentBlock, isCollapsedRange, isColonToken, isCommaExpression, isCommaListExpression, isCommaSequence, isCommaToken, isComment, isCommonJsExportPropertyAssignment, isCommonJsExportedExpression, isCompoundAssignment, isComputedNonLiteralName, isComputedPropertyName, isConciseBody, isConditionalExpression, isConditionalTypeNode, isConstAssertion, isConstTypeReference, isConstructSignatureDeclaration, isConstructorDeclaration, isConstructorTypeNode, isContextualKeyword, isContinueStatement, isCustomPrologue, isDebuggerStatement, isDeclaration, isDeclarationBindingElement, isDeclarationFileName, isDeclarationName, isDeclarationNameOfEnumOrNamespace, isDeclarationReadonly, isDeclarationStatement, isDeclarationWithTypeParameterChildren, isDeclarationWithTypeParameters, isDecorator, isDecoratorTarget, isDefaultClause, isDefaultImport, isDefaultModifier, isDefaultedExpandoInitializer, isDeleteExpression, isDeleteTarget, isDeprecatedDeclaration, isDestructuringAssignment, isDiagnosticWithLocation, isDiskPathRoot, isDoStatement, isDocumentRegistryEntry, isDotDotDotToken, isDottedName, isDynamicName, isESSymbolIdentifier, isEffectiveExternalModule, isEffectiveModuleDeclaration, isEffectiveStrictModeSourceFile, isElementAccessChain, isElementAccessExpression, isEmittedFileOfProgram, isEmptyArrayLiteral, isEmptyBindingElement, isEmptyBindingPattern, isEmptyObjectLiteral, isEmptyStatement, isEmptyStringLiteral, isEntityName, isEntityNameExpression, isEnumConst, isEnumDeclaration, isEnumMember, isEqualityOperatorKind, isEqualsGreaterThanToken, isExclamationToken, isExcludedFile, isExclusivelyTypeOnlyImportOrExport, isExpandoPropertyDeclaration, isExportAssignment, isExportDeclaration, isExportModifier, isExportName, isExportNamespaceAsDefaultDeclaration, isExportOrDefaultModifier, isExportSpecifier, isExportsIdentifier, isExportsOrModuleExportsOrAlias, isExpression, isExpressionNode, isExpressionOfExternalModuleImportEqualsDeclaration, isExpressionOfOptionalChainRoot, isExpressionStatement, isExpressionWithTypeArguments, isExpressionWithTypeArgumentsInClassExtendsClause, isExternalModule, isExternalModuleAugmentation, isExternalModuleImportEqualsDeclaration, isExternalModuleIndicator, isExternalModuleNameRelative, isExternalModuleReference, isExternalModuleSymbol, isExternalOrCommonJsModule, isFileLevelReservedGeneratedIdentifier, isFileLevelUniqueName, isFileProbablyExternalModule, isFirstDeclarationOfSymbolParameter, isFixablePromiseHandler, isForInOrOfStatement, isForInStatement, isForInitializer, isForOfStatement, isForStatement, isFullSourceFile, isFunctionBlock, isFunctionBody, isFunctionDeclaration, isFunctionExpression, isFunctionExpressionOrArrowFunction, isFunctionLike, isFunctionLikeDeclaration, isFunctionLikeKind, isFunctionLikeOrClassStaticBlockDeclaration, isFunctionOrConstructorTypeNode, isFunctionOrModuleBlock, isFunctionSymbol, isFunctionTypeNode, isFutureReservedKeyword, isGeneratedIdentifier, isGeneratedPrivateIdentifier, isGetAccessor, isGetAccessorDeclaration, isGetOrSetAccessorDeclaration, isGlobalDeclaration, isGlobalScopeAugmentation, isGlobalSourceFile, isGrammarError, isHeritageClause, isHoistedFunction, isHoistedVariableStatement, isIdentifier, isIdentifierANonContextualKeyword, isIdentifierName, isIdentifierOrThisTypeNode, isIdentifierPart, isIdentifierStart, isIdentifierText, isIdentifierTypePredicate, isIdentifierTypeReference, isIfStatement, isIgnoredFileFromWildCardWatching, isImplicitGlob, isImportAttribute, isImportAttributeName, isImportAttributes, isImportCall, isImportClause, isImportDeclaration, isImportEqualsDeclaration, isImportKeyword, isImportMeta, isImportOrExportSpecifier, isImportOrExportSpecifierName, isImportSpecifier, isImportTypeAssertionContainer, isImportTypeNode, isImportableFile, isInComment, isInCompoundLikeAssignment, isInExpressionContext, isInJSDoc, isInJSFile, isInJSXText, isInJsonFile, isInNonReferenceComment, isInReferenceComment, isInRightSideOfInternalImportEqualsDeclaration, isInString, isInTemplateString, isInTopLevelContext, isInTypeQuery, isIncrementalCompilation, isIndexSignatureDeclaration, isIndexedAccessTypeNode, isInferTypeNode, isInfinityOrNaNString, isInitializedProperty, isInitializedVariable, isInsideJsxElement, isInsideJsxElementOrAttribute, isInsideNodeModules, isInsideTemplateLiteral, isInstanceOfExpression, isInstantiatedModule, isInterfaceDeclaration, isInternalDeclaration, isInternalModuleImportEqualsDeclaration, isInternalName, isIntersectionTypeNode, isIntrinsicJsxName, isIterationStatement, isJSDoc, isJSDocAllType, isJSDocAugmentsTag, isJSDocAuthorTag, isJSDocCallbackTag, isJSDocClassTag, isJSDocCommentContainingNode, isJSDocConstructSignature, isJSDocDeprecatedTag, isJSDocEnumTag, isJSDocFunctionType, isJSDocImplementsTag, isJSDocImportTag, isJSDocIndexSignature, isJSDocLikeText, isJSDocLink, isJSDocLinkCode, isJSDocLinkLike, isJSDocLinkPlain, isJSDocMemberName, isJSDocNameReference, isJSDocNamepathType, isJSDocNamespaceBody, isJSDocNode, isJSDocNonNullableType, isJSDocNullableType, isJSDocOptionalParameter, isJSDocOptionalType, isJSDocOverloadTag, isJSDocOverrideTag, isJSDocParameterTag, isJSDocPrivateTag, isJSDocPropertyLikeTag, isJSDocPropertyTag, isJSDocProtectedTag, isJSDocPublicTag, isJSDocReadonlyTag, isJSDocReturnTag, isJSDocSatisfiesExpression, isJSDocSatisfiesTag, isJSDocSeeTag, isJSDocSignature, isJSDocTag, isJSDocTemplateTag, isJSDocThisTag, isJSDocThrowsTag, isJSDocTypeAlias, isJSDocTypeAssertion, isJSDocTypeExpression, isJSDocTypeLiteral, isJSDocTypeTag, isJSDocTypedefTag, isJSDocUnknownTag, isJSDocUnknownType, isJSDocVariadicType, isJSXTagName, isJsonEqual, isJsonSourceFile, isJsxAttribute, isJsxAttributeLike, isJsxAttributeName, isJsxAttributes, isJsxChild, isJsxClosingElement, isJsxClosingFragment, isJsxElement, isJsxExpression, isJsxFragment, isJsxNamespacedName, isJsxOpeningElement, isJsxOpeningFragment, isJsxOpeningLikeElement, isJsxOpeningLikeElementTagName, isJsxSelfClosingElement, isJsxSpreadAttribute, isJsxTagNameExpression, isJsxText, isJumpStatementTarget, isKeyword, isKeywordOrPunctuation, isKnownSymbol, isLabelName, isLabelOfLabeledStatement, isLabeledStatement, isLateVisibilityPaintedStatement, isLeftHandSideExpression, isLeftHandSideOfAssignment, isLet, isLineBreak, isLiteralComputedPropertyDeclarationName, isLiteralExpression, isLiteralExpressionOfObject, isLiteralImportTypeNode, isLiteralKind, isLiteralLikeAccess, isLiteralLikeElementAccess, isLiteralNameOfPropertyDeclarationOrIndexAccess, isLiteralTypeLikeExpression, isLiteralTypeLiteral, isLiteralTypeNode, isLocalName, isLogicalOperator, isLogicalOrCoalescingAssignmentExpression, isLogicalOrCoalescingAssignmentOperator, isLogicalOrCoalescingBinaryExpression, isLogicalOrCoalescingBinaryOperator, isMappedTypeNode, isMemberName, isMetaProperty, isMethodDeclaration, isMethodOrAccessor, isMethodSignature, isMinusToken, isMissingDeclaration, isMissingPackageJsonInfo, isModifier, isModifierKind, isModifierLike, isModuleAugmentationExternal, isModuleBlock, isModuleBody, isModuleDeclaration, isModuleExportsAccessExpression, isModuleIdentifier, isModuleName, isModuleOrEnumDeclaration, isModuleReference, isModuleSpecifierLike, isModuleWithStringLiteralName, isNameOfFunctionDeclaration, isNameOfModuleDeclaration, isNamedClassElement, isNamedDeclaration, isNamedEvaluation, isNamedEvaluationSource, isNamedExportBindings, isNamedExports, isNamedImportBindings, isNamedImports, isNamedImportsOrExports, isNamedTupleMember, isNamespaceBody, isNamespaceExport, isNamespaceExportDeclaration, isNamespaceImport, isNamespaceReexportDeclaration, isNewExpression, isNewExpressionTarget, isNoSubstitutionTemplateLiteral, isNode, isNodeArray, isNodeArrayMultiLine, isNodeDescendantOf, isNodeKind, isNodeLikeSystem, isNodeModulesDirectory, isNodeWithPossibleHoistedDeclaration, isNonContextualKeyword, isNonExportDefaultModifier, isNonGlobalAmbientModule, isNonGlobalDeclaration, isNonNullAccess, isNonNullChain, isNonNullExpression, isNonStaticMethodOrAccessorWithPrivateName, isNotEmittedOrPartiallyEmittedNode, isNotEmittedStatement, isNullishCoalesce, isNumber, isNumericLiteral, isNumericLiteralName, isObjectBindingElementWithoutPropertyName, isObjectBindingOrAssignmentElement, isObjectBindingOrAssignmentPattern, isObjectBindingPattern, isObjectLiteralElement, isObjectLiteralElementLike, isObjectLiteralExpression, isObjectLiteralMethod, isObjectLiteralOrClassExpressionMethodOrAccessor, isObjectTypeDeclaration, isOctalDigit, isOmittedExpression, isOptionalChain, isOptionalChainRoot, isOptionalDeclaration, isOptionalJSDocPropertyLikeTag, isOptionalTypeNode, isOuterExpression, isOutermostOptionalChain, isOverrideModifier, isPackageJsonInfo, isPackedArrayLiteral, isParameter, isParameterPropertyDeclaration, isParameterPropertyModifier, isParenthesizedExpression, isParenthesizedTypeNode, isParseTreeNode, isPartOfParameterDeclaration, isPartOfTypeNode, isPartOfTypeQuery, isPartiallyEmittedExpression, isPatternMatch, isPinnedComment, isPlainJsFile, isPlusToken, isPossiblyTypeArgumentPosition, isPostfixUnaryExpression, isPrefixUnaryExpression, isPrimitiveLiteralValue, isPrivateIdentifier, isPrivateIdentifierClassElementDeclaration, isPrivateIdentifierPropertyAccessExpression, isPrivateIdentifierSymbol, isProgramBundleEmitBuildInfo, isProgramUptoDate, isPrologueDirective, isPropertyAccessChain, isPropertyAccessEntityNameExpression, isPropertyAccessExpression, isPropertyAccessOrQualifiedName, isPropertyAccessOrQualifiedNameOrImportTypeNode, isPropertyAssignment, isPropertyDeclaration, isPropertyName, isPropertyNameLiteral, isPropertySignature, isProtoSetter, isPrototypeAccess, isPrototypePropertyAssignment, isPunctuation, isPushOrUnshiftIdentifier, isQualifiedName, isQuestionDotToken, isQuestionOrExclamationToken, isQuestionOrPlusOrMinusToken, isQuestionToken, isRawSourceMap, isReadonlyKeyword, isReadonlyKeywordOrPlusOrMinusToken, isRecognizedTripleSlashComment, isReferenceFileLocation, isReferencedFile, isRegularExpressionLiteral, isRequireCall, isRequireVariableStatement, isRestParameter, isRestTypeNode, isReturnStatement, isReturnStatementWithFixablePromiseHandler, isRightSideOfAccessExpression, isRightSideOfInstanceofExpression, isRightSideOfPropertyAccess, isRightSideOfQualifiedName, isRightSideOfQualifiedNameOrPropertyAccess, isRightSideOfQualifiedNameOrPropertyAccessOrJSDocMemberName, isRootedDiskPath, isSameEntityName, isSatisfiesExpression, isScopeMarker, isSemicolonClassElement, isSetAccessor, isSetAccessorDeclaration, isShebangTrivia, isShiftOperatorOrHigher, isShorthandAmbientModuleSymbol, isShorthandPropertyAssignment, isSignedNumericLiteral, isSimpleCopiableExpression, isSimpleInlineableExpression, isSimpleParameter, isSimpleParameterList, isSingleOrDoubleQuote, isSourceFile, isSourceFileFromLibrary, isSourceFileJS, isSourceFileNotJS, isSourceFileNotJson, isSourceMapping, isSpecialPropertyDeclaration, isSpreadAssignment, isSpreadElement, isStatement, isStatementButNotDeclaration, isStatementOrBlock, isStatementWithLocals, isStatic, isStaticModifier, isString, isStringAKeyword, isStringANonContextualKeyword, isStringAndEmptyAnonymousObjectIntersection, isStringDoubleQuoted, isStringLiteral, isStringLiteralLike, isStringLiteralOrJsxExpression, isStringLiteralOrTemplate, isStringOrNumericLiteralLike, isStringOrRegularExpressionOrTemplateLiteral, isStringTextContainingNode, isSuperCall, isSuperKeyword, isSuperOrSuperProperty, isSuperProperty, isSupportedSourceFileName, isSwitchStatement, isSyntaxList, isSyntheticExpression, isSyntheticReference, isTagName, isTaggedTemplateExpression, isTaggedTemplateTag, isTemplateExpression, isTemplateHead, isTemplateLiteral, isTemplateLiteralKind, isTemplateLiteralToken, isTemplateLiteralTypeNode, isTemplateLiteralTypeSpan, isTemplateMiddle, isTemplateMiddleOrTemplateTail, isTemplateSpan, isTemplateTail, isTextWhiteSpaceLike, isThis, isThisContainerOrFunctionBlock, isThisIdentifier, isThisInTypeQuery, isThisInitializedDeclaration, isThisInitializedObjectBindingExpression, isThisProperty, isThisTypeNode, isThisTypeParameter, isThisTypePredicate, isThrowStatement, isToken, isTokenKind, isTraceEnabled, isTransientSymbol, isTrivia, isTryStatement, isTupleTypeNode, isTypeAlias, isTypeAliasDeclaration, isTypeAssertionExpression, isTypeDeclaration, isTypeElement, isTypeKeyword, isTypeKeywordToken, isTypeKeywordTokenOrIdentifier, isTypeLiteralNode, isTypeNode, isTypeNodeKind, isTypeOfExpression, isTypeOnlyExportDeclaration, isTypeOnlyImportDeclaration, isTypeOnlyImportOrExportDeclaration, isTypeOperatorNode, isTypeParameterDeclaration, isTypePredicateNode, isTypeQueryNode, isTypeReferenceNode, isTypeReferenceType, isTypeUsableAsPropertyName, isUMDExportSymbol, isUnaryExpression, isUnaryExpressionWithWrite, isUnicodeIdentifierStart, isUnionTypeNode, isUrl, isValidBigIntString, isValidESSymbolDeclaration, isValidTypeOnlyAliasUseSite, isValueSignatureDeclaration, isVarAwaitUsing, isVarConst, isVarConstLike, isVarUsing, isVariableDeclaration, isVariableDeclarationInVariableStatement, isVariableDeclarationInitializedToBareOrAccessedRequire, isVariableDeclarationInitializedToRequire, isVariableDeclarationList, isVariableLike, isVariableLikeOrAccessor, isVariableStatement, isVoidExpression, isWatchSet, isWhileStatement, isWhiteSpaceLike, isWhiteSpaceSingleLine, isWithStatement, isWriteAccess, isWriteOnlyAccess, isYieldExpression, jsxModeNeedsExplicitImport, keywordPart, last, lastOrUndefined, length, libMap, libs, lineBreakPart, linkNamePart, linkPart, linkTextPart, listFiles, loadModuleFromGlobalCache, loadWithModeAwareCache, makeIdentifierFromModuleName, makeImport, makeStringLiteral, mangleScopedPackageName, map, mapAllOrFail, mapDefined, mapDefinedEntries, mapDefinedIterator, mapEntries, mapIterator, mapOneOrMany, mapToDisplayParts, matchFiles, matchPatternOrExact, matchedText, matchesExclude, maybeBind, maybeSetLocalizedDiagnosticMessages, memoize, memoizeCached, memoizeOne, memoizeWeak, metadataHelper, min, minAndMax, missingFileModifiedTime, modifierToFlag, modifiersToFlags, moduleOptionDeclaration, moduleResolutionIsEqualTo, moduleResolutionNameAndModeGetter, moduleResolutionOptionDeclarations, moduleResolutionSupportsPackageJsonExportsAndImports, moduleResolutionUsesNodeModules, moduleSpecifierToValidIdentifier, moduleSpecifiers, moduleSymbolToValidIdentifier, moveEmitHelpers, moveRangeEnd, moveRangePastDecorators, moveRangePastModifiers, moveRangePos, moveSyntheticComments, mutateMap, mutateMapSkippingNewValues, needsParentheses, needsScopeMarker, newCaseClauseTracker, newPrivateEnvironment, noEmitNotification, noEmitSubstitution, noTransformers, noTruncationMaximumTruncationLength, nodeCanBeDecorated, nodeHasName, nodeIsDecorated, nodeIsMissing, nodeIsPresent, nodeIsSynthesized, nodeModuleNameResolver, nodeModulesPathPart, nodeNextJsonConfigResolver, nodeOrChildIsDecorated, nodeOverlapsWithStartEnd, nodePosToString, nodeSeenTracker, nodeStartsNewLexicalEnvironment, nodeToDisplayParts, noop, noopFileWatcher, normalizePath, normalizeSlashes, not, notImplemented, notImplementedResolver, nullNodeConverters, nullParenthesizerRules, nullTransformationContext, objectAllocator, operatorPart, optionDeclarations, optionMapToObject, optionsAffectingProgramStructure, optionsForBuild, optionsForWatch, optionsHaveChanges, optionsHaveModuleResolutionChanges, or, orderedRemoveItem, orderedRemoveItemAt, packageIdToPackageName, packageIdToString, paramHelper, parameterIsThisKeyword, parameterNamePart, parseBaseNodeFactory, parseBigInt, parseBuildCommand, parseCommandLine, parseCommandLineWorker, parseConfigFileTextToJson, parseConfigFileWithSystem, parseConfigHostFromCompilerHostLike, parseCustomTypeOption, parseIsolatedEntityName, parseIsolatedJSDocComment, parseJSDocTypeExpressionForTests, parseJsonConfigFileContent, parseJsonSourceFileConfigFileContent, parseJsonText, parseListTypeOption, parseNodeFactory, parseNodeModuleFromPath, parsePackageName, parsePseudoBigInt, parseValidBigInt, pasteEdits, patchWriteFileEnsuringDirectory, pathContainsNodeModules, pathIsAbsolute, pathIsBareSpecifier, pathIsRelative, patternText, perfLogger, performIncrementalCompilation, performance, plainJSErrors, positionBelongsToNode, positionIsASICandidate, positionIsSynthesized, positionsAreOnSameLine, preProcessFile, probablyUsesSemicolons, processCommentPragmas, processPragmasIntoFields, processTaggedTemplateExpression, programContainsEsModules, programContainsModules, projectReferenceIsEqualTo, propKeyHelper, propertyNamePart, pseudoBigIntToString, punctuationPart, pushIfUnique, quote, quotePreferenceFromString, rangeContainsPosition, rangeContainsPositionExclusive, rangeContainsRange, rangeContainsRangeExclusive, rangeContainsStartEnd, rangeEndIsOnSameLineAsRangeStart, rangeEndPositionsAreOnSameLine, rangeEquals, rangeIsOnSingleLine, rangeOfNode, rangeOfTypeParameters, rangeOverlapsWithStartEnd, rangeStartIsOnSameLineAsRangeEnd, rangeStartPositionsAreOnSameLine, readBuilderProgram, readConfigFile, readHelper, readJson, readJsonConfigFile, readJsonOrUndefined, reduceEachLeadingCommentRange, reduceEachTrailingCommentRange, reduceLeft, reduceLeftIterator, reducePathComponents, refactor, regExpEscape, regularExpressionFlagToCharacter, relativeComplement, removeAllComments, removeEmitHelper, removeExtension, removeFileExtension, removeIgnoredPath, removeMinAndVersionNumbers, removeOptionality, removePrefix, removeSuffix, removeTrailingDirectorySeparator, repeatString, replaceElement, replaceFirstStar, resolutionExtensionIsTSOrJson, resolveConfigFileProjectName, resolveJSModule, resolveLibrary, resolveModuleName, resolveModuleNameFromCache, resolvePackageNameToPackageJson, resolvePath, resolveProjectReferencePath, resolveTripleslashReference, resolveTypeReferenceDirective, resolvingEmptyArray, restHelper, returnFalse, returnNoopFileWatcher, returnTrue, returnUndefined, returnsPromise, runInitializersHelper, sameFlatMap, sameMap, sameMapping, scanShebangTrivia, scanTokenAtPosition, scanner, screenStartingMessageCodes, semanticDiagnosticsOptionDeclarations, serializeCompilerOptions, server, servicesVersion, setCommentRange, setConfigFileInOptions, setConstantValue, setEachParent, setEmitFlags, setFunctionNameHelper, setGetSourceFileAsHashVersioned, setIdentifierAutoGenerate, setIdentifierGeneratedImportReference, setIdentifierTypeArguments, setInternalEmitFlags, setLocalizedDiagnosticMessages, setModuleDefaultHelper, setNodeChildren, setNodeFlags, setObjectAllocator, setOriginalNode, setParent, setParentRecursive, setPrivateIdentifier, setSnippetElement, setSourceMapRange, setStackTraceLimit, setStartsOnNewLine, setSyntheticLeadingComments, setSyntheticTrailingComments, setSys, setSysLog, setTextRange, setTextRangeEnd, setTextRangePos, setTextRangePosEnd, setTextRangePosWidth, setTokenSourceMapRange, setTypeNode, setUILocale, setValueDeclaration, shouldAllowImportingTsExtension, shouldPreserveConstEnums, shouldUseUriStyleNodeCoreModules, showModuleSpecifier, signatureHasLiteralTypes, signatureHasRestParameter, signatureToDisplayParts, single, singleElementArray, singleIterator, singleOrMany, singleOrUndefined, skipAlias, skipAssertions, skipConstraint, skipOuterExpressions, skipParentheses, skipPartiallyEmittedExpressions, skipTrivia, skipTypeChecking, skipTypeParentheses, skipWhile, sliceAfter, some, sort, sortAndDeduplicate, sortAndDeduplicateDiagnostics, sourceFileAffectingCompilerOptions, sourceFileMayBeEmitted, sourceMapCommentRegExp, sourceMapCommentRegExpDontCareLineStart, spacePart, spanMap, spreadArrayHelper, stableSort, startEndContainsRange, startEndOverlapsWithStartEnd, startOnNewLine, startTracing, startsWith, startsWithDirectory, startsWithUnderscore, startsWithUseStrict, stringContainsAt, stringToToken, stripQuotes, supportedDeclarationExtensions, supportedJSExtensions, supportedJSExtensionsFlat, supportedLocaleDirectories, supportedTSExtensions, supportedTSExtensionsFlat, supportedTSImplementationExtensions, suppressLeadingAndTrailingTrivia, suppressLeadingTrivia, suppressTrailingTrivia, symbolEscapedNameNoDefault, symbolName, symbolNameNoDefault, symbolPart, symbolToDisplayParts, syntaxMayBeASICandidate, syntaxRequiresTrailingSemicolonOrASI, sys, sysLog, tagNamesAreEquivalent, takeWhile, targetOptionDeclaration, templateObjectHelper, testFormatSettings, textChangeRangeIsUnchanged, textChangeRangeNewSpan, textChanges, textOrKeywordPart, textPart, textRangeContainsPositionInclusive, textSpanContainsPosition, textSpanContainsTextSpan, textSpanEnd, textSpanIntersection, textSpanIntersectsWith, textSpanIntersectsWithPosition, textSpanIntersectsWithTextSpan, textSpanIsEmpty, textSpanOverlap, textSpanOverlapsWith, textSpansEqual, textToKeywordObj, timestamp, toArray, toBuilderFileEmit, toBuilderStateFileInfoForMultiEmit, toEditorSettings, toFileNameLowerCase, toLowerCase, toPath, toProgramEmitPending, tokenIsIdentifierOrKeyword, tokenIsIdentifierOrKeywordOrGreaterThan, tokenToString, trace, tracing, tracingEnabled, transferSourceFileChildren, transform, transformClassFields, transformDeclarations, transformECMAScriptModule, transformES2015, transformES2016, transformES2017, transformES2018, transformES2019, transformES2020, transformES2021, transformESDecorators, transformESNext, transformGenerators, transformJsx, transformLegacyDecorators, transformModule, transformNamedEvaluation, transformNodeModule, transformNodes, transformSystemModule, transformTypeScript, transpile, transpileDeclaration, transpileModule, transpileOptionValueCompilerOptions, tryAddToSet, tryAndIgnoreErrors, tryCast, tryDirectoryExists, tryExtractTSExtension, tryFileExists, tryGetClassExtendingExpressionWithTypeArguments, tryGetClassImplementingOrExtendingExpressionWithTypeArguments, tryGetDirectories, tryGetExtensionFromPath, tryGetImportFromModuleSpecifier, tryGetJSDocSatisfiesTypeNode, tryGetModuleNameFromFile, tryGetModuleSpecifierFromDeclaration, tryGetNativePerformanceHooks, tryGetPropertyAccessOrIdentifierToString, tryGetPropertyNameOfBindingOrAssignmentElement, tryGetSourceMappingURL, tryGetTextOfPropertyName, tryIOAndConsumeErrors, tryParseJson, tryParsePattern, tryParsePatterns, tryParseRawSourceMap, tryReadDirectory, tryReadFile, tryRemoveDirectoryPrefix, tryRemoveExtension, tryRemovePrefix, tryRemoveSuffix, typeAcquisitionDeclarations, typeAliasNamePart, typeDirectiveIsEqualTo, typeKeywords, typeParameterNamePart, typeToDisplayParts, unchangedPollThresholds, unchangedTextChangeRange, unescapeLeadingUnderscores, unmangleScopedPackageName, unorderedRemoveItem, unorderedRemoveItemAt, unreachableCodeIsError, unsetNodeChildren, unusedLabelIsError, unwrapInnermostStatementOfLabel, unwrapParenthesizedExpression, updateErrorForNoInputFiles, updateLanguageServiceSourceFile, updateMissingFilePathsWatch, updateResolutionField, updateSharedExtendedConfigFileWatcher, updateSourceFile, updateWatchingWildcardDirectories, usesExtensionsOnImports, usingSingleLineStringWriter, utf16EncodeAsString, validateLocaleAndSetLanguage, valuesHelper, version, versionMajorMinor, visitArray, visitCommaListElements, visitEachChild, visitFunctionBody, visitIterationBody, visitLexicalEnvironment, visitNode, visitNodes, visitParameterList, walkUpBindingElementsAndPatterns, walkUpLexicalEnvironments, walkUpOuterExpressions, walkUpParenthesizedExpressions, walkUpParenthesizedTypes, walkUpParenthesizedTypesAndGetParentAndChild, whitespaceOrMapCommentRegExp, writeCommentRange, writeFile, writeFileEnsuringDirectories, zipWith }); })({ get exports() { return ts; }, set exports(v) { ts = v; if (typeof module !== "undefined" && module.exports) { module.exports = v; } } }) //# sourceMappingURL=typescript.js.map