Skip to content

Commit 49ef1d5

Browse files
authored
Merge pull request #3456 from sharwell/empty-project
Disable SA0002 (Invalid settings file) for empty projects
2 parents feea263 + 411129f commit 49ef1d5

2 files changed

Lines changed: 57 additions & 12 deletions

File tree

StyleCop.Analyzers/StyleCop.Analyzers.Test/SpecialRules/SA0002UnitTests.cs

Lines changed: 50 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,30 @@ public async Task TestMissingSettingsAsync()
3434
await VerifyCSharpDiagnosticAsync(TestCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
3535
}
3636

37+
[Fact]
38+
[WorkItem(3453, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3453")]
39+
public async Task TestNoSourceFilesAsync()
40+
{
41+
string emptySettings = @"{ ""settings"": { } }";
42+
await new CSharpTest
43+
{
44+
TestState =
45+
{
46+
Sources = { string.Empty },
47+
AdditionalFiles = { ("stylecop.json", emptySettings) },
48+
AdditionalProjects =
49+
{
50+
["EmptyProjectWithSettings"] =
51+
{
52+
// The main test state doesn't allow empty Sources, so we use a second project to validate
53+
// the completely empty case.
54+
AdditionalFiles = { ("stylecop.json", emptySettings) },
55+
},
56+
},
57+
},
58+
}.RunAsync(CancellationToken.None).ConfigureAwait(false);
59+
}
60+
3761
[Fact]
3862
public async Task TestValidSettingsAsync()
3963
{
@@ -329,18 +353,33 @@ public async Task TestEmptySettingsAsync()
329353
}
330354

331355
[Fact]
332-
public void TestUnexpectedExceptionNotCaught()
356+
public async Task TestUnexpectedExceptionNotCaughtAsync()
333357
{
334-
var analysisContext = new AnalysisContextMissingOptions();
335-
var analyzer = new SA0002InvalidSettingsFile();
336-
analyzer.Initialize(analysisContext);
337-
Assert.NotNull(analysisContext.CompilationAction);
338-
339-
var additionalFiles = ImmutableArray.Create<AdditionalText>(new InvalidAdditionalText());
340-
Assert.Null(additionalFiles[0].Path);
341-
Assert.Null(additionalFiles[0].GetText(CancellationToken.None));
342-
var context = new CompilationAnalysisContext(compilation: null, options: new AnalyzerOptions(additionalFiles), reportDiagnostic: null, isSupportedDiagnostic: null, cancellationToken: CancellationToken.None);
343-
Assert.Throws<ArgumentNullException>(() => analysisContext.CompilationAction(context));
358+
await new CSharpTest
359+
{
360+
TestSources = { string.Empty },
361+
SolutionTransforms =
362+
{
363+
// Run additional validation here with access to a Compilation
364+
(solution, projectId) =>
365+
{
366+
var compilation = solution.GetProject(projectId).GetCompilationAsync(CancellationToken.None).GetAwaiter().GetResult();
367+
368+
var analysisContext = new AnalysisContextMissingOptions();
369+
var analyzer = new SA0002InvalidSettingsFile();
370+
analyzer.Initialize(analysisContext);
371+
Assert.NotNull(analysisContext.CompilationAction);
372+
373+
var additionalFiles = ImmutableArray.Create<AdditionalText>(new InvalidAdditionalText());
374+
Assert.Null(additionalFiles[0].Path);
375+
Assert.Null(additionalFiles[0].GetText(CancellationToken.None));
376+
var context = new CompilationAnalysisContext(compilation, options: new AnalyzerOptions(additionalFiles), reportDiagnostic: null, isSupportedDiagnostic: null, cancellationToken: CancellationToken.None);
377+
Assert.Throws<ArgumentNullException>(() => analysisContext.CompilationAction(context));
378+
379+
return solution;
380+
},
381+
},
382+
}.RunAsync(CancellationToken.None).ConfigureAwait(false);
344383
}
345384

346385
private class InvalidAdditionalText : AdditionalText

StyleCop.Analyzers/StyleCop.Analyzers/SpecialRules/SA0002InvalidSettingsFile.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,15 @@ public override void Initialize(AnalysisContext context)
5151

5252
private static void HandleCompilation(CompilationAnalysisContext context)
5353
{
54+
var firstSyntaxTree = context.Compilation.SyntaxTrees.FirstOrDefault();
55+
if (firstSyntaxTree is null)
56+
{
57+
return;
58+
}
59+
5460
try
5561
{
56-
SettingsHelper.GetStyleCopSettings(context.Options, context.Compilation?.SyntaxTrees.FirstOrDefault(), DeserializationFailureBehavior.ThrowException, context.CancellationToken);
62+
SettingsHelper.GetStyleCopSettings(context.Options, firstSyntaxTree, DeserializationFailureBehavior.ThrowException, context.CancellationToken);
5763
}
5864
catch (Exception ex) when (ex is JsonParseException || ex is InvalidSettingsException)
5965
{

0 commit comments

Comments
 (0)