Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
a41e5c9f
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,发现更多精彩内容 >>
提交
a41e5c9f
编写于
5月 17, 2016
作者:
H
Heejae Chang
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #11367 from heejaechang/ProjectError
make us to accept project level build errors as well.
上级
dcd141b9
0c99deaa
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
150 addition
and
72 deletion
+150
-72
src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.ProjectState.cs
...cs/EngineV2/DiagnosticIncrementalAnalyzer.ProjectState.cs
+4
-2
src/VisualStudio/Core/Def/Implementation/TaskList/ExternalErrorDiagnosticUpdateSource.cs
...mentation/TaskList/ExternalErrorDiagnosticUpdateSource.cs
+82
-52
src/VisualStudio/Core/Def/Implementation/TaskList/ProjectExternalErrorReporter.cs
...f/Implementation/TaskList/ProjectExternalErrorReporter.cs
+48
-17
src/VisualStudio/Core/Test/Diagnostics/ExternalDiagnosticUpdateSourceTests.vb
...e/Test/Diagnostics/ExternalDiagnosticUpdateSourceTests.vb
+16
-1
未找到文件。
src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.ProjectState.cs
浏览文件 @
a41e5c9f
...
...
@@ -99,7 +99,8 @@ public async Task<AnalysisResult> GetAnalysisDataAsync(Project project, bool avo
if
(!
await
TryDeserializeAsync
(
serializer
,
project
,
project
.
Id
,
_owner
.
NonLocalStateName
,
builder
.
AddOthers
,
cancellationToken
).
ConfigureAwait
(
false
))
{
Contract
.
Requires
(
false
,
"How this can happen?"
);
// this can happen if SaveAsync is not yet called but active file merge happened. one of case is if user did build before the very first
// analysis happened.
}
return
builder
.
ToResult
();
...
...
@@ -178,7 +179,8 @@ public async Task<AnalysisResult> GetProjectAnalysisDataAsync(Project project, b
if
(!
await
TryDeserializeAsync
(
serializer
,
project
,
project
.
Id
,
_owner
.
NonLocalStateName
,
builder
.
AddOthers
,
cancellationToken
).
ConfigureAwait
(
false
))
{
Contract
.
Requires
(
false
,
"How this can happen?"
);
// this can happen if SaveAsync is not yet called but active file merge happened. one of case is if user did build before the very first
// analysis happened.
}
return
builder
.
ToResult
();
...
...
src/VisualStudio/Core/Def/Implementation/TaskList/ExternalErrorDiagnosticUpdateSource.cs
浏览文件 @
a41e5c9f
...
...
@@ -76,6 +76,11 @@ public ImmutableArray<DiagnosticData> GetBuildErrors()
return
_lastBuiltResult
;
}
public
bool
SupportedDiagnosticId
(
ProjectId
projectId
,
string
id
)
{
return
_state
?.
SupportedDiagnosticId
(
projectId
,
id
)
??
false
;
}
public
void
ClearErrors
(
ProjectId
projectId
)
{
// capture state if it exists
...
...
@@ -88,7 +93,7 @@ public void ClearErrors(ProjectId projectId)
// otherwise (such as closing solution or removing project), no need to record it
state
?.
Built
(
projectId
);
ClearProjectErrors
(
projectId
);
ClearProjectErrors
(
state
?.
Solution
??
_workspace
.
CurrentSolution
,
projectId
);
}).
CompletesAsyncOperation
(
asyncToken
);
}
...
...
@@ -102,7 +107,7 @@ private void OnWorkspaceChanged(object sender, WorkspaceChangeEventArgs e)
case
WorkspaceChangeKind
.
SolutionReloaded
:
{
var
asyncToken
=
_listener
.
BeginAsyncOperation
(
"OnSolutionChanged"
);
_taskQueue
.
ScheduleTask
(()
=>
e
.
OldSolution
.
ProjectIds
.
Do
(
p
=>
ClearProjectErrors
(
p
,
e
.
OldSolution
))).
CompletesAsyncOperation
(
asyncToken
);
_taskQueue
.
ScheduleTask
(()
=>
e
.
OldSolution
.
ProjectIds
.
Do
(
p
=>
ClearProjectErrors
(
e
.
OldSolution
,
p
))).
CompletesAsyncOperation
(
asyncToken
);
break
;
}
...
...
@@ -110,7 +115,7 @@ private void OnWorkspaceChanged(object sender, WorkspaceChangeEventArgs e)
case
WorkspaceChangeKind
.
ProjectReloaded
:
{
var
asyncToken
=
_listener
.
BeginAsyncOperation
(
"OnProjectChanged"
);
_taskQueue
.
ScheduleTask
(()
=>
ClearProjectErrors
(
e
.
ProjectId
,
e
.
OldSolution
)).
CompletesAsyncOperation
(
asyncToken
);
_taskQueue
.
ScheduleTask
(()
=>
ClearProjectErrors
(
e
.
OldSolution
,
e
.
ProjectId
)).
CompletesAsyncOperation
(
asyncToken
);
break
;
}
...
...
@@ -118,7 +123,7 @@ private void OnWorkspaceChanged(object sender, WorkspaceChangeEventArgs e)
case
WorkspaceChangeKind
.
DocumentReloaded
:
{
var
asyncToken
=
_listener
.
BeginAsyncOperation
(
"OnDocumentRemoved"
);
_taskQueue
.
ScheduleTask
(()
=>
ClearDocumentErrors
(
e
.
ProjectId
,
e
.
DocumentId
)).
CompletesAsyncOperation
(
asyncToken
);
_taskQueue
.
ScheduleTask
(()
=>
ClearDocumentErrors
(
e
.
OldSolution
,
e
.
ProjectId
,
e
.
DocumentId
)).
CompletesAsyncOperation
(
asyncToken
);
break
;
}
...
...
@@ -169,16 +174,11 @@ internal void OnSolutionBuild(object sender, UIContextChangedEventArgs e)
// pause live analyzer
using
(
var
operation
=
_notificationService
.
Start
(
"BuildDone"
))
{
// we will have a race here since we can't track version of solution the out of proc build actually used.
// result of the race will be us dropping some diagnostics from the build to the floor.
var
solution
=
_workspace
.
CurrentSolution
;
var
supportedIdMap
=
GetSupportedLiveDiagnosticId
(
solution
,
inprogressState
);
Func
<
DiagnosticData
,
bool
>
liveDiagnosticChecker
=
d
=>
{
// REVIEW: we probably need a better design on de-duplicating live and build errors. or don't de-dup at all.
// for now, we are special casing compiler error case.
var
project
=
s
olution
.
GetProject
(
d
.
ProjectId
);
var
project
=
inprogressState
.
S
olution
.
GetProject
(
d
.
ProjectId
);
if
(
project
==
null
)
{
// project doesn't exist
...
...
@@ -194,8 +194,7 @@ internal void OnSolutionBuild(object sender, UIContextChangedEventArgs e)
return
false
;
}
HashSet
<
string
>
set
;
if
(
supportedIdMap
.
TryGetValue
(
d
.
ProjectId
,
out
set
)
&&
set
.
Contains
(
d
.
Id
))
if
(
inprogressState
.
SupportedDiagnosticId
(
d
.
ProjectId
,
d
.
Id
))
{
return
true
;
}
...
...
@@ -206,8 +205,8 @@ internal void OnSolutionBuild(object sender, UIContextChangedEventArgs e)
var
diagnosticService
=
_diagnosticService
as
DiagnosticAnalyzerService
;
if
(
diagnosticService
!=
null
)
{
await
CleanupAllLiveErrorsIfNeededAsync
(
diagnosticService
,
s
olution
,
inprogressState
).
ConfigureAwait
(
false
);
await
SyncBuildErrorsAndReportAsync
(
diagnosticService
,
inprogressState
.
GetLiveDiagnosticsPerProject
(
liveDiagnosticChecker
)).
ConfigureAwait
(
false
);
await
CleanupAllLiveErrorsIfNeededAsync
(
diagnosticService
,
inprogressState
.
S
olution
,
inprogressState
).
ConfigureAwait
(
false
);
await
SyncBuildErrorsAndReportAsync
(
diagnosticService
,
inprogressState
.
Solution
,
inprogressState
.
GetLiveDiagnosticsPerProject
(
liveDiagnosticChecker
)).
ConfigureAwait
(
false
);
}
inprogressState
.
Done
();
...
...
@@ -239,7 +238,8 @@ private System.Threading.Tasks.Task CleanupAllLiveErrors(DiagnosticAnalyzerServi
return
diagnosticService
.
SynchronizeWithBuildAsync
(
_workspace
,
map
);
}
private
async
System
.
Threading
.
Tasks
.
Task
SyncBuildErrorsAndReportAsync
(
DiagnosticAnalyzerService
diagnosticService
,
ImmutableDictionary
<
ProjectId
,
ImmutableArray
<
DiagnosticData
>>
map
)
private
async
System
.
Threading
.
Tasks
.
Task
SyncBuildErrorsAndReportAsync
(
DiagnosticAnalyzerService
diagnosticService
,
Solution
solution
,
ImmutableDictionary
<
ProjectId
,
ImmutableArray
<
DiagnosticData
>>
map
)
{
// make those errors live errors
await
diagnosticService
.
SynchronizeWithBuildAsync
(
_workspace
,
map
).
ConfigureAwait
(
false
);
...
...
@@ -253,56 +253,36 @@ private async System.Threading.Tasks.Task SyncBuildErrorsAndReportAsync(Diagnost
foreach
(
var
projectGroup
in
group
.
GroupBy
(
g
=>
g
.
ProjectId
))
{
Contract
.
ThrowIfNull
(
projectGroup
.
Key
);
ReportBuildErrors
(
projectGroup
.
Key
,
projectGroup
.
ToImmutableArray
());
ReportBuildErrors
(
projectGroup
.
Key
,
solution
,
projectGroup
.
ToImmutableArray
());
}
continue
;
}
ReportBuildErrors
(
group
.
Key
,
group
.
ToImmutableArray
());
ReportBuildErrors
(
group
.
Key
,
solution
,
group
.
ToImmutableArray
());
}
}
private
void
ReportBuildErrors
<
T
>(
T
item
,
ImmutableArray
<
DiagnosticData
>
buildErrors
)
private
void
ReportBuildErrors
<
T
>(
T
item
,
Solution
solution
,
ImmutableArray
<
DiagnosticData
>
buildErrors
)
{
var
projectId
=
item
as
ProjectId
;
if
(
projectId
!=
null
)
{
RaiseDiagnosticsCreated
(
projectId
,
projectId
,
null
,
buildErrors
);
RaiseDiagnosticsCreated
(
projectId
,
solution
,
projectId
,
null
,
buildErrors
);
return
;
}
// must be not null
var
documentId
=
item
as
DocumentId
;
RaiseDiagnosticsCreated
(
documentId
,
documentId
.
ProjectId
,
documentId
,
buildErrors
);
}
private
Dictionary
<
ProjectId
,
HashSet
<
string
>>
GetSupportedLiveDiagnosticId
(
Solution
solution
,
InprogressState
state
)
{
var
map
=
new
Dictionary
<
ProjectId
,
HashSet
<
string
>>();
// here, we don't care about perf that much since build is already expensive work
foreach
(
var
projectId
in
state
.
GetProjectsWithErrors
(
solution
))
{
var
project
=
solution
.
GetProject
(
projectId
);
if
(
project
==
null
)
{
continue
;
}
var
descriptorMap
=
_diagnosticService
.
GetDiagnosticDescriptors
(
project
);
map
.
Add
(
project
.
Id
,
new
HashSet
<
string
>(
descriptorMap
.
Values
.
SelectMany
(
v
=>
v
.
Select
(
d
=>
d
.
Id
))));
}
return
map
;
RaiseDiagnosticsCreated
(
documentId
,
solution
,
documentId
.
ProjectId
,
documentId
,
buildErrors
);
}
private
void
ClearProjectErrors
(
ProjectId
projectId
,
Solution
solution
=
null
)
private
void
ClearProjectErrors
(
Solution
solution
,
ProjectId
projectId
)
{
// remove all project errors
RaiseDiagnosticsRemoved
(
projectId
,
projectId
,
documentId
:
null
);
RaiseDiagnosticsRemoved
(
projectId
,
solution
,
projectId
,
documentId
:
null
);
var
project
=
(
solution
??
_workspace
.
CurrentSolution
)
.
GetProject
(
projectId
);
var
project
=
solution
.
GetProject
(
projectId
);
if
(
project
==
null
)
{
return
;
...
...
@@ -311,13 +291,25 @@ private void ClearProjectErrors(ProjectId projectId, Solution solution = null)
// remove all document errors
foreach
(
var
documentId
in
project
.
DocumentIds
)
{
ClearDocumentErrors
(
projectId
,
documentId
);
ClearDocumentErrors
(
solution
,
projectId
,
documentId
);
}
}
private
void
ClearDocumentErrors
(
ProjectId
projectId
,
DocumentId
documentId
)
private
void
ClearDocumentErrors
(
Solution
solution
,
ProjectId
projectId
,
DocumentId
documentId
)
{
RaiseDiagnosticsRemoved
(
documentId
,
projectId
,
documentId
);
RaiseDiagnosticsRemoved
(
documentId
,
solution
,
projectId
,
documentId
);
}
public
void
AddNewErrors
(
ProjectId
projectId
,
DiagnosticData
diagnostic
)
{
// capture state that will be processed in background thread.
var
state
=
GetOrCreateInprogressState
();
var
asyncToken
=
_listener
.
BeginAsyncOperation
(
"Project New Errors"
);
_taskQueue
.
ScheduleTask
(()
=>
{
state
.
AddError
(
projectId
,
diagnostic
);
}).
CompletesAsyncOperation
(
asyncToken
);
}
public
void
AddNewErrors
(
DocumentId
documentId
,
DiagnosticData
diagnostic
)
...
...
@@ -354,22 +346,25 @@ private InprogressState GetOrCreateInprogressState()
{
if
(
_state
==
null
)
{
Interlocked
.
CompareExchange
(
ref
_state
,
new
InprogressState
(
this
),
null
);
// here, we take current snapshot of solution when the state is first created. and through out this code, we use this snapshot.
// since we have no idea what actual snapshot of solution the out of proc build has picked up, it doesn't remove the race we can have
// between build and diagnostic service, but this at least make us to consistent inside of our code.
Interlocked
.
CompareExchange
(
ref
_state
,
new
InprogressState
(
this
,
_workspace
.
CurrentSolution
),
null
);
}
return
_state
;
}
private
void
RaiseDiagnosticsCreated
(
object
id
,
ProjectId
projectId
,
DocumentId
documentId
,
ImmutableArray
<
DiagnosticData
>
items
)
private
void
RaiseDiagnosticsCreated
(
object
id
,
Solution
solution
,
ProjectId
projectId
,
DocumentId
documentId
,
ImmutableArray
<
DiagnosticData
>
items
)
{
DiagnosticsUpdated
?.
Invoke
(
this
,
DiagnosticsUpdatedArgs
.
DiagnosticsCreated
(
CreateArgumentKey
(
id
),
_workspace
,
_workspace
.
CurrentS
olution
,
projectId
,
documentId
,
items
));
CreateArgumentKey
(
id
),
_workspace
,
s
olution
,
projectId
,
documentId
,
items
));
}
private
void
RaiseDiagnosticsRemoved
(
object
id
,
ProjectId
projectId
,
DocumentId
documentId
)
private
void
RaiseDiagnosticsRemoved
(
object
id
,
Solution
solution
,
ProjectId
projectId
,
DocumentId
documentId
)
{
DiagnosticsUpdated
?.
Invoke
(
this
,
DiagnosticsUpdatedArgs
.
DiagnosticsRemoved
(
CreateArgumentKey
(
id
),
_workspace
,
_workspace
.
CurrentS
olution
,
projectId
,
documentId
));
CreateArgumentKey
(
id
),
_workspace
,
s
olution
,
projectId
,
documentId
));
}
private
static
ArgumentKey
CreateArgumentKey
(
object
id
)
=>
new
ArgumentKey
(
id
);
...
...
@@ -392,14 +387,17 @@ private void RaiseBuildStarted(bool started)
private
class
InprogressState
{
private
readonly
ExternalErrorDiagnosticUpdateSource
_owner
;
private
readonly
Solution
_solution
;
private
readonly
HashSet
<
ProjectId
>
_builtProjects
=
new
HashSet
<
ProjectId
>();
private
readonly
Dictionary
<
ProjectId
,
HashSet
<
DiagnosticData
>>
_projectMap
=
new
Dictionary
<
ProjectId
,
HashSet
<
DiagnosticData
>>();
private
readonly
Dictionary
<
DocumentId
,
HashSet
<
DiagnosticData
>>
_documentMap
=
new
Dictionary
<
DocumentId
,
HashSet
<
DiagnosticData
>>();
private
readonly
Dictionary
<
ProjectId
,
HashSet
<
string
>>
_diagnosticIdMap
=
new
Dictionary
<
ProjectId
,
HashSet
<
string
>>();
public
InprogressState
(
ExternalErrorDiagnosticUpdateSource
owner
)
public
InprogressState
(
ExternalErrorDiagnosticUpdateSource
owner
,
Solution
solution
)
{
_owner
=
owner
;
_solution
=
solution
;
// let people know build has started
// TODO: to be more accurate, it probably needs to be counted. but for now,
...
...
@@ -407,11 +405,38 @@ public InprogressState(ExternalErrorDiagnosticUpdateSource owner)
_owner
.
RaiseBuildStarted
(
started
:
true
);
}
public
Solution
Solution
=>
_solution
;
public
void
Done
()
{
_owner
.
RaiseBuildStarted
(
started
:
false
);
}
public
bool
SupportedDiagnosticId
(
ProjectId
projectId
,
string
id
)
{
HashSet
<
string
>
ids
;
if
(
_diagnosticIdMap
.
TryGetValue
(
projectId
,
out
ids
))
{
return
ids
.
Contains
(
id
);
}
// set ids set
var
map
=
new
HashSet
<
string
>();
_diagnosticIdMap
.
Add
(
projectId
,
map
);
var
project
=
_solution
.
GetProject
(
projectId
);
if
(
project
==
null
)
{
// projectId no longer exist, return false;
return
false
;
}
var
descriptorMap
=
_owner
.
_diagnosticService
.
GetDiagnosticDescriptors
(
project
);
map
.
UnionWith
(
descriptorMap
.
Values
.
SelectMany
(
v
=>
v
.
Select
(
d
=>
d
.
Id
)));
return
map
.
Contains
(
id
);
}
public
ImmutableArray
<
DiagnosticData
>
GetBuildDiagnostics
()
{
return
ImmutableArray
.
CreateRange
(
_projectMap
.
Values
.
SelectMany
(
d
=>
d
).
Concat
(
_documentMap
.
Values
.
SelectMany
(
d
=>
d
)));
...
...
@@ -467,6 +492,11 @@ public void AddError(DocumentId key, DiagnosticData diagnostic)
AddError
(
_documentMap
,
key
,
diagnostic
);
}
public
void
AddError
(
ProjectId
key
,
DiagnosticData
diagnostic
)
{
AddError
(
_projectMap
,
key
,
diagnostic
);
}
private
void
AddErrors
<
T
>(
Dictionary
<
T
,
HashSet
<
DiagnosticData
>>
map
,
T
key
,
HashSet
<
DiagnosticData
>
diagnostics
)
{
var
errors
=
GetErrorSet
(
map
,
key
);
...
...
src/VisualStudio/Core/Def/Implementation/TaskList/ProjectExternalErrorReporter.cs
浏览文件 @
a41e5c9f
...
...
@@ -24,6 +24,7 @@ internal class ProjectExternalErrorReporter : IVsReportExternalErrors, IVsLangua
private
readonly
ProjectId
_projectId
;
private
readonly
string
_errorCodePrefix
;
private
readonly
VisualStudioWorkspaceImpl
_workspace
;
private
readonly
ExternalErrorDiagnosticUpdateSource
_diagnosticProvider
;
...
...
@@ -31,11 +32,23 @@ public ProjectExternalErrorReporter(ProjectId projectId, string errorCodePrefix,
{
_projectId
=
projectId
;
_errorCodePrefix
=
errorCodePrefix
;
_diagnosticProvider
=
serviceProvider
.
GetMefService
<
ExternalErrorDiagnosticUpdateSource
>();
_workspace
=
serviceProvider
.
GetMefService
<
VisualStudioWorkspaceImpl
>();
_diagnosticProvider
=
serviceProvider
.
GetMefService
<
ExternalErrorDiagnosticUpdateSource
>();
Debug
.
Assert
(
_diagnosticProvider
!=
null
);
Debug
.
Assert
(
_workspace
!=
null
);
Debug
.
Assert
(
_diagnosticProvider
!=
null
);
}
private
bool
CanHandle
(
string
errorId
)
{
// we accept all compiler diagnostics
if
(
errorId
.
StartsWith
(
_errorCodePrefix
))
{
return
true
;
}
return
_diagnosticProvider
.
SupportedDiagnosticId
(
_projectId
,
errorId
);
}
public
int
AddNewErrors
(
IVsEnumExternalErrors
pErrors
)
...
...
@@ -134,28 +147,20 @@ public int ReportError(string bstrErrorMessage, string bstrErrorId, [ComAliasNam
// TODO: Use PreserveSig instead of throwing these exceptions for common cases.
public
void
ReportError2
(
string
bstrErrorMessage
,
string
bstrErrorId
,
[
ComAliasName
(
"VsShell.VSTASKPRIORITY"
)]
VSTASKPRIORITY
nPriority
,
int
iStartLine
,
int
iStartColumn
,
int
iEndLine
,
int
iEndColumn
,
string
bstrFileName
)
{
if
((
iEndLine
>=
0
&&
iEndColumn
>=
0
)
&&
((
iEndLine
<
iStartLine
)
||
(
iEndLine
==
iStartLine
&&
iEndColumn
<
iStartColumn
)))
{
throw
new
ArgumentException
(
ServicesVSResources
.
EndPositionMustBeGreaterThanStart
);
}
// We only handle errors that have positions. For the rest, we punt back to the
// project system.
if
(
iStartLine
<
0
||
iStartColumn
<
0
)
// first we check whether given error is something we can take care.
if
(!
CanHandle
(
bstrErrorId
))
{
// it is not, let project system takes care.
throw
new
NotImplementedException
();
}
var
hostProject
=
_workspace
.
GetHostProject
(
_projectId
);
if
(!
hostProject
.
ContainsFile
(
bstrFileName
))
if
((
iEndLine
>=
0
&&
iEndColumn
>=
0
)
&&
((
iEndLine
<
iStartLine
)
||
(
iEndLine
==
iStartLine
&&
iEndColumn
<
iStartColumn
)))
{
throw
new
NotImplementedException
(
);
throw
new
ArgumentException
(
ServicesVSResources
.
EndPositionMustBeGreaterThanStart
);
}
var
hostDocument
=
hostProject
.
GetCurrentDocumentFromPath
(
bstrFileName
);
var
priority
=
(
VSTASKPRIORITY
)
nPriority
;
DiagnosticSeverity
severity
;
switch
(
priority
)
...
...
@@ -173,6 +178,32 @@ public void ReportError2(string bstrErrorMessage, string bstrErrorId, [ComAliasN
throw
new
ArgumentException
(
ServicesVSResources
.
NotAValidValue
,
nameof
(
nPriority
));
}
if
(
iStartLine
<
0
||
iStartColumn
<
0
)
{
// we now takes care of errors that is not belong to file as well.
var
projectDiagnostic
=
GetDiagnosticData
(
null
,
bstrErrorId
,
bstrErrorMessage
,
severity
,
null
,
0
,
0
,
0
,
0
,
bstrFileName
,
0
,
0
,
0
,
0
);
_diagnosticProvider
.
AddNewErrors
(
_projectId
,
projectDiagnostic
);
return
;
}
var
hostProject
=
_workspace
.
GetHostProject
(
_projectId
);
if
(!
hostProject
.
ContainsFile
(
bstrFileName
))
{
var
projectDiagnostic
=
GetDiagnosticData
(
null
,
bstrErrorId
,
bstrErrorMessage
,
severity
,
null
,
iStartLine
,
iStartColumn
,
iEndLine
,
iEndColumn
,
bstrFileName
,
iStartLine
,
iStartColumn
,
iEndLine
,
iEndColumn
);
_diagnosticProvider
.
AddNewErrors
(
_projectId
,
projectDiagnostic
);
return
;
}
var
hostDocument
=
hostProject
.
GetCurrentDocumentFromPath
(
bstrFileName
);
var
diagnostic
=
GetDiagnosticData
(
hostDocument
.
Id
,
bstrErrorId
,
bstrErrorMessage
,
severity
,
null
,
iStartLine
,
iStartColumn
,
iEndLine
,
iEndColumn
,
...
...
src/VisualStudio/Core/Test/Diagnostics/ExternalDiagnosticUpdateSourceTests.vb
浏览文件 @
a41e5c9f
...
...
@@ -53,6 +53,21 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Diagnostics
End
Using
End
Function
<
Fact
>
Public
Async
Function
TestExternalDiagnostics_SupportedId
()
As
Task
Using
workspace
=
Await
TestWorkspace
.
CreateCSharpAsync
(
String
.
Empty
)
Dim
waiter
=
New
Waiter
()
Dim
service
=
New
TestDiagnosticAnalyzerService
()
Dim
source
=
New
ExternalErrorDiagnosticUpdateSource
(
workspace
,
service
,
New
MockDiagnosticUpdateSourceRegistrationService
(),
waiter
)
Dim
project
=
workspace
.
CurrentSolution
.
Projects
.
First
()
source
.
OnSolutionBuild
(
Me
,
Shell
.
UIContextChangedEventArgs
.
From
(
True
))
Assert
.
True
(
source
.
SupportedDiagnosticId
(
project
.
Id
,
"CS1002"
))
Assert
.
False
(
source
.
SupportedDiagnosticId
(
project
.
Id
,
"CA1002"
))
End
Using
End
Function
<
Fact
>
Public
Async
Function
TestExternalDiagnostics_DuplicatedError
()
As
Task
Using
workspace
=
Await
TestWorkspace
.
CreateCSharpAsync
(
String
.
Empty
)
...
...
@@ -169,7 +184,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Diagnostics
End
Sub
Public
Function
GetDiagnosticDescriptors
(
projectOpt
As
Project
)
As
ImmutableDictionary
(
Of
String
,
ImmutableArray
(
Of
DiagnosticDescriptor
))
Implements
IDiagnosticAnalyzerService
.
GetDiagnosticDescriptors
Return
ImmutableDictionary
(
Of
String
,
ImmutableArray
(
Of
DiagnosticDescriptor
)).
Empty
Return
ImmutableDictionary
(
Of
String
,
ImmutableArray
(
Of
DiagnosticDescriptor
)).
Empty
.
Add
(
"reference"
,
ImmutableArray
.
Create
(
Of
DiagnosticDescriptor
)(
New
DiagnosticDescriptor
(
"CS1002"
,
"test"
,
"test"
,
"test"
,
DiagnosticSeverity
.
Warning
,
True
)))
End
Function
Public
Function
GetDiagnosticsForSpanAsync
(
document
As
Document
,
range
As
TextSpan
,
Optional
includeSuppressedDiagnostics
As
Boolean
=
False
,
Optional
cancellationToken
As
CancellationToken
=
Nothing
)
As
Task
(
Of
IEnumerable
(
Of
DiagnosticData
))
Implements
IDiagnosticAnalyzerService
.
GetDiagnosticsForSpanAsync
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录