Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
44f1b686
V
vscode
项目概览
xxadev
/
vscode
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
vscode
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
44f1b686
编写于
7月 24, 2018
作者:
A
Alex Dima
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Fixes #54773: Check model version id right before applying the edits
上级
580a0aa7
变更
2
显示空白变更内容
内联
并排
Showing
2 changed file
with
69 addition
and
1 deletion
+69
-1
src/vs/workbench/services/bulkEdit/electron-browser/bulkEditService.ts
...nch/services/bulkEdit/electron-browser/bulkEditService.ts
+26
-0
src/vs/workbench/test/electron-browser/api/mainThreadEditors.test.ts
...bench/test/electron-browser/api/mainThreadEditors.test.ts
+43
-1
未找到文件。
src/vs/workbench/services/bulkEdit/electron-browser/bulkEditService.ts
浏览文件 @
44f1b686
...
...
@@ -47,11 +47,14 @@ abstract class Recording {
abstract
hasChanged
(
resource
:
URI
):
boolean
;
}
type
ValidationResult
=
{
canApply
:
true
}
|
{
canApply
:
false
,
reason
:
URI
};
class
ModelEditTask
implements
IDisposable
{
private
readonly
_model
:
ITextModel
;
protected
_edits
:
IIdentifiedSingleEditOperation
[];
private
_expectedModelVersionId
:
number
|
undefined
;
protected
_newEol
:
EndOfLineSequence
;
constructor
(
private
readonly
_modelReference
:
IReference
<
ITextEditorModel
>
)
{
...
...
@@ -64,6 +67,7 @@ class ModelEditTask implements IDisposable {
}
addEdit
(
resourceEdit
:
ResourceTextEdit
):
void
{
this
.
_expectedModelVersionId
=
resourceEdit
.
modelVersionId
;
for
(
const
edit
of
resourceEdit
.
edits
)
{
if
(
typeof
edit
.
eol
===
'
number
'
)
{
// honor eol-change
...
...
@@ -82,6 +86,13 @@ class ModelEditTask implements IDisposable {
}
}
validate
():
ValidationResult
{
if
(
typeof
this
.
_expectedModelVersionId
===
'
undefined
'
||
this
.
_model
.
getVersionId
()
===
this
.
_expectedModelVersionId
)
{
return
{
canApply
:
true
};
}
return
{
canApply
:
false
,
reason
:
this
.
_model
.
uri
};
}
apply
():
void
{
if
(
this
.
_edits
.
length
>
0
)
{
this
.
_edits
=
mergeSort
(
this
.
_edits
,
(
a
,
b
)
=>
Range
.
compareRangesUsingStarts
(
a
.
range
,
b
.
range
));
...
...
@@ -191,6 +202,16 @@ class BulkEditModel implements IDisposable {
return
this
;
}
validate
():
ValidationResult
{
for
(
const
task
of
this
.
_tasks
)
{
const
result
=
task
.
validate
();
if
(
!
result
.
canApply
)
{
return
result
;
}
}
return
{
canApply
:
true
};
}
apply
():
void
{
for
(
const
task
of
this
.
_tasks
)
{
task
.
apply
();
...
...
@@ -330,6 +351,11 @@ export class BulkEdit {
throw
new
Error
(
localize
(
'
conflict
'
,
"
These files have changed in the meantime: {0}
"
,
conflicts
.
join
(
'
,
'
)));
}
const
validationResult
=
model
.
validate
();
if
(
validationResult
.
canApply
===
false
)
{
throw
new
Error
(
`
${
validationResult
.
reason
.
toString
()}
has changed in the meantime`
);
}
await
model
.
apply
();
model
.
dispose
();
}
...
...
src/vs/workbench/test/electron-browser/api/mainThreadEditors.test.ts
浏览文件 @
44f1b686
...
...
@@ -26,6 +26,8 @@ import { TPromise } from 'vs/base/common/winjs.base';
import
{
ResourceTextEdit
}
from
'
vs/editor/common/modes
'
;
import
{
BulkEditService
}
from
'
vs/workbench/services/bulkEdit/electron-browser/bulkEditService
'
;
import
{
NullLogService
}
from
'
vs/platform/log/common/log
'
;
import
{
ITextModelService
,
ITextEditorModel
}
from
'
vs/editor/common/services/resolverService
'
;
import
{
IReference
,
ImmortalReference
}
from
'
vs/base/common/lifecycle
'
;
suite
(
'
MainThreadEditors
'
,
()
=>
{
...
...
@@ -71,8 +73,16 @@ suite('MainThreadEditors', () => {
};
const
workbenchEditorService
=
new
TestEditorService
();
const
editorGroupService
=
new
TestEditorGroupsService
();
const
textModelService
=
new
class
extends
mock
<
ITextModelService
>
()
{
createModelReference
(
resource
:
URI
):
TPromise
<
IReference
<
ITextEditorModel
>>
{
const
textEditorModel
:
ITextEditorModel
=
new
class
extends
mock
<
ITextEditorModel
>
()
{
textEditorModel
=
modelService
.
getModel
(
resource
);
};
return
TPromise
.
as
(
new
ImmortalReference
(
textEditorModel
));
}
};
const
bulkEditService
=
new
BulkEditService
(
new
NullLogService
(),
modelService
,
new
TestEditorService
(),
null
,
new
TestFileService
(),
textFileService
,
TestEnvironmentService
,
new
TestContextService
());
const
bulkEditService
=
new
BulkEditService
(
new
NullLogService
(),
modelService
,
new
TestEditorService
(),
textModelService
,
new
TestFileService
(),
textFileService
,
TestEnvironmentService
,
new
TestContextService
());
const
rpcProtocol
=
new
TestRPCProtocol
();
rpcProtocol
.
set
(
ExtHostContext
.
ExtHostDocuments
,
new
class
extends
mock
<
ExtHostDocumentsShape
>
()
{
...
...
@@ -129,6 +139,38 @@ suite('MainThreadEditors', () => {
});
});
test
(
`issue #54773: applyWorkspaceEdit checks model version in race situation`
,
()
=>
{
let
model
=
modelService
.
createModel
(
'
something
'
,
null
,
resource
);
let
workspaceResourceEdit1
:
ResourceTextEdit
=
{
resource
:
resource
,
modelVersionId
:
model
.
getVersionId
(),
edits
:
[{
text
:
'
asdfg
'
,
range
:
new
Range
(
1
,
1
,
1
,
1
)
}]
};
let
workspaceResourceEdit2
:
ResourceTextEdit
=
{
resource
:
resource
,
modelVersionId
:
model
.
getVersionId
(),
edits
:
[{
text
:
'
asdfg
'
,
range
:
new
Range
(
1
,
1
,
1
,
1
)
}]
};
let
p1
=
editors
.
$tryApplyWorkspaceEdit
({
edits
:
[
workspaceResourceEdit1
]
}).
then
((
result
)
=>
{
// first edit request succeeds
assert
.
equal
(
result
,
true
);
});
let
p2
=
editors
.
$tryApplyWorkspaceEdit
({
edits
:
[
workspaceResourceEdit2
]
}).
then
((
result
)
=>
{
// second edit request fails
assert
.
equal
(
result
,
false
);
});
return
TPromise
.
join
([
p1
,
p2
]);
});
test
(
`applyWorkspaceEdit with only resource edit`
,
()
=>
{
return
editors
.
$tryApplyWorkspaceEdit
({
edits
:
[
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录