SLBaseExpr MarshalClosureTypeSpec(BaseDeclaration declContext, string name, ClosureTypeSpec closure)
        {
            // retuns a value
            // let p = swiftClosureToFunc(name)
            // -- or --
            // no return value
            // let p = swiftClosureToAction<at0, at1, ...>(name)
            // expr will be toIntPtr(p)
            // ...
            // p.deallocate()

            Ex.ThrowOnNull(closure, "closure");
            imports.AddIfNotPresent("XamGlue");
            var funcToCall = closure.HasReturn() ? "swiftClosureToFunc" : "swiftClosureToAction";
            var localPtr   = new SLIdentifier(MarshalEngine.Uniqueify("ptr", identifiersUsed));
            var ptrAlloc   = new SLFunctionCall(funcToCall, false, true,
                                                new SLArgument(new SLIdentifier("a1"), new SLIdentifier(name), true));
            var decl = new SLLine(new SLDeclaration(true, localPtr.Name, null, ptrAlloc, Visibility.None));

            preMarshalCode.Add(decl);

            var ptrDealloc = SLFunctionCall.FunctionCallLine($"{localPtr.Name}.deallocate");

            postMarshalCode.Add(ptrDealloc);
            return(new SLFunctionCall("toIntPtr", false, true,
                                      new SLArgument(new SLIdentifier("value"), localPtr, true)));
        }
        static bool TypeMatches(FunctionDeclaration decl, ClosureTypeSpec cs, SwiftType st, TypeMapper typeMap)
        {
            SwiftBaseFunctionType bft = st as SwiftBaseFunctionType;

            return(TypeMatches(decl, cs.Arguments, bft.Parameters, typeMap) &&
                   TypeMatches(decl, cs.ReturnType, bft.ReturnType, typeMap));
        }
        bool ClosureTypesMatch(FunctionDeclaration protoFunc, ClosureTypeSpec protoType, FunctionDeclaration classFunc, ClosureTypeSpec classType)
        {
            var argsMatch = TypesMatch(protoFunc, protoType.Arguments, classFunc, classType.Arguments);
            var retsMatch = TypesMatch(protoFunc, protoType.ReturnType, classFunc, classType.ReturnType);

            return(argsMatch && retsMatch);
        }
        public void TestFuncVoidVoid()
        {
            ClosureTypeSpec close = TypeSpecParser.Parse("() -> ()") as ClosureTypeSpec;

            Assert.NotNull(close);
            TupleTypeSpec ts = close.Arguments as TupleTypeSpec;

            Assert.NotNull(ts);
            Assert.AreEqual(0, ts.Elements.Count);
            ts = close.ReturnType as TupleTypeSpec;
            Assert.NotNull(ts);
            Assert.AreEqual(0, ts.Elements.Count);
        }
        public void TestFuncIntInt()
        {
            ClosureTypeSpec close = TypeSpecParser.Parse("Swift.Int -> Swift.Int") as ClosureTypeSpec;

            Assert.NotNull(close);
            NamedTypeSpec ns = close.Arguments as NamedTypeSpec;

            Assert.NotNull(ns);
            Assert.AreEqual("Swift.Int", ns.Name);
            ns = close.ReturnType as NamedTypeSpec;
            Assert.NotNull(ns);
            Assert.AreEqual("Swift.Int", ns.Name);
        }
        TypeSpec RebuildTypeWithGenericType(ClosureTypeSpec type, out bool changed)
        {
            bool argsChanged, resultChanged;
            var  args   = RebuildTypeWithGenericType(type.Arguments, out argsChanged);
            var  result = RebuildTypeWithGenericType(type.ReturnType, out resultChanged);

            changed = argsChanged || resultChanged;
            if (changed)
            {
                return(new ClosureTypeSpec(args, result));
            }
            return(type);
        }
        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);
        }
 bool IsAction(ClosureTypeSpec closure)
 {
     return(closure.ReturnType.IsEmptyTuple);
 }
Ejemplo n.º 9
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);
        }
 void GetUniqueGenericTypeNamesFor(ClosureTypeSpec candidate, HashSet <string> result)
 {
     GetUniqueGenericTypeNamesFor(candidate.Arguments, result);
     GetUniqueGenericTypeNamesFor(candidate.ReturnType, result);
 }