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