@@ -151,4 +151,61 @@ private FunctionPointerParameterSyntax TranslateDelegateToFunctionPointer(TypeHa
151151
152152 return FunctionPointerParameter ( parameterTypeInfo . ToTypeSyntax ( this . functionPointerTypeSettings , GeneratingElement . FunctionPointer , customAttributeHandles ? . QualifyWith ( this ) ) . GetUnmarshaledType ( ) ) ;
153153 }
154+
155+ // Generates an unsafe readonly struct that wraps the native function pointer for a delegate type definition.
156+ // Structure:
157+ // unsafe readonly struct <Name> { public readonly delegate* unmanaged<...> Value; public <Name>(delegate* unmanaged<...> value) => Value = value; public bool IsNull => Value is null; implicit conversions }
158+ private StructDeclarationSyntax DeclareTypeDefStructForNativeFunctionPointer ( TypeDefinition typeDef , Context context )
159+ {
160+ // Delegates are generally managed types, except when using source generators when they never are.
161+ bool isManagedType = ! this . UseSourceGenerators ;
162+ string name = this . GetMangledIdentifier ( this . Reader . GetString ( typeDef . Name ) , context . AllowMarshaling , isManagedType ) ;
163+
164+ FunctionPointerTypeSyntax fpType = this . FunctionPointer ( typeDef ) ;
165+
166+ // public readonly delegate* unmanaged<...> Value;
167+ FieldDeclarationSyntax valueField = FieldDeclaration (
168+ VariableDeclaration ( fpType . WithTrailingTrivia ( TriviaList ( Space ) ) )
169+ . AddVariables ( VariableDeclarator ( Identifier ( "Value" ) ) ) )
170+ . AddModifiers ( TokenWithSpace ( SyntaxKind . PublicKeyword ) , TokenWithSpace ( SyntaxKind . ReadOnlyKeyword ) ) ;
171+
172+ // public <Name>(delegate* unmanaged<...> value) => Value = value;
173+ ConstructorDeclarationSyntax ctor = ConstructorDeclaration ( Identifier ( name ) )
174+ . AddModifiers ( TokenWithSpace ( SyntaxKind . PublicKeyword ) )
175+ . AddParameterListParameters ( Parameter ( Identifier ( "value" ) ) . WithType ( fpType ) )
176+ . WithExpressionBody ( ArrowExpressionClause ( AssignmentExpression ( SyntaxKind . SimpleAssignmentExpression , IdentifierName ( "Value" ) , IdentifierName ( "value" ) ) ) )
177+ . WithSemicolonToken ( SemicolonWithLineFeed ) ;
178+
179+ // public static <Name> Null => default;
180+ PropertyDeclarationSyntax nullProperty = PropertyDeclaration ( IdentifierName ( name ) . WithTrailingTrivia ( Space ) , Identifier ( "Null" ) )
181+ . AddModifiers ( TokenWithSpace ( SyntaxKind . PublicKeyword ) , TokenWithSpace ( SyntaxKind . StaticKeyword ) )
182+ . WithExpressionBody ( ArrowExpressionClause ( LiteralExpression ( SyntaxKind . DefaultLiteralExpression ) ) )
183+ . WithSemicolonToken ( SemicolonWithLineFeed ) ;
184+
185+ // public bool IsNull => Value is null;
186+ PropertyDeclarationSyntax isNullProperty = PropertyDeclaration ( PredefinedType ( TokenWithSpace ( SyntaxKind . BoolKeyword ) ) , Identifier ( "IsNull" ) )
187+ . AddModifiers ( TokenWithSpace ( SyntaxKind . PublicKeyword ) )
188+ . WithExpressionBody ( ArrowExpressionClause ( IsPatternExpression ( IdentifierName ( "Value" ) , ConstantPattern ( LiteralExpression ( SyntaxKind . NullLiteralExpression ) ) ) ) )
189+ . WithSemicolonToken ( SemicolonWithLineFeed ) ;
190+
191+ // public static implicit operator <Name>(delegate* unmanaged<...> value) => new(value);
192+ ConversionOperatorDeclarationSyntax implicitFromPointer = ConversionOperatorDeclaration ( Token ( SyntaxKind . ImplicitKeyword ) , IdentifierName ( name ) )
193+ . AddModifiers ( TokenWithSpace ( SyntaxKind . PublicKeyword ) , TokenWithSpace ( SyntaxKind . StaticKeyword ) )
194+ . AddParameterListParameters ( Parameter ( Identifier ( "value" ) ) . WithType ( fpType ) )
195+ . WithExpressionBody ( ArrowExpressionClause ( ObjectCreationExpression ( IdentifierName ( name ) ) . AddArgumentListArguments ( Argument ( IdentifierName ( "value" ) ) ) ) )
196+ . WithSemicolonToken ( SemicolonWithLineFeed ) ;
197+
198+ // public static implicit operator delegate* unmanaged<...>(<Name> value) => value.Value;
199+ ConversionOperatorDeclarationSyntax implicitToPointer = ConversionOperatorDeclaration ( Token ( SyntaxKind . ImplicitKeyword ) , fpType )
200+ . AddModifiers ( TokenWithSpace ( SyntaxKind . PublicKeyword ) , TokenWithSpace ( SyntaxKind . StaticKeyword ) )
201+ . AddParameterListParameters ( Parameter ( Identifier ( "value" ) ) . WithType ( IdentifierName ( name ) . WithTrailingTrivia ( Space ) ) )
202+ . WithExpressionBody ( ArrowExpressionClause ( MemberAccessExpression ( SyntaxKind . SimpleMemberAccessExpression , IdentifierName ( "value" ) , IdentifierName ( "Value" ) ) ) )
203+ . WithSemicolonToken ( SemicolonWithLineFeed ) ;
204+
205+ StructDeclarationSyntax result = StructDeclaration ( Identifier ( name ) )
206+ . AddModifiers ( TokenWithSpace ( this . Visibility ) , TokenWithSpace ( SyntaxKind . UnsafeKeyword ) , TokenWithSpace ( SyntaxKind . ReadOnlyKeyword ) )
207+ . AddMembers ( valueField , ctor , nullProperty , isNullProperty , implicitFromPointer , implicitToPointer ) ;
208+
209+ return result ;
210+ }
154211}
0 commit comments