/// <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
                );
        }
Exemplo n.º 2
0
        /// <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());
        }
Exemplo n.º 3
0
        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));
        }
Exemplo n.º 4
0
        /// <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));
            }
        }
Exemplo n.º 5
0
        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);
            }
        }
Exemplo n.º 6
0
        /// <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
                         ));
        }