2c180f62d9
- Moves interop functions to UnmanagedCallbacks struct that contains the function pointers and is passed to C#. - Implements UnmanagedCallbacksGenerator, a C# source generator that generates the UnmanagedCallbacks struct in C# and the body for the NativeFuncs methods (their implementation just calls the function pointer in the UnmanagedCallbacks). The generated methods are needed because .NET pins byref parameters of native calls, even if they are 'ref struct's, which don't need pinning. The generated methods use `Unsafe.AsPointer` so that we can benefit from byref parameters without suffering overhead of pinning. Co-authored-by: Raul Santos <raulsntos@gmail.com>
65 lines
2.6 KiB
C#
65 lines
2.6 KiB
C#
using Microsoft.CodeAnalysis;
|
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
|
|
|
namespace Godot.SourceGenerators.Internal;
|
|
|
|
internal static class Common
|
|
{
|
|
public static void ReportNonPartialUnmanagedCallbacksClass(
|
|
GeneratorExecutionContext context,
|
|
ClassDeclarationSyntax cds, INamedTypeSymbol symbol
|
|
)
|
|
{
|
|
string message =
|
|
"Missing partial modifier on declaration of type '" +
|
|
$"{symbol.FullQualifiedName()}' which has attribute '{GeneratorClasses.GenerateUnmanagedCallbacksAttr}'";
|
|
|
|
string description = $"{message}. Classes with attribute '{GeneratorClasses.GenerateUnmanagedCallbacksAttr}' " +
|
|
"must be declared with the partial modifier.";
|
|
|
|
context.ReportDiagnostic(Diagnostic.Create(
|
|
new DiagnosticDescriptor(id: "GODOT-INTERNAL-G0001",
|
|
title: message,
|
|
messageFormat: message,
|
|
category: "Usage",
|
|
DiagnosticSeverity.Error,
|
|
isEnabledByDefault: true,
|
|
description),
|
|
cds.GetLocation(),
|
|
cds.SyntaxTree.FilePath));
|
|
}
|
|
|
|
public static void ReportNonPartialUnmanagedCallbacksOuterClass(
|
|
GeneratorExecutionContext context,
|
|
TypeDeclarationSyntax outerTypeDeclSyntax
|
|
)
|
|
{
|
|
var outerSymbol = context.Compilation
|
|
.GetSemanticModel(outerTypeDeclSyntax.SyntaxTree)
|
|
.GetDeclaredSymbol(outerTypeDeclSyntax);
|
|
|
|
string fullQualifiedName = outerSymbol is INamedTypeSymbol namedTypeSymbol ?
|
|
namedTypeSymbol.FullQualifiedName() :
|
|
"type not found";
|
|
|
|
string message =
|
|
$"Missing partial modifier on declaration of type '{fullQualifiedName}', " +
|
|
$"which contains one or more subclasses with attribute " +
|
|
$"'{GeneratorClasses.GenerateUnmanagedCallbacksAttr}'";
|
|
|
|
string description = $"{message}. Classes with attribute " +
|
|
$"'{GeneratorClasses.GenerateUnmanagedCallbacksAttr}' and their " +
|
|
"containing types must be declared with the partial modifier.";
|
|
|
|
context.ReportDiagnostic(Diagnostic.Create(
|
|
new DiagnosticDescriptor(id: "GODOT-INTERNAL-G0002",
|
|
title: message,
|
|
messageFormat: message,
|
|
category: "Usage",
|
|
DiagnosticSeverity.Error,
|
|
isEnabledByDefault: true,
|
|
description),
|
|
outerTypeDeclSyntax.GetLocation(),
|
|
outerTypeDeclSyntax.SyntaxTree.FilePath));
|
|
}
|
|
}
|