mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-04 21:53:42 -06:00
Support 'tsconfig.json' when converting TextChanges to CodeEdits (#24667)
* Support 'tsconfig.json' when converting TextChanges to CodeEdits * Create Project#getSourceFileOrConfigFile to use instead
This commit is contained in:
parent
fde6f22408
commit
399ae51406
@ -466,7 +466,7 @@ namespace ts.projectSystem {
|
||||
return newRequest;
|
||||
}
|
||||
|
||||
export function openFilesForSession(files: File[], session: server.Session) {
|
||||
export function openFilesForSession(files: ReadonlyArray<File>, session: server.Session) {
|
||||
for (const file of files) {
|
||||
const request = makeSessionRequest<protocol.OpenRequestArgs>(CommandNames.Open, { file: file.path });
|
||||
session.executeCommand(request);
|
||||
@ -6192,6 +6192,69 @@ namespace ts.projectSystem {
|
||||
renameLocation: { line: 2, offset: 3 },
|
||||
});
|
||||
});
|
||||
|
||||
it("handles text changes in tsconfig.json", () => {
|
||||
const aTs = {
|
||||
path: "/a.ts",
|
||||
content: "export const a = 0;",
|
||||
};
|
||||
const tsconfig = {
|
||||
path: "/tsconfig.json",
|
||||
content: '{ "files": ["./a.ts"] }',
|
||||
};
|
||||
|
||||
const session = createSession(createServerHost([aTs, tsconfig]));
|
||||
openFilesForSession([aTs], session);
|
||||
|
||||
const response1 = session.executeCommandSeq<server.protocol.GetEditsForRefactorRequest>({
|
||||
command: server.protocol.CommandTypes.GetEditsForRefactor,
|
||||
arguments: {
|
||||
refactor: "Move to a new file",
|
||||
action: "Move to a new file",
|
||||
file: "/a.ts",
|
||||
startLine: 1,
|
||||
startOffset: 1,
|
||||
endLine: 1,
|
||||
endOffset: 20,
|
||||
},
|
||||
}).response;
|
||||
assert.deepEqual(response1, {
|
||||
edits: [
|
||||
{
|
||||
fileName: "/a.ts",
|
||||
textChanges: [
|
||||
{
|
||||
start: { line: 1, offset: 1 },
|
||||
end: { line: 1, offset: 20 },
|
||||
newText: "",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
fileName: "/tsconfig.json",
|
||||
textChanges: [
|
||||
{
|
||||
start: { line: 1, offset: 21 },
|
||||
end: { line: 1, offset: 21 },
|
||||
newText: ", \"./a.1.ts\"",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
fileName: "/a.1.ts",
|
||||
textChanges: [
|
||||
{
|
||||
start: { line: 0, offset: 0 },
|
||||
end: { line: 0, offset: 0 },
|
||||
newText: "export const a = 0;",
|
||||
},
|
||||
],
|
||||
}
|
||||
],
|
||||
renameFilename: undefined,
|
||||
renameLocation: undefined,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("tsserverProjectSystem CachingFileSystemInformation", () => {
|
||||
|
||||
@ -550,6 +550,12 @@ namespace ts.server {
|
||||
return this.program.getSourceFileByPath(path);
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
getSourceFileOrConfigFile(path: Path): SourceFile | undefined {
|
||||
const options = this.program.getCompilerOptions();
|
||||
return path === options.configFilePath ? options.configFile : this.getSourceFile(path);
|
||||
}
|
||||
|
||||
close() {
|
||||
if (this.program) {
|
||||
// if we have a program - release all files that are enlisted in program but arent root
|
||||
|
||||
@ -1771,20 +1771,10 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
private mapTextChangesToCodeEdits(project: Project, textChanges: ReadonlyArray<FileTextChanges>): protocol.FileCodeEdits[] {
|
||||
return textChanges.map(change => this.mapTextChangesToCodeEditsUsingScriptinfo(change, project.getScriptInfoForNormalizedPath(toNormalizedPath(change.fileName))!));
|
||||
}
|
||||
|
||||
private mapTextChangesToCodeEditsUsingScriptinfo(textChanges: FileTextChanges, scriptInfo: ScriptInfo | undefined): protocol.FileCodeEdits {
|
||||
Debug.assert(!!textChanges.isNewFile === !scriptInfo);
|
||||
if (scriptInfo) {
|
||||
return {
|
||||
fileName: textChanges.fileName,
|
||||
textChanges: textChanges.textChanges.map(textChange => this.convertTextChangeToCodeEdit(textChange, scriptInfo))
|
||||
};
|
||||
}
|
||||
else {
|
||||
return this.convertNewFileTextChangeToCodeEdit(textChanges);
|
||||
}
|
||||
return textChanges.map(change => {
|
||||
const path = normalizedPathToPath(toNormalizedPath(change.fileName), this.host.getCurrentDirectory(), fileName => this.getCanonicalFileName(fileName));
|
||||
return mapTextChangesToCodeEdits(change, project.getSourceFileOrConfigFile(path));
|
||||
});
|
||||
}
|
||||
|
||||
private convertTextChangeToCodeEdit(change: TextChange, scriptInfo: ScriptInfo): protocol.CodeEdit {
|
||||
@ -1795,13 +1785,6 @@ namespace ts.server {
|
||||
};
|
||||
}
|
||||
|
||||
private convertNewFileTextChangeToCodeEdit(textChanges: FileTextChanges): protocol.FileCodeEdits {
|
||||
Debug.assert(textChanges.textChanges.length === 1);
|
||||
const change = first(textChanges.textChanges);
|
||||
Debug.assert(change.span.start === 0 && change.span.length === 0);
|
||||
return { fileName: textChanges.fileName, textChanges: [{ start: { line: 0, offset: 0 }, end: { line: 0, offset: 0 }, newText: change.newText }] };
|
||||
}
|
||||
|
||||
private getBraceMatching(args: protocol.FileLocationRequestArgs, simplifiedResult: boolean): protocol.TextSpan[] | TextSpan[] | undefined {
|
||||
const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args);
|
||||
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file)!;
|
||||
@ -2280,6 +2263,34 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
function mapTextChangesToCodeEdits(textChanges: FileTextChanges, sourceFile: SourceFile | undefined): protocol.FileCodeEdits {
|
||||
Debug.assert(!!textChanges.isNewFile === !sourceFile);
|
||||
if (sourceFile) {
|
||||
return {
|
||||
fileName: textChanges.fileName,
|
||||
textChanges: textChanges.textChanges.map(textChange => convertTextChangeToCodeEdit(textChange, sourceFile)),
|
||||
};
|
||||
}
|
||||
else {
|
||||
return convertNewFileTextChangeToCodeEdit(textChanges);
|
||||
}
|
||||
}
|
||||
|
||||
function convertTextChangeToCodeEdit(change: TextChange, sourceFile: SourceFile): protocol.CodeEdit {
|
||||
return {
|
||||
start: convertToLocation(sourceFile.getLineAndCharacterOfPosition(change.span.start)),
|
||||
end: convertToLocation(sourceFile.getLineAndCharacterOfPosition(change.span.start + change.span.length)),
|
||||
newText: change.newText ? change.newText : "",
|
||||
};
|
||||
}
|
||||
|
||||
function convertNewFileTextChangeToCodeEdit(textChanges: FileTextChanges): protocol.FileCodeEdits {
|
||||
Debug.assert(textChanges.textChanges.length === 1);
|
||||
const change = first(textChanges.textChanges);
|
||||
Debug.assert(change.span.start === 0 && change.span.length === 0);
|
||||
return { fileName: textChanges.fileName, textChanges: [{ start: { line: 0, offset: 0 }, end: { line: 0, offset: 0 }, newText: change.newText }] };
|
||||
}
|
||||
|
||||
export interface HandlerResponse {
|
||||
response?: {};
|
||||
responseRequired?: boolean;
|
||||
|
||||
@ -8564,9 +8564,7 @@ declare namespace ts.server {
|
||||
private mapCodeAction;
|
||||
private mapCodeFixAction;
|
||||
private mapTextChangesToCodeEdits;
|
||||
private mapTextChangesToCodeEditsUsingScriptinfo;
|
||||
private convertTextChangeToCodeEdit;
|
||||
private convertNewFileTextChangeToCodeEdit;
|
||||
private getBraceMatching;
|
||||
private getDiagnosticsForProject;
|
||||
getCanonicalFileName(fileName: string): string;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user