mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-06 02:33:53 -06:00
Dont depend on project in document position mapper so that we can unload or remove projects independently
This commit is contained in:
parent
12428d45c0
commit
afdf1e90ec
@ -2195,6 +2195,70 @@ namespace ts.server {
|
||||
return this.filenameToScriptInfo.get(fileName);
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
getDocumentPositionMapper(fileName: string, project: Project): DocumentPositionMapper | undefined {
|
||||
const declarationInfo = this.getOrCreateScriptInfoNotOpenedByClient(fileName, project.currentDirectory, project.directoryStructureHost);
|
||||
if (!declarationInfo) return undefined;
|
||||
|
||||
declarationInfo.getSnapshot(); // Ensure synchronized
|
||||
const existingMapper = declarationInfo.textStorage.mapper;
|
||||
if (existingMapper !== undefined) {
|
||||
return existingMapper ? existingMapper : undefined;
|
||||
}
|
||||
|
||||
// Create the mapper
|
||||
declarationInfo.mapInfo = undefined;
|
||||
|
||||
let readMapFile: ((fileName: string) => string | undefined) | undefined = fileName => {
|
||||
const mapInfo = this.getOrCreateScriptInfoNotOpenedByClient(fileName, project.currentDirectory, project.directoryStructureHost);
|
||||
if (!mapInfo) return undefined;
|
||||
declarationInfo.mapInfo = mapInfo;
|
||||
const snap = mapInfo.getSnapshot();
|
||||
return snap.getText(0, snap.getLength());
|
||||
};
|
||||
const projectName = project.projectName;
|
||||
const mapper = getDocumentPositionMapper(
|
||||
{ getCanonicalFileName: this.toCanonicalFileName, log: s => this.logger.info(s), getSourceFileLike: f => this.getSourceFileLike(f, projectName) },
|
||||
declarationInfo.fileName,
|
||||
declarationInfo.textStorage.getLineInfo(),
|
||||
readMapFile
|
||||
);
|
||||
readMapFile = undefined; // Remove ref to project
|
||||
declarationInfo.textStorage.mapper = mapper || false;
|
||||
return mapper;
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
getSourceFileLike(fileName: string, projectName: string | Project) {
|
||||
const project = (projectName as Project).projectName ? projectName as Project : this.findProject(projectName as string);
|
||||
if (project) {
|
||||
const path = project.toPath(fileName);
|
||||
const sourceFile = project.getSourceFile(path);
|
||||
if (sourceFile && sourceFile.resolvedPath === path) return sourceFile;
|
||||
}
|
||||
|
||||
// Need to look for other files.
|
||||
const info = this.getOrCreateScriptInfoNotOpenedByClient(fileName, (project || this).currentDirectory, project ? project.directoryStructureHost : this.host);
|
||||
if (!info) return undefined;
|
||||
|
||||
// Key doesnt matter since its only for text and lines
|
||||
if (info.cacheSourceFile) return info.cacheSourceFile.sourceFile;
|
||||
if (info.textStorage.sourceFileLike) return info.textStorage.sourceFileLike;
|
||||
|
||||
info.textStorage.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) => info.lineOffsetToPosition(line + 1, character + 1)
|
||||
};
|
||||
return info.textStorage.sourceFileLike;
|
||||
}
|
||||
|
||||
setHostConfiguration(args: protocol.ConfigureRequestArguments) {
|
||||
if (args.file) {
|
||||
const info = this.getScriptInfoForNormalizedPath(toNormalizedPath(args.file));
|
||||
|
||||
@ -505,62 +505,12 @@ namespace ts.server {
|
||||
|
||||
/*@internal*/
|
||||
getDocumentPositionMapper(fileName: string): DocumentPositionMapper | undefined {
|
||||
const declarationInfo = this.projectService.getOrCreateScriptInfoNotOpenedByClient(fileName, this.currentDirectory, this.directoryStructureHost);
|
||||
if (!declarationInfo) return undefined;
|
||||
|
||||
declarationInfo.getSnapshot(); // Ensure synchronized
|
||||
const existingMapper = declarationInfo.textStorage.mapper;
|
||||
if (existingMapper !== undefined) {
|
||||
return existingMapper ? existingMapper : undefined;
|
||||
}
|
||||
|
||||
// Create the mapper
|
||||
declarationInfo.mapInfo = undefined;
|
||||
|
||||
const mapper = getDocumentPositionMapper({
|
||||
getCanonicalFileName: this.projectService.toCanonicalFileName,
|
||||
log: s => this.log(s),
|
||||
readMapFile: f => this.readMapFile(f, declarationInfo),
|
||||
getSourceFileLike: f => this.getSourceFileLike(f)
|
||||
}, declarationInfo.fileName, declarationInfo.textStorage.getLineInfo());
|
||||
declarationInfo.textStorage.mapper = mapper || false;
|
||||
return mapper;
|
||||
}
|
||||
|
||||
private readMapFile(fileName: string, declarationInfo: ScriptInfo) {
|
||||
const mapInfo = this.projectService.getOrCreateScriptInfoNotOpenedByClient(fileName, this.currentDirectory, this.directoryStructureHost);
|
||||
if (!mapInfo) return undefined;
|
||||
declarationInfo.mapInfo = mapInfo;
|
||||
const snap = mapInfo.getSnapshot();
|
||||
return snap.getText(0, snap.getLength());
|
||||
return this.projectService.getDocumentPositionMapper(fileName, this);
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
getSourceFileLike(fileName: string) {
|
||||
const path = this.toPath(fileName);
|
||||
const sourceFile = this.getSourceFile(path);
|
||||
if (sourceFile && sourceFile.resolvedPath === path) return sourceFile;
|
||||
|
||||
// Need to look for other files.
|
||||
const info = this.projectService.getOrCreateScriptInfoNotOpenedByClient(fileName, this.currentDirectory, this.directoryStructureHost);
|
||||
if (!info) return undefined;
|
||||
|
||||
// Key doesnt matter since its only for text and lines
|
||||
if (info.cacheSourceFile) return info.cacheSourceFile.sourceFile;
|
||||
if (info.textStorage.sourceFileLike) return info.textStorage.sourceFileLike;
|
||||
|
||||
info.textStorage.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) => info.lineOffsetToPosition(line + 1, character + 1)
|
||||
};
|
||||
return info.textStorage.sourceFileLike;
|
||||
return this.projectService.getSourceFileLike(fileName, this);
|
||||
}
|
||||
|
||||
private shouldEmitFile(scriptInfo: ScriptInfo) {
|
||||
|
||||
@ -42,12 +42,12 @@ namespace ts {
|
||||
}
|
||||
else if (host.readFile) {
|
||||
const file = getSourceFileLike(fileName);
|
||||
mapper = file && ts.getDocumentPositionMapper({
|
||||
getSourceFileLike,
|
||||
getCanonicalFileName,
|
||||
log: s => host.log(s),
|
||||
readMapFile: f => !host.fileExists || host.fileExists(f) ? host.readFile!(f) : undefined
|
||||
}, fileName, getLineInfo(file.text, getLineStarts(file)));
|
||||
mapper = file && ts.getDocumentPositionMapper(
|
||||
{ getSourceFileLike, getCanonicalFileName, log: s => host.log(s) },
|
||||
fileName,
|
||||
getLineInfo(file.text, getLineStarts(file)),
|
||||
f => !host.fileExists || host.fileExists(f) ? host.readFile!(f) : undefined
|
||||
);
|
||||
}
|
||||
documentPositionMappers.set(path, mapper || identitySourceMapConsumer);
|
||||
return mapper || identitySourceMapConsumer;
|
||||
@ -118,7 +118,6 @@ namespace ts {
|
||||
}
|
||||
|
||||
function toLineColumnOffset(fileName: string, position: number): LineAndCharacter {
|
||||
// TODO:: shkamat
|
||||
const file = getSourceFileLike(fileName)!; // TODO: GH#18217
|
||||
return file.getLineAndCharacterOfPosition(position);
|
||||
}
|
||||
@ -129,11 +128,11 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
export interface GetDocumentPositionMapperHost extends DocumentPositionMapperHost {
|
||||
readMapFile(fileName: string): string | undefined;
|
||||
}
|
||||
|
||||
export function getDocumentPositionMapper(host: GetDocumentPositionMapperHost, generatedFileName: string, generatedFileLineInfo: LineInfo) {
|
||||
export function getDocumentPositionMapper(
|
||||
host: DocumentPositionMapperHost,
|
||||
generatedFileName: string,
|
||||
generatedFileLineInfo: LineInfo,
|
||||
readMapFile: (fileName: string) => string | undefined) {
|
||||
let mapFileName = tryGetSourceMappingURL(generatedFileLineInfo);
|
||||
if (mapFileName) {
|
||||
const match = base64UrlRegExp.exec(mapFileName);
|
||||
@ -153,7 +152,7 @@ namespace ts {
|
||||
possibleMapLocations.push(generatedFileName + ".map");
|
||||
for (const location of possibleMapLocations) {
|
||||
const mapFileName = getNormalizedAbsolutePath(location, getDirectoryPath(generatedFileName));
|
||||
const mapFileContents = host.readMapFile(mapFileName);
|
||||
const mapFileContents = readMapFile(mapFileName);
|
||||
if (mapFileContents) {
|
||||
return convertDocumentToSourceMapper(host, mapFileContents, mapFileName);
|
||||
}
|
||||
|
||||
@ -8210,7 +8210,6 @@ declare namespace ts.server {
|
||||
getGlobalProjectErrors(): ReadonlyArray<Diagnostic>;
|
||||
getAllProjectErrors(): ReadonlyArray<Diagnostic>;
|
||||
getLanguageService(ensureSynchronized?: boolean): LanguageService;
|
||||
private readMapFile;
|
||||
private shouldEmitFile;
|
||||
getCompileOnSaveAffectedFileList(scriptInfo: ScriptInfo): string[];
|
||||
/**
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user