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