Add request applyChangesToOpenFiles

This commit is contained in:
Sheetal Nandi
2019-02-25 14:58:59 -08:00
parent 6fd7011870
commit 2258bb2fb7
9 changed files with 182 additions and 27 deletions

View File

@@ -407,6 +407,21 @@ namespace ts.server {
}
}
/*@internal*/
export interface OpenFileArguments {
fileName: string;
content?: string;
scriptKind?: protocol.ScriptKindName | ScriptKind;
hasMixedContent?: boolean;
projectRootPath?: string;
}
/*@internal*/
export interface ChangeFileArguments {
fileName: string;
changes: Iterator<TextChange>;
}
export class ProjectService {
/*@internal*/
@@ -2770,18 +2785,22 @@ namespace ts.server {
}
/* @internal */
applyChangesInOpenFiles(openFiles: protocol.ExternalFile[] | undefined, changedFiles: protocol.ChangedOpenFile[] | undefined, closedFiles: string[] | undefined): void {
applyChangesInOpenFiles(openFiles: Iterator<OpenFileArguments> | undefined, changedFiles?: Iterator<ChangeFileArguments>, closedFiles?: string[]): void {
if (openFiles) {
for (const file of openFiles) {
while (true) {
const { value: file, done } = openFiles.next();
if (done) break;
const scriptInfo = this.getScriptInfo(file.fileName);
Debug.assert(!scriptInfo || !scriptInfo.isScriptOpen(), "Script should not exist and not be open already");
const normalizedPath = scriptInfo ? scriptInfo.fileName : toNormalizedPath(file.fileName);
this.openClientFileWithNormalizedPath(normalizedPath, file.content, tryConvertScriptKindName(file.scriptKind!), file.hasMixedContent); // TODO: GH#18217
this.openClientFileWithNormalizedPath(normalizedPath, file.content, tryConvertScriptKindName(file.scriptKind!), file.hasMixedContent, file.projectRootPath ? toNormalizedPath(file.projectRootPath) : undefined); // TODO: GH#18217
}
}
if (changedFiles) {
for (const file of changedFiles) {
while (true) {
const { value: file, done } = changedFiles.next();
if (done) break;
const scriptInfo = this.getScriptInfo(file.fileName)!;
Debug.assert(!!scriptInfo);
this.applyChangesToFile(scriptInfo, file.changes);
@@ -2796,10 +2815,10 @@ namespace ts.server {
}
/* @internal */
applyChangesToFile(scriptInfo: ScriptInfo, changes: TextChange[]) {
// apply changes in reverse order
for (let i = changes.length - 1; i >= 0; i--) {
const change = changes[i];
applyChangesToFile(scriptInfo: ScriptInfo, changes: Iterator<TextChange>) {
while (true) {
const { value: change, done } = changes.next();
if (done) break;
scriptInfo.editContent(change.span.start, change.span.start + change.span.length, change.newText);
}
}

View File

@@ -92,6 +92,7 @@ namespace ts.server.protocol {
SynchronizeProjectList = "synchronizeProjectList",
/* @internal */
ApplyChangedToOpenFiles = "applyChangedToOpenFiles",
ApplyChangesToOpenFiles = "applyChangesToOpenFiles",
/* @internal */
EncodedSemanticClassificationsFull = "encodedSemanticClassifications-full",
/* @internal */
@@ -1543,6 +1544,32 @@ namespace ts.server.protocol {
closedFiles?: string[];
}
/**
* Request to synchronize list of open files with the client
*/
export interface ApplyChangesToOpenFilesRequest extends Request {
command: CommandTypes.ApplyChangesToOpenFiles;
arguments: ApplyChangesToOpenFilesRequestArgs;
}
/**
* Arguments to ApplyChangesToOpenFilesRequest
*/
export interface ApplyChangesToOpenFilesRequestArgs {
/**
* List of newly open files
*/
openFiles?: OpenRequestArgs[];
/**
* List of open files files that were changes
*/
changedFiles?: FileCodeEdits[];
/**
* List of files that were closed
*/
closedFiles?: string[];
}
/**
* Request to set compiler options for inferred projects.
* External projects are opened / closed explicitly.

View File

@@ -1654,10 +1654,10 @@ namespace ts.server {
const end = scriptInfo.lineOffsetToPosition(args.endLine, args.endOffset);
if (start >= 0) {
this.changeSeq++;
this.projectService.applyChangesToFile(scriptInfo, [{
this.projectService.applyChangesToFile(scriptInfo, singleIterator({
span: { start, length: end - start },
newText: args.insertString! // TODO: GH#18217
}]);
}));
}
}
@@ -2096,9 +2096,39 @@ namespace ts.server {
});
return this.requiredResponse(converted);
},
[CommandNames.ApplyChangesToOpenFiles]: (request: protocol.ApplyChangesToOpenFilesRequest) => {
this.changeSeq++;
this.projectService.applyChangesInOpenFiles(
request.arguments.openFiles && mapIterator(arrayIterator(request.arguments.openFiles), file => ({
fileName: file.file,
content: file.fileContent,
scriptKind: file.scriptKindName,
projectRootPath: file.projectRootPath
})),
request.arguments.changedFiles && mapIterator(arrayIterator(request.arguments.changedFiles), file => ({
fileName: file.fileName,
changes: mapDefinedIterator(arrayIterator(file.textChanges), change => {
const scriptInfo = Debug.assertDefined(this.projectService.getScriptInfo(file.fileName));
const start = scriptInfo.lineOffsetToPosition(change.start.line, change.start.offset);
const end = scriptInfo.lineOffsetToPosition(change.end.line, change.end.offset);
return start >= 0 ? { span: { start, length: end - start }, newText: change.newText } : undefined;
})
})),
request.arguments.closedFiles
);
return this.requiredResponse(/*response*/ true);
},
[CommandNames.ApplyChangedToOpenFiles]: (request: protocol.ApplyChangedToOpenFilesRequest) => {
this.changeSeq++;
this.projectService.applyChangesInOpenFiles(request.arguments.openFiles, request.arguments.changedFiles!, request.arguments.closedFiles!); // TODO: GH#18217
this.projectService.applyChangesInOpenFiles(
request.arguments.openFiles && arrayIterator(request.arguments.openFiles),
request.arguments.changedFiles && mapIterator(arrayIterator(request.arguments.changedFiles), file => ({
fileName: file.fileName,
// apply changes in reverse order
changes: arrayReverseIterator(file.changes)
})),
request.arguments.closedFiles
);
// TODO: report errors
return this.requiredResponse(/*response*/ true);
},