/// <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 ); }
/// <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()); }
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)); }
/// <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 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 <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 )); }