Skip to content
Open
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
27 changes: 27 additions & 0 deletions Source/ExcelDna.Integration/ExcelDna.Integration.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,14 @@
<Reference Include="Microsoft.VisualBasic" />
</ItemGroup>

<ItemGroup>
<None Include="Registration\ExtendedFunc.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>ExtendedFunc.tt</DependentUpon>
</None>
</ItemGroup>

<ItemGroup>
<PackageReference Include="ExcelDna.Interop" Version="15.0.1" />
</ItemGroup>
Expand All @@ -48,4 +56,23 @@
</PackageReference>
</ItemGroup>

<ItemGroup>
<None Update="Registration\ExtendedFunc.tt">
<Generator>TextTemplatingFileGenerator</Generator>
<LastGenOutput>ExtendedFunc.cs</LastGenOutput>
</None>
</ItemGroup>

<ItemGroup>
<Service Include="{508349b6-6b84-4df5-91f0-309beebad82d}" />
</ItemGroup>

<ItemGroup>
<Compile Update="Registration\ExtendedFunc.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>ExtendedFunc.tt</DependentUpon>
</Compile>
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,12 @@ public ExcelFunctionRegistration(MethodInfo methodInfo)
var paramExprs = methodInfo.GetParameters()
.Select(pi => Expression.Parameter(pi.ParameterType, pi.Name))
.ToList();
FunctionLambda = Expression.Lambda(Expression.Call(methodInfo, paramExprs), methodInfo.Name, paramExprs);
FunctionLambda =
#if !AOT_COMPATIBLE
(paramExprs.Count > 16) ?
Expression.Lambda(GetExtendedDelegateType(methodInfo), Expression.Call(methodInfo, paramExprs), methodInfo.Name, paramExprs) :
#endif
Expression.Lambda(Expression.Call(methodInfo, paramExprs), methodInfo.Name, paramExprs);

var allMethodAttributes = methodInfo.GetCustomAttributes(true);
foreach (var att in allMethodAttributes)
Expand Down Expand Up @@ -147,5 +152,29 @@ public ExcelFunctionRegistration(MethodInfo methodInfo)
// Check that we haven't made a mistake
Debug.Assert(IsValid());
}

#if !AOT_COMPATIBLE
private static Type GetExtendedDelegateType(MethodInfo methodInfo)
{
if (methodInfo.ReturnType != typeof(void))
{
Type genericBase = ExtendedFuncUtil.GetFuncType(methodInfo.GetParameters().Length);
var args = methodInfo.GetParameters().Select(p => p.ParameterType)
.Concat(new[] { methodInfo.ReturnType })
.ToArray();
return genericBase.MakeGenericType(args);
}
else
{
Type genericBase = ExtendedFuncUtil.GetActionType(methodInfo.GetParameters().Length);
if (!genericBase.IsGenericType)
return genericBase;

var args = methodInfo.GetParameters().Select(p => p.ParameterType)
.ToArray();
return genericBase.MakeGenericType(args);
}
}
#endif
}
}
2,078 changes: 2,078 additions & 0 deletions Source/ExcelDna.Integration/Registration/ExtendedFunc.cs

Large diffs are not rendered by default.

57 changes: 57 additions & 0 deletions Source/ExcelDna.Integration/Registration/ExtendedFunc.tt
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ output extension=".cs" #>
<# int maxArguments = 255; #>
#if !AOT_COMPATIBLE

using System;

namespace ExcelDna.Registration
{
internal class ExtendedFuncUtil
{
public static Type GetFuncType(int i)
{
switch(i)
{
<# for (int i = 0; i <= maxArguments; ++i) {#>
case <# Write(i.ToString());#>:
return typeof(ExtendedFunc<# Write(i.ToString());#><<# Write(new string(',', i));#>>);
<# } #>
default:
throw new NotImplementedException($"GetFuncType({i})");
}
}

public static Type GetActionType(int i)
{
switch(i)
{
<# for (int i = 0; i <= maxArguments; ++i) {#>
case <# Write(i.ToString());#>:
return typeof(ExtendedAction<# Write(i.ToString());#><# Write((i > 0 ? "<" + new string(',', i-1) + ">":""));#>);
<# } #>
default:
throw new NotImplementedException($"GetActionType({i})");
}
}
}

<# for (int i = 0; i <= maxArguments; ++i) {#>
<# string types=""; #>
<# string args=""; #>
<# for (int k = 1; k <= i; ++k) {#>
<# types +=$"T{k}{(k != i ? "," : "")}"; #>
<# args += $"T{k} arg{k}{(k !=i ?"," : "")}"; #>
<# } #>
internal delegate TResult ExtendedFunc<# Write(i.ToString());#><<# Write(types + (i > 0 ? "," : ""));#>TResult>
(<# Write(args);#>);
internal delegate void ExtendedAction<# Write(i.ToString());#><# Write((i > 0 ? "<" : "") + types + (i > 0 ? ">" : ""));#>
(<# Write(args);#>);
<# } #>
}

#endif
14 changes: 14 additions & 0 deletions Source/Tests/ExcelDna.AddIn.RuntimeTests/MyFunctions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,20 @@ public static string MyParamsJoinString(string separator, params string[] values
return String.Join(separator, values);
}

[ExcelFunction]
public static string MyEnum16(int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9, int i10, int i11, int i12, int i13, int i14, int i15, TestEnum e)
{
int sum = i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9 + i10 + i11 + i12 + i13 + i14 + i15;
return $"{e} {sum}";
}

[ExcelFunction]
public static string MyEnum17(int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9, int i10, int i11, int i12, int i13, int i14, int i15, int i16, TestEnum e)
{
int sum = i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9 + i10 + i11 + i12 + i13 + i14 + i15 + i16;
return $"{e} {sum}";
}

[ExcelFunction]
public static string MyWindowHandle()
{
Expand Down
11 changes: 11 additions & 0 deletions Source/Tests/ExcelDna.AddIn.RuntimeTests/TestEnum.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace ExcelDna.AddIn.RuntimeTests
{
public enum TestEnum
{
Value1,
Value2,
Value3,
Value16,
Value17,
}
}
15 changes: 15 additions & 0 deletions Source/Tests/ExcelDna.RuntimeTests/Registration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -650,5 +650,20 @@ public void DynamicFunctions()
Assert.Equal("Dynamic Optional VAL: 0", functionRange.Value.ToString());
}
}

[ExcelFact(Workbook = "", AddIn = AddInPath.RuntimeTests)]
public void CollectableEnum()
{
{
Range functionRange = ((Worksheet)ExcelDna.Testing.Util.Workbook.Sheets[1]).Range["B1"];
functionRange.Formula = "=MyEnum16(1,0,0,0,0,0,0,0,0,10,0,0,0,0,15,\"Value16\")";
Assert.Equal("Value16 26", functionRange.Value.ToString());
}
{
Range functionRange = ((Worksheet)ExcelDna.Testing.Util.Workbook.Sheets[1]).Range["C1"];
functionRange.Formula = "=MyEnum17(1,0,0,0,0,0,0,0,0,10,0,0,0,0,0,16,\"Value17\")";
Assert.Equal("Value17 27", functionRange.Value.ToString());
}
}
}
}