diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 643a39e5e683b..44c05f5d0194a 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -276,14 +276,10 @@ namespace FourSlash { if (configFileName) { const baseDir = ts.normalizePath(ts.getDirectoryPath(configFileName)); const host = new Utils.MockParseConfigHost(baseDir, /*ignoreCase*/ false, this.inputFiles); - - const configJsonObj = ts.parseConfigFileTextToJson(configFileName, this.inputFiles.get(configFileName)); - assert.isTrue(configJsonObj.config !== undefined); - - compilationOptions = ts.parseJsonConfigFileContent(configJsonObj.config, host, baseDir, compilationOptions, configFileName).options; + const jsonSourceFile = ts.parseJsonText(configFileName, this.inputFiles.get(configFileName)); + compilationOptions = ts.parseJsonSourceFileConfigFileContent(jsonSourceFile, host, baseDir, compilationOptions, configFileName).options; } - if (compilationOptions.typeRoots) { compilationOptions.typeRoots = compilationOptions.typeRoots.map(p => ts.getNormalizedAbsolutePath(p, this.basePath)); } diff --git a/src/services/getEditsForFileRename.ts b/src/services/getEditsForFileRename.ts index 60fbd5b70f3cc..09bbdc11e7890 100644 --- a/src/services/getEditsForFileRename.ts +++ b/src/services/getEditsForFileRename.ts @@ -3,16 +3,33 @@ namespace ts { export function getEditsForFileRename(program: Program, oldFilePath: string, newFilePath: string, host: LanguageServiceHost, formatContext: formatting.FormatContext): ReadonlyArray { const pathUpdater = getPathUpdater(oldFilePath, newFilePath, host); return textChanges.ChangeTracker.with({ host, formatContext }, changeTracker => { + updateTsconfigFiles(program, changeTracker, oldFilePath, newFilePath); for (const { sourceFile, toUpdate } of getImportsToUpdate(program, oldFilePath)) { const newPath = pathUpdater(isRef(toUpdate) ? toUpdate.fileName : toUpdate.text); if (newPath !== undefined) { - const range = isRef(toUpdate) ? toUpdate : createTextRange(toUpdate.getStart(sourceFile) + 1, toUpdate.end - 1); + const range = isRef(toUpdate) ? toUpdate : createStringRange(toUpdate, sourceFile); changeTracker.replaceRangeWithText(sourceFile, range, isRef(toUpdate) ? newPath : removeFileExtension(newPath)); } } }); } + function updateTsconfigFiles(program: Program, changeTracker: textChanges.ChangeTracker, oldFilePath: string, newFilePath: string): void { + const cfg = program.getCompilerOptions().configFile; + if (!cfg) return; + const oldFile = cfg.jsonObject && getFilesEntry(cfg.jsonObject, oldFilePath); + if (oldFile) { + changeTracker.replaceRangeWithText(cfg, createStringRange(oldFile, cfg), newFilePath); + } + } + + function getFilesEntry(cfg: ObjectLiteralExpression, fileName: string): StringLiteral | undefined { + const filesProp = find(cfg.properties, (prop): prop is PropertyAssignment => + isPropertyAssignment(prop) && isStringLiteral(prop.name) && prop.name.text === "files"); + const files = filesProp && filesProp.initializer; + return files && isArrayLiteralExpression(files) ? find(files.elements, (e): e is StringLiteral => isStringLiteral(e) && e.text === fileName) : undefined; + } + interface ToUpdate { readonly sourceFile: SourceFile; readonly toUpdate: StringLiteralLike | FileReference; @@ -52,4 +69,8 @@ namespace ts { return ensurePathIsRelative(normalizePath(combinePaths(getDirectoryPath(oldPath), rel))); }; } + + function createStringRange(node: StringLiteralLike, sourceFile: SourceFileLike): TextRange { + return createTextRange(node.getStart(sourceFile) + 1, node.end - 1); + } } diff --git a/tests/cases/fourslash/getEditsForFileRename.ts b/tests/cases/fourslash/getEditsForFileRename.ts index b000ce28dd872..f2694818d1d9d 100644 --- a/tests/cases/fourslash/getEditsForFileRename.ts +++ b/tests/cases/fourslash/getEditsForFileRename.ts @@ -12,6 +12,9 @@ /////// ////import old from "../old"; +// @Filename: /tsconfig.json +////{ "files": ["/a.ts", "/src/a.ts", "/src/foo/a.ts", "/src/old.ts"] } + verify.getEditsForFileRename({ oldPath: "/src/old.ts", newPath: "/src/new.ts", @@ -19,5 +22,6 @@ verify.getEditsForFileRename({ "/a.ts": '/// \nimport old from "./src/new";', "/src/a.ts": '/// \nimport old from "./new";', "/src/foo/a.ts": '/// \nimport old from "../new";', + "/tsconfig.json": '{ "files": ["/a.ts", "/src/a.ts", "/src/foo/a.ts", "/src/new.ts"] }', }, });