-
Notifications
You must be signed in to change notification settings - Fork 482
Write CA1824 as non-compilation-end #6873
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,7 @@ | |
using System.Collections.Generic; | ||
using System.Collections.Immutable; | ||
using System.Linq; | ||
using System.Runtime.CompilerServices; | ||
using System.Threading; | ||
using Analyzer.Utilities; | ||
using Analyzer.Utilities.Extensions; | ||
|
@@ -33,10 +34,9 @@ public abstract class MarkAssembliesWithNeutralResourcesLanguageAnalyzer : Diagn | |
RuleLevel.IdeSuggestion, | ||
description: CreateLocalizableResourceString(nameof(MarkAssembliesWithNeutralResourcesLanguageDescription)), | ||
isPortedFxCopRule: true, | ||
isDataflowRule: false, | ||
isReportedAtCompilationEnd: true); | ||
isDataflowRule: false); | ||
|
||
protected abstract void RegisterAttributeAnalyzer(CompilationStartAnalysisContext context, Action onResourceFound, INamedTypeSymbol generatedCode); | ||
protected abstract void RegisterAttributeAnalyzer(CompilationStartAnalysisContext context, Func<bool> shouldAnalyze, Action<SyntaxNodeAnalysisContext> onResourceFound, INamedTypeSymbol generatedCode); | ||
|
||
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; } = ImmutableArray.Create(Rule); | ||
|
||
|
@@ -68,28 +68,48 @@ public override void Initialize(AnalysisContext context) | |
return; | ||
} | ||
|
||
var hasResource = false; | ||
RegisterAttributeAnalyzer(context, () => hasResource = true, generatedCode); | ||
var alreadyReportedDiagnostic = new StrongBox<bool>(false); | ||
var @lock = new object(); | ||
|
||
context.RegisterCompilationEndAction(context => | ||
{ | ||
// there is nothing to do. | ||
if (!hasResource) | ||
RegisterAttributeAnalyzer( | ||
context, | ||
shouldAnalyze: () => | ||
{ | ||
return; | ||
} | ||
|
||
if (data != null && | ||
data.ApplicationSyntaxReference?.GetSyntax(context.CancellationToken) is { } attributeSyntax) | ||
// This value can only change from false to true. So no need to lock if it's already true here. | ||
if (alreadyReportedDiagnostic.Value) | ||
{ | ||
return false; | ||
} | ||
|
||
lock (@lock) | ||
{ | ||
return !alreadyReportedDiagnostic.Value; | ||
} | ||
}, | ||
onResourceFound: context => | ||
{ | ||
// we have the attribute but its doing it wrong. | ||
context.ReportDiagnostic(attributeSyntax.CreateDiagnostic(Rule)); | ||
return; | ||
} | ||
|
||
// attribute just don't exist | ||
context.ReportNoLocationDiagnostic(Rule); | ||
}); | ||
lock (@lock) | ||
{ | ||
if (alreadyReportedDiagnostic.Value) | ||
{ | ||
return; | ||
} | ||
|
||
alreadyReportedDiagnostic.Value = true; | ||
|
||
if (data != null && | ||
data.ApplicationSyntaxReference?.GetSyntax(context.CancellationToken) is { } attributeSyntax) | ||
{ | ||
// we have the attribute but its doing it wrong. | ||
context.ReportDiagnostic(attributeSyntax.CreateDiagnostic(Rule)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ❗ This diagnostic (the one with a specific location) should always be reported. Edit: It cannot set There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Diagnostic with location will always be reported if we find a source assembly attribute here, otherwise a no-location diagnostic will always be reported - I believe the logic here is deterministic because |
||
return; | ||
} | ||
|
||
// attribute just don't exist | ||
context.ReportNoLocationDiagnostic(Rule); | ||
} | ||
}, | ||
generatedCode); | ||
}); | ||
} | ||
|
||
|
Uh oh!
There was an error while loading. Please reload this page.