diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/SpecialRules/SA0002UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/SpecialRules/SA0002UnitTests.cs index 5dd51f4b2..9bfa73197 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/SpecialRules/SA0002UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/SpecialRules/SA0002UnitTests.cs @@ -34,6 +34,30 @@ public async Task TestMissingSettingsAsync() await VerifyCSharpDiagnosticAsync(TestCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false); } + [Fact] + [WorkItem(3453, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3453")] + public async Task TestNoSourceFilesAsync() + { + string emptySettings = @"{ ""settings"": { } }"; + await new CSharpTest + { + TestState = + { + Sources = { string.Empty }, + AdditionalFiles = { ("stylecop.json", emptySettings) }, + AdditionalProjects = + { + ["EmptyProjectWithSettings"] = + { + // The main test state doesn't allow empty Sources, so we use a second project to validate + // the completely empty case. + AdditionalFiles = { ("stylecop.json", emptySettings) }, + }, + }, + }, + }.RunAsync(CancellationToken.None).ConfigureAwait(false); + } + [Fact] public async Task TestValidSettingsAsync() { @@ -329,18 +353,33 @@ public async Task TestEmptySettingsAsync() } [Fact] - public void TestUnexpectedExceptionNotCaught() + public async Task TestUnexpectedExceptionNotCaughtAsync() { - var analysisContext = new AnalysisContextMissingOptions(); - var analyzer = new SA0002InvalidSettingsFile(); - analyzer.Initialize(analysisContext); - Assert.NotNull(analysisContext.CompilationAction); - - var additionalFiles = ImmutableArray.Create(new InvalidAdditionalText()); - Assert.Null(additionalFiles[0].Path); - Assert.Null(additionalFiles[0].GetText(CancellationToken.None)); - var context = new CompilationAnalysisContext(compilation: null, options: new AnalyzerOptions(additionalFiles), reportDiagnostic: null, isSupportedDiagnostic: null, cancellationToken: CancellationToken.None); - Assert.Throws(() => analysisContext.CompilationAction(context)); + await new CSharpTest + { + TestSources = { string.Empty }, + SolutionTransforms = + { + // Run additional validation here with access to a Compilation + (solution, projectId) => + { + var compilation = solution.GetProject(projectId).GetCompilationAsync(CancellationToken.None).GetAwaiter().GetResult(); + + var analysisContext = new AnalysisContextMissingOptions(); + var analyzer = new SA0002InvalidSettingsFile(); + analyzer.Initialize(analysisContext); + Assert.NotNull(analysisContext.CompilationAction); + + var additionalFiles = ImmutableArray.Create(new InvalidAdditionalText()); + Assert.Null(additionalFiles[0].Path); + Assert.Null(additionalFiles[0].GetText(CancellationToken.None)); + var context = new CompilationAnalysisContext(compilation, options: new AnalyzerOptions(additionalFiles), reportDiagnostic: null, isSupportedDiagnostic: null, cancellationToken: CancellationToken.None); + Assert.Throws(() => analysisContext.CompilationAction(context)); + + return solution; + }, + }, + }.RunAsync(CancellationToken.None).ConfigureAwait(false); } private class InvalidAdditionalText : AdditionalText diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/SpecialRules/SA0002InvalidSettingsFile.cs b/StyleCop.Analyzers/StyleCop.Analyzers/SpecialRules/SA0002InvalidSettingsFile.cs index 9759413da..f030056cd 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/SpecialRules/SA0002InvalidSettingsFile.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers/SpecialRules/SA0002InvalidSettingsFile.cs @@ -51,9 +51,15 @@ public override void Initialize(AnalysisContext context) private static void HandleCompilation(CompilationAnalysisContext context) { + var firstSyntaxTree = context.Compilation.SyntaxTrees.FirstOrDefault(); + if (firstSyntaxTree is null) + { + return; + } + try { - SettingsHelper.GetStyleCopSettings(context.Options, context.Compilation?.SyntaxTrees.FirstOrDefault(), DeserializationFailureBehavior.ThrowException, context.CancellationToken); + SettingsHelper.GetStyleCopSettings(context.Options, firstSyntaxTree, DeserializationFailureBehavior.ThrowException, context.CancellationToken); } catch (Exception ex) when (ex is JsonParseException || ex is InvalidSettingsException) {