fix dto to API conversion of workspace edits with snippet edits (#178812)

fixes https://github.com/microsoft/vscode/issues/178654
This commit is contained in:
Johannes Rieken 2023-03-31 16:22:21 +02:00 committed by GitHub
parent 13562cc6f5
commit f720dba429
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 45 additions and 7 deletions

View file

@ -9,7 +9,7 @@ import { IDataTransferItem, UriList, VSDataTransfer } from 'vs/base/common/dataT
import { once } from 'vs/base/common/functional';
import * as htmlContent from 'vs/base/common/htmlContent';
import { DisposableStore } from 'vs/base/common/lifecycle';
import { ResourceSet } from 'vs/base/common/map';
import { ResourceMap, ResourceSet } from 'vs/base/common/map';
import { marked } from 'vs/base/common/marked/marked';
import { parse } from 'vs/base/common/marshalling';
import { Mimes } from 'vs/base/common/mime';
@ -649,13 +649,30 @@ export namespace WorkspaceEdit {
export function to(value: extHostProtocol.IWorkspaceEditDto) {
const result = new types.WorkspaceEdit();
const edits = new ResourceMap<(types.TextEdit | types.SnippetTextEdit)[]>();
for (const edit of value.edits) {
if ((<extHostProtocol.IWorkspaceTextEditDto>edit).textEdit) {
result.replace(
URI.revive((<extHostProtocol.IWorkspaceTextEditDto>edit).resource),
Range.to((<extHostProtocol.IWorkspaceTextEditDto>edit).textEdit.range),
(<extHostProtocol.IWorkspaceTextEditDto>edit).textEdit.text
);
const item = <extHostProtocol.IWorkspaceTextEditDto>edit;
const uri = URI.revive(item.resource);
const range = Range.to(item.textEdit.range);
const text = item.textEdit.text;
const isSnippet = item.textEdit.insertAsSnippet;
let editOrSnippetTest: types.TextEdit | types.SnippetTextEdit;
if (isSnippet) {
editOrSnippetTest = types.SnippetTextEdit.replace(range, new types.SnippetString(text));
} else {
editOrSnippetTest = types.TextEdit.replace(range, text);
}
const array = edits.get(uri);
if (!array) {
edits.set(uri, [editOrSnippetTest]);
} else {
array.push(editOrSnippetTest);
}
} else {
result.renameFile(
URI.revive((<extHostProtocol.IWorkspaceFileEditDto>edit).oldResource!),
@ -664,6 +681,10 @@ export namespace WorkspaceEdit {
);
}
}
for (const [uri, array] of edits) {
result.set(uri, array);
}
return result;
}
}

View file

@ -6,10 +6,11 @@
import * as assert from 'assert';
import * as extHostTypes from 'vs/workbench/api/common/extHostTypes';
import { MarkdownString, NotebookCellOutputItem, NotebookData, LanguageSelector } from 'vs/workbench/api/common/extHostTypeConverters';
import { MarkdownString, NotebookCellOutputItem, NotebookData, LanguageSelector, WorkspaceEdit } from 'vs/workbench/api/common/extHostTypeConverters';
import { isEmptyObject } from 'vs/base/common/types';
import { LogLevel as _MainLogLevel } from 'vs/platform/log/common/log';
import { URI } from 'vs/base/common/uri';
import { IWorkspaceTextEditDto } from 'vs/workbench/api/common/extHost.protocol';
suite('ExtHostTypeConverter', function () {
function size<T>(from: Record<any, any>): number {
@ -122,4 +123,20 @@ suite('ExtHostTypeConverter', function () {
exclusive: undefined,
});
});
test('JS/TS Surround With Code Actions provide bad Workspace Edits when obtained by VSCode Command API #178654', function () {
const uri = URI.parse('file:///foo/bar');
const ws = new extHostTypes.WorkspaceEdit();
ws.set(uri, [extHostTypes.SnippetTextEdit.insert(new extHostTypes.Position(1, 1), new extHostTypes.SnippetString('foo$0bar'))]);
const dto = WorkspaceEdit.from(ws);
const first = <IWorkspaceTextEditDto>dto.edits[0];
assert.strictEqual(first.textEdit.insertAsSnippet, true);
const ws2 = WorkspaceEdit.to(dto);
const dto2 = WorkspaceEdit.from(ws2);
const first2 = <IWorkspaceTextEditDto>dto2.edits[0];
assert.strictEqual(first2.textEdit.insertAsSnippet, true);
});
});