public bool TryGetParameterVariant(Parameter parameter, out Parameter variant, Project core) { if (parameter.Type.OriginalGroup is null || core.Enums.All (x => x.Name != parameter.Type.OriginalGroup) /* || (parameter.Type.OriginalName != "GLenum" && * parameter.Type.OriginalName != "CLenum")*/) { variant = null; return(false); } var t = new TypeSignatureBuilder(parameter.Type).WithName (parameter.Type.OriginalGroup) .Build(); t.OriginalName = t.Name; // stop GLenum mapping variant = new ParameterSignatureBuilder(parameter).WithType ( t ) .Build() ; return(true); }
/// <inheritdoc/> public IEnumerable <Overload> CreateOverloads(Function function) { if (!IsApplicable(function)) { yield break; } var arrayParameter = function.Parameters.Last(); var arrayParameterType = arrayParameter.Type; var newName = function.Name.Singularize(false); var newParameters = SkipLastExtension.SkipLast(new List <Parameter>(function.Parameters), 2).ToList(); var newArrayParameterType = new TypeSignatureBuilder(arrayParameterType) .WithArrayDimensions(0) .WithIndirectionLevel(0) .Build(); var newArrayParameter = new ParameterSignatureBuilder(arrayParameter) .WithType(newArrayParameterType) .Build(); newParameters.Add(newArrayParameter); var sb = new StringBuilder(); sb.AppendLine("// ArrayParameterOverloader"); sb.AppendLine(function.Name + "(1, &" + newArrayParameter.Name + ");"); yield return(new Overload(new FunctionSignatureBuilder(function) .WithName(newName) .WithParameters(newParameters) .Build(), sb, true)); }
public bool TryGetParameterVariant(Parameter parameter, out Parameter variant, Project core) { if (parameter.Type.ToString() == "char*" || parameter.Type.ToString() == "byte*" || parameter.Type.ToString() == "GLchar*" || parameter.Type.ToString() == "GLbyte*" || parameter.Type.ToString() == "GLubyte*") { var variantBuilder = new ParameterSignatureBuilder(parameter) .WithType ( new Type { Name = "string", IndirectionLevels = 0, IsOut = parameter.Flow == FlowDirection.Out && ((parameter.Count?.IsStatic ?? false) || (parameter.Count?.IsReference ?? false)) } ); if (!(parameter.Flow == FlowDirection.Out && ((parameter.Count?.IsStatic ?? false) || (parameter.Count?.IsReference ?? false)))) { variantBuilder = variantBuilder.WithCount(null); } variant = variantBuilder.Build(); return(true); } variant = null; return(false); }
public IEnumerable <ImplementedFunction> CreateOverloads(Function function) { var @params = new List <Parameter>(function.Parameters); var sb = new StringBuilder(); sb.AppendLine("// IntPtrOverloader"); if (function.ReturnType.ToString() != "void") { sb.Append("return "); } sb.Append($"{function.Name}("); var ret = false; for (var i = 0; i < function.Parameters.Count; i++) { var parameter = function.Parameters[i]; var parameterName = Utilities.CSharpKeywords.Contains(parameter.Name) ? $"@{parameter.Name}" : parameter.Name; if (parameter.Type.IsIntPtr() && !(parameter.Type.IsOut)) { @params[i] = new ParameterSignatureBuilder(parameter) .WithType(new TypeSignatureBuilder(parameter.Type).WithName("int").Build()) .Build(); sb.Append($"new IntPtr({parameterName})"); ret = true; } else if (parameter.Type.IsUIntPtr() && !(parameter.Type.IsOut)) { @params[i] = new ParameterSignatureBuilder(parameter) .WithType(new TypeSignatureBuilder(parameter.Type).WithName("uint").Build()) .Build(); sb.Append($"new UIntPtr({parameterName})"); ret = true; } else { var prefix = parameter.Type.IsOut ? "out " : parameter.Type.IsByRef ? "ref " : string.Empty; sb.Append($"{prefix}{parameterName}"); } if (i != function.Parameters.Count - 1) { sb.Append(", "); } } sb.AppendLine(");"); if (ret) { yield return(new ImplementedFunction(new FunctionSignatureBuilder(function).WithParameters(@params).Build(), sb)); } }
/// <inheritdoc/> public IEnumerable <FunctionSignature> CreateOverloads(FunctionSignature function) { var baseParameters = function.Parameters; var staticCountPermutation = new List <ParameterSignature>(baseParameters); for (int i = 0; i < baseParameters.Count; ++i) { var baseParameter = baseParameters[i]; var baseType = baseParameter.Type; if (!HasStaticCount(baseParameter)) { continue; } // ReSharper disable once PossibleNullReferenceException var count = baseParameter.Count.Count; if (count > 1) { // TODO: Support higher-ranked types continue; } if (!baseType.IsPointer || baseType.IndirectionLevel > 1) { continue; } var refTypeBuilder = new TypeSignatureBuilder(baseType) .WithIndirectionLevel(0) .WithByRef(true); if (baseParameter.Flow == FlowDirection.Out) { refTypeBuilder = refTypeBuilder.WithIsOut(true); } var refType = refTypeBuilder.Build(); var refParameter = new ParameterSignatureBuilder(baseParameter) .WithType(refType) .Build(); staticCountPermutation[i] = refParameter; } yield return(new FunctionSignatureBuilder(function) .WithParameters(staticCountPermutation) .Build()); }
public IEnumerable <Overload> CreateOverloads(Function function) { var @params = new List <Parameter>(function.Parameters); var sb = new StringBuilder(); sb.AppendLine("// IntPtrOverloader"); if (function.ReturnType.ToString() != "void") { sb.Append("return "); } sb.Append(function.Name + "("); var ret = false; for (var i = 0; i < function.Parameters.Count; i++) { var parameter = function.Parameters[i]; if (parameter.Type.IsIntPtr()) { @params[i] = new ParameterSignatureBuilder(parameter) .WithType(new TypeSignatureBuilder(parameter.Type).WithName("int").Build()) .Build(); sb.Append("new IntPtr(" + parameter.Name + ")"); ret = true; } else if (parameter.Type.IsUIntPtr()) { @params[i] = new ParameterSignatureBuilder(parameter) .WithType(new TypeSignatureBuilder(parameter.Type).WithName("uint").Build()) .Build(); sb.Append("new UIntPtr(" + parameter.Name + ")"); ret = true; } else { sb.Append(parameter.Name); } if (i != function.Parameters.Count - 1) { sb.Append(", "); } } sb.AppendLine(");"); if (ret) { yield return(new Overload(new FunctionSignatureBuilder(function).WithParameters(@params).Build(), sb)); } }
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); }
public bool TryCreateVariant(Parameter parameter, out Parameter variant, Project core) { if (parameter.Type.ToString() == "char*" || parameter.Type.ToString() == "byte*" || parameter.Type.ToString() == "GLchar*" || parameter.Type.ToString() == "GLbyte*" || parameter.Type.ToString() == "GLubyte*") { variant = new ParameterSignatureBuilder(parameter) .WithType ( new Type { Name = "string", IndirectionLevels = 0, IsOut = parameter.Flow == FlowDirection.Out && ((parameter.Count?.IsStatic ?? false) || (parameter.Count?.IsReference ?? false)) } ) .WithCount(null) // scrap the count as it causes trouble later down the line .Build(); if (variant.Type.IsOut) { variant.Attributes.Add ( new Attribute { Name = "Ultz.SuperInvoke.InteropServices.CountAttribute", Arguments = new List <string> { parameter.Count.IsStatic ? "Ultz.SuperInvoke.InteropServices.CountType.Constant" : "Ultz.SuperInvoke.InteropServices.CountType.ParameterReference", (parameter.Count.IsStatic ? parameter.Count.StaticCount : parameter.Origin.Parameters.FindIndex (x => x.Name == parameter.Count.ValueReference) - parameter.Origin.Parameters.IndexOf(parameter)).ToString() } } ); } return(true); } variant = null; return(false); }
public bool TryGetParameterVariant(Parameter parameter, out Parameter variant, Project core) { Struct s; if (parameter.Type.OriginalClass is null || (s = core.Structs.FirstOrDefault (x => x.NativeName == parameter.Type.OriginalClass)) is null) { variant = null; return(false); } var t = new TypeSignatureBuilder(parameter.Type).WithName(s.Name).Build(); t.OriginalName = t.Name; // stop GLenum mapping variant = new ParameterSignatureBuilder(parameter).WithType(t).Build(); return(true); }
public bool TryGetParameterVariant(Parameter parameter, out Parameter varied, Project core) { if (parameter.Type.IsPointer) { varied = new ParameterSignatureBuilder(parameter).WithType ( new TypeSignatureBuilder(parameter.Type) .WithIndirectionLevel(parameter.Type.IndirectionLevels - 1) .WithByRef(parameter.Flow != FlowDirection.In && parameter.Flow != FlowDirection.Out) .WithIsIn(parameter.Flow == FlowDirection.In) .WithIsOut(parameter.Flow == FlowDirection.Out) .WithIsGenericType(parameter.Type.IndirectionLevels == 1 && parameter.Type.Name == "void") .Build() ) .Build(); return(true); } varied = null; return(false); }
public bool TryGetParameterVariant(Parameter parameter, out Parameter variant, Project core) { if (parameter.Type.ToString() == "char*" || parameter.Type.ToString() == "byte*" || parameter.Type.ToString() == "GLchar*" || parameter.Type.ToString() == "GLbyte*" || parameter.Type.ToString() == "GLubyte*") { var variantBuilder = new ParameterSignatureBuilder(parameter) .WithType ( new Type { Name = "string", IndirectionLevels = 0, IsOut = parameter.Flow == FlowDirection.Out && ((parameter.Count?.IsStatic ?? false) || (parameter.Count?.IsReference ?? false)), OriginalName = parameter.Type.OriginalName } ); if (!(parameter.Flow == FlowDirection.Out && ((parameter.Count?.IsStatic ?? false) || (parameter.Count?.IsReference ?? false)))) { variantBuilder = variantBuilder.WithCount(null); } variant = variantBuilder.Build(); variant.Attributes.Add ( new() { Name = "UnmanagedType", Arguments = new() { variant.Type.MapUnmanagedType() } } ); return(true); } variant = null; return(false); }
/// <inheritdoc/> public bool TryGetFunctionVariant(Function function, out ImplementedFunction overload, Project core) { if (!IsApplicable(function)) { overload = null; return(false); } var arrayParameter = function.Parameters.Last(); var arrayParameterType = arrayParameter.Type; var newName = function.Name.Singularize(false); var newParameters = SkipLastExtension.SkipLast(new List <Parameter>(function.Parameters), 2).ToList(); var newArrayParameterType = new TypeSignatureBuilder(arrayParameterType) .WithArrayDimensions(0) .WithIndirectionLevel(0) .Build(); var newArrayParameter = new ParameterSignatureBuilder(arrayParameter) .WithType(newArrayParameterType) .Build(); newParameters.Add(newArrayParameter); var sb = new StringBuilder(); sb.AppendLine("// ArrayParameterOverloader"); sb.AppendLine($"{function.Name}(1, &{newArrayParameter.Name});"); overload = new ImplementedFunction(new FunctionSignatureBuilder(function) .WithName(newName) .WithParameters(newParameters) .Build(), sb, function, true); return(true); }
/// <inheritdoc/> public IEnumerable <FunctionSignature> CreateOverloads(FunctionSignature function) { var arrayParameter = function.Parameters.Last(); var arrayParameterType = arrayParameter.Type; var newName = function.Name.Singularize(false); var newParameters = SkipLastExtension.SkipLast(new List <ParameterSignature>(function.Parameters), 2).ToList(); var newArrayParameterType = new TypeSignatureBuilder(arrayParameterType) .WithArrayDimensions(0) .WithIndirectionLevel(0) .Build(); var newArrayParameter = new ParameterSignatureBuilder(arrayParameter) .WithType(newArrayParameterType) .Build(); newParameters.Add(newArrayParameter); yield return(new FunctionSignatureBuilder(function) .WithName(newName) .WithParameters(newParameters) .Build()); }
/// <inheritdoc/> public IEnumerable <(FunctionSignature, StringBuilder)> CreateOverloads(FunctionSignature function) { if (!function.Parameters.Any(p => p.Type.IsVoidPointer())) { yield break; } var baseParameters = function.Parameters; var newIntPtrParameters = new List <ParameterSignature>(baseParameters); var newGenericArray1DParameters = new List <ParameterSignature>(baseParameters); var newGenericArray2DParameters = new List <ParameterSignature>(baseParameters); var newGenericArray3DParameters = new List <ParameterSignature>(baseParameters); var newGenericTypeParameters = new List <GenericTypeParameterSignature>(); for (var i = 0; i < baseParameters.Count; ++i) { var parameter = baseParameters[i]; if (!parameter.Type.IsVoidPointer()) { continue; } var genericTypeParameterName = baseParameters.Count(p => p.Type.IsVoidPointer()) > 1 ? $"T{newGenericTypeParameters.Count + 1}" : "T"; var genericTypeParameter = new GenericTypeParameterSignature( genericTypeParameterName, new[] { "unmanaged" }); newGenericTypeParameters.Add(genericTypeParameter); var newIntPtrParameterType = new TypeSignatureBuilder(parameter.Type) .WithIndirectionLevel(0) .WithName(nameof(IntPtr)) .Build(); // TODO: Simplify and generalize this var newGenericArray1DParameterType = new TypeSignatureBuilder(parameter.Type) .WithIndirectionLevel(0) .WithArrayDimensions(1) .WithName(genericTypeParameterName) .Build(); var newGenericArray2DParameterType = new TypeSignatureBuilder(parameter.Type) .WithIndirectionLevel(0) .WithArrayDimensions(2) .WithName(genericTypeParameterName) .Build(); var newGenericArray3DParameterType = new TypeSignatureBuilder(parameter.Type) .WithIndirectionLevel(0) .WithArrayDimensions(3) .WithName(genericTypeParameterName) .Build(); newIntPtrParameters[i] = new ParameterSignatureBuilder(parameter) .WithType(newIntPtrParameterType) .Build(); newGenericArray1DParameters[i] = new ParameterSignatureBuilder(parameter) .WithType(newGenericArray1DParameterType) .Build(); newGenericArray2DParameters[i] = new ParameterSignatureBuilder(parameter) .WithType(newGenericArray2DParameterType) .Build(); newGenericArray3DParameters[i] = new ParameterSignatureBuilder(parameter) .WithType(newGenericArray3DParameterType) .Build(); } yield return(ToPointer ( new FunctionSignatureBuilder(function) .WithParameters(newIntPtrParameters) .Build(), function )); yield return(Fixed ( new FunctionSignatureBuilder(function) .WithParameters(newGenericArray1DParameters) .WithGenericTypeParameters(newGenericTypeParameters) .Build() )); yield return(Fixed ( new FunctionSignatureBuilder(function) .WithParameters(newGenericArray2DParameters) .WithGenericTypeParameters(newGenericTypeParameters) .Build() )); yield return(Fixed ( new FunctionSignatureBuilder(function) .WithParameters(newGenericArray3DParameters) .WithGenericTypeParameters(newGenericTypeParameters) .Build() )); }
public IEnumerable <Overload> CreateOverloads(Function function) { if (!function.Parameters.Any(IsApplicable)) { yield break; } var newParameters = new List <Parameter>(function.Parameters); var sb = new StringBuilder(); for (var i = 0; i < newParameters.Count; i++) { var param = newParameters[i]; if (!IsApplicable(param)) { continue; } sb.AppendLine("// StaticCountOverloader"); sb.Append("var " + param.Name + " = stackalloc " + param.Type.Name); sb.AppendLine("[" + param.Count.StaticCount + "];"); for (var j = 0; j < param.Count.StaticCount; j++) { if (j == 0) { newParameters[i + j] = new ParameterSignatureBuilder(param) .WithName(param.Name + j) .WithType(new TypeSignatureBuilder(param.Type).WithIndirectionLevel(0).Build()) .WithCount(null) .Build(); } else { newParameters.Insert(i + (j - 1), new ParameterSignatureBuilder(param) .WithName(param.Name + j) .WithCount(null) .WithType(new TypeSignatureBuilder(param.Type).WithIndirectionLevel(0).Build()) .Build()); } sb.AppendLine(param.Name + "[" + j + "] = " + param.Name + j + ";"); } } if (function.ReturnType.ToString() != "void") { sb.Append("return "); } sb.Append(function.Name + "("); sb.Append(string.Join(", ", function.Parameters.Select(x => Format(x.Name)))); sb.Append(");"); sb.AppendLine(); yield return(new Overload ( new FunctionSignatureBuilder(function).WithParameters(newParameters).Build(), sb, true )); string Format(string n) { if (Utilities.CSharpKeywords.Contains(n)) { return("@" + n); } return(n); } }
public IEnumerable <ImplementedFunction> CreateOverloads(Function function) { for (var i = 0; i < function.Parameters.Count; i++) { var param = function.Parameters[i]; if (param.Type.ToString() == "char**" && !param.Type.IsOut) { var parameters = function.Parameters.ToArray(); var o = new StringBuilder(); parameters[i] = new ParameterSignatureBuilder(param).WithType ( new Type { Name = "string", ArrayDimensions = 1 } ) .Build(); o.AppendLine ($"var {param.Name}_o = SilkMarshal.MarshalStringArrayToPtr({ConvertName(param.Name)});"); if (function.ReturnType.ToString() != "void") { o.Append("var silkReturn = "); } o.Append(function.Name); o.Append("("); o.Append ( string.Join ( ", ", function.Parameters.Select((x, j) => j == i ? $"(char**){param.Name}_o" : Convert(x)) ) ); o.AppendLine(");"); o.AppendLine($"SilkMarshal.FreeStringArrayPtr({param.Name}_o, {ConvertName(param.Name)}.Length);"); if (function.ReturnType.ToString() != "void") { o.Append("return silkReturn;"); } yield return(new ImplementedFunction (new FunctionSignatureBuilder(function).WithParameters(parameters).Build(), o, true)); } else if ((param.Type.ToString() == "char*" || param.Type.ToString() == "byte*") && function.Parameters.Any (x => x.Name == param.Count?.ValueReference) && param.Flow == FlowDirection.Out) { var parameters = function.Parameters.ToArray(); var o = new StringBuilder(); o.AppendLine($"var {param.Name}_s = SilkMarshal.NewStringPtr({param.Count.ValueReference});"); parameters[i] = new ParameterSignatureBuilder(param).WithType (new Type { Name = "string", IsOut = true }) .Build(); if (function.ReturnType.ToString() != "void") { o.Append("var silkReturn = "); } o.Append(function.Name); o.Append("("); o.Append ( string.Join ( ", ", function.Parameters.Select((x, j) => j == i ? $"({param.Type}){param.Name}_s" : Convert(x)) ) ); o.AppendLine(");"); o.AppendLine($"{ConvertName(param.Name)} = SilkMarshal.MarshalPtrToString({param.Name}_s);"); o.AppendLine($"SilkMarshal.FreeStringPtr({param.Name}_s);"); if (function.ReturnType.ToString() != "void") { o.Append("return silkReturn;"); } yield return(new ImplementedFunction (new FunctionSignatureBuilder(function).WithParameters(parameters).Build(), o, true)); } else if ((param.Type.ToString() == "char*" || param.Type.ToString() == "byte*") && !param.Type.IsOut) { var parameters = function.Parameters.ToArray(); var o = new StringBuilder(); o.AppendLine($"var {param.Name}_s = SilkMarshal.MarshalStringToPtr({ConvertName(param.Name)});"); parameters[i] = new ParameterSignatureBuilder(param).WithType(new Type { Name = "string" }).Build(); if (function.ReturnType.ToString() != "void") { o.Append("var silkReturn = "); } o.Append(function.Name); o.Append("("); o.Append ( string.Join ( ", ", function.Parameters.Select((x, j) => j == i ? $"({param.Type}){param.Name}_s" : Convert(x)) ) ); o.AppendLine(");"); o.AppendLine($"{ConvertName(param.Name)} = SilkMarshal.MarshalPtrToString({param.Name}_s);"); o.AppendLine($"SilkMarshal.FreeStringPtr({param.Name}_s);"); if (function.ReturnType.ToString() != "void") { o.Append("return silkReturn;"); } yield return(new ImplementedFunction (new FunctionSignatureBuilder(function).WithParameters(parameters).Build(), o, true)); } } }
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); } }
/// <inheritdoc/> public IEnumerable <FunctionSignature> CreateOverloads(FunctionSignature function) { var baseParameters = function.Parameters; var newIntPtrParameters = new List <ParameterSignature>(baseParameters); var newGenericArray1DParameters = new List <ParameterSignature>(baseParameters); var newGenericArray2DParameters = new List <ParameterSignature>(baseParameters); var newGenericArray3DParameters = new List <ParameterSignature>(baseParameters); var newGenericRefParameters = new List <ParameterSignature>(baseParameters); var newGenericTypeParameters = new List <GenericTypeParameterSignature>(); for (int i = 0; i < baseParameters.Count; ++i) { var parameter = baseParameters[i]; if (!parameter.Type.IsVoidPointer()) { continue; } string genericTypeParameterName; if (baseParameters.Count(p => p.Type.IsVoidPointer()) > 1) { genericTypeParameterName = $"T{newGenericTypeParameters.Count + 1}"; } else { genericTypeParameterName = "T"; } var genericTypeParameter = new GenericTypeParameterSignature(genericTypeParameterName); newGenericTypeParameters.Add(genericTypeParameter); var newIntPtrParameterType = new TypeSignatureBuilder(parameter.Type) .WithIndirectionLevel(0) .WithName(nameof(IntPtr)) .Build(); // TODO: Simplify and generalize this var newGenericArray1DParameterType = new TypeSignatureBuilder(parameter.Type) .WithIndirectionLevel(0) .WithArrayDimensions(1) .WithName(genericTypeParameterName) .Build(); var newGenericArray2DParameterType = new TypeSignatureBuilder(parameter.Type) .WithIndirectionLevel(0) .WithArrayDimensions(2) .WithName(genericTypeParameterName) .Build(); var newGenericArray3DParameterType = new TypeSignatureBuilder(parameter.Type) .WithIndirectionLevel(0) .WithArrayDimensions(3) .WithName(genericTypeParameterName) .Build(); var newGenericRefParameterType = new TypeSignatureBuilder(parameter.Type) .WithIndirectionLevel(0) .WithName(genericTypeParameterName) .WithByRef(true) .Build(); newIntPtrParameters[i] = new ParameterSignatureBuilder(parameter) .WithType(newIntPtrParameterType) .Build(); newGenericArray1DParameters[i] = new ParameterSignatureBuilder(parameter) .WithType(newGenericArray1DParameterType) .Build(); newGenericArray2DParameters[i] = new ParameterSignatureBuilder(parameter) .WithType(newGenericArray2DParameterType) .Build(); newGenericArray3DParameters[i] = new ParameterSignatureBuilder(parameter) .WithType(newGenericArray3DParameterType) .Build(); newGenericRefParameters[i] = new ParameterSignatureBuilder(parameter) .WithType(newGenericRefParameterType) .Build(); } yield return(new FunctionSignatureBuilder(function) .WithParameters(newIntPtrParameters) .Build()); yield return(new FunctionSignatureBuilder(function) .WithParameters(newGenericArray1DParameters) .WithGenericTypeParameters(newGenericTypeParameters) .Build()); yield return(new FunctionSignatureBuilder(function) .WithParameters(newGenericArray2DParameters) .WithGenericTypeParameters(newGenericTypeParameters) .Build()); yield return(new FunctionSignatureBuilder(function) .WithParameters(newGenericArray3DParameters) .WithGenericTypeParameters(newGenericTypeParameters) .Build()); yield return(new FunctionSignatureBuilder(function) .WithParameters(newGenericRefParameters) .WithGenericTypeParameters(newGenericTypeParameters) .Build()); }
/// <inheritdoc/> public IEnumerable <FunctionSignature> CreateOverloads(FunctionSignature function) { var baseParameters = function.Parameters; var refParameterPermutation = new List <ParameterSignature>(baseParameters); var arrayParameterPermutation = new List <ParameterSignature>(baseParameters); for (int i = 0; i < baseParameters.Count; ++i) { var baseParameter = baseParameters[i]; var baseType = baseParameter.Type; if (!baseType.IsPointer || baseType.IndirectionLevel > 1) { continue; } if (baseType.Name.Equals(typeof(void).Name, StringComparison.OrdinalIgnoreCase)) { // Skip void pointers continue; } var refTypeBuilder = new TypeSignatureBuilder(baseType) .WithIndirectionLevel(0) .WithByRef(true); if (baseParameter.Flow == FlowDirection.Out) { refTypeBuilder = refTypeBuilder.WithIsOut(true); } var refType = refTypeBuilder.Build(); var refParameter = new ParameterSignatureBuilder(baseParameter) .WithType(refType) .Build(); refParameterPermutation[i] = refParameter; if (!(baseParameter.Count is null) && baseParameter.Count.IsStatic && baseParameter.Count.Count == 1) { // Single-element count pointers don't need array overloads continue; } var arrayType = new TypeSignatureBuilder(baseType) .WithIndirectionLevel(0) .WithArrayDimensions(1) .Build(); var arrayParameter = new ParameterSignatureBuilder(baseParameter) .WithType(arrayType) .Build(); arrayParameterPermutation[i] = arrayParameter; } yield return(new FunctionSignatureBuilder(function) .WithParameters(refParameterPermutation) .Build()); yield return(new FunctionSignatureBuilder(function) .WithParameters(arrayParameterPermutation) .Build()); }
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 bool TryGetFunctionVariant(Function function, out ImplementedFunction overload, Project core) { // SilkTouch currently can't properly marshal string spans, so we need to help out. var sb = new StringBuilder(); var pl = new List <Parameter>(); var ep = new List <string>(); var varied = false; sb.AppendLine("// StringArrayOverloader"); pl.AddRange(function.Parameters); for (var i = 0; i < pl.Count; i++) { var parameter = pl[i]; if (parameter.Type.ToString() == "char**" || parameter.Type.ToString() == "byte**") { pl[i] = new ParameterSignatureBuilder(parameter).WithType ( new Type { Name = "string", ArrayDimensions = 1, OriginalName = parameter.Type.OriginalName } ) .WithName(parameter.Name + "Sa") .Build(); varied = true; sb.AppendLine ( $"var {parameter.Name} = ({parameter.Type}) SilkMarshal.StringArrayToPtr({parameter.Name}Sa);" ); ep.Add($"SilkMarshal.CopyPtrToStringArray((nint) {parameter.Name}, {parameter.Name}Sa);"); ep.Add($"SilkMarshal.Free((nint) {parameter.Name});"); } } if (function.ReturnType.ToString() != "void") { sb.Append("var ret = "); } sb.AppendLine ( $"{function.Name}" + "(" + string.Join ( ", ", function.Parameters.Select ( x => (x.Type.IsIn ? "in " : string.Empty) + (x.Type.IsOut ? "out " : string.Empty) + (x.Type.IsByRef ? "ref " : string.Empty) + (Utilities.CSharpKeywords.Contains (x.Name) ? "@" : string.Empty) + x.Name ) ) + ");" ); foreach (var epilogueLine in ep) { sb.AppendLine(epilogueLine); } if (function.ReturnType.ToString() != "void") { sb.AppendLine("return ret;"); } if (varied) { overload = new ImplementedFunction (new FunctionSignatureBuilder(function).WithParameters(pl).Build(), sb, function); return(true); } overload = null; return(false); }
public bool TryCreateOverload(Function function, out ImplementedFunction overload, Project core) { if (function.NativeName == "clEnqueueSVMMigrateMem" || function.NativeName == "clEnqueueNativeKernel") { // BUG these functions think a span variant exists where one doesnt, was unable to filter out. overload = null; return(false); } var @params = new List <Parameter>(function.Parameters); var sb = new StringBuilder(); sb.AppendLine("// IntPtrOverloader"); if (function.ReturnType.ToString() != "void") { sb.Append("return "); } sb.Append($"{function.Name}("); var ret = false; for (var i = 0; i < function.Parameters.Count; i++) { var parameter = function.Parameters[i]; var parameterName = Utilities.CSharpKeywords.Contains(parameter.Name) ? $"@{parameter.Name}" : parameter.Name; if (parameter.Type.IsIntPtr() && !(parameter.Type.IsOut)) { @params[i] = new ParameterSignatureBuilder(parameter) .WithType(new TypeSignatureBuilder(parameter.Type).WithName("int").Build()) .Build(); sb.Append($"new IntPtr({parameterName})"); ret = true; } else if (parameter.Type.IsUIntPtr() && !(parameter.Type.IsOut)) { @params[i] = new ParameterSignatureBuilder(parameter) .WithType(new TypeSignatureBuilder(parameter.Type).WithName("uint").Build()) .Build(); sb.Append($"new UIntPtr({parameterName})"); ret = true; } else { var prefix = parameter.Type.IsOut ? "out " : parameter.Type.IsByRef ? "ref " : string.Empty; sb.Append($"{prefix}{parameterName}"); } if (i != function.Parameters.Count - 1) { sb.Append(", "); } } sb.AppendLine(");"); if (ret) { overload = new ImplementedFunction(new FunctionSignatureBuilder(function).WithParameters(@params).Build(), sb, function); return(true); } overload = null; return(false); }
public IEnumerable <ImplementedFunction> CreateOverloads(Function function) { if (!function.Parameters.Any(IsApplicable)) { yield break; } var newParameters = new List <Parameter>(function.Parameters); var sb = new StringBuilder(); for (var i = 0; i < newParameters.Count; i++) { var param = newParameters[i]; if (!IsApplicable(param)) { continue; } sb.AppendLine("// StaticCountOverloader"); sb.Append($"var {param.Name} = stackalloc {param.Type.Name}"); sb.AppendLine($"[{param.Count.StaticCount}];"); for (var j = 0; j < param.Count.StaticCount; j++) { if (j == 0) { newParameters[i + j] = new ParameterSignatureBuilder(param) .WithName(param.Name + j) .WithType(new TypeSignatureBuilder(param.Type).WithIndirectionLevel(0).Build()) .WithCount(null) .Build(); } else { newParameters.Insert(i + (j - 1), new ParameterSignatureBuilder(param) .WithName(param.Name + j) .WithCount(null) .WithType(new TypeSignatureBuilder(param.Type).WithIndirectionLevel(0).Build()) .Build()); } sb.AppendLine($"{param.Name}[{j}] = {param.Name}{j};"); } } if (function.ReturnType.ToString() != "void") { sb.Append("return "); } sb.Append($"{function.Name}("); sb.Append(string.Join(", ", function.Parameters.Select(x => GetOut(x.Type) + Format(x.Name)))); sb.Append(");"); sb.AppendLine(); yield return(new ImplementedFunction ( new FunctionSignatureBuilder(function).WithParameters(newParameters).Build(), sb, true )); string GetOut(Type t) { return(t.IsOut ? "out " : string.Empty); } string Format(string n) { if (Utilities.CSharpKeywords.Contains(n)) { return($"@{n}"); } return(n); } }
public bool TryGetFunctionVariant(Function original, out ImplementedFunction varied, Project core) { varied = null; // use the ref overload for simplicity if (original.Kind != SignatureKind.SimpleOverload) { return(false); } var applicable = false; var invocationParameters = new List <string>(); var parameters = new List <Parameter>(original.Parameters); for (var i = 0; i < original.Parameters.Count; i++) { var parameter = original.Parameters[i]; var name = (Utilities.CSharpKeywords.Contains(parameter.Name) ? "@" : string.Empty) + parameter.Name; if (parameter.Type.IsIn && !parameter.Type.IsPointer) { applicable = true; parameters[i] = new ParameterSignatureBuilder(parameter).WithType ( new Type { Name = "ReadOnlySpan", GenericTypes = new List <Type> { new TypeSignatureBuilder(parameter.Type).WithIsIn(false).Build() }, IsGenericTypeParameterReference = parameter.Type.IsGenericTypeParameterReference, OriginalName = parameter.Type.OriginalName } ) .Build(); invocationParameters.Add($"in {name}.GetPinnableReference()"); } else if (parameter.Type.IsOut && !parameter.Type.IsPointer) { applicable = true; parameters[i] = new ParameterSignatureBuilder(parameter).WithType ( new Type { Name = "Span", GenericTypes = new List <Type> { new TypeSignatureBuilder(parameter.Type).WithIsOut(false).Build() }, IsGenericTypeParameterReference = parameter.Type.IsGenericTypeParameterReference, OriginalName = parameter.Type.OriginalName } ) .Build(); invocationParameters.Add($"out {name}.GetPinnableReference()"); } else if (parameter.Type.IsByRef && !parameter.Type.IsPointer) { applicable = true; parameters[i] = new ParameterSignatureBuilder(parameter).WithType ( new Type { Name = "Span", GenericTypes = new List <Type> { new TypeSignatureBuilder(parameter.Type).WithByRef(false).Build() }, IsGenericTypeParameterReference = parameter.Type.IsGenericTypeParameterReference, OriginalName = parameter.Type.OriginalName } ) .Build(); invocationParameters.Add($"ref {name}.GetPinnableReference()"); } else { invocationParameters.Add ( (parameter.Type.IsIn ? "in " : parameter.Type.IsOut ? "out " : parameter.Type.IsByRef ? "ref " : string.Empty) + name ); } } if (applicable) { var sb = new StringBuilder(); sb.AppendLine("// SpanOverloader"); if (original.ReturnType.ToString() != "void") { sb.Append("return "); } sb.Append("thisApi." + original.Name); sb.Append("("); sb.Append(string.Join(", ", invocationParameters)); sb.Append(");"); varied = new ImplementedFunction ( new FunctionSignatureBuilder(original) .WithParameters(parameters) .WithKind(SignatureKind.PotentiallyConflictingOverload) .Build(), sb, original ); } return(applicable); }
public bool TryCreateOverload(Function function, out ImplementedFunction overload, Project core) { // SuperInvoke currently can't properly marshal string spans, so we need to help out. var sb = new StringBuilder(); var pl = new List <Parameter>(); var ep = new List <string>(); var varied = false; sb.AppendLine("// StringArrayOverloader"); pl.AddRange(function.Parameters); for (var i = 0; i < pl.Count; i++) { var parameter = pl[i]; if (parameter.Type.ToString() == "char**" || parameter.Type.ToString() == "byte**") { pl[i] = new ParameterSignatureBuilder(parameter).WithType ( new Type { Name = "string", ArrayDimensions = 1 } ) .WithName(parameter.Name + "Sa") .Build(); varied = true; sb.AppendLine ( $"var {parameter.Name} = ({parameter.Type}) SilkMarshal.MarshalStringArrayToPtr({parameter.Name}Sa);" ); ep.Add($"SilkMarshal.CopyPtrToStringArray((IntPtr) {parameter.Name}, {parameter.Name}Sa);"); } } if (function.ReturnType.ToString() != "void") { sb.Append("var ret = "); } sb.AppendLine ( $"{function.Name}" + $"({string.Join(", ", function.Parameters.Select(x => (x.Type.IsByRef ? "ref " : string.Empty) + x.Name))});" ); foreach (var epilogueLine in ep) { sb.AppendLine(epilogueLine); } if (function.ReturnType.ToString() != "void") { sb.AppendLine("return ret;"); } if (varied) { overload = new ImplementedFunction (new FunctionSignatureBuilder(function).WithParameters(pl).Build(), sb, function); return(true); } overload = null; return(false); }