diff --git a/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalysisState.cs b/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalysisState.cs index 21f0c04280aec9b346ad2a4275197c803a6a99da..a019635eca049384efa6853df2597e4f36bb99d0 100644 --- a/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalysisState.cs +++ b/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalysisState.cs @@ -175,7 +175,7 @@ private PerAnalyzerState GetAnalyzerState(DiagnosticAnalyzer analyzer) var fullSpan = tree.GetRoot(cancellationToken).FullSpan; var declarationInfos = new List(); model.ComputeDeclarationsInSpan(fullSpan, getSymbol: true, builder: declarationInfos, cancellationToken: cancellationToken); - return declarationInfos.Select(declInfo => declInfo.DeclaredSymbol).WhereNotNull(); + return declarationInfos.Select(declInfo => declInfo.DeclaredSymbol).Distinct().WhereNotNull(); } private static ImmutableArray CreateCompilationEventsForTree(IEnumerable declaredSymbols, SyntaxTree tree, Compilation compilation) diff --git a/src/EditorFeatures/Test2/Diagnostics/DiagnosticServiceTests.vb b/src/EditorFeatures/Test2/Diagnostics/DiagnosticServiceTests.vb index ad1fc5aea7178ccdbdd3763e48fba712c05de300..55f3a531d47801715f6a4378cc7ec94e7e5ea06c 100644 --- a/src/EditorFeatures/Test2/Diagnostics/DiagnosticServiceTests.vb +++ b/src/EditorFeatures/Test2/Diagnostics/DiagnosticServiceTests.vb @@ -809,6 +809,38 @@ class AnonymousFunctions End Using End Function + + Public Sub TestMultiplePartialDefinitionsInAFile() + Dim test = + + + partial class Foo { } + partial class Foo { } + + + + + Using workspace = TestWorkspace.CreateWorkspace(test) + Dim project = workspace.CurrentSolution.Projects.Single() + Dim analyzer = New NamedTypeAnalyzer + Dim analyzerReference = New AnalyzerImageReference(ImmutableArray.Create(Of DiagnosticAnalyzer)(analyzer)) + project = project.AddAnalyzerReference(analyzerReference) + Dim diagnosticService = New TestDiagnosticAnalyzerService() + + Dim incrementalAnalyzer = diagnosticService.CreateIncrementalAnalyzer(workspace) + Dim descriptorsMap = diagnosticService.GetDiagnosticDescriptors(project) + Assert.Equal(1, descriptorsMap.Count) + + ' Verify no duplicate analysis/diagnostics. + Dim document = project.Documents.Single() + Dim diagnostics = diagnosticService.GetDiagnosticsAsync(project.Solution, project.Id) _ + .WaitAndGetResult(CancellationToken.None) _ + .Select(Function(d) d.Id = NamedTypeAnalyzer.DiagDescriptor.Id) + + Assert.Equal(1, diagnostics.Count) + End Using + End Sub + Public Sub TestPartialTypeInGeneratedCode() Dim test = @@ -1354,6 +1386,29 @@ public class B End Sub End Class + Private Class NamedTypeAnalyzer + Inherits DiagnosticAnalyzer + + Public Shared ReadOnly DiagDescriptor As DiagnosticDescriptor = DescriptorFactory.CreateSimpleDescriptor("DummyDiagnostic") + Public Overrides ReadOnly Property SupportedDiagnostics As ImmutableArray(Of DiagnosticDescriptor) + Get + Return ImmutableArray.Create(DiagDescriptor) + End Get + End Property + + Public Overrides Sub Initialize(context As AnalysisContext) + context.RegisterCompilationStartAction(Sub(compStartContext As CompilationStartAnalysisContext) + Dim symbols = New HashSet(Of ISymbol) + compStartContext.RegisterSymbolAction(Sub(sc As SymbolAnalysisContext) + If (symbols.Contains(sc.Symbol)) Then + Throw New Exception("Duplicate symbol callback") + End If + sc.ReportDiagnostic(Diagnostic.Create(DiagDescriptor, sc.Symbol.Locations.First())) + End Sub, SymbolKind.NamedType) + End Sub) + End Sub + End Class + Private Class DummySymbolAnalyzer Inherits DiagnosticAnalyzer