EventHandlerSuffixSuppressor.cs 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. using System.Collections.Immutable;
  2. using System.Linq;
  3. using System.Threading;
  4. using Microsoft.CodeAnalysis;
  5. using Microsoft.CodeAnalysis.CSharp.Syntax;
  6. using Microsoft.CodeAnalysis.Diagnostics;
  7. namespace Godot.SourceGenerators
  8. {
  9. [DiagnosticAnalyzer(LanguageNames.CSharp)]
  10. public class EventHandlerSuffixSuppressor : DiagnosticSuppressor
  11. {
  12. private static readonly SuppressionDescriptor _descriptor = new(
  13. id: "GDSP0001",
  14. suppressedDiagnosticId: "CA1711",
  15. justification: "Signal delegates are used in events so the naming follows the guidelines.");
  16. public override ImmutableArray<SuppressionDescriptor> SupportedSuppressions =>
  17. ImmutableArray.Create(_descriptor);
  18. public override void ReportSuppressions(SuppressionAnalysisContext context)
  19. {
  20. foreach (var diagnostic in context.ReportedDiagnostics)
  21. {
  22. AnalyzeDiagnostic(context, diagnostic, context.CancellationToken);
  23. }
  24. }
  25. private static void AnalyzeDiagnostic(SuppressionAnalysisContext context, Diagnostic diagnostic, CancellationToken cancellationToken = default)
  26. {
  27. var location = diagnostic.Location;
  28. var root = location.SourceTree?.GetRoot(cancellationToken);
  29. var dds = root?
  30. .FindNode(location.SourceSpan)
  31. .DescendantNodesAndSelf()
  32. .OfType<DelegateDeclarationSyntax>()
  33. .FirstOrDefault();
  34. if (dds == null)
  35. return;
  36. var semanticModel = context.GetSemanticModel(dds.SyntaxTree);
  37. var delegateSymbol = semanticModel.GetDeclaredSymbol(dds, cancellationToken);
  38. if (delegateSymbol == null)
  39. return;
  40. if (delegateSymbol.GetAttributes().Any(a => a.AttributeClass?.IsGodotSignalAttribute() ?? false))
  41. {
  42. context.ReportSuppression(Suppression.Create(_descriptor, diagnostic));
  43. }
  44. }
  45. }
  46. }