mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-09 12:15:34 -06:00
Rename through all projects with the same file symLink
This commit is contained in:
parent
ef7f131398
commit
428e0529fd
@ -524,7 +524,12 @@ namespace ts {
|
||||
process.exit(exitCode);
|
||||
},
|
||||
realpath(path: string): string {
|
||||
return _fs.realpathSync(path);
|
||||
try {
|
||||
return _fs.realpathSync(path);
|
||||
}
|
||||
catch {
|
||||
return path;
|
||||
}
|
||||
},
|
||||
debugMode: some(<string[]>process.execArgv, arg => /^--(inspect|debug)(-brk)?(=\d+)?$/i.test(arg)),
|
||||
tryEnableSourceMapsForHost() {
|
||||
|
||||
@ -6604,6 +6604,7 @@ namespace ts.projectSystem {
|
||||
const host = createServerHost(files);
|
||||
const session = createSession(host);
|
||||
const projectService = session.getProjectService();
|
||||
debugger;
|
||||
session.executeCommandSeq<protocol.OpenRequest>({
|
||||
command: protocol.CommandTypes.Open,
|
||||
arguments: {
|
||||
@ -6637,6 +6638,7 @@ namespace ts.projectSystem {
|
||||
assert.isDefined(projectService.configuredProjects.get(aTsconfig.path));
|
||||
assert.isDefined(projectService.configuredProjects.get(bTsconfig.path));
|
||||
|
||||
debugger;
|
||||
verifyRenameResponse(session.executeCommandSeq<protocol.RenameRequest>({
|
||||
command: protocol.CommandTypes.Rename,
|
||||
arguments: {
|
||||
@ -6650,20 +6652,25 @@ namespace ts.projectSystem {
|
||||
|
||||
function verifyRenameResponse({ info, locs }: protocol.RenameResponseBody) {
|
||||
assert.isTrue(info.canRename);
|
||||
assert.equal(locs.length, 2); // Currently 2 but needs to be 4
|
||||
assert.deepEqual(locs[0], {
|
||||
file: aFile.path,
|
||||
locs: [
|
||||
{ start: { line: 1, offset: 39 }, end: { line: 1, offset: 40 } },
|
||||
{ start: { line: 1, offset: 9 }, end: { line: 1, offset: 10 } }
|
||||
]
|
||||
});
|
||||
assert.deepEqual(locs[1], {
|
||||
file: aFc,
|
||||
locs: [
|
||||
{ start: { line: 1, offset: 14 }, end: { line: 1, offset: 15 } }
|
||||
]
|
||||
});
|
||||
assert.equal(locs.length, 4);
|
||||
verifyLocations(0, aFile.path, aFc);
|
||||
verifyLocations(2, bFile.path, bFc);
|
||||
|
||||
function verifyLocations(locStartIndex: number, firstFile: string, secondFile: string) {
|
||||
assert.deepEqual(locs[locStartIndex], {
|
||||
file: firstFile,
|
||||
locs: [
|
||||
{ start: { line: 1, offset: 39 }, end: { line: 1, offset: 40 } },
|
||||
{ start: { line: 1, offset: 9 }, end: { line: 1, offset: 10 } }
|
||||
]
|
||||
});
|
||||
assert.deepEqual(locs[locStartIndex + 1], {
|
||||
file: secondFile,
|
||||
locs: [
|
||||
{ start: { line: 1, offset: 14 }, end: { line: 1, offset: 15 } }
|
||||
]
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@ -88,7 +88,7 @@ interface Array<T> {}`
|
||||
}
|
||||
|
||||
interface SymLink extends FSEntry {
|
||||
symLink: Path;
|
||||
symLink: string;
|
||||
}
|
||||
|
||||
function isFolder(s: FSEntry): s is Folder {
|
||||
@ -526,7 +526,7 @@ interface Array<T> {}`
|
||||
return {
|
||||
path: this.toPath(fullPath),
|
||||
fullPath,
|
||||
symLink: this.toPath(getNormalizedAbsolutePath(fileOrDirectory.symLink, getDirectoryPath(fullPath)))
|
||||
symLink: getNormalizedAbsolutePath(fileOrDirectory.symLink, getDirectoryPath(fullPath))
|
||||
};
|
||||
}
|
||||
|
||||
@ -539,17 +539,13 @@ interface Array<T> {}`
|
||||
};
|
||||
}
|
||||
|
||||
private isFile(fsEntry: FSEntry) {
|
||||
return !!this.getRealFile(fsEntry.path, fsEntry);
|
||||
}
|
||||
|
||||
private getRealFile(path: Path, fsEntry = this.fs.get(path)): File | undefined {
|
||||
if (isFile(fsEntry)) {
|
||||
private getRealFsEntry<T extends FSEntry>(isFsEntry: (fsEntry: FSEntry) => fsEntry is T, path: Path, fsEntry = this.fs.get(path)): T | undefined {
|
||||
if (isFsEntry(fsEntry)) {
|
||||
return fsEntry;
|
||||
}
|
||||
|
||||
if (isSymLink(fsEntry)) {
|
||||
return this.getRealFile(fsEntry.symLink);
|
||||
return this.getRealFsEntry(isFsEntry, this.toPath(fsEntry.symLink));
|
||||
}
|
||||
|
||||
if (fsEntry) {
|
||||
@ -557,42 +553,28 @@ interface Array<T> {}`
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const dir = getDirectoryPath(path);
|
||||
const dirEntry = this.getRealFolder(dir);
|
||||
if (dirEntry && dirEntry.path !== dir) {
|
||||
return this.getRealFile(combinePaths(dirEntry.path, getBaseFileName(path)) as Path);
|
||||
const realpath = this.realpath(path);
|
||||
if (path !== realpath) {
|
||||
return this.getRealFsEntry(isFsEntry, realpath as Path);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private isFile(fsEntry: FSEntry) {
|
||||
return !!this.getRealFile(fsEntry.path, fsEntry);
|
||||
}
|
||||
|
||||
private getRealFile(path: Path, fsEntry?: FSEntry): File | undefined {
|
||||
return this.getRealFsEntry(isFile, path, fsEntry);
|
||||
}
|
||||
|
||||
private isFolder(fsEntry: FSEntry) {
|
||||
return !!this.getRealFolder(fsEntry.path, fsEntry);
|
||||
}
|
||||
|
||||
private getRealFolder(path: Path, fsEntry = this.fs.get(path)): Folder | undefined {
|
||||
if (isFolder(fsEntry)) {
|
||||
return fsEntry;
|
||||
}
|
||||
|
||||
if (isSymLink(fsEntry)) {
|
||||
return this.getRealFolder(fsEntry.symLink);
|
||||
}
|
||||
|
||||
if (fsEntry) {
|
||||
// This fs entry is something else
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const baseName = getBaseFileName(path);
|
||||
const dir = getDirectoryPath(path);
|
||||
if (dir !== baseName) {
|
||||
const dirEntry = this.getRealFolder(dir);
|
||||
if (dirEntry && dirEntry.path !== dir) {
|
||||
return this.getRealFolder(combinePaths(dirEntry.path, baseName) as Path);
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
return this.getRealFsEntry(isFolder, path, fsEntry);
|
||||
}
|
||||
|
||||
fileExists(s: string) {
|
||||
@ -765,16 +747,21 @@ interface Array<T> {}`
|
||||
clear(this.output);
|
||||
}
|
||||
|
||||
realpath(s: string) {
|
||||
while (true) {
|
||||
const fsEntry = this.fs.get(this.toFullPath(s));
|
||||
if (isSymLink(fsEntry)) {
|
||||
s = fsEntry.symLink;
|
||||
}
|
||||
else {
|
||||
return s;
|
||||
}
|
||||
realpath(s: string): string {
|
||||
const fullPath = this.toNormalizedAbsolutePath(s);
|
||||
const path = this.toPath(fullPath);
|
||||
if (getDirectoryPath(path) === path) {
|
||||
// Root
|
||||
return s;
|
||||
}
|
||||
const dirFullPath = this.realpath(getDirectoryPath(fullPath));
|
||||
const realFullPath = combinePaths(dirFullPath, getBaseFileName(fullPath));
|
||||
const fsEntry = this.fs.get(this.toPath(realFullPath));
|
||||
if (isSymLink(fsEntry)) {
|
||||
return this.realpath(fsEntry.symLink);
|
||||
}
|
||||
|
||||
return realFullPath;
|
||||
}
|
||||
|
||||
readonly existMessage = "System Exit";
|
||||
|
||||
@ -198,16 +198,6 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This helper function processes a list of projects and return the concatenated, sortd and deduplicated output of processing each project.
|
||||
*/
|
||||
export function combineProjectOutput<T>(projects: ReadonlyArray<Project>, action: (project: Project) => ReadonlyArray<T>, comparer?: (a: T, b: T) => number, areEqual?: (a: T, b: T) => boolean) {
|
||||
const outputs = flatMap(projects, action);
|
||||
return comparer
|
||||
? sortAndDeduplicate(outputs, comparer, areEqual)
|
||||
: deduplicate(outputs, areEqual);
|
||||
}
|
||||
|
||||
export interface HostConfiguration {
|
||||
formatCodeOptions: FormatCodeSettings;
|
||||
hostInfo: string;
|
||||
@ -335,6 +325,11 @@ namespace ts.server {
|
||||
* Container of all known scripts
|
||||
*/
|
||||
private readonly filenameToScriptInfo = createMap<ScriptInfo>();
|
||||
/**
|
||||
* Map to the real path of the infos
|
||||
*/
|
||||
/* @internal */
|
||||
readonly realpathToScriptInfos: MultiMap<ScriptInfo> | undefined;
|
||||
/**
|
||||
* maps external project file name to list of config files that were the part of this project
|
||||
*/
|
||||
@ -427,7 +422,9 @@ namespace ts.server {
|
||||
this.typesMapLocation = (opts.typesMapLocation === undefined) ? combinePaths(this.getExecutingFilePath(), "../typesMap.json") : opts.typesMapLocation;
|
||||
|
||||
Debug.assert(!!this.host.createHash, "'ServerHost.createHash' is required for ProjectService");
|
||||
|
||||
if (this.host.realpath) {
|
||||
this.realpathToScriptInfos = createMultiMap();
|
||||
}
|
||||
this.currentDirectory = this.host.getCurrentDirectory();
|
||||
this.toCanonicalFileName = createGetCanonicalFileName(this.host.useCaseSensitiveFileNames);
|
||||
this.throttledOperations = new ThrottledOperations(this.host, this.logger);
|
||||
@ -768,7 +765,7 @@ namespace ts.server {
|
||||
if (info.containingProjects.length === 0) {
|
||||
// Orphan script info, remove it as we can always reload it on next open file request
|
||||
this.stopWatchingScriptInfo(info);
|
||||
this.filenameToScriptInfo.delete(info.path);
|
||||
this.deleteScriptInfo(info);
|
||||
}
|
||||
else {
|
||||
// file has been changed which might affect the set of referenced files in projects that include
|
||||
@ -785,7 +782,7 @@ namespace ts.server {
|
||||
// TODO: handle isOpen = true case
|
||||
|
||||
if (!info.isScriptOpen()) {
|
||||
this.filenameToScriptInfo.delete(info.path);
|
||||
this.deleteScriptInfo(info);
|
||||
|
||||
// capture list of projects since detachAllProjects will wipe out original list
|
||||
const containingProjects = info.containingProjects.slice();
|
||||
@ -1019,11 +1016,19 @@ namespace ts.server {
|
||||
if (!info.isScriptOpen() && info.isOrphan()) {
|
||||
// if there are not projects that include this script info - delete it
|
||||
this.stopWatchingScriptInfo(info);
|
||||
this.filenameToScriptInfo.delete(info.path);
|
||||
this.deleteScriptInfo(info);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private deleteScriptInfo(info: ScriptInfo) {
|
||||
this.filenameToScriptInfo.delete(info.path);
|
||||
const realpath = info.getRealpathIfDifferent();
|
||||
if (realpath) {
|
||||
this.realpathToScriptInfos.remove(realpath, info);
|
||||
}
|
||||
}
|
||||
|
||||
private configFileExists(configFileName: NormalizedPath, canonicalConfigFilePath: string, info: ScriptInfo) {
|
||||
let configFileExistenceInfo = this.configFileExistenceInfoCache.get(canonicalConfigFilePath);
|
||||
if (configFileExistenceInfo) {
|
||||
@ -1736,6 +1741,43 @@ namespace ts.server {
|
||||
return this.getScriptInfoForNormalizedPath(toNormalizedPath(uncheckedFileName));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the projects that contain script info through SymLink
|
||||
* Note that this does not return projects in info.containingProjects
|
||||
*/
|
||||
/*@internal*/
|
||||
getSymlinkedProjects(info: ScriptInfo): MultiMap<Project> | undefined {
|
||||
let projects: MultiMap<Project> | undefined;
|
||||
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: ScriptInfo) {
|
||||
if (toAddInfo !== info) {
|
||||
for (const project of toAddInfo.containingProjects) {
|
||||
// Add the projects only if they can use symLink targets and not already in the list
|
||||
if (project.languageServiceEnabled &&
|
||||
!project.getCompilerOptions().preserveSymlinks &&
|
||||
!contains(info.containingProjects, 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private watchClosedScriptInfo(info: ScriptInfo) {
|
||||
Debug.assert(!info.fileWatcher);
|
||||
// do not watch files with mixed content - server doesn't know how to interpret it
|
||||
|
||||
@ -213,6 +213,10 @@ namespace ts.server {
|
||||
/*@internal*/
|
||||
readonly isDynamic: boolean;
|
||||
|
||||
/*@internal*/
|
||||
/** Set to real path if path is different from info.path */
|
||||
private realpath: Path | undefined;
|
||||
|
||||
constructor(
|
||||
private readonly host: ServerHost,
|
||||
readonly fileName: NormalizedPath,
|
||||
@ -224,6 +228,7 @@ namespace ts.server {
|
||||
this.textStorage = new TextStorage(host, fileName);
|
||||
if (hasMixedContent || this.isDynamic) {
|
||||
this.textStorage.reload("");
|
||||
this.realpath = this.path;
|
||||
}
|
||||
this.scriptKind = scriptKind
|
||||
? scriptKind
|
||||
@ -264,6 +269,30 @@ namespace ts.server {
|
||||
return this.textStorage.getSnapshot();
|
||||
}
|
||||
|
||||
private ensureRealPath() {
|
||||
if (this.realpath === undefined) {
|
||||
// Default is just the path
|
||||
this.realpath = this.path;
|
||||
if (this.host.realpath) {
|
||||
Debug.assert(!!this.containingProjects.length);
|
||||
const project = this.containingProjects[0];
|
||||
const realpath = this.host.realpath(this.path);
|
||||
if (realpath) {
|
||||
this.realpath = project.toPath(realpath);
|
||||
// If it is different from this.path, add to the map
|
||||
if (this.realpath !== this.path) {
|
||||
project.projectService.realpathToScriptInfos.add(this.realpath, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
getRealpathIfDifferent(): Path | undefined {
|
||||
return this.realpath && this.realpath !== this.path ? this.realpath : undefined;
|
||||
}
|
||||
|
||||
getFormatCodeSettings() {
|
||||
return this.formatCodeSettings;
|
||||
}
|
||||
@ -272,6 +301,9 @@ namespace ts.server {
|
||||
const isNew = !this.isAttached(project);
|
||||
if (isNew) {
|
||||
this.containingProjects.push(project);
|
||||
if (!project.getCompilerOptions().preserveSymlinks) {
|
||||
this.ensureRealPath();
|
||||
}
|
||||
}
|
||||
return isNew;
|
||||
}
|
||||
|
||||
@ -255,6 +255,32 @@ namespace ts.server {
|
||||
};
|
||||
}
|
||||
|
||||
type Projects = ReadonlyArray<Project> | {
|
||||
projects: ReadonlyArray<Project>;
|
||||
symLinkedProjects: MultiMap<Project>;
|
||||
};
|
||||
|
||||
function isProjectsArray(projects: Projects): projects is ReadonlyArray<Project> {
|
||||
return !!(<ReadonlyArray<Project>>projects).length;
|
||||
}
|
||||
|
||||
/**
|
||||
* This helper function processes a list of projects and return the concatenated, sortd and deduplicated output of processing each project.
|
||||
*/
|
||||
function combineProjectOutput<T, U>(defaultValue: T, getValue: (path: Path) => T, projects: Projects, action: (project: Project, value: T) => ReadonlyArray<U> | U | undefined, comparer?: (a: U, b: U) => number, areEqual?: (a: U, b: U) => boolean) {
|
||||
const outputs = flatMap(isProjectsArray(projects) ? projects : projects.projects, project => action(project, defaultValue));
|
||||
if (!isProjectsArray(projects) && projects.symLinkedProjects) {
|
||||
projects.symLinkedProjects.forEach((projects, path) => {
|
||||
const value = getValue(path as Path);
|
||||
outputs.push(...flatMap(projects, project => action(project, value)));
|
||||
});
|
||||
}
|
||||
|
||||
return comparer
|
||||
? sortAndDeduplicate(outputs, comparer, areEqual)
|
||||
: deduplicate(outputs, areEqual);
|
||||
}
|
||||
|
||||
export interface SessionOptions {
|
||||
host: ServerHost;
|
||||
cancellationToken: ServerCancellationToken;
|
||||
@ -789,8 +815,9 @@ namespace ts.server {
|
||||
return project.getLanguageService().getRenameInfo(file, position);
|
||||
}
|
||||
|
||||
private getProjects(args: protocol.FileRequestArgs) {
|
||||
let projects: Project[];
|
||||
private getProjects(args: protocol.FileRequestArgs): Projects {
|
||||
let projects: ReadonlyArray<Project>;
|
||||
let symLinkedProjects: MultiMap<Project> | undefined;
|
||||
if (args.projectFileName) {
|
||||
const project = this.getProject(args.projectFileName);
|
||||
if (project) {
|
||||
@ -800,13 +827,14 @@ namespace ts.server {
|
||||
else {
|
||||
const scriptInfo = this.projectService.getScriptInfo(args.file);
|
||||
projects = scriptInfo.containingProjects;
|
||||
symLinkedProjects = this.projectService.getSymlinkedProjects(scriptInfo);
|
||||
}
|
||||
// filter handles case when 'projects' is undefined
|
||||
projects = filter(projects, p => p.languageServiceEnabled);
|
||||
if (!projects || !projects.length) {
|
||||
if ((!projects || !projects.length) && !symLinkedProjects) {
|
||||
return Errors.ThrowNoProject();
|
||||
}
|
||||
return projects;
|
||||
return symLinkedProjects ? { projects, symLinkedProjects } : projects;
|
||||
}
|
||||
|
||||
private getDefaultProject(args: protocol.FileRequestArgs) {
|
||||
@ -841,8 +869,10 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
const fileSpans = combineProjectOutput(
|
||||
file,
|
||||
path => this.projectService.getScriptInfoForPath(path).fileName,
|
||||
projects,
|
||||
(project: Project) => {
|
||||
(project, file) => {
|
||||
const renameLocations = project.getLanguageService().findRenameLocations(file, position, args.findInStrings, args.findInComments);
|
||||
if (!renameLocations) {
|
||||
return emptyArray;
|
||||
@ -881,8 +911,10 @@ namespace ts.server {
|
||||
}
|
||||
else {
|
||||
return combineProjectOutput(
|
||||
file,
|
||||
path => this.projectService.getScriptInfoForPath(path).fileName,
|
||||
projects,
|
||||
p => p.getLanguageService().findRenameLocations(file, position, args.findInStrings, args.findInComments),
|
||||
(p, file) => p.getLanguageService().findRenameLocations(file, position, args.findInStrings, args.findInComments),
|
||||
/*comparer*/ undefined,
|
||||
renameLocationIsEqualTo
|
||||
);
|
||||
@ -938,9 +970,11 @@ namespace ts.server {
|
||||
const nameSpan = nameInfo.textSpan;
|
||||
const nameColStart = scriptInfo.positionToLineOffset(nameSpan.start).offset;
|
||||
const nameText = scriptInfo.getSnapshot().getText(nameSpan.start, textSpanEnd(nameSpan));
|
||||
const refs = combineProjectOutput<protocol.ReferencesResponseItem>(
|
||||
const refs = combineProjectOutput<NormalizedPath, protocol.ReferencesResponseItem>(
|
||||
file,
|
||||
path => this.projectService.getScriptInfoForPath(path).fileName,
|
||||
projects,
|
||||
(project: Project) => {
|
||||
(project, file) => {
|
||||
const references = project.getLanguageService().getReferencesAtPosition(file, position);
|
||||
if (!references) {
|
||||
return emptyArray;
|
||||
@ -974,8 +1008,10 @@ namespace ts.server {
|
||||
}
|
||||
else {
|
||||
return combineProjectOutput(
|
||||
file,
|
||||
path => this.projectService.getScriptInfoForPath(path).fileName,
|
||||
projects,
|
||||
project => project.getLanguageService().findReferences(file, position),
|
||||
(project, file) => project.getLanguageService().findReferences(file, position),
|
||||
/*comparer*/ undefined,
|
||||
equateValues
|
||||
);
|
||||
@ -1240,20 +1276,25 @@ namespace ts.server {
|
||||
return emptyArray;
|
||||
}
|
||||
|
||||
const result: protocol.CompileOnSaveAffectedFileListSingleProject[] = [];
|
||||
|
||||
// if specified a project, we only return affected file list in this project
|
||||
const projectsToSearch = args.projectFileName ? [this.projectService.findProject(args.projectFileName)] : info.containingProjects;
|
||||
for (const project of projectsToSearch) {
|
||||
if (project.compileOnSaveEnabled && project.languageServiceEnabled && !project.getCompilationSettings().noEmit) {
|
||||
result.push({
|
||||
projectFileName: project.getProjectName(),
|
||||
fileNames: project.getCompileOnSaveAffectedFileList(info),
|
||||
projectUsesOutFile: !!project.getCompilationSettings().outFile || !!project.getCompilationSettings().out
|
||||
});
|
||||
const projects = args.projectFileName ? [this.projectService.findProject(args.projectFileName)] : info.containingProjects;
|
||||
const symLinkedProjects = !args.projectFileName && this.projectService.getSymlinkedProjects(info);
|
||||
return combineProjectOutput(
|
||||
info,
|
||||
path => this.projectService.getScriptInfoForPath(path),
|
||||
symLinkedProjects ? { projects, symLinkedProjects } : projects,
|
||||
(project, info) => {
|
||||
let result: protocol.CompileOnSaveAffectedFileListSingleProject;
|
||||
if (project.compileOnSaveEnabled && project.languageServiceEnabled && !project.getCompilationSettings().noEmit) {
|
||||
result = {
|
||||
projectFileName: project.getProjectName(),
|
||||
fileNames: project.getCompileOnSaveAffectedFileList(info),
|
||||
projectUsesOutFile: !!project.getCompilationSettings().outFile || !!project.getCompilationSettings().out
|
||||
};
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
);
|
||||
}
|
||||
|
||||
private emitFile(args: protocol.CompileOnSaveEmitFileRequestArgs) {
|
||||
@ -1406,8 +1447,14 @@ namespace ts.server {
|
||||
const fileName = args.currentFileOnly ? args.file && normalizeSlashes(args.file) : undefined;
|
||||
if (simplifiedResult) {
|
||||
return combineProjectOutput(
|
||||
fileName,
|
||||
() => undefined,
|
||||
projects,
|
||||
project => {
|
||||
(project, file) => {
|
||||
if (fileName && !file) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const navItems = project.getLanguageService().getNavigateToItems(args.searchValue, args.maxResultCount, fileName, /*excludeDts*/ project.isNonTsProject());
|
||||
if (!navItems) {
|
||||
return emptyArray;
|
||||
@ -1443,8 +1490,15 @@ namespace ts.server {
|
||||
}
|
||||
else {
|
||||
return combineProjectOutput(
|
||||
fileName,
|
||||
() => undefined,
|
||||
projects,
|
||||
project => project.getLanguageService().getNavigateToItems(args.searchValue, args.maxResultCount, fileName, /*excludeDts*/ project.isNonTsProject()),
|
||||
(project, file) => {
|
||||
if (fileName && !file) {
|
||||
return undefined;
|
||||
}
|
||||
return project.getLanguageService().getNavigateToItems(args.searchValue, args.maxResultCount, fileName, /*excludeDts*/ project.isNonTsProject());
|
||||
},
|
||||
/*comparer*/ undefined,
|
||||
navigateToItemIsEqualTo);
|
||||
}
|
||||
|
||||
@ -7151,6 +7151,7 @@ declare namespace ts.server {
|
||||
open(newText: string): void;
|
||||
close(fileExists?: boolean): void;
|
||||
getSnapshot(): IScriptSnapshot;
|
||||
private ensureRealPath();
|
||||
getFormatCodeSettings(): FormatCodeSettings;
|
||||
attachToProject(project: Project): boolean;
|
||||
isAttached(project: Project): boolean;
|
||||
@ -7523,10 +7524,6 @@ declare namespace ts.server {
|
||||
function convertCompilerOptions(protocolOptions: protocol.ExternalProjectCompilerOptions): CompilerOptions & protocol.CompileOnSaveMixin;
|
||||
function tryConvertScriptKindName(scriptKindName: protocol.ScriptKindName | ScriptKind): ScriptKind;
|
||||
function convertScriptKindName(scriptKindName: protocol.ScriptKindName): ScriptKind.Unknown | ScriptKind.JS | ScriptKind.JSX | ScriptKind.TS | ScriptKind.TSX;
|
||||
/**
|
||||
* This helper function processes a list of projects and return the concatenated, sortd and deduplicated output of processing each project.
|
||||
*/
|
||||
function combineProjectOutput<T>(projects: ReadonlyArray<Project>, action: (project: Project) => ReadonlyArray<T>, comparer?: (a: T, b: T) => number, areEqual?: (a: T, b: T) => boolean): T[];
|
||||
interface HostConfiguration {
|
||||
formatCodeOptions: FormatCodeSettings;
|
||||
hostInfo: string;
|
||||
@ -7662,6 +7659,7 @@ declare namespace ts.server {
|
||||
*/
|
||||
private closeOpenFile(info);
|
||||
private deleteOrphanScriptInfoNotInAnyProject();
|
||||
private deleteScriptInfo(info);
|
||||
private configFileExists(configFileName, canonicalConfigFilePath, info);
|
||||
private setConfigFileExistenceByNewConfiguredProject(project);
|
||||
/**
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user