Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
ef6a246e
R
roslyn
项目概览
lwm1986
/
roslyn
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
roslyn
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
ef6a246e
编写于
1月 19, 2017
作者:
H
Heejae Chang
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
add proper additional document update change handler in incremental solution updater
added unit test
上级
b2715a06
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
126 addition
and
33 deletion
+126
-33
src/VisualStudio/Core/Test.Next/Services/SolutionServiceTests.cs
...ualStudio/Core/Test.Next/Services/SolutionServiceTests.cs
+91
-23
src/Workspaces/Remote/Core/Services/SolutionCreator.cs
src/Workspaces/Remote/Core/Services/SolutionCreator.cs
+35
-10
未找到文件。
src/VisualStudio/Core/Test.Next/Services/SolutionServiceTests.cs
浏览文件 @
ef6a246e
...
...
@@ -191,42 +191,110 @@ public async Task TestAddUpdateRemoveProjects()
});
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
RemoteHost
)]
public
async
Task
TestAdditionalDocument
()
{
var
code
=
@"class Test { void Method() { } }"
;
using
(
var
workspace
=
await
TestWorkspace
.
CreateCSharpAsync
(
code
))
{
var
projectId
=
workspace
.
CurrentSolution
.
ProjectIds
.
First
();
var
additionalDocumentId
=
DocumentId
.
CreateNewId
(
projectId
);
var
additionalDocumentInfo
=
DocumentInfo
.
Create
(
additionalDocumentId
,
"additionalFile"
,
loader
:
TextLoader
.
From
(
TextAndVersion
.
Create
(
SourceText
.
From
(
"test"
),
VersionStamp
.
Create
())));
await
VerifySolutionUpdate
(
workspace
,
s
=>
{
return
s
.
AddAdditionalDocument
(
additionalDocumentInfo
);
});
workspace
.
OnAdditionalDocumentAdded
(
additionalDocumentInfo
);
await
VerifySolutionUpdate
(
workspace
,
s
=>
{
return
s
.
WithAdditionalDocumentText
(
additionalDocumentId
,
SourceText
.
From
(
"changed"
));
});
await
VerifySolutionUpdate
(
workspace
,
s
=>
{
return
s
.
RemoveAdditionalDocument
(
additionalDocumentId
);
});
}
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
RemoteHost
)]
public
async
Task
TestDocument
()
{
var
code
=
@"class Test { void Method() { } }"
;
using
(
var
workspace
=
await
TestWorkspace
.
CreateCSharpAsync
(
code
))
{
var
projectId
=
workspace
.
CurrentSolution
.
ProjectIds
.
First
();
var
documentId
=
DocumentId
.
CreateNewId
(
projectId
);
var
documentInfo
=
DocumentInfo
.
Create
(
documentId
,
"sourceFile"
,
loader
:
TextLoader
.
From
(
TextAndVersion
.
Create
(
SourceText
.
From
(
"class A { }"
),
VersionStamp
.
Create
())));
await
VerifySolutionUpdate
(
workspace
,
s
=>
{
return
s
.
AddDocument
(
documentInfo
);
});
workspace
.
OnDocumentAdded
(
documentInfo
);
await
VerifySolutionUpdate
(
workspace
,
s
=>
{
return
s
.
WithDocumentText
(
documentId
,
SourceText
.
From
(
"class Changed { }"
));
});
await
VerifySolutionUpdate
(
workspace
,
s
=>
{
return
s
.
RemoveDocument
(
documentId
);
});
}
}
private
static
async
Task
VerifySolutionUpdate
(
string
code
,
Func
<
Solution
,
Solution
>
newSolutionGetter
)
{
using
(
var
workspace
=
await
TestWorkspace
.
CreateCSharpAsync
(
code
))
{
var
map
=
new
Dictionary
<
Checksum
,
object
>();
await
VerifySolutionUpdate
(
workspace
,
newSolutionGetter
);
}
}
var
solution
=
workspace
.
CurrentSolution
;
var
service
=
await
GetSolutionServiceAsync
(
solution
,
map
);
private
static
async
Task
VerifySolutionUpdate
(
TestWorkspace
workspace
,
Func
<
Solution
,
Solution
>
newSolutionGetter
)
{
var
map
=
new
Dictionary
<
Checksum
,
object
>();
var
solutionChecksum
=
await
solution
.
State
.
GetChecksumAsync
(
CancellationToken
.
None
);
var
solution
=
workspace
.
CurrentSolution
;
var
service
=
await
GetSolutionServiceAsync
(
solution
,
map
);
// update primary workspace
await
service
.
UpdatePrimaryWorkspaceAsync
(
solutionChecksum
,
CancellationToken
.
None
);
var
first
=
await
service
.
GetSolutionAsync
(
solutionChecksum
,
CancellationToken
.
None
);
var
solutionChecksum
=
await
solution
.
State
.
GetChecksumAsync
(
CancellationToken
.
None
);
Assert
.
Equal
(
solutionChecksum
,
await
first
.
State
.
GetChecksumAsync
(
CancellationToken
.
None
));
Assert
.
True
(
object
.
ReferenceEquals
(
PrimaryWorkspace
.
Workspace
.
PrimaryBranchId
,
first
.
BranchId
));
// update primary workspace
await
service
.
UpdatePrimaryWorkspaceAsync
(
solutionChecksum
,
CancellationToken
.
None
);
var
first
=
await
service
.
GetSolutionAsync
(
solutionChecksum
,
CancellationToken
.
None
);
// get new solution
var
newSolution
=
newSolutionGetter
(
solution
);
var
newSolutionChecksum
=
await
newSolution
.
State
.
GetChecksumAsync
(
CancellationToken
.
None
);
newSolution
.
AppendAssetMap
(
map
);
Assert
.
Equal
(
solutionChecksum
,
await
first
.
State
.
GetChecksumAsync
(
CancellationToken
.
None
));
Assert
.
True
(
object
.
ReferenceEquals
(
PrimaryWorkspace
.
Workspace
.
PrimaryBranchId
,
first
.
BranchId
));
// get solution without updating primary workspace
var
second
=
await
service
.
GetSolutionAsync
(
newSolutionChecksum
,
CancellationToken
.
None
);
// get new solution
var
newSolution
=
newSolutionGetter
(
solution
);
var
newSolutionChecksum
=
await
newSolution
.
State
.
GetChecksumAsync
(
CancellationToken
.
None
);
newSolution
.
AppendAssetMap
(
map
);
Assert
.
Equal
(
newSolutionChecksum
,
await
second
.
State
.
GetChecksumAsync
(
CancellationToken
.
None
));
Assert
.
False
(
object
.
ReferenceEquals
(
PrimaryWorkspace
.
Workspace
.
PrimaryBranchId
,
second
.
BranchId
)
);
// get solution without updating primary workspace
var
second
=
await
service
.
GetSolutionAsync
(
newSolutionChecksum
,
CancellationToken
.
None
);
// do same once updating primary workspace
await
service
.
UpdatePrimaryWorkspaceAsync
(
newSolutionChecksum
,
CancellationToken
.
None
);
var
third
=
await
service
.
GetSolutionAsync
(
newSolutionChecksum
,
CancellationToken
.
None
);
Assert
.
Equal
(
newSolutionChecksum
,
await
second
.
State
.
GetChecksumAsync
(
CancellationToken
.
None
));
Assert
.
False
(
object
.
ReferenceEquals
(
PrimaryWorkspace
.
Workspace
.
PrimaryBranchId
,
second
.
BranchId
));
Assert
.
Equal
(
newSolutionChecksum
,
await
third
.
State
.
GetChecksumAsync
(
CancellationToken
.
None
));
Assert
.
True
(
object
.
ReferenceEquals
(
PrimaryWorkspace
.
Workspace
.
PrimaryBranchId
,
third
.
BranchId
));
}
// do same once updating primary workspace
await
service
.
UpdatePrimaryWorkspaceAsync
(
newSolutionChecksum
,
CancellationToken
.
None
);
var
third
=
await
service
.
GetSolutionAsync
(
newSolutionChecksum
,
CancellationToken
.
None
);
Assert
.
Equal
(
newSolutionChecksum
,
await
third
.
State
.
GetChecksumAsync
(
CancellationToken
.
None
));
Assert
.
True
(
object
.
ReferenceEquals
(
PrimaryWorkspace
.
Workspace
.
PrimaryBranchId
,
third
.
BranchId
));
}
private
static
async
Task
<
SolutionService
>
GetSolutionServiceAsync
(
Solution
solution
,
Dictionary
<
Checksum
,
object
>
map
=
null
)
...
...
src/Workspaces/Remote/Core/Services/SolutionCreator.cs
浏览文件 @
ef6a246e
...
...
@@ -265,8 +265,8 @@ private async Task<Project> UpdateDocumentsAsync(Project project, HashSet<Checks
{
if
(!
oldMap
.
ContainsKey
(
kv
.
Key
))
{
// we have new
projec
t added
project
=
AddDocument
(
project
,
await
CreateDocumentInfoAsync
(
kv
.
Value
.
Checksum
).
ConfigureAwait
(
false
));
// we have new
documen
t added
project
=
AddDocument
(
project
,
await
CreateDocumentInfoAsync
(
kv
.
Value
.
Checksum
).
ConfigureAwait
(
false
)
,
additionalText
);
}
}
...
...
@@ -282,7 +282,8 @@ private async Task<Project> UpdateDocumentsAsync(Project project, HashSet<Checks
var
newDocumentChecksums
=
kv
.
Value
;
Contract
.
ThrowIfTrue
(
oldDocumentChecksums
.
Checksum
==
newDocumentChecksums
.
Checksum
);
project
=
await
UpdateDocumentAsync
(
project
.
GetDocument
(
kv
.
Key
),
oldDocumentChecksums
,
newDocumentChecksums
).
ConfigureAwait
(
false
);
var
document
=
additionalText
?
project
.
GetAdditionalDocument
(
kv
.
Key
)
:
project
.
GetDocument
(
kv
.
Key
);
project
=
await
UpdateDocumentAsync
(
document
,
oldDocumentChecksums
,
newDocumentChecksums
,
additionalText
).
ConfigureAwait
(
false
);
}
// removed project
...
...
@@ -290,33 +291,48 @@ private async Task<Project> UpdateDocumentsAsync(Project project, HashSet<Checks
{
if
(!
newMap
.
ContainsKey
(
kv
.
Key
))
{
// we have a project removed
project
=
project
.
RemoveDocument
(
kv
.
Key
);
// we have a document removed
if
(
additionalText
)
{
project
=
project
.
RemoveAdditionalDocument
(
kv
.
Key
);
}
else
{
project
=
project
.
RemoveDocument
(
kv
.
Key
);
}
}
}
return
project
;
}
private
async
Task
<
Project
>
UpdateDocumentAsync
(
Document
document
,
DocumentStateChecksums
oldDocumentChecksums
,
DocumentStateChecksums
newDocumentChecksums
)
private
async
Task
<
Project
>
UpdateDocumentAsync
(
TextDocument
document
,
DocumentStateChecksums
oldDocumentChecksums
,
DocumentStateChecksums
newDocumentChecksums
,
bool
additionalText
)
{
// changed info
if
(
oldDocumentChecksums
.
Info
!=
newDocumentChecksums
.
Info
)
{
document
=
await
UpdateDocumentInfoAsync
(
document
,
newDocumentChecksums
.
Info
).
ConfigureAwait
(
false
);
document
=
await
UpdateDocumentInfoAsync
(
document
,
newDocumentChecksums
.
Info
,
additionalText
).
ConfigureAwait
(
false
);
}
// changed text
if
(
oldDocumentChecksums
.
Text
!=
newDocumentChecksums
.
Text
)
{
var
sourceText
=
await
_assetService
.
GetAssetAsync
<
SourceText
>(
newDocumentChecksums
.
Text
,
_cancellationToken
).
ConfigureAwait
(
false
);
document
=
document
.
Project
.
Solution
.
WithDocumentText
(
document
.
Id
,
sourceText
).
GetDocument
(
document
.
Id
);
if
(
additionalText
)
{
document
=
document
.
Project
.
Solution
.
WithAdditionalDocumentText
(
document
.
Id
,
sourceText
).
GetAdditionalDocument
(
document
.
Id
);
}
else
{
document
=
document
.
Project
.
Solution
.
WithDocumentText
(
document
.
Id
,
sourceText
).
GetDocument
(
document
.
Id
);
}
}
return
document
.
Project
;
}
private
async
Task
<
Document
>
UpdateDocumentInfoAsync
(
Document
document
,
Checksum
infoChecksum
)
private
async
Task
<
TextDocument
>
UpdateDocumentInfoAsync
(
TextDocument
document
,
Checksum
infoChecksum
,
bool
additionalText
)
{
var
newDocumentInfo
=
await
_assetService
.
GetAssetAsync
<
DocumentInfo
.
DocumentAttributes
>(
infoChecksum
,
_cancellationToken
).
ConfigureAwait
(
false
);
...
...
@@ -328,11 +344,15 @@ private async Task<Document> UpdateDocumentInfoAsync(Document document, Checksum
if
(
document
.
State
.
Info
.
Attributes
.
Folders
!=
newDocumentInfo
.
Folders
)
{
// additional document can't change folder once created
Contract
.
ThrowIfTrue
(
additionalText
);
document
=
document
.
Project
.
Solution
.
WithDocumentFolders
(
document
.
Id
,
newDocumentInfo
.
Folders
).
GetDocument
(
document
.
Id
);
}
if
(
document
.
State
.
Info
.
Attributes
.
SourceCodeKind
!=
newDocumentInfo
.
SourceCodeKind
)
{
// additional document can't change sourcecode kind once created
Contract
.
ThrowIfTrue
(
additionalText
);
document
=
document
.
Project
.
Solution
.
WithDocumentSourceCodeKind
(
document
.
Id
,
newDocumentInfo
.
SourceCodeKind
).
GetDocument
(
document
.
Id
);
}
...
...
@@ -493,8 +513,13 @@ private async Task<DocumentInfo> CreateDocumentInfoAsync(Checksum documentChecks
documentInfo
.
IsGenerated
);
}
private
Project
AddDocument
(
Project
project
,
DocumentInfo
documentInfo
)
private
Project
AddDocument
(
Project
project
,
DocumentInfo
documentInfo
,
bool
additionalText
)
{
if
(
additionalText
)
{
return
project
.
Solution
.
AddAdditionalDocument
(
documentInfo
).
GetProject
(
project
.
Id
);
}
return
project
.
Solution
.
AddDocument
(
documentInfo
).
GetProject
(
project
.
Id
);
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录