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