Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 12 additions & 5 deletions TypeShim.Generator/CSharp/CSharpTypeConversionRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,9 @@ private void RenderInlineTypeDownConversion(InteropTypeInfo typeInfo, string acc
{
RenderInlineObjectTypeDownConversion(typeInfo, accessorExpressionRenderer);
}
else if (typeInfo.IsDelegateType() && typeInfo.ArgumentInfo is DelegateArgumentInfo argumentInfo) // Action/Action<T1...Tn>/Func<T1...Tn>
else if (typeInfo.IsDelegateType()) // Action/Action<T1...Tn>/Func<T1...Tn>
{
RenderInlineDelegateTypeDownConversion(argumentInfo, accessorName, accessorExpressionRenderer);
RenderInlineDelegateTypeDownConversion(typeInfo, accessorName, accessorExpressionRenderer);
}
else
{
Expand Down Expand Up @@ -226,9 +226,13 @@ private string RenderNullableTaskTypeConversion(InteropTypeInfo targetNullableTa
return $"{tcsVarName}?.Task";
}

private void RenderInlineDelegateTypeDownConversion(DelegateArgumentInfo argumentInfo, string accessorName, DeferredExpressionRenderer accessorExpressionRenderer)
private void RenderInlineDelegateTypeDownConversion(InteropTypeInfo typeInfo, string accessorName, DeferredExpressionRenderer accessorExpressionRenderer)
{
_ctx.Append('(');
DelegateArgumentInfo argumentInfo = typeInfo.ArgumentInfo ?? throw new InvalidOperationException("Delegate type is missing argumentinfo.");
_ctx.Append("MarshallArgumentsTable.GetOrCreate<").Append(typeInfo.CSharpTypeSyntax).Append(">(");
accessorExpressionRenderer.Render();
_ctx.Append(", () => ")
.Append('(');
for (int i = 0; i < argumentInfo.ParameterTypes.Length; i++)
{
if (i > 0) _ctx.Append(", ");
Expand Down Expand Up @@ -257,11 +261,13 @@ private void RenderInlineDelegateTypeDownConversion(DelegateArgumentInfo argumen
{
invocationExpressionRenderer.Render();
}
_ctx.Append(')');
}

private void RenderInlineDelegateTypeUpConversion(InteropTypeInfo typeInfo, string varName, DelegateArgumentInfo argumentInfo)
{
_ctx.Append('(');
_ctx.Append("MarshallArgumentsTable.GetOrCreate<").Append(typeInfo.CSharpInteropTypeSyntax).Append(">(").Append(varName).Append(", () => ")
.Append('(');
for (int i = 0; i < argumentInfo.ParameterTypes.Length; i++)
{
if (i > 0)
Expand Down Expand Up @@ -299,5 +305,6 @@ private void RenderInlineDelegateTypeUpConversion(InteropTypeInfo typeInfo, stri
{
invocationExpressionRenderer.Render();
}
_ctx.Append(')');
}
}
14 changes: 14 additions & 0 deletions TypeShim/MarshallArgumentsTable.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System.Runtime.CompilerServices;

namespace TypeShim;

public static class MarshallArgumentsTable
{
private static readonly ConditionalWeakTable<Type, ConditionalWeakTable<object, object>> _typeTables = new();

public static T GetOrCreate<T>(object target, Func<T> factory) where T : class
{
ConditionalWeakTable<object, object> table = _typeTables.GetValue(typeof(T), _ => new ConditionalWeakTable<object, object>());
return (T)table.GetValue(target, _ => factory()!);
}
}
Loading