SLType ToClosure(SLImportModules modules, SwiftFunctionType func)
        {
            var args          = func.EachParameter.Select(p => new SLUnnamedParameter(MapType(modules, p), ToParameterKind(p)));
            var returnType    = MapType(modules, func.ReturnType);
            var closureResult = new SLFuncType(returnType, args);

            return(closureResult);
        }
        SLFuncType ToMarshaledClosureType(BaseDeclaration declContext, ClosureTypeSpec closure)
        {
            var newFunc = new SLFuncType(new SLTupleType(), new List <SLUnnamedParameter> ());

            if (!closure.ReturnType.IsEmptyTuple)
            {
                newFunc.Parameters.Add(new SLUnnamedParameter(new SLBoundGenericType("UnsafeMutablePointer", typeMapper.TypeSpecMapper.MapType(declContext, imports, closure.ReturnType, false))));
            }
            if (!closure.Arguments.IsEmptyTuple)
            {
                newFunc.Parameters.Add(new SLUnnamedParameter(new SLBoundGenericType("UnsafeMutablePointer", typeMapper.TypeSpecMapper.MapType(declContext, imports, closure.Arguments, false))));
            }
            return(newFunc);
        }
예제 #3
0
        SLType MapType(BaseDeclaration declContext, SLImportModules modules, ClosureTypeSpec spec, bool isForReturn)
        {
            if (spec.Throws)
            {
                throw ErrorHelper.CreateError(ReflectorError.kTypeMapBase + 16, $"In {declContext.ToFullyQualifiedName ()}, closure type {spec.ToString ()} throws, which is not supported yet.");
            }
            var argumentTypes = new List <SLType> ();

            if (spec.Arguments is TupleTypeSpec)
            {
                argumentTypes.AddRange(((TupleTypeSpec)spec.Arguments).Elements.Select(arg => MapType(declContext, modules, arg, false)));
            }
            else
            {
                argumentTypes.Add(MapType(declContext, modules, spec.Arguments, false));
            }


            SLFuncType funcType = null;

            if (isForOverride)
            {
                var arguments = new SLTupleType(argumentTypes.Select(at => new SLNameTypePair((string)null, at)).ToList());
                if (spec.ReturnType.IsEmptyTuple)
                {
                    // Action ->
                    funcType = new SLFuncType(arguments ?? new SLTupleType(), new SLTupleType());
                }
                else
                {
                    // Func
                    SLType slRetType = MapType(declContext, modules, spec.ReturnType, true);
                    funcType = new SLFuncType(arguments ?? new SLTupleType(), slRetType);
                }
                if (spec.IsEscaping)
                {
                    SLAttribute.Escaping().AttachBefore(funcType);
                }
            }
            else if (isForReturn)
            {
                var arguments = argumentTypes.Select(at => new SLNameTypePair("_", at)).ToList();

                if (spec.ReturnType.IsEmptyTuple)
                {
                    // Action ->
                    // (UnsafeMutablePointer<(argumentTypes)>) -> ()
                    var pointerToArgTuple = arguments.Count != 0 ?
                                            new SLBoundGenericType("UnsafeMutablePointer", new SLTupleType(arguments))
                                                                         : null;
                    if (pointerToArgTuple != null)
                    {
                        funcType = new SLFuncType(new SLTupleType(new SLNameTypePair("_", pointerToArgTuple)),
                                                  new SLTupleType());
                    }
                    else                         // should never happen?
                    {
                        funcType = new SLFuncType(new SLTupleType(), new SLTupleType());
                    }
                }
                else
                {
                    // Func
                    // (UnsafeMutablePointer<returnType>,UnsafeMutablePointer<(argumentTypes)>) -> ()
                    SLType slRetType         = MapType(declContext, modules, spec.ReturnType, true);
                    var    pointerToArgTuple = arguments.Count != 0 ?
                                               new SLBoundGenericType("UnsafeMutablePointer", new SLTupleType(arguments))
                                                                         : null;
                    if (pointerToArgTuple != null)
                    {
                        funcType = new SLFuncType(new SLTupleType(new SLNameTypePair("_", new SLBoundGenericType("UnsafeMutablePointer", slRetType)),
                                                                  new SLNameTypePair("_", pointerToArgTuple)),
                                                  new SLTupleType());
                    }
                    else
                    {
                        funcType = new SLFuncType(new SLTupleType(new SLNameTypePair("_", new SLBoundGenericType("UnsafeMutablePointer", slRetType))),
                                                  new SLTupleType());
                    }
                }
            }
            else
            {
                var arguments        = argumentTypes.Select(at => new SLNameTypePair("_", at)).ToList();
                var opaquePointerArg = new SLNameTypePair("_", SLSimpleType.OpaquePointer);

                if (spec.ReturnType.IsEmptyTuple)
                {
                    // Action ->
                    // (UnsafeMutablePointer<(argumentTypes)>, OpaquePointer) -> ()
                    var pointerToArgTuple = arguments.Count != 0 ?
                                            new SLBoundGenericType("UnsafeMutablePointer", new SLTupleType(arguments))
                                                                         : null;
                    if (pointerToArgTuple != null)
                    {
                        funcType = new SLFuncType(new SLTupleType(new SLNameTypePair("_", pointerToArgTuple), opaquePointerArg),
                                                  new SLTupleType());
                    }
                    else                         // should never happen?
                    {
                        funcType = new SLFuncType(new SLTupleType(opaquePointerArg), new SLTupleType());
                    }
                }
                else
                {
                    // Func
                    // (UnsafeMutablePointer<returnType>,UnsafeMutablePointer<(argumentTypes)>) -> ()
                    SLType slRetType         = MapType(declContext, modules, spec.ReturnType, true);
                    var    pointerToArgTuple = arguments.Count != 0 ?
                                               new SLBoundGenericType("UnsafeMutablePointer", new SLTupleType(arguments))
                                                                         : null;
                    if (pointerToArgTuple != null)
                    {
                        funcType = new SLFuncType(new SLTupleType(new SLNameTypePair("_", new SLBoundGenericType("UnsafeMutablePointer", slRetType)),
                                                                  new SLNameTypePair("_", pointerToArgTuple),
                                                                  opaquePointerArg),
                                                  new SLTupleType());
                    }
                    else
                    {
                        funcType = new SLFuncType(new SLTupleType(new SLNameTypePair("_", new SLBoundGenericType("UnsafeMutablePointer", slRetType)),
                                                                  opaquePointerArg),
                                                  new SLTupleType());
                    }
                }

                if (!isForReturn)
                {
                    funcType.Attributes.Add(new SLAttribute("escaping", null));
                }
            }


            return(funcType);
        }