Skip to content

Commit afdf1e9

Browse files
committed
Dont depend on project in document position mapper so that we can unload or remove projects independently
1 parent 12428d4 commit afdf1e9

File tree

4 files changed

+78
-66
lines changed

4 files changed

+78
-66
lines changed

src/server/editorServices.ts

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2195,6 +2195,70 @@ namespace ts.server {
21952195
return this.filenameToScriptInfo.get(fileName);
21962196
}
21972197

2198+
/*@internal*/
2199+
getDocumentPositionMapper(fileName: string, project: Project): DocumentPositionMapper | undefined {
2200+
const declarationInfo = this.getOrCreateScriptInfoNotOpenedByClient(fileName, project.currentDirectory, project.directoryStructureHost);
2201+
if (!declarationInfo) return undefined;
2202+
2203+
declarationInfo.getSnapshot(); // Ensure synchronized
2204+
const existingMapper = declarationInfo.textStorage.mapper;
2205+
if (existingMapper !== undefined) {
2206+
return existingMapper ? existingMapper : undefined;
2207+
}
2208+
2209+
// Create the mapper
2210+
declarationInfo.mapInfo = undefined;
2211+
2212+
let readMapFile: ((fileName: string) => string | undefined) | undefined = fileName => {
2213+
const mapInfo = this.getOrCreateScriptInfoNotOpenedByClient(fileName, project.currentDirectory, project.directoryStructureHost);
2214+
if (!mapInfo) return undefined;
2215+
declarationInfo.mapInfo = mapInfo;
2216+
const snap = mapInfo.getSnapshot();
2217+
return snap.getText(0, snap.getLength());
2218+
};
2219+
const projectName = project.projectName;
2220+
const mapper = getDocumentPositionMapper(
2221+
{ getCanonicalFileName: this.toCanonicalFileName, log: s => this.logger.info(s), getSourceFileLike: f => this.getSourceFileLike(f, projectName) },
2222+
declarationInfo.fileName,
2223+
declarationInfo.textStorage.getLineInfo(),
2224+
readMapFile
2225+
);
2226+
readMapFile = undefined; // Remove ref to project
2227+
declarationInfo.textStorage.mapper = mapper || false;
2228+
return mapper;
2229+
}
2230+
2231+
/*@internal*/
2232+
getSourceFileLike(fileName: string, projectName: string | Project) {
2233+
const project = (projectName as Project).projectName ? projectName as Project : this.findProject(projectName as string);
2234+
if (project) {
2235+
const path = project.toPath(fileName);
2236+
const sourceFile = project.getSourceFile(path);
2237+
if (sourceFile && sourceFile.resolvedPath === path) return sourceFile;
2238+
}
2239+
2240+
// Need to look for other files.
2241+
const info = this.getOrCreateScriptInfoNotOpenedByClient(fileName, (project || this).currentDirectory, project ? project.directoryStructureHost : this.host);
2242+
if (!info) return undefined;
2243+
2244+
// Key doesnt matter since its only for text and lines
2245+
if (info.cacheSourceFile) return info.cacheSourceFile.sourceFile;
2246+
if (info.textStorage.sourceFileLike) return info.textStorage.sourceFileLike;
2247+
2248+
info.textStorage.sourceFileLike = {
2249+
get text() {
2250+
Debug.fail("shouldnt need text");
2251+
return "";
2252+
},
2253+
getLineAndCharacterOfPosition: pos => {
2254+
const lineOffset = info.positionToLineOffset(pos);
2255+
return { line: lineOffset.line - 1, character: lineOffset.offset - 1 };
2256+
},
2257+
getPositionOfLineAndCharacter: (line, character) => info.lineOffsetToPosition(line + 1, character + 1)
2258+
};
2259+
return info.textStorage.sourceFileLike;
2260+
}
2261+
21982262
setHostConfiguration(args: protocol.ConfigureRequestArguments) {
21992263
if (args.file) {
22002264
const info = this.getScriptInfoForNormalizedPath(toNormalizedPath(args.file));

src/server/project.ts

Lines changed: 2 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -505,62 +505,12 @@ namespace ts.server {
505505

506506
/*@internal*/
507507
getDocumentPositionMapper(fileName: string): DocumentPositionMapper | undefined {
508-
const declarationInfo = this.projectService.getOrCreateScriptInfoNotOpenedByClient(fileName, this.currentDirectory, this.directoryStructureHost);
509-
if (!declarationInfo) return undefined;
510-
511-
declarationInfo.getSnapshot(); // Ensure synchronized
512-
const existingMapper = declarationInfo.textStorage.mapper;
513-
if (existingMapper !== undefined) {
514-
return existingMapper ? existingMapper : undefined;
515-
}
516-
517-
// Create the mapper
518-
declarationInfo.mapInfo = undefined;
519-
520-
const mapper = getDocumentPositionMapper({
521-
getCanonicalFileName: this.projectService.toCanonicalFileName,
522-
log: s => this.log(s),
523-
readMapFile: f => this.readMapFile(f, declarationInfo),
524-
getSourceFileLike: f => this.getSourceFileLike(f)
525-
}, declarationInfo.fileName, declarationInfo.textStorage.getLineInfo());
526-
declarationInfo.textStorage.mapper = mapper || false;
527-
return mapper;
528-
}
529-
530-
private readMapFile(fileName: string, declarationInfo: ScriptInfo) {
531-
const mapInfo = this.projectService.getOrCreateScriptInfoNotOpenedByClient(fileName, this.currentDirectory, this.directoryStructureHost);
532-
if (!mapInfo) return undefined;
533-
declarationInfo.mapInfo = mapInfo;
534-
const snap = mapInfo.getSnapshot();
535-
return snap.getText(0, snap.getLength());
508+
return this.projectService.getDocumentPositionMapper(fileName, this);
536509
}
537510

538511
/*@internal*/
539512
getSourceFileLike(fileName: string) {
540-
const path = this.toPath(fileName);
541-
const sourceFile = this.getSourceFile(path);
542-
if (sourceFile && sourceFile.resolvedPath === path) return sourceFile;
543-
544-
// Need to look for other files.
545-
const info = this.projectService.getOrCreateScriptInfoNotOpenedByClient(fileName, this.currentDirectory, this.directoryStructureHost);
546-
if (!info) return undefined;
547-
548-
// Key doesnt matter since its only for text and lines
549-
if (info.cacheSourceFile) return info.cacheSourceFile.sourceFile;
550-
if (info.textStorage.sourceFileLike) return info.textStorage.sourceFileLike;
551-
552-
info.textStorage.sourceFileLike = {
553-
get text() {
554-
Debug.fail("shouldnt need text");
555-
return "";
556-
},
557-
getLineAndCharacterOfPosition: pos => {
558-
const lineOffset = info.positionToLineOffset(pos);
559-
return { line: lineOffset.line - 1, character: lineOffset.offset - 1 };
560-
},
561-
getPositionOfLineAndCharacter: (line, character) => info.lineOffsetToPosition(line + 1, character + 1)
562-
};
563-
return info.textStorage.sourceFileLike;
513+
return this.projectService.getSourceFileLike(fileName, this);
564514
}
565515

566516
private shouldEmitFile(scriptInfo: ScriptInfo) {

src/services/sourcemaps.ts

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,12 @@ namespace ts {
4242
}
4343
else if (host.readFile) {
4444
const file = getSourceFileLike(fileName);
45-
mapper = file && ts.getDocumentPositionMapper({
46-
getSourceFileLike,
47-
getCanonicalFileName,
48-
log: s => host.log(s),
49-
readMapFile: f => !host.fileExists || host.fileExists(f) ? host.readFile!(f) : undefined
50-
}, fileName, getLineInfo(file.text, getLineStarts(file)));
45+
mapper = file && ts.getDocumentPositionMapper(
46+
{ getSourceFileLike, getCanonicalFileName, log: s => host.log(s) },
47+
fileName,
48+
getLineInfo(file.text, getLineStarts(file)),
49+
f => !host.fileExists || host.fileExists(f) ? host.readFile!(f) : undefined
50+
);
5151
}
5252
documentPositionMappers.set(path, mapper || identitySourceMapConsumer);
5353
return mapper || identitySourceMapConsumer;
@@ -118,7 +118,6 @@ namespace ts {
118118
}
119119

120120
function toLineColumnOffset(fileName: string, position: number): LineAndCharacter {
121-
// TODO:: shkamat
122121
const file = getSourceFileLike(fileName)!; // TODO: GH#18217
123122
return file.getLineAndCharacterOfPosition(position);
124123
}
@@ -129,11 +128,11 @@ namespace ts {
129128
}
130129
}
131130

132-
export interface GetDocumentPositionMapperHost extends DocumentPositionMapperHost {
133-
readMapFile(fileName: string): string | undefined;
134-
}
135-
136-
export function getDocumentPositionMapper(host: GetDocumentPositionMapperHost, generatedFileName: string, generatedFileLineInfo: LineInfo) {
131+
export function getDocumentPositionMapper(
132+
host: DocumentPositionMapperHost,
133+
generatedFileName: string,
134+
generatedFileLineInfo: LineInfo,
135+
readMapFile: (fileName: string) => string | undefined) {
137136
let mapFileName = tryGetSourceMappingURL(generatedFileLineInfo);
138137
if (mapFileName) {
139138
const match = base64UrlRegExp.exec(mapFileName);
@@ -153,7 +152,7 @@ namespace ts {
153152
possibleMapLocations.push(generatedFileName + ".map");
154153
for (const location of possibleMapLocations) {
155154
const mapFileName = getNormalizedAbsolutePath(location, getDirectoryPath(generatedFileName));
156-
const mapFileContents = host.readMapFile(mapFileName);
155+
const mapFileContents = readMapFile(mapFileName);
157156
if (mapFileContents) {
158157
return convertDocumentToSourceMapper(host, mapFileContents, mapFileName);
159158
}

tests/baselines/reference/api/tsserverlibrary.d.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8210,7 +8210,6 @@ declare namespace ts.server {
82108210
getGlobalProjectErrors(): ReadonlyArray<Diagnostic>;
82118211
getAllProjectErrors(): ReadonlyArray<Diagnostic>;
82128212
getLanguageService(ensureSynchronized?: boolean): LanguageService;
8213-
private readMapFile;
82148213
private shouldEmitFile;
82158214
getCompileOnSaveAffectedFileList(scriptInfo: ScriptInfo): string[];
82168215
/**

0 commit comments

Comments
 (0)