/// <inheritdoc/> public IEnumerable <(FunctionSignature, StringBuilder)> CreateOverloads(FunctionSignature function) { if (!IsApplicable(function)) { yield break; } var lastParameterType = function.Parameters.Last().Type; var newReturnType = new TypeSignatureBuilder(lastParameterType) .WithIndirectionLevel(lastParameterType.IndirectionLevel - 1) .WithArrayDimensions(0) .Build(); var newParameters = SkipLastExtension.SkipLast(function.Parameters, 1).ToList(); var newName = function.Name.Singularize(false); var functionBuilder = new FunctionSignatureBuilder(function) .WithName(newName) .WithReturnType(newReturnType); var sb = new StringBuilder(); var strParams = newParameters.Select(x => Utilities.CSharpKeywords.Contains(x.Name) ? "@" + x.Name : x.Name) .Concat(new[] { "ret" }); sb.AppendLine(lastParameterType + " ret = null;"); sb.Append(function.Name + "("); sb.Append(string.Join(", ", strParams)); sb.AppendLine(");"); sb.AppendLine("return *ret;"); if (!newParameters.Any()) { yield return(functionBuilder .WithParameters(newParameters) .Build(), sb); yield break; } // TODO: check if this has anything to do with CLS compliance var sizeParameterType = newParameters.Last().Type; if (!sizeParameterType.Name.StartsWith("int", StringComparison.OrdinalIgnoreCase) || sizeParameterType.IsPointer) { yield return(functionBuilder .WithParameters(newParameters) .Build(), sb); yield break; } newParameters = SkipLastExtension.SkipLast(newParameters, 1).ToList(); yield return ( functionBuilder .WithParameters(newParameters) .Build(), sb ); }
public IEnumerable <ImplementedFunction> CreateOverloads(Function function) { if (function.ReturnType.ToString() == "char*" || function.ReturnType.ToString() == "byte*") { var sb = new StringBuilder(); sb.Append($"return Marshal.PtrToStringAnsi((IntPtr) {function.Name}("); sb.Append(string.Join(", ", function.Parameters.Select(Convert))); sb.AppendLine("));"); var sig = new FunctionSignatureBuilder(function).WithReturnType(new Type { Name = "string" }).WithName(function.Name + "S").Build(); yield return(new ImplementedFunction(sig, sb, true)); } }
public static bool TryGetEarlyVariant(Function function, out Function finalVariant, Project core) { var parameters = new List <Parameter>(); var returnType = function.ReturnType; parameters.AddRange(function.Parameters); var parametersVaried = false; var returnTypeVaried = false; for (var i = 0; i < parameters.Count; i++) { foreach (var earlyOverloader in Pipeline) { parameters[i].Origin = function; if (earlyOverloader.TryCreateVariant(parameters[i], out var variant, core)) { parametersVaried = true; parameters[i] = variant; break; } parameters[i].Origin = null; } } foreach (var earlyOverloader in Pipeline) { if (earlyOverloader.TryCreateVariant(returnType, out var variant, core)) { returnTypeVaried = true; returnType = variant; break; } } if (returnTypeVaried || parametersVaried) { finalVariant = new FunctionSignatureBuilder(function) .WithParameters(parameters) .WithReturnType(returnType) .WithName(returnTypeVaried && !parametersVaried ? function.Name + "S" : function.Name) .Build(); return(true); } finalVariant = null; return(false); }
private IEnumerable <FunctionSignature> MapGenericEnumFunctions ( [NotNull] ApiProfile profile, [NotNull, ItemNotNull] IReadOnlyList <FunctionSignature> genericEnumFunctions ) { var mappedGenericEnumFunctions = new List <FunctionSignature>(); foreach (var functionWithGenericEnum in genericEnumFunctions) { var newParameters = new List <ParameterSignature>(functionWithGenericEnum.Parameters); for (var i = 0; i < newParameters.Count; ++i) { var parameter = newParameters[i]; var parameterType = parameter.Type; if (parameterType.Name != "GLenum") { continue; } var newParameterType = MapGenericEnumerationType(profile, functionWithGenericEnum, parameterType); var newParameter = new ParameterSignatureBuilder(parameter).WithType(newParameterType).Build(); newParameters[i] = newParameter; } var newReturnType = functionWithGenericEnum.ReturnType; if (newReturnType.Name == "GLenum") { newReturnType = MapGenericEnumerationType(profile, functionWithGenericEnum, newReturnType); } var newFunction = new FunctionSignatureBuilder(functionWithGenericEnum) .WithParameters(newParameters) .WithReturnType(newReturnType) .Build(); mappedGenericEnumFunctions.Add(newFunction); Debug.WriteLine ( $"Mapped parameters in \"{functionWithGenericEnum.Name}\" to generic enum types. Consider adding" + " an override to a more specialized enum." ); } return(mappedGenericEnumFunctions); }
private bool TryCreateEnumVariant(Function function, out Function variant, Project core) { var varied = false; var newParameters = new List <Parameter>(); var paramsMod = false; Type newReturnType = function.ReturnType; foreach (var functionParameter in function.Parameters) { if (functionParameter.Type.OriginalGroup is null || core.Enums.All (x => x.Name != functionParameter.Type.OriginalGroup)) { newParameters.Add(functionParameter); continue; } paramsMod = true; varied = true; var t = new TypeSignatureBuilder(functionParameter.Type).WithName (functionParameter.Type.OriginalGroup) .Build(); t.OriginalName = t.Name; // stop GLenum mapping newParameters.Add ( new ParameterSignatureBuilder(functionParameter).WithType ( t ).Build() ); } if (!(function.ReturnType.OriginalGroup is null || core.Enums.All (x => x.Name != function.ReturnType.OriginalGroup))) { varied = true; newReturnType = new TypeSignatureBuilder(function.ReturnType).WithName (function.ReturnType.OriginalGroup) .Build(); newReturnType.OriginalName = newReturnType.Name; } variant = new FunctionSignatureBuilder(function).WithParameters(newParameters) .WithName(paramsMod ? function.Name : function.Name + "G") .WithReturnType(newReturnType) .Build(); return(varied); }
/// <inheritdoc/> public IEnumerable <FunctionSignature> CreateOverloads(FunctionSignature function) { var lastParameterType = function.Parameters.Last().Type; var newReturnType = new TypeSignatureBuilder(lastParameterType) .WithIndirectionLevel(lastParameterType.IndirectionLevel - 1) .WithArrayDimensions(0) .Build(); var newParameters = SkipLastExtension.SkipLast(function.Parameters, 1).ToList(); var newName = function.Name.Singularize(false); var functionBuilder = new FunctionSignatureBuilder(function) .WithName(newName) .WithReturnType(newReturnType); if (!newParameters.Any()) { yield return(functionBuilder .WithParameters(newParameters) .Build()); yield break; } // TODO: check if this has anything to do with CLS compliance var sizeParameterType = newParameters.Last().Type; if (!sizeParameterType.Name.StartsWith("int", StringComparison.OrdinalIgnoreCase) || sizeParameterType.IsPointer) { yield return(functionBuilder .WithParameters(newParameters) .Build()); yield break; } newParameters = SkipLastExtension.SkipLast(newParameters, 1).ToList(); yield return(functionBuilder .WithParameters(newParameters) .Build()); }
/// <summary> /// Returns an enumerable containing the original function signature, as well as all overload variants /// generated by the overloaders. /// </summary> /// <param name="original">The original function signature.</param> /// <param name="core">The core project for this profile. May be used by some overloads.</param> /// <param name="overloaders">The overloaders to use in getting function overloads.</param> /// <returns>An enumerable containing the original function signature and all overloads.</returns> public static IEnumerable <Function> GetWithOverloads(Function original, Project core, params ISimpleReturnOverloader[] overloaders) { yield return(original); foreach (var overloader in overloaders) { if (overloader.TryGetReturnTypeVariant(original.ReturnType, out var varied, core)) { var ret = new FunctionSignatureBuilder(original) .WithName(original.Name + ReturnOverloadSuffix) .WithReturnType(varied) .Build(); ret.Kind = SignatureKind.ReturnOverload; yield return(ret); break; // only overload the return type once } } }
public IEnumerable <Overload> CreateOverloads(Function function) { if (!function.Parameters.Any(x => x.Type.IsPointer && !x.Type.IsVoidPointer())) { yield break; } var sb = new StringBuilder(); var parameters = new List <string>(); var ind = string.Empty; var sig = new FunctionSignatureBuilder(function); var newParameters = new Parameter[function.Parameters.Count]; sb.AppendLine("// FlowPointerOverloader"); for (var i = 0; i < function.Parameters.Count; i++) { var param = function.Parameters[i]; if (param.Type.IsPointer && !param.Type.IsVoidPointer()) { var newParameterType = new TypeSignatureBuilder(param.Type) .WithIndirectionLevel(param.Type.IndirectionLevels - 1); switch (param.Flow) { case FlowDirection.Undefined: newParameterType = newParameterType.WithByRef(true); break; case FlowDirection.In: newParameterType = newParameterType.WithIsIn(true); break; case FlowDirection.Out: newParameterType = newParameterType.WithIsOut(true); break; default: throw new ArgumentOutOfRangeException(); } var newParameter = new ParameterSignatureBuilder(param).WithType(newParameterType.Build()); var ptrName = (param.Name + "Ptr").Replace("@", ""); parameters.Add(ptrName); sb.AppendLine(ind + $"fixed ({param.Type} {ptrName} = &{param.Name})"); sb.AppendLine(ind + "{"); ind += " "; newParameters[i] = newParameter.Build(); } else { parameters.Add((Utilities.CSharpKeywords.Contains(param.Name) ? "@" : string.Empty) + param.Name); newParameters[i] = param; } } sb.Append(ind); if (function.ReturnType.ToString() != "void") { sb.Append("return "); } sb.AppendLine(function.Name + "(" + string.Join(", ", parameters) + ");"); while (!string.IsNullOrEmpty(ind)) { ind = ind.Remove(ind.Length - 4, 4); sb.AppendLine(ind + "}"); } yield return(new Overload(sig.WithParameters(newParameters).Build(), sb, true)); }
public static void Implement(StringBuilder sb, Function function, Struct parent, int index, bool retDeref = false) { if (function.Attributes.IsBuildToolsIntrinsic(out var args) && args[0] == "$CPPRETFIXUP") { sb.AppendLine($"{function.ReturnType} silkDotNetReturnFixupResult;"); sb.AppendLine("var pSilkDotNetReturnFixupResult = &silkDotNetReturnFixupResult;"); var indIncremented = new TypeSignatureBuilder(function.ReturnType) .WithIndirectionLevel(function.ReturnType.IndirectionLevels + 1) .Build(); var fixedUpFunction = new FunctionSignatureBuilder(function) .WithReturnType(indIncremented) .WithAttributes(Array.Empty <Attribute>()) .WithParameters ( function.Parameters.Prepend ( new Parameter { Name = "pSilkDotNetReturnFixupResult", Type = indIncremented } ).ToArray() ).Build(); Implement(sb, fixedUpFunction, parent, index, true); function.Attributes.RemoveAll(x => x.Name == "BuildToolsIntrinsic"); return; } var ind = ""; sb.AppendLine($"var @this = ({parent.Name}*) Unsafe.AsPointer(ref Unsafe.AsRef(in this));"); var epilogue = new List <Action>(); var parameterInvocations = new List <(Type Type, string Parameter)> { (new Type { Name = parent.Name, IndirectionLevels = 1 }, "@this") }; if (function.ReturnType.ToString() != "void") { sb.AppendLine($"{function.ReturnType} ret = default;"); } for (var i = 0; i < function.Parameters.Count; i++) { var parameter = function.Parameters[i]; if (parameter.Type.Name == "string") { // assume ansi if (parameter.Type.IsIn) { sb.AppendLine ($"var {parameter.Name}PtrInit = (byte*) Marshal.StringToHGlobalAnsi({parameter.Name});"); sb.AppendLine($"var {parameter.Name}Ptr = &{parameter.Name}PtrInit;"); parameterInvocations.Add ((new Type { Name = "byte", IndirectionLevels = 2 }, $"{parameter.Name}Ptr")); epilogue.Add(() => sb.AppendLine($"Marshal.FreeHGlobal((nint){parameter.Name}PtrInit);")); } else if (parameter.Type.IsByRef) { sb.AppendLine ($"var {parameter.Name}PtrInit = (byte*) Marshal.StringToHGlobalAnsi({parameter.Name});"); sb.AppendLine($"var {parameter.Name}Ptr = &{parameter.Name}PtrInit;"); parameterInvocations.Add ((new Type { Name = "byte", IndirectionLevels = 2 }, $"{parameter.Name}Ptr")); epilogue.Add ( () => { sb.AppendLine($"{parameter.Name} = Marshal.PtrToStringAnsi(*{parameter.Name}Ptr);"); sb.AppendLine($"Marshal.FreeHGlobal((nint){parameter.Name}PtrInit);"); } ); } else if (parameter.Type.IsOut) { throw new NotSupportedException ( "COM VTables don't support out strings due to lack of flow and count information." ); } else { sb.AppendLine ($"var {parameter.Name}Ptr = (byte*) Marshal.StringToHGlobalAnsi({parameter.Name});"); parameterInvocations.Add ((new Type { Name = "byte", IndirectionLevels = 1 }, $"{parameter.Name}Ptr")); epilogue.Add ( () => { sb.AppendLine($"Marshal.FreeHGlobal((nint){parameter.Name}Ptr);"); } ); } } else if (parameter.Type.IsIn || parameter.Type.IsOut || parameter.Type.IsByRef) { var noRef = new TypeSignatureBuilder(parameter.Type) .WithByRef(false) .WithIsIn(false) .WithIsOut(false) .WithIndirectionLevel(parameter.Type.IndirectionLevels + 1) .Build(); sb.AppendLine ( ind + $"fixed ({noRef} {parameter.Name}Ptr = &{parameter.Name})" ); sb.AppendLine(ind + "{"); parameterInvocations.Add((noRef, $"{parameter.Name}Ptr")); ind += " "; epilogue.Add ( () => { ind = ind.Substring(0, ind.Length - 4); sb.AppendLine(ind + "}"); } ); } else { parameterInvocations.Add((parameter.Type, parameter.Name)); } } if (function.ReturnType.ToString() != "void") { sb.Append(ind + "ret = "); } else { sb.Append(ind); } var conv = function.Convention switch { CallingConvention.Winapi => throw new NotImplementedException(), CallingConvention.Cdecl => "Cdecl", CallingConvention.StdCall => "Stdcall", CallingConvention.ThisCall => "Thiscall", CallingConvention.FastCall => "Fastcall", _ => "Cdecl" }; var fnPtrSig = string.Join(", ", parameterInvocations.Select(x => x.Type.ToString())); if (!string.IsNullOrWhiteSpace(fnPtrSig)) { fnPtrSig += ", "; } fnPtrSig += function.ReturnType; sb.Append($"((delegate* unmanaged[{conv}]<{fnPtrSig}>)"); sb.Append($"LpVtbl[{index}])"); sb.AppendLine("(" + string.Join(", ", parameterInvocations.Select(x => x.Parameter)) + ");"); for (var i = epilogue.Count - 1; i >= 0; i--) { epilogue[i](); } if (retDeref) { sb.AppendLine("return *ret;"); } else if (function.ReturnType.ToString() != "void") { sb.AppendLine("return ret;"); } } }
/// <inheritdoc/> public IEnumerable <ImplementedFunction> CreateOverloads(Function function) { if (!IsApplicable(function)) { yield break; } var lastParameterType = function.Parameters.Last().Type; var newReturnType = new TypeSignatureBuilder(lastParameterType) .WithIndirectionLevel(lastParameterType.IndirectionLevels - 1) .WithArrayDimensions(0) .Build(); var newParameters = SkipLastExtension.SkipLast(function.Parameters, 1).ToList(); var newName = function.Name.Singularize(false); var functionBuilder = new FunctionSignatureBuilder(function) .WithName(newName) .WithReturnType(newReturnType); var sb = new StringBuilder(); var strParams = newParameters.Select(Convert).Concat(new[] { "&ret" }); sb.AppendLine("// ReturnTypeOverloader"); sb.AppendLine($"{newReturnType} ret = default;"); sb.Append($"{function.Name}("); sb.Append(string.Join(", ", strParams)); sb.AppendLine(");"); sb.AppendLine("return ret;"); if (!newParameters.Any()) { yield return(new ImplementedFunction(functionBuilder .WithParameters(newParameters) .Build(), sb, true)); yield break; } var sizeParameterType = newParameters.Last().Type; if ((sizeParameterType.Name != "int" && sizeParameterType.Name != "uint") || sizeParameterType.IsPointer) { yield return(new ImplementedFunction(functionBuilder .WithParameters(newParameters) .Build(), sb, true)); yield break; } var n = newParameters.Last().Name; sb.Insert(0, $"const {(sizeParameterType.Name == "uint" ? "uint " : "int ")}{(Utilities.CSharpKeywords.Contains(n) ? "@" : "")}{n} = 1;\n" ); newParameters = SkipLastExtension.SkipLast(newParameters, 1).ToList(); yield return(new ImplementedFunction ( functionBuilder .WithParameters(newParameters) .Build(), sb, true )); string Convert(Parameter x) { var pre = x.Type.IsOut ? "out " : string.Empty; return(pre + (Utilities.CSharpKeywords.Contains(x.Name) ? $"@{x.Name}" : x.Name)); } }
public bool TryCreateVariant(Function function, out Function variant, Project core) { var varied = false; var parameters = new List <Parameter>(); parameters.AddRange(function.Parameters); var genericParams = new List <GenericTypeParameter>(); for (var i = 0; i < parameters.Count; i++) { var param = parameters[i]; var typeName = param.Type.Name == "void" ? $"T{genericParams.Count}" : param.Type.Name; if (param.Type.Name == "void") { genericParams.Add ( new GenericTypeParameter { Name = $"T{genericParams.Count}", Constraints = new List <string> { "unmanaged" } } ); } if (param.Type.IndirectionLevels == 1 && (param.Count?.IsMultiple ?? true)) { varied = true; parameters[i] = new ParameterSignatureBuilder(param).WithType ( new Type { GenericTypes = new List <Type> { new TypeSignatureBuilder(param.Type).WithName(typeName).WithIndirectionLevel(0).Build() }, Name = "Span" } ) .Build(); continue; } if (param.Type.IsPointer && !(param.Count?.IsMultiple ?? true)) { varied = true; parameters[i] = new ParameterSignatureBuilder(param).WithType ( new TypeSignatureBuilder(param.Type) .WithIndirectionLevel(param.Type.IndirectionLevels - 1) .WithName(typeName) .WithByRef(param.Flow != FlowDirection.Out) .WithIsOut(param.Flow == FlowDirection.Out) .Build() ) .Build(); } } if (varied) { variant = new FunctionSignatureBuilder(function).WithParameters (parameters) .WithGenericTypeParameters(genericParams) .Build(); return(true); } variant = null; return(false); }
public IEnumerable <ImplementedFunction> CreateOverloads(Function function) { var returnTypeChanged = false; var parameterChanged = false; var sb = new StringBuilder(); sb.AppendLine("// SpanOverloader"); var parameters = function.Parameters.ToList(); var fun = new FunctionSignatureBuilder(function); // TODO we need a length for span returns, so I've disabled them for now //if (function.ReturnType.IndirectionLevels == 1 && function.ReturnType.Name != "void") //{ // fun.WithReturnType // ( // new Type // { // Name = "Span", OriginalName = "Span", // GenericTypes = new List<Type> {new Type {Name = function.ReturnType.Name}} // } // ); // returnTypeChanged = true; //} var ind = string.Empty; for (var i = 0; i < function.Parameters.Count; i++) { var param = function.Parameters[i]; if (param.Type.IndirectionLevels == 1 && param.Type.Name != "void" && !param.Type.IsOut && !param.Type.IsIn && !param.Type.IsByRef) { parameterChanged = true; parameters[i] = new ParameterSignatureBuilder(param).WithName($"{param.Name}Span") .WithType ( new Type { Name = "Span", OriginalName = "Span", GenericTypes = new List <Type> { new Type { Name = param.Type.Name, OriginalName = param.Type.OriginalName } } } ) .Build(); sb.AppendLine($"{ind}fixed ({param.Type} {param.Name} = {param.Name}Span)"); sb.AppendLine($"{ind}{{"); ind += " "; } else { parameters[i] = param; } } if (returnTypeChanged) { sb.Append($"{ind}return (Span<{function.ReturnType.Name}>) "); } else if (function.ReturnType.ToString() != "void") { sb.Append($"{ind}return "); } else { sb.Append(ind); } sb.Append($"{function.Name}("); sb.Append(string.Join(", ", function.Parameters.Select(x => GetPrefix(x.Type) + Format(x.Name)))); sb.AppendLine(");"); while (!string.IsNullOrEmpty(ind)) { ind = ind.Remove(ind.Length - 4, 4); sb.AppendLine($"{ind}}}"); } fun.WithParameters(parameters); if (returnTypeChanged && !parameterChanged) { yield return(new ImplementedFunction(fun.WithName($"{function.Name}AsSpan").Build(), sb, true)); } else if (parameterChanged) { yield return(new ImplementedFunction(fun.Build(), sb, true)); } string GetPrefix(Type t) { return(t.IsOut ? "out " : t.IsByRef ? "ref " : string.Empty); } string Format(string n) { if (Utilities.CSharpKeywords.Contains(n)) { return($"@{n}"); } return(n); } }
/// <summary> /// Returns an enumerable containing the original function signature, as well as all overload variants /// generated by the /// </summary> /// <param name="original">The original function signature.</param> /// <param name="core">The core project for this profile. May be used by some overloads.</param> /// <param name="overloaders">The overloaders to use in getting function overloads.</param> /// <returns>An enumerable containing the original function signature and all overloads.</returns> public static IEnumerable <Function> GetWithOverloads ( Function original, Project core, params ISimpleParameterOverloader[] overloaders ) { if (original.Parameters.Count == 0) { yield return(original); yield break; } var parameters = original.Parameters.Select(x => new List <Parameter> { x }).ToList(); foreach (var parameter in parameters) { foreach (var overloader in overloaders) { if (overloader.TryGetParameterVariant(parameter[0], out var variant, core)) { parameter.Add(variant); } } } foreach (var combination in Combinations(parameters)) { var numGenericTypeParams = 0; var ret = new FunctionSignatureBuilder(original).WithParameters ( combination.Select ( x => !x.Type.IsGenericTypeParameterReference ? x : new ParameterSignatureBuilder(x).WithType ( new TypeSignatureBuilder(x.Type).WithName("T" + numGenericTypeParams++) .Build() ) .Build() ) .ToList() ) .WithGenericTypeParameters ( Enumerable.Range(0, numGenericTypeParams) .Select ( x => new GenericTypeParameter { Name = "T" + x, Constraints = new List <string> { "unmanaged" } } ) .ToList() ) .Build(); ret.Kind = original.Kind == SignatureKind.Normal ? ret.Parameters.SequenceEqual (original.Parameters) ? SignatureKind.Normal : SignatureKind.SimpleOverload : original.Kind; yield return(ret); } }
/// <inheritdoc/> public IEnumerable <Overload> CreateOverloads(Function function) { if (!IsApplicable(function)) { yield break; } var lastParameterType = function.Parameters.Last().Type; var newReturnType = new TypeSignatureBuilder(lastParameterType) .WithIndirectionLevel(lastParameterType.IndirectionLevels - 1) .WithArrayDimensions(0) .Build(); var newParameters = SkipLastExtension.SkipLast(function.Parameters, 1).ToList(); var newName = function.Name.Singularize(false); var functionBuilder = new FunctionSignatureBuilder(function) .WithName(newName) .WithReturnType(newReturnType); var sb = new StringBuilder(); var strParams = newParameters.Select(x => Utilities.CSharpKeywords.Contains(x.Name) ? "@" + x.Name : x.Name) .Concat(new[] { "&ret" }); sb.AppendLine("// ReturnTypeOverloader"); sb.AppendLine(newReturnType + " ret = default;"); sb.Append(function.Name + "("); sb.Append(string.Join(", ", strParams)); sb.AppendLine(");"); sb.AppendLine("return ret;"); if (!newParameters.Any()) { yield return(new Overload(functionBuilder .WithParameters(newParameters) .Build(), sb, true)); yield break; } var sizeParameterType = newParameters.Last().Type; if ((sizeParameterType.Name != "int" && sizeParameterType.Name != "uint") || sizeParameterType.IsPointer) { yield return(new Overload(functionBuilder .WithParameters(newParameters) .Build(), sb, true)); yield break; } var n = newParameters.Last().Name; sb.Insert(0, "const " + (sizeParameterType.Name == "uint" ? "uint " : "int ") + (Utilities.CSharpKeywords.Contains(n) ? "@" : "") + n + " = 1;\n"); newParameters = SkipLastExtension.SkipLast(newParameters, 1).ToList(); yield return(new Overload ( functionBuilder .WithParameters(newParameters) .Build(), sb, true )); }
/// <summary> /// Returns an enumerable containing the original function signature, as well as all overload variants /// generated by the /// </summary> /// <param name="original">The original function signature.</param> /// <param name="core">The core project for this profile. May be used by some overloads.</param> /// <param name="overloaders">The overloaders to use in getting function overloads.</param> /// <returns>An enumerable containing the original function signature and all overloads.</returns> public static IEnumerable <Function> GetWithOverloads ( Function original, Project core, IEnumerable <ISimpleParameterOverloader> overloaders ) { if (original.Parameters.Count == 0) { yield return(original); yield break; } var parameters = original.Parameters.Select(x => new List <Parameter> { x }).ToList(); foreach (var parameter in parameters) { foreach (var overloader in overloaders) { if (overloader.TryGetParameterVariant(parameter[0], out var variant, core)) { parameter.Add(variant); } } } foreach (var combination in Combinations(parameters)) { var numGenericTypeParams = 0; var ret = new FunctionSignatureBuilder(original).WithParameters ( combination.Select ( x => !x.Type.IsGenericTypeParameterReference ? x : new ParameterSignatureBuilder(x).WithType ( new TypeSignatureBuilder(x.Type).WithName("T" + numGenericTypeParams++) .Build() ) .Build() ) .ToList() ) .WithGenericTypeParameters ( Enumerable.Range(0, numGenericTypeParams) .Select ( x => new GenericTypeParameter { Name = "T" + x, Constraints = new List <string> { "unmanaged" } } ) .ToList() ) .Build(); ret.Kind = original.Kind == SignatureKind.Normal ? ret.Parameters.SequenceEqual (original.Parameters) ? SignatureKind.Normal : SignatureKind.SimpleOverload : original.Kind; if (ret.NativeName.ConstitutesVulkanOutOverload() && (ret.Parameters.LastOrDefault()?.Type.IsOut ?? false)) { var last = ret.Parameters.Last(); var outStruct = core.Structs.FirstOrDefault(x => x.Name == last.Type.Name); var outSType = outStruct?.Fields.FirstOrDefault(); if (outSType is not null && outSType.Name == "SType" && outSType.DefaultAssignment is not null) { ret.Attributes.Add ( new() { Name = "Inject", Arguments = new() { "SilkTouchStage.Begin", $"\"{last.Name} = new({outSType.DefaultAssignment});\"" } } ); } } yield return(ret); } }