diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 90b516dadfc..dd05b562cff 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -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)); diff --git a/src/server/project.ts b/src/server/project.ts index 566a2b9abe9..6ea9589cb4b 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -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) { diff --git a/src/services/sourcemaps.ts b/src/services/sourcemaps.ts index c679688e6c0..00d2696abf5 100644 --- a/src/services/sourcemaps.ts +++ b/src/services/sourcemaps.ts @@ -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); } diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index b788d46ac9f..1a104716c28 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -8210,7 +8210,6 @@ declare namespace ts.server { getGlobalProjectErrors(): ReadonlyArray; getAllProjectErrors(): ReadonlyArray; getLanguageService(ensureSynchronized?: boolean): LanguageService; - private readMapFile; private shouldEmitFile; getCompileOnSaveAffectedFileList(scriptInfo: ScriptInfo): string[]; /**