55 lines
2.1 KiB
C#
55 lines
2.1 KiB
C#
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 sealed 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)
|
|
{
|
|
context.ReportDiagnostic(Diagnostic.Create(
|
|
Common.GlobalClassMustNotBeGenericRule,
|
|
typeSymbol.Locations.FirstLocationWithSourceTreeOrDefault(),
|
|
typeSymbol.ToDisplayString()
|
|
));
|
|
}
|
|
|
|
if (!typeSymbol.InheritsFrom("GodotSharp", GodotClasses.GodotObject))
|
|
{
|
|
context.ReportDiagnostic(Diagnostic.Create(
|
|
Common.GlobalClassMustDeriveFromGodotObjectRule,
|
|
typeSymbol.Locations.FirstLocationWithSourceTreeOrDefault(),
|
|
typeSymbol.ToDisplayString()
|
|
));
|
|
}
|
|
}
|
|
}
|
|
}
|