Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 64 additions & 1 deletion src/harness/unittests/tsserverProjectSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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", () => {
Expand Down
6 changes: 6 additions & 0 deletions src/server/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
53 changes: 32 additions & 21 deletions src/server/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1770,20 +1770,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 {
Expand All @@ -1794,13 +1784,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)!;
Expand Down Expand Up @@ -2279,6 +2262,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;
Expand Down
2 changes: 0 additions & 2 deletions tests/baselines/reference/api/tsserverlibrary.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8556,9 +8556,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;
Expand Down