summaryrefslogtreecommitdiffstats
path: root/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GlobalClassAnalyzer.cs
diff options
context:
space:
mode:
Diffstat (limited to 'modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GlobalClassAnalyzer.cs')
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GlobalClassAnalyzer.cs42
1 files changed, 42 insertions, 0 deletions
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GlobalClassAnalyzer.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GlobalClassAnalyzer.cs
new file mode 100644
index 0000000000..bcb35dae8a
--- /dev/null
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GlobalClassAnalyzer.cs
@@ -0,0 +1,42 @@
+using System.Collections.Immutable;
+using System.Linq;
+
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using Microsoft.CodeAnalysis.Diagnostics;
+
+namespace Godot.SourceGenerators
+{
+ [DiagnosticAnalyzer(LanguageNames.CSharp)]
+ public class GlobalClassAnalyzer : DiagnosticAnalyzer
+ {
+ public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics
+ => ImmutableArray.Create(
+ Common.GlobalClassMustDeriveFromGodotObjectRule,
+ Common.GlobalClassMustNotBeGenericRule);
+
+ public override void Initialize(AnalysisContext context)
+ {
+ context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
+ context.EnableConcurrentExecution();
+ context.RegisterSyntaxNodeAction(AnalyzeNode, SyntaxKind.ClassDeclaration);
+ }
+
+ private void AnalyzeNode(SyntaxNodeAnalysisContext context)
+ {
+ var typeClassDecl = (ClassDeclarationSyntax)context.Node;
+
+ // Return if not a type symbol or the type is not a global class.
+ if (context.ContainingSymbol is not INamedTypeSymbol typeSymbol ||
+ !typeSymbol.GetAttributes().Any(a => a.AttributeClass?.IsGodotGlobalClassAttribute() ?? false))
+ return;
+
+ if (typeSymbol.IsGenericType)
+ Common.ReportGlobalClassMustNotBeGeneric(context, typeClassDecl, typeSymbol);
+
+ if (!typeSymbol.InheritsFrom("GodotSharp", GodotClasses.GodotObject))
+ Common.ReportGlobalClassMustDeriveFromGodotObject(context, typeClassDecl, typeSymbol);
+ }
+ }
+}