// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ output extension=".Generated.cs" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<# const int maxArgCount = 16; #>
using System;
using System.Reflection;
using System.Diagnostics.CodeAnalysis;
namespace Microsoft.ClearScript
{
internal static partial class DelegateFactory
{
private const int maxArgCount = <#= maxArgCount #>;
<#
for (var count = 0; count <= maxArgCount; count++)
{
var typeParamList = (count == 0) ? "" : "<" + string.Join(", ", Enumerable.Range(1, count).Select(index => "T" + index)) + ", TDelegate>";
var allByValueExpr = (count == 0) ? "true" : "GetAllByValue(" + string.Join(", ", Enumerable.Range(1, count).Select(index => "typeof(T" + index + ")")) + ")";
var methodParamList = string.Join(", ", Enumerable.Range(1, count).Select(index => "T" + index + " a" + index));
var argList = string.Join(", ", Enumerable.Range(1, count).Select(index => "a" + index));
var varDeclList = string.Join("\r\n ", Enumerable.Range(1, count).Select(index => "var v" + index + " = GetArgValue(a" + index + ");"));
var byRefArgList = string.Join(", ", Enumerable.Range(1, count).Select(index => "ref v" + index));
var varAssignList = string.Join("\r\n ", Enumerable.Range(1, count).Select(index => "SetArgValue(a" + index + ", v" + index + ");"));
#>
[ExcludeFromCodeCoverage]
private class ProcShim<#= typeParamList #> : ProcShim
{
private static readonly MethodInfo method = typeof(ProcShim<#= typeParamList #>).GetMethod("InvokeTarget");
private static readonly bool allByValue = <#= allByValueExpr #>;
private readonly object target;
private readonly Delegate del;
public ProcShim(ScriptEngine engine, object target)
: base(engine)
{
this.target = GetCompatibleTarget(typeof(TDelegate), target);
del = Delegate.CreateDelegate(typeof(TDelegate), this, method);
}
// ReSharper disable UnusedMember.Local
public void InvokeTarget(<#= methodParamList #>)
{
if (allByValue || Engine.EnableAutoHostVariables)
{
Invoke(() => ((dynamic)target)(<#= argList #>));
}
else
{
<#= varDeclList #>
try
{
Invoke(() => ((dynamic)target)(<#= byRefArgList #>));
}
finally
{
<#= varAssignList #>
}
}
}
// ReSharper restore UnusedMember.Local
#region DelegateShim overrides
public override Delegate Delegate
{
get { return del; }
}
#endregion
}
<#
}
#>
<#
for (var count = 0; count <= maxArgCount; count++)
{
var typeParamList = (count == 0) ? "" : "<" + string.Join(", ", Enumerable.Range(1, count).Select(index => "T" + index)) + ", TResult, TDelegate>";
var allByValueExpr = (count == 0) ? "true" : "GetAllByValue(" + string.Join(", ", Enumerable.Range(1, count).Select(index => "typeof(T" + index + ")")) + ")";
var methodParamList = string.Join(", ", Enumerable.Range(1, count).Select(index => "T" + index + " a" + index));
var argList = string.Join(", ", Enumerable.Range(1, count).Select(index => "a" + index));
var varDeclList = string.Join("\r\n ", Enumerable.Range(1, count).Select(index => "var v" + index + " = GetArgValue(a" + index + ");"));
var byRefArgList = string.Join(", ", Enumerable.Range(1, count).Select(index => "ref v" + index));
var varAssignList = string.Join("\r\n ", Enumerable.Range(1, count).Select(index => "SetArgValue(a" + index + ", v" + index + ");"));
#>
[ExcludeFromCodeCoverage]
private class FuncShim<#= typeParamList #> : FuncShim
{
private static readonly MethodInfo method = typeof(FuncShim<#= typeParamList #>).GetMethod("InvokeTarget");
private static readonly bool allByValue = <#= allByValueExpr #>;
private readonly object target;
private readonly Delegate del;
public FuncShim(ScriptEngine engine, object target)
: base(engine)
{
this.target = GetCompatibleTarget(typeof(TDelegate), target);
del = Delegate.CreateDelegate(typeof(TDelegate), this, method);
}
// ReSharper disable UnusedMember.Local
public TResult InvokeTarget(<#= methodParamList #>)
{
if (allByValue || Engine.EnableAutoHostVariables)
{
return Invoke(() => (TResult)((dynamic)target)(<#= argList #>));
}
<#= varDeclList #>
try
{
return Invoke(() => (TResult)((dynamic)target)(<#= byRefArgList #>));
}
finally
{
<#= varAssignList #>
}
}
// ReSharper restore UnusedMember.Local
#region DelegateShim overrides
public override Delegate Delegate
{
get { return del; }
}
#endregion
}
<#
}
#>
private static readonly Type[] procTemplates =
{
<#
for (var count = 0; count <= maxArgCount; count++)
{
var typeArgList = (count == 0) ? "" : "<" + string.Join(", ", Enumerable.Range(1, count).Select(index => "/*T" + index + "*/")) + ">";
#>
typeof(Action<#= typeArgList #>),
<#
}
#>
};
private static readonly Type[] funcTemplates =
{
<#
for (var count = 0; count <= maxArgCount; count++)
{
var typeArgList = (count == 0) ? "*TResult*/>" : "<" + string.Join(", ", Enumerable.Range(1, count).Select(index => "/*T" + index + "*/")) + ", /*TResult*/>";
#>
typeof(Func<#= typeArgList #>),
<#
}
#>
};
private static readonly Type[] procShimTemplates =
{
<#
for (var count = 0; count <= maxArgCount; count++)
{
var typeArgList = (count == 0) ? "*TDelegate*/>" : "<" + string.Join(", ", Enumerable.Range(1, count).Select(index => "/*T" + index + "*/")) + ", /*TDelegate*/>";
#>
typeof(ProcShim<#= typeArgList #>),
<#
}
#>
};
private static readonly Type[] funcShimTemplates =
{
<#
for (var count = 0; count <= maxArgCount; count++)
{
var typeArgList = (count == 0) ? "*TResult*/, /*TDelegate*/>" : "<" + string.Join(", ", Enumerable.Range(1, count).Select(index => "/*T" + index + "*/")) + ", /*TResult*/, /*TDelegate*/>";
#>
typeof(FuncShim<#= typeArgList #>),
<#
}
#>
};
}
}