From 67f0ea17ad7e5ac5d4a5fd821c5c715822629c9c Mon Sep 17 00:00:00 2001 From: Heejae Chang Date: Wed, 5 Dec 2018 00:30:57 -0800 Subject: [PATCH] make sure VS to not crash when analyzer.initialize throws (#31543) --- .../Portable/Diagnostics/AnalyzerHelper.cs | 32 ++++++++++++------- .../DiagnosticIncrementalAnalyzer.StateSet.cs | 9 +++++- 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/src/Features/Core/Portable/Diagnostics/AnalyzerHelper.cs b/src/Features/Core/Portable/Diagnostics/AnalyzerHelper.cs index 1ce0bd15a08..2e4aaa4a0e8 100644 --- a/src/Features/Core/Portable/Diagnostics/AnalyzerHelper.cs +++ b/src/Features/Core/Portable/Diagnostics/AnalyzerHelper.cs @@ -292,7 +292,7 @@ private static IEnumerable Convert(IEnumerable<(Diagnos return analyzerPerf.Select(kv => new AnalyzerPerformanceInfo(kv.analyzer.GetAnalyzerId(), DiagnosticAnalyzerLogger.AllowsTelemetry(kv.analyzer, serviceOpt), kv.timeSpan)); } - public static bool IsCompilationEndAnalyzer(this DiagnosticAnalyzer analyzer, Project project, Compilation compilation) + public static bool? IsCompilationEndAnalyzer(this DiagnosticAnalyzer analyzer, Project project, Compilation compilation) { if (!project.SupportsCompilation) { @@ -301,16 +301,26 @@ public static bool IsCompilationEndAnalyzer(this DiagnosticAnalyzer analyzer, Pr Contract.ThrowIfNull(compilation); - // currently, this is only way to see whether analyzer has compilation end analysis or not. - // also, analyzer being compilation end analyzer or not is dynamic. so this can return different value based on - // given compilation or options. - // - // but for now, this is what we decided in design meeting until we decide how to deal with compilation end analyzer - // long term - var context = new CollectCompilationActionsContext(compilation, project.AnalyzerOptions); - analyzer.Initialize(context); - - return context.IsCompilationEndAnalyzer; + try + { + // currently, this is only way to see whether analyzer has compilation end analysis or not. + // also, analyzer being compilation end analyzer or not is dynamic. so this can return different value based on + // given compilation or options. + // + // but for now, this is what we decided in design meeting until we decide how to deal with compilation end analyzer + // long term + var context = new CollectCompilationActionsContext(compilation, project.AnalyzerOptions); + analyzer.Initialize(context); + + return context.IsCompilationEndAnalyzer; + } + catch + { + // analyzer.initialize can throw. when that happens, we will try again next time. + // we are not logging anything here since it will be logged by CompilationWithAnalyzer later + // in the error list + return null; + } } /// diff --git a/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.StateSet.cs b/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.StateSet.cs index c398f31e990..8102af2d93c 100644 --- a/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.StateSet.cs +++ b/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.StateSet.cs @@ -265,7 +265,14 @@ public void ComputeCompilationEndAnalyzer(Project project, Compilation compilati } // running this multiple time is fine - _compilationEndAnalyzer = _analyzer.IsCompilationEndAnalyzer(project, compilation) ? 1 : 0; + var result = _analyzer.IsCompilationEndAnalyzer(project, compilation); + if (!result.HasValue) + { + // try again next time. + return; + } + + _compilationEndAnalyzer = result.Value ? 1 : 0; } public bool IsCompilationEndAnalyzer(Project project, Compilation compilation) -- GitLab