GlobalClassAnalyzer.cs 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. using System.Collections.Immutable;
  2. using System.Linq;
  3. using Microsoft.CodeAnalysis;
  4. using Microsoft.CodeAnalysis.CSharp;
  5. using Microsoft.CodeAnalysis.Diagnostics;
  6. namespace Godot.SourceGenerators
  7. {
  8. [DiagnosticAnalyzer(LanguageNames.CSharp)]
  9. public sealed class GlobalClassAnalyzer : DiagnosticAnalyzer
  10. {
  11. public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics
  12. => ImmutableArray.Create(
  13. Common.GlobalClassMustDeriveFromGodotObjectRule,
  14. Common.GlobalClassMustNotBeGenericRule);
  15. public override void Initialize(AnalysisContext context)
  16. {
  17. context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
  18. context.EnableConcurrentExecution();
  19. context.RegisterSyntaxNodeAction(AnalyzeNode, SyntaxKind.ClassDeclaration);
  20. }
  21. private static void AnalyzeNode(SyntaxNodeAnalysisContext context)
  22. {
  23. // Return if not a type symbol or the type is not a global class.
  24. if (context.ContainingSymbol is not INamedTypeSymbol typeSymbol ||
  25. !typeSymbol.GetAttributes().Any(a => a.AttributeClass?.IsGodotGlobalClassAttribute() ?? false))
  26. return;
  27. if (typeSymbol.IsGenericType)
  28. {
  29. context.ReportDiagnostic(Diagnostic.Create(
  30. Common.GlobalClassMustNotBeGenericRule,
  31. typeSymbol.Locations.FirstLocationWithSourceTreeOrDefault(),
  32. typeSymbol.ToDisplayString()
  33. ));
  34. }
  35. if (!typeSymbol.InheritsFrom("GodotSharp", GodotClasses.GodotObject))
  36. {
  37. context.ReportDiagnostic(Diagnostic.Create(
  38. Common.GlobalClassMustDeriveFromGodotObjectRule,
  39. typeSymbol.Locations.FirstLocationWithSourceTreeOrDefault(),
  40. typeSymbol.ToDisplayString()
  41. ));
  42. }
  43. }
  44. }
  45. }