static ObjCProtocolCompiler() { var arg = new CSSimpleType("NSObject").Typeof(); var argList = new CSArgumentList(); argList.Add(new CSArgument(arg)); kBaseTypeNSObject = new CSAttribute(new CSIdentifier("BaseType"), argList, true); }
void MakeHandler(CSClass cl, string name, string propName) { CSSimpleType evtType = new CSSimpleType(typeof(EventArgs)); CSProperty prop = CSProperty.PublicGetSet(evtType, propName); cl.Properties.Add(prop); CSParameterList pl = new CSParameterList(); pl.Add(new CSParameter(CSSimpleType.Object, "sender")); pl.Add(new CSParameter(evtType, "args")); CSCodeBlock body = new CSCodeBlock(); body.Add(CSAssignment.Assign(propName, CSAssignmentOperator.Assign, new CSIdentifier("args"))); CSMethod meth = new CSMethod(CSVisibility.Public, CSMethodKind.None, CSSimpleType.Void, new CSIdentifier(name), pl, body); cl.Methods.Add(meth); }
public void StructBadInnerEnumSmokeTest() { string swiftCode = "public struct CommandCougar {\n" + " public enum Errors : Error { \n" + " case validate(String)\n" + " case callback(String)\n" + " case parse(String)\n" + " }\n" + "}"; // typeof (CommandCougar.Errors).FullName var innerTypeName = new CSSimpleType("CommandCougar.Errors").Typeof().Dot(new CSIdentifier("FullName")); var printer = CSFunctionCall.ConsoleWriteLine(innerTypeName); var callingCode = CSCodeBlock.Create(printer); TestRunning.TestAndExecute(swiftCode, callingCode, "InnerEnumTests.CommandCougar+Errors\n"); }
CSType MapType(TypeReference typeReference) { CSType commonType = null; if (TryGetCommonName(typeReference.FullName, out commonType)) { return(commonType); } if (typeReference.HasGenericParameters) { var generics = typeReference.GenericParameters.Select(gen => MapType(gen)).ToArray(); var genericType = new CSSimpleType(typeReference.Name, false, generics); return(genericType); } else { var theType = new CSSimpleType(typeReference.Name); return(theType); } }
void WrapGenPrivField(string cstype, string val1, string expected) { string swiftCode = $"public struct BarWGPV{cstype} {{\npublic var X:Int32 = 0;\npublic init(x:Int32) {{\n X = x;\n}}\n}}\n" + $"public struct FooWGPV{cstype}<T> {{\nprivate var x:T\npublic init(a:T) {{\nx = a\n }}\n}}\n"; CSSimpleType fooType = new CSSimpleType($"FooWGPV{cstype}", false, cstype); CSLine fooDecl = CSVariableDeclaration.VarLine(new CSSimpleType($"FooWGPV{cstype}", false, new CSSimpleType(cstype)), "foo", new CSFunctionCall(fooType.ToString(), true, new CSIdentifier(val1))); CSLine printer = CSFunctionCall.ConsoleWriteLine(CSFunctionCall.Function("StructMarshal.Marshaler.Sizeof", CSFunctionCall.Function("foo.GetType"))); CSCodeBlock callingCode = CSCodeBlock.Create(fooDecl, printer); TestRunning.TestAndExecute(swiftCode, callingCode, expected, testName: $"WrapGenPrivField{cstype}"); }
void WrapGenEnum(string cstype, string val1, string expected) { string swiftCode = $"public struct BarWGE{cstype} {{\npublic var X:Int32 = 0;\npublic init(x:Int32) {{\n X = x;\n}}\n}}\n" + $"public enum MyOptionWGE{cstype}<T> {{\ncase Some(T)\ncase None\n}}\n"; CSSimpleType fooType = new CSSimpleType($"MyOptionWGE{cstype}", false, cstype); CSLine fooDecl = CSVariableDeclaration.VarLine(fooType, "foo", new CSFunctionCall($"{fooType.ToString ()}.NewSome", false, new CSIdentifier(val1))); CSLine printer = CSFunctionCall.ConsoleWriteLine((CSIdentifier)$"foo.ValueSome"); CSCodeBlock callingCode = CSCodeBlock.Create(fooDecl, printer); TestRunning.TestAndExecute(swiftCode, callingCode, expected, testName: $"WrapGenEnum{cstype}"); }
void WrapGenFieldGetOnly(string appendage, string cstype, string val1, string expected) { string swiftCode = $"public struct BarWGFGO{appendage} {{\npublic var X:Int32 = 0;\npublic init(x:Int32) {{\n X = x;\n}}\n}}\n" + $"public struct FooWGFGO{appendage}<T> {{\npublic private(set) var x:T\npublic init(a:T) {{\nx = a\n }}\n}}\n"; CSSimpleType fooType = new CSSimpleType($"FooWGFGO{appendage}", false, cstype); CSLine fooDecl = CSVariableDeclaration.VarLine(new CSSimpleType($"FooWGFGO{appendage}", false, new CSSimpleType(cstype)), "foo", new CSFunctionCall(fooType.ToString(), true, new CSIdentifier(val1))); CSLine printer = CSFunctionCall.ConsoleWriteLine((CSIdentifier)"foo.X"); CSCodeBlock callingCode = CSCodeBlock.Create(fooDecl, printer); TestRunning.TestAndExecute(swiftCode, callingCode, expected, testName: $"WrapGenFieldGetOnly{appendage}"); }
public void CanGetProtocolConformanceDescMarshal() { // var confDesc = StructMarshal.Marshaler.ProtocolConformanceof (typeof (IIteratorProtocol<>), // typeof (SwiftIteratorProtocolProxy<nint>); // Console.WriteLine (confDesc != IntPtr.Zero); var swiftCode = @" public func canGetProtocolConfDescMarshal () { } "; var confDescID = new CSIdentifier("confDesc"); var concreteType = new CSSimpleType("SwiftIteratorProtocolProxy<nint>").Typeof(); var ifaceType = new CSSimpleType("IIteratorProtocol<>").Typeof(); var confDescDecl = CSVariableDeclaration.VarLine(CSSimpleType.Var, confDescID, new CSFunctionCall("StructMarshal.Marshaler.ProtocolConformanceof", false, ifaceType, concreteType)); var printer = CSFunctionCall.ConsoleWriteLine(confDescID.Dot(new CSIdentifier("Handle")) != new CSIdentifier("IntPtr.Zero")); var callingCode = CSCodeBlock.Create(confDescDecl, printer); TestRunning.TestAndExecute(swiftCode, callingCode, "True\n"); }
public void ClosureIdentityIntBool() { var swiftCode = "public func closureIdentityIntBool(a: @escaping (Int) -> Bool) -> (Int) -> (Bool) {\n" + " return a\n" + "}\n"; var callingCode = new CodeElementCollection <ICodeElement> (); var body = new CSCodeBlock(); body.Add(CSFunctionCall.ConsoleWriteLine((CSIdentifier)"i")); body.Add(CSReturn.ReturnLine(CSConstant.Val(true))); var lambda = new CSLambda(body, "i"); var returnType = new CSSimpleType("Func", false, new CSSimpleType("nint"), CSSimpleType.Bool); callingCode.Add(CSVariableDeclaration.VarLine(returnType, "lam", lambda)); callingCode.Add(CSVariableDeclaration.VarLine(returnType, "lamreturn", new CSFunctionCall("TopLevelEntities.ClosureIdentityIntBool", false, new CSIdentifier("lam")))); callingCode.Add(CSFunctionCall.FunctionCallLine("lamreturn", false, CSConstant.Val(17))); TestRunning.TestAndExecute(swiftCode, callingCode, "17\n"); }
public void ClosureActionStringString() { var swiftCode = "public func closureIdentityStringString (a: @escaping (String, String)->()) -> (String, String) -> () {\n" + " return a\n" + "}\n"; var callingCode = new CodeElementCollection <ICodeElement> (); var body = new CSCodeBlock(); body.Add(CSFunctionCall.ConsoleWriteLine(CSFunctionCall.Function("stra.ToString") + CSFunctionCall.Function("strb.ToString"))); var lambda = new CSLambda(body, "stra", "strb"); var returnType = new CSSimpleType("Action", false, new CSSimpleType("SwiftString"), new CSSimpleType("SwiftString")); callingCode.Add(CSVariableDeclaration.VarLine(returnType, "lam", lambda)); callingCode.Add(CSVariableDeclaration.VarLine(returnType, "lamreturn", new CSFunctionCall("TopLevelEntities.ClosureIdentityStringString", false, new CSIdentifier("lam")))); callingCode.Add(CSFunctionCall.FunctionCallLine("lamreturn", false, new CSFunctionCall("SwiftString.FromString", false, CSConstant.Val("hi ")), new CSFunctionCall("SwiftString.FromString", false, CSConstant.Val("mom")))); TestRunning.TestAndExecute(swiftCode, callingCode, "hi mom\n"); }
void WrapGenSubscriptGetSet(string cstype, string val1, string val2, string expected) { string swiftCode = $"public struct BarWGSbGS{cstype} {{\npublic var X:Int32 = 0;\npublic init(x:Int32) {{\n X = x;\n}}\n}}\n" + $"public struct FooWGSbGS{cstype}<T> {{\nprivate var x:T\npublic init(a:T) {{\nx = a\n }}\n" + $"public subscript(index:T) -> T {{\nget {{\nreturn x\n}}\nset {{\n x = newValue\n}}\n}}\n}}\n"; CSSimpleType fooType = new CSSimpleType($"FooWGSbGS{cstype}", false, cstype); CSLine fooDecl = CSVariableDeclaration.VarLine(new CSSimpleType($"FooWGSbGS{cstype}", false, new CSSimpleType(cstype)), "foo", new CSFunctionCall(fooType.ToString(), true, new CSIdentifier(val1))); CSLine printer = CSFunctionCall.ConsoleWriteLine((CSIdentifier)$"foo[{val1}]"); CSLine setter = CSAssignment.Assign($"foo[{val1}]", CSAssignmentOperator.Assign, new CSIdentifier(val2)); CSCodeBlock callingCode = CSCodeBlock.Create(fooDecl, printer, setter, printer); TestRunning.TestAndExecute(swiftCode, callingCode, expected, testName: $"WrapGenSubscriptGetSet{cstype}"); }
public void ClosureIdentityDoubleDoubleDouble() { var swiftCode = "public func closureIdentityDoubleDoubleDouble(a: @escaping (Double, Double) -> Double) -> (Double, Double) -> Double {\n" + " return a\n" + "}\n"; var callingCode = new CodeElementCollection <ICodeElement> (); var body = new CSCodeBlock(); var aId = new CSIdentifier("a"); var bId = new CSIdentifier("b"); body.Add(CSFunctionCall.ConsoleWriteLine(aId + bId)); body.Add(CSReturn.ReturnLine(aId + bId)); var lambda = new CSLambda(body, "a", "b"); var returnType = new CSSimpleType("Func", false, CSSimpleType.Double, CSSimpleType.Double, CSSimpleType.Double); callingCode.Add(CSVariableDeclaration.VarLine(returnType, "lam", lambda)); callingCode.Add(CSVariableDeclaration.VarLine(returnType, "lamreturn", new CSFunctionCall("TopLevelEntities.ClosureIdentityDoubleDoubleDouble", false, new CSIdentifier("lam")))); callingCode.Add(CSFunctionCall.FunctionCallLine("lamreturn", false, CSConstant.Val(3.1), CSConstant.Val(4.0))); TestRunning.TestAndExecute(swiftCode, callingCode, "7.1\n"); }
public void ArcClassStruct() { string swiftCode = "public final class Foo {\npublic var _nm:String\npublic init(name:String) {\n_nm = name }\n" + "deinit {\nprint(_nm)\n}\n}\n" + "public struct Bar {\n public var a:Foo\n public init(f:Foo) {\n a = f\n}\n }\n" ; swiftCode += TestRunning.CreateSwiftConsoleRedirect(); using (TempDirectoryFilenameProvider provider = new TempDirectoryFilenameProvider(null, true)) { Utils.CompileSwift(swiftCode, provider); string libFileName = Path.Combine(provider.DirectoryPath, "libXython.dylib"); var errors = new ErrorHandling(); ModuleInventory.FromFile(libFileName, errors); Utils.CheckErrors(errors); Utils.CompileToCSharp(provider); CSUsingPackages use = new CSUsingPackages("System", "System.Runtime.InteropServices", "SwiftRuntimeLibrary"); CSNamespace ns = new CSNamespace("Xython"); CSFile csfile = CSFile.Create(use, ns); CSIdentifier inst = new CSIdentifier("inst"); CSLine newer = CSVariableDeclaration.VarLine((CSSimpleType)"Foo", inst, CSFunctionCall.Ctor("Foo", CSFunctionCall.Function("SwiftString.FromString", CSConstant.Val("nothing")))); CSIdentifier inst1 = new CSIdentifier("bar"); CSLine newer1 = CSVariableDeclaration.VarLine((CSSimpleType)"Bar", inst1, CSFunctionCall.Ctor("Bar", inst)); CSLine disposer = CSFunctionCall.FunctionCallLine(inst.Name + ".Dispose", false); CSLine disposer1 = CSFunctionCall.FunctionCallLine(inst1.Name + ".Dispose", false); CSCodeBlock mainBody = CSCodeBlock.Create(newer, newer1, disposer, disposer1); CSMethod main = new CSMethod(CSVisibility.Public, CSMethodKind.Static, CSSimpleType.Void, (CSIdentifier)"Main", new CSParameterList(new CSParameter(CSSimpleType.CreateArray("string"), "args")), mainBody); CSClass mainClass = new CSClass(CSVisibility.Public, "NameNotImportant", new CSMethod [] { main }); ns.Block.Add(mainClass); string csOutFilename = provider.ProvideFileFor(provider.UniqueName(null, "CSWrap", "cs")); var exeOutFilename = provider.UniquePath(null, "CSWrap", "exe"); CodeWriter.WriteToFile(csOutFilename, csfile); Compiler.CSCompile(provider.DirectoryPath, Directory.GetFiles(provider.DirectoryPath, "*.cs"), exeOutFilename); TestRunning.CopyTestReferencesTo(provider.DirectoryPath); string output = Compiler.RunWithMono(exeOutFilename, provider.DirectoryPath); Assert.AreEqual("nothing\n", output); } }
public List <ICodeElement> MarshalFromLambdaReceiverToCSFunc(CSType thisType, string csProxyName, CSParameterList delegateParams, FunctionDeclaration funcDecl, CSType methodType, CSParameterList methodParams, string methodName, bool isObjC) { bool thisIsInterface = csProxyName != null; bool isIndexer = funcDecl.IsSubscript; bool needsReturn = methodType != null && methodType != CSSimpleType.Void; bool isSetter = funcDecl.IsSubscriptSetter; bool returnIsGeneric = funcDecl.IsTypeSpecGeneric(funcDecl.ReturnTypeSpec); var entity = !returnIsGeneric?typeMapper.GetEntityForTypeSpec(funcDecl.ReturnTypeSpec) : null; var returnEntity = entity; var entityType = !returnIsGeneric?typeMapper.GetEntityTypeForTypeSpec(funcDecl.ReturnTypeSpec) : EntityType.None; bool returnIsStruct = needsReturn && entity != null && entity.IsStructOrEnum; bool returnIsClass = needsReturn && entity != null && entity.EntityType == EntityType.Class; bool returnIsProtocol = needsReturn && ((entity != null && entity.EntityType == EntityType.Protocol) || entityType == EntityType.ProtocolList); bool returnIsTuple = needsReturn && entityType == EntityType.Tuple; bool returnIsClosure = needsReturn && entityType == EntityType.Closure; var callParams = new List <CSBaseExpression> (); var preMarshalCode = new List <CSLine> (); var postMarshalCode = new List <CSLine> (); CSBaseExpression valueExpr = null; bool marshalingThrows = false; if (isSetter) { var valueID = delegateParams [1].Name; valueExpr = valueID; var swiftNewValue = funcDecl.ParameterLists [1] [0]; bool newValueIsGeneric = funcDecl.IsTypeSpecGeneric(funcDecl.PropertyType); entity = !newValueIsGeneric?typeMapper.GetEntityForTypeSpec(swiftNewValue.TypeSpec) : null; entityType = !newValueIsGeneric?typeMapper.GetEntityTypeForTypeSpec(swiftNewValue.TypeSpec) : EntityType.None; var isUnusualNewValue = IsUnusualParameter(entity, delegateParams [1]); if (entityType == EntityType.Class || entity.IsObjCProtocol) { var csParmType = new CSSimpleType(entity.SharpNamespace + "." + entity.SharpTypeName); if (csParmType == null) { throw ErrorHelper.CreateError(ReflectorError.kTypeMapBase + 26, "Inconceivable! The class type for a subscript was NOT a CSSimpleType!"); } use.AddIfNotPresent(typeof(SwiftObjectRegistry)); var fullClassName = entity.Type.ToFullyQualifiedName(true); valueExpr = NewClassCompiler.SafeMarshalClassFromIntPtr(valueID, csParmType, use, fullClassName, typeMapper, entity.IsObjCProtocol); } else if (entityType == EntityType.Protocol) { var csParmType = new CSSimpleType(entity.SharpNamespace + "." + entity.SharpTypeName); if (csParmType == null) { throw ErrorHelper.CreateError(ReflectorError.kTypeMapBase + 27, "Inconceivable! The protocol type for a subscript was NOT a CSSimpleType!"); } use.AddIfNotPresent(typeof(StructMarshal)); use.AddIfNotPresent(typeof(SwiftObjectRegistry)); valueExpr = new CSFunctionCall($"SwiftObjectRegistry.Registry.InterfaceForExistentialContainer<{csParmType.ToString ()}>", false, valueID); } else if ((entityType == EntityType.Struct || entityType == EntityType.Enum) && !isUnusualNewValue) { var csParmType = new CSSimpleType(entity.SharpNamespace + "." + entity.SharpTypeName); if (csParmType == null) { throw ErrorHelper.CreateError(ReflectorError.kTypeMapBase + 28, $"Inconceivable! The {entityType} type for a subscript was NOT a CSSimpleType!"); } use.AddIfNotPresent(typeof(StructMarshal)); string valMarshalName = MarshalEngine.Uniqueify("val", identifiersUsed); var valMarshalId = new CSIdentifier(valMarshalName); CSLine valDecl = CSVariableDeclaration.VarLine(csParmType, valMarshalId, new CSCastExpression(csParmType, new CSFunctionCall("StructMarshal.Marshaler.ToNet", false, valueID, csParmType.Typeof()))); preMarshalCode.Add(valDecl); valueExpr = valMarshalId; } else if (entityType == EntityType.Tuple) { var csParmType = new CSSimpleType(entity.SharpNamespace + "." + entity.SharpTypeName); if (csParmType == null) { throw ErrorHelper.CreateError(ReflectorError.kTypeMapBase + 29, "Inconceivable! The tuple type for a subscript was NOT a CSSimpleType!"); } use.AddIfNotPresent(typeof(StructMarshal)); string valMarshalName = MarshalEngine.Uniqueify("val", identifiersUsed); var valMarshalId = new CSIdentifier(valMarshalName); var valDecl = CSVariableDeclaration.VarLine(csParmType, valMarshalId, new CSCastExpression(csParmType, new CSFunctionCall("StructMarshal.Marshaler.ToNet", false, valueID, csParmType.Typeof()))); preMarshalCode.Add(valDecl); valueExpr = valMarshalId; } else if (newValueIsGeneric) { var depthIndex = funcDecl.GetGenericDepthAndIndex(swiftNewValue.TypeSpec); var genRef = new CSGenericReferenceType(depthIndex.Item1, depthIndex.Item2); if (genRef == null) { throw ErrorHelper.CreateError(ReflectorError.kTypeMapBase + 30, "Inconceivable! The generic type for a parameter in a method was NOT a CSGenericReferenceType!"); } use.AddIfNotPresent(typeof(StructMarshal)); string valMarshalName = MarshalEngine.Uniqueify("valTemp", identifiersUsed); var valMarshalId = new CSIdentifier(valMarshalName); var valDecl = CSVariableDeclaration.VarLine(genRef, valMarshalId, new CSCastExpression(genRef, new CSFunctionCall("StructMarshal.Marshaler.ToNet", false, valueID, genRef.Typeof()))); preMarshalCode.Add(valDecl); valueExpr = valMarshalId; } } int j = 0; int k = isSetter ? 1 : 0; for (int i = (funcDecl.HasThrows || returnIsStruct || returnIsProtocol || isSetter || returnIsGeneric) ? 2 : 1; i < delegateParams.Count; i++, j++, k++) { var swiftParm = funcDecl.ParameterLists [1] [k]; bool parmIsGeneric = funcDecl.IsTypeSpecGeneric(swiftParm); entity = !parmIsGeneric?typeMapper.GetEntityForTypeSpec(swiftParm.TypeSpec) : null; entityType = !parmIsGeneric?typeMapper.GetEntityTypeForTypeSpec(swiftParm.TypeSpec) : EntityType.None; var isUnusualParameter = IsUnusualParameter(entity, delegateParams [i]); var csParm = methodParams [j]; if (entityType == EntityType.Class || (entity != null && entity.IsObjCProtocol)) { var csParmType = csParm.CSType as CSSimpleType; if (csParmType == null) { throw ErrorHelper.CreateError(ReflectorError.kTypeMapBase + 31, "Inconceivable! The class type for a method was NOT a CSSimpleType!"); } use.AddIfNotPresent(typeof(SwiftObjectRegistry)); var fullClassName = entity.Type.ToFullyQualifiedName(true); var retrievecall = NewClassCompiler.SafeMarshalClassFromIntPtr(delegateParams [0].Name, csParmType, use, fullClassName, typeMapper, entity.IsObjCProtocol); if (csParm.ParameterKind == CSParameterKind.Out || csParm.ParameterKind == CSParameterKind.Ref) { string id = MarshalEngine.Uniqueify(delegateParams [i].Name.Name, identifiersUsed); identifiersUsed.Add(id); preMarshalCode.Add(CSFieldDeclaration.FieldLine(csParmType, id, retrievecall)); callParams.Add(new CSIdentifier(String.Format("{0} {1}", csParm.ParameterKind == CSParameterKind.Out ? "out" : "ref", id))); postMarshalCode.Add(CSAssignment.Assign(delegateParams [i].Name, NewClassCompiler.SafeBackingFieldAccessor(new CSIdentifier(id), use, entity.Type.ToFullyQualifiedName(true), typeMapper))); } else { callParams.Add(retrievecall); } } else if (entityType == EntityType.Protocol) { var thePtr = new CSIdentifier(MarshalEngine.Uniqueify("p", identifiersUsed)); var csParmType = csParm.CSType as CSSimpleType; if (csParmType == null) { throw ErrorHelper.CreateError(ReflectorError.kTypeMapBase + 32, "Inconceivable! The protocol type for a method was NOT a CSSimpleType!"); } use.AddIfNotPresent(typeof(SwiftObjectRegistry)); string csParmProxyType = NewClassCompiler.CSProxyNameForProtocol(entity.Type.ToFullyQualifiedName(true), typeMapper); if (csParmProxyType == null) { throw ErrorHelper.CreateError(ReflectorError.kTypeMapBase + 33, $"Unable to find C# interface type for protocol {entity.Type.ToFullyQualifiedName ()}"); } var retrievecall = new CSFunctionCall($"SwiftObjectRegistry.Registry.InterfaceForExistentialContainer<{csParmType.Name}>", false, delegateParams [i].Name); if (csParm.ParameterKind == CSParameterKind.Out || csParm.ParameterKind == CSParameterKind.Ref) { CSIdentifier id = new CSIdentifier(MarshalEngine.Uniqueify(delegateParams [i].Name.Name, identifiersUsed)); identifiersUsed.Add(id.Name); preMarshalCode.Add(CSFieldDeclaration.FieldLine(csParmType, id.Name, retrievecall)); callParams.Add(new CSIdentifier(String.Format("{0} {1}", csParm.ParameterKind == CSParameterKind.Out ? "out" : "ref", id))); postMarshalCode.Add(CSAssignment.Assign(delegateParams [i].Name, new CSFunctionCall("SwiftExistentialContainer1", true, new CSFunctionCall("SwiftObjectRegistry.Registry.ExistentialContainerForProtocol", false, id, csParmType.Typeof())))); } else { callParams.Add(retrievecall); } } else if ((entityType == EntityType.Struct || entityType == EntityType.Enum) && !isUnusualParameter) { var csParmType = csParm.CSType as CSSimpleType; if (csParmType == null) { throw ErrorHelper.CreateError(ReflectorError.kTypeMapBase + 34, $"Inconceivable! The {entityType} type for a method was NOT a CSSimpleType!"); } use.AddIfNotPresent(typeof(StructMarshal)); use.AddIfNotPresent(typeof(StructMarshal)); string valMarshalName = MarshalEngine.Uniqueify(delegateParams [i].Name + "Temp", identifiersUsed); var valMarshalId = new CSIdentifier(valMarshalName); var valDecl = CSVariableDeclaration.VarLine(csParmType, valMarshalId, new CSCastExpression(csParmType, new CSFunctionCall("StructMarshal.Marshaler.ToNet", false, delegateParams [i].Name, csParmType.Typeof()))); preMarshalCode.Add(valDecl); callParams.Add(valMarshalId); } else if (entityType == EntityType.Tuple) { var csParmType = csParm.CSType as CSSimpleType; if (csParmType == null) { throw ErrorHelper.CreateError(ReflectorError.kTypeMapBase + 35, "Inconceivable! The tuple type for a parameter in a method was NOT a CSSimpleType!"); } use.AddIfNotPresent(typeof(StructMarshal)); string valMarshalName = MarshalEngine.Uniqueify(delegateParams [i].Name + "Temp", identifiersUsed); var valMarshalId = new CSIdentifier(valMarshalName); var valDecl = CSVariableDeclaration.VarLine(csParmType, valMarshalId, new CSCastExpression(csParmType, new CSFunctionCall("StructMarshal.Marshaler.ToNet", false, delegateParams [i].Name, csParmType.Typeof()))); preMarshalCode.Add(valDecl); callParams.Add(valMarshalId); } else if (entityType == EntityType.Closure) { // parm is a SwiftClosureRepresentation // (FuncType)StructMarshal.Marshaler.MakeDelegateFromBlindClosure (arg, argTypes, returnType); var argTypesId = new CSIdentifier(MarshalEngine.Uniqueify("argTypes" + delegateParams [i], identifiersUsed)); identifiersUsed.Add(argTypesId.Name); var parmType = csParm.CSType as CSSimpleType; if (parmType == null) { throw ErrorHelper.CreateError(ReflectorError.kTypeMapBase + 44, "Inconceivable! The type for a closure should be a CSSimpleType"); } var hasReturn = parmType.GenericTypeName == "Func"; var returnType = hasReturn ? (CSBaseExpression)parmType.GenericTypes [parmType.GenericTypes.Length - 1].Typeof() : CSConstant.Null; var argTypesLength = hasReturn ? parmType.GenericTypes.Length - 1 : parmType.GenericTypes.Length; var argTypes = new CSBaseExpression [argTypesLength]; for (int idx = 0; idx < argTypesLength; idx++) { argTypes [idx] = parmType.GenericTypes [idx].Typeof(); } var typeArr = new CSArray1DInitialized(CSSimpleType.Type, argTypes); var closureExpr = new CSFunctionCall("StructMarshal.Marshaler.MakeDelegateFromBlindClosure", false, delegateParams [i].Name, typeArr, returnType); var castTo = new CSCastExpression(csParm.CSType, closureExpr); callParams.Add(castTo); } else if (entityType == EntityType.ProtocolList) { preMarshalCode.Add(CSFunctionCall.FunctionCallLine("throw new NotImplementedException", false, CSConstant.Val($"Argument {csParm.Name} is a protocol list type and can't be marshaled from a virtual method."))); callParams.Add(CSConstant.Null); marshalingThrows = true; } else if (parmIsGeneric) { // parm is an IntPtr to some T // to get T, we ask funcDecl for the depthIndex of T // T someVal = (T)StructMarshal.Marshaler.ToNet(parm, typeof(T)); // someVal gets passed in var genRef = csParm.CSType as CSGenericReferenceType; if (genRef == null) { throw ErrorHelper.CreateError(ReflectorError.kTypeMapBase + 36, "Inconceivable! The generic type for a parameter in a method was NOT a CSGenericReferenceType!"); } use.AddIfNotPresent(typeof(StructMarshal)); string valMarshalName = MarshalEngine.Uniqueify(delegateParams [i].Name + "Temp", identifiersUsed); var valMarshalId = new CSIdentifier(valMarshalName); var valDecl = CSVariableDeclaration.VarLine(genRef, valMarshalId, new CSCastExpression(genRef, new CSFunctionCall("StructMarshal.Marshaler.ToNet", false, delegateParams [i].Name, genRef.Typeof()))); preMarshalCode.Add(valDecl); callParams.Add(valMarshalId); } else { if (csParm.ParameterKind == CSParameterKind.Out || csParm.ParameterKind == CSParameterKind.Ref) { callParams.Add(new CSIdentifier(String.Format("{0} {1}", csParm.ParameterKind == CSParameterKind.Out ? "out" : "ref", delegateParams [i].Name.Name))); } else { callParams.Add(delegateParams [i].Name); } } } var body = new CSCodeBlock(); if (isObjC) { use.AddIfNotPresent("ObjCRuntime"); } else { use.AddIfNotPresent(typeof(SwiftObjectRegistry)); } CSBaseExpression invoker = null; if (isIndexer) { if (thisIsInterface) { invoker = new CSIndexExpression( $"SwiftObjectRegistry.Registry.InterfaceForExistentialContainer<{thisType.ToString ()}> (self)", false, callParams.ToArray()); } else { var registryCall = isObjC ? $"Runtime.GetNSObject<{thisType.ToString ()}> (self)" : $"SwiftObjectRegistry.Registry.CSObjectForSwiftObject <{thisType.ToString ()}> (self)"; invoker = new CSIndexExpression(registryCall, false, callParams.ToArray()); } } else { if (thisIsInterface) { invoker = new CSFunctionCall( $"SwiftObjectRegistry.Registry.InterfaceForExistentialContainer<{thisType.ToString ()}> (self).{methodName}", false, callParams.ToArray()); } else { var registryCall = isObjC ? $"Runtime.GetNSObject<{thisType.ToString ()}>(self).{methodName}" : $"SwiftObjectRegistry.Registry.CSObjectForSwiftObject <{thisType.ToString ()}> (self).{methodName}"; invoker = new CSFunctionCall(registryCall, false, callParams.ToArray()); } } var tryBlock = funcDecl.HasThrows ? new CSCodeBlock() : null; var catchBlock = funcDecl.HasThrows ? new CSCodeBlock() : null; var altBody = tryBlock ?? body; string catchName = MarshalEngine.Uniqueify("e", identifiersUsed); var catchID = new CSIdentifier(catchName); altBody.AddRange(preMarshalCode); if (marshalingThrows) { return(altBody); } if (funcDecl.HasThrows || needsReturn) // function that returns or getter { if (funcDecl.HasThrows) { use.AddIfNotPresent(typeof(SwiftError)); use.AddIfNotPresent(typeof(Tuple)); use.AddIfNotPresent(typeof(StructMarshal)); CSType returnTuple = null; if (needsReturn) { returnTuple = new CSSimpleType("Tuple", false, methodType, new CSSimpleType(typeof(SwiftError)), CSSimpleType.Bool); } else { returnTuple = new CSSimpleType("Tuple", false, new CSSimpleType(typeof(SwiftError)), CSSimpleType.Bool); } if (needsReturn) { string retvalName = MarshalEngine.Uniqueify("retval", identifiersUsed); var retvalId = new CSIdentifier(retvalName); altBody.Add(CSFieldDeclaration.VarLine(methodType, retvalId, invoker)); postMarshalCode.Add(CSFunctionCall.FunctionCallLine("StructMarshal.Marshaler.ToSwift", false, methodType.Typeof(), retvalId, delegateParams [0].Name)); altBody.Add(CSFunctionCall.FunctionCallLine("StructMarshal.Marshaler.SetErrorNotThrown", false, delegateParams [0].Name, returnTuple.Typeof())); } else { if (isSetter) { altBody.Add(CSAssignment.Assign(invoker, CSAssignmentOperator.Assign, valueExpr)); } else { altBody.Add(new CSLine(invoker)); } altBody.Add(CSFunctionCall.FunctionCallLine("StructMarshal.Marshaler.SetErrorNotThrown", false, delegateParams [0].Name, returnTuple.Typeof())); } string swiftError = MarshalEngine.Uniqueify("err", identifiersUsed); var swiftErrorIdentifier = new CSIdentifier(swiftError); catchBlock.Add(CSFieldDeclaration.VarLine(new CSSimpleType(typeof(SwiftError)), swiftErrorIdentifier, new CSFunctionCall("SwiftError.FromException", false, catchID))); catchBlock.Add(CSFunctionCall.FunctionCallLine("StructMarshal.Marshaler.SetErrorThrown", false, delegateParams [0].Name, swiftErrorIdentifier, returnTuple.Typeof())); } else { if (returnIsClass) { string retvalName = MarshalEngine.Uniqueify("retval", identifiersUsed); CSIdentifier retvalId = new CSIdentifier(retvalName); altBody.Add(CSFieldDeclaration.VarLine(methodType, retvalId, invoker)); postMarshalCode.Add(CSReturn.ReturnLine( NewClassCompiler.SafeBackingFieldAccessor(retvalId, use, returnEntity.Type.ToFullyQualifiedName(), typeMapper))); } else if (returnIsProtocol) { string retvalName = MarshalEngine.Uniqueify("retval", identifiersUsed); identifiersUsed.Add(retvalName); var retvalId = new CSIdentifier(retvalName); altBody.Add(CSFieldDeclaration.VarLine(methodType, retvalId, invoker)); var returnContainer = MarshalEngine.Uniqueify("returnContainer", identifiersUsed); identifiersUsed.Add(returnContainer); var returnContainerId = new CSIdentifier(returnContainer); var protoGetter = new CSFunctionCall($"SwiftObjectRegistry.Registry.ExistentialContainerForProtocols", false, retvalId, methodType.Typeof()); var protoDecl = CSVariableDeclaration.VarLine(CSSimpleType.Var, returnContainerId, protoGetter); var marshalBack = CSFunctionCall.FunctionCallLine($"{returnContainer}.CopyTo", delegateParams [0].Name); postMarshalCode.Add(protoDecl); postMarshalCode.Add(marshalBack); } else if (returnIsStruct) { // non-blitable means that the parameter is an IntPtr and we can call the // marshaler to copy into it use.AddIfNotPresent(typeof(StructMarshal)); var marshalCall = CSFunctionCall.FunctionCallLine("StructMarshal.Marshaler.ToSwift", false, invoker, delegateParams [0].Name); altBody.Add(marshalCall); } else if (returnIsTuple) { // non-blitable means that the parameter is an IntPtr and we can call the // marshaler to copy into it use.AddIfNotPresent(typeof(StructMarshal)); var marshalCall = CSFunctionCall.FunctionCallLine("StructMarshal.Marshaler.ToSwift", false, invoker, delegateParams [0].Name); altBody.Add(marshalCall); } else if (returnIsGeneric) { // T retval = invoker(); // if (retval is ISwiftObject) { // Marshal.WriteIntPtr(delegateParams [0].Name, ((ISwiftObject)retval).SwiftObject); // } // else { // StructMarshal.Marshaler.ToSwift(typeof(T), retval, delegateParams[0].Name); // } string retvalName = MarshalEngine.Uniqueify("retval", identifiersUsed); var retvalId = new CSIdentifier(retvalName); altBody.Add(CSFieldDeclaration.VarLine(methodType, retvalId, invoker)); var ifClause = new CSCodeBlock(); ifClause.Add(CSFunctionCall.FunctionCallLine("Marshal.WriteIntPtr", false, delegateParams [0].Name, new CSParenthesisExpression(new CSCastExpression("ISwiftObject", retvalId)).Dot(NewClassCompiler.kSwiftObjectGetter))); var elseClause = new CSCodeBlock(); elseClause.Add(CSFunctionCall.FunctionCallLine("StructMarshal.Marshaler.ToSwift", false, methodType.Typeof(), retvalId, delegateParams [0].Name)); CSBaseExpression ifExpr = new CSSimpleType("ISwiftObject").Typeof().Dot(new CSFunctionCall("IsAssignableFrom", false, methodType.Typeof())); var retTest = new CSIfElse(ifExpr, ifClause, elseClause); altBody.Add(retTest); } else { if (returnIsClosure) { invoker = MarshalEngine.BuildBlindClosureCall(invoker, methodType as CSSimpleType, use); } if (postMarshalCode.Count > 0) { string retvalName = MarshalEngine.Uniqueify("retval", identifiersUsed); CSIdentifier retvalId = new CSIdentifier(retvalName); altBody.Add(CSFieldDeclaration.VarLine(methodType, retvalId, invoker)); postMarshalCode.Add(CSReturn.ReturnLine(retvalId)); } else { altBody.Add(CSReturn.ReturnLine(invoker)); } } } } else // no return or setter { if (isSetter) { altBody.Add(CSAssignment.Assign(invoker, CSAssignmentOperator.Assign, valueExpr)); } else { altBody.Add(new CSLine(invoker)); } } altBody.AddRange(postMarshalCode); if (funcDecl.HasThrows) { body.Add(new CSTryCatch(tryBlock, new CSCatch(typeof(Exception), catchName, catchBlock))); } return(body); }
public static CSNamespace CreateManagedConsoleRedirect() { // Same as GetManagedConsoleRedirectCode, just different format. var cs = new CSNamespace(); var console = new CSClass(CSVisibility.Public, "Console", isStatic: true); console.Fields.Add(CSFieldDeclaration.FieldLine(CSSimpleType.String, new CSIdentifier("filename"), isStatic: true)); console.Properties.Add( new CSProperty( CSSimpleType.String, CSMethodKind.Static, new CSIdentifier("Filename"), CSVisibility.None, CSCodeBlock.Create( new CSIfElse( new CSBinaryExpression( CSBinaryOperator.Equal, new CSIdentifier("filename"), new CSIdentifier("null") ), CSCodeBlock.Create( CSAssignment.Assign( new CSIdentifier("filename"), new CSBinaryExpression( CSBinaryOperator.NullCoalesce, CSFunctionCall.Function( "Environment.GetEnvironmentVariable", CSConstant.Val("LEAKTEST_STDOUT_PATH") ), new CSIdentifier("string.Empty") ) ) ) ), CSReturn.ReturnLine(new CSIdentifier("filename")) ), CSVisibility.None, null ) ); console.Methods.Add( new CSMethod( CSVisibility.Public, CSMethodKind.Static, CSSimpleType.Void, new CSIdentifier("write"), new CSParameterList( new CSParameter(CSSimpleType.String, new CSIdentifier("value")) ), CSCodeBlock.Create( new CSIfElse( new CSIdentifier("string.IsNullOrEmpty (Filename)"), CSCodeBlock.Create(CSFunctionCall.FunctionCallLine("global::System.Console.Write", new CSIdentifier("value"))), CSCodeBlock.Create(CSFunctionCall.FunctionCallLine("System.IO.File.AppendAllText", new CSIdentifier("Filename"), new CSIdentifier("value"))) ) ) ) ); console.Methods.Add( new CSMethod( CSVisibility.Public, CSMethodKind.Static, CSSimpleType.Void, new CSIdentifier("Write"), new CSParameterList( new CSParameter(CSSimpleType.Object, new CSIdentifier("value")) ), CSCodeBlock.Create( CSFunctionCall.FunctionCallLine( "write", false, new CSIdentifier("value?.ToString ()") ) ) ) ); console.Methods.Add( new CSMethod( CSVisibility.Public, CSMethodKind.Static, CSSimpleType.Void, new CSIdentifier("Write"), new CSParameterList( new CSParameter(CSSimpleType.String, new CSIdentifier("value")), new CSParameter(CSSimpleType.CreateArray("object"), new CSIdentifier("args"), CSParameterKind.Params) ), CSCodeBlock.Create( CSFunctionCall.FunctionCallLine( "write", false, new CSIdentifier("value == null ? string.Empty : string.Format (value, args)") ) ) ) ); console.Methods.Add( new CSMethod( CSVisibility.Public, CSMethodKind.Static, CSSimpleType.Void, new CSIdentifier("WriteLine"), new CSParameterList( new CSParameter(CSSimpleType.Object, new CSIdentifier("value")) ), CSCodeBlock.Create( CSFunctionCall.FunctionCallLine( "write", false, new CSIdentifier("value?.ToString () + Environment.NewLine") ) ) ) ); console.Methods.Add( new CSMethod( CSVisibility.Public, CSMethodKind.Static, CSSimpleType.Void, new CSIdentifier("WriteLine"), new CSParameterList( new CSParameter(CSSimpleType.String, new CSIdentifier("value")), new CSParameter(CSSimpleType.CreateArray("object"), new CSIdentifier("args"), CSParameterKind.Params) ), CSCodeBlock.Create( CSFunctionCall.FunctionCallLine( "write", false, new CSIdentifier("(value == null ? string.Empty : string.Format (value, args)) + Environment.NewLine") ) ) ) ); cs.Block.Add(console); return(cs); }
static CSFile GeneratePInvokesFromTypes(TypeAggregator types, PlatformName platform, string framework) { var fileName = Path.GetFileNameWithoutExtension(framework); // /path/XamGlue.framework -> XamGlue var dylibFile = Path.Combine(framework, fileName); var funcs = TLFunctionsForFile(dylibFile, platform); var ns = new CSNamespace("SwiftRuntimeLibrary.SwiftMarshal"); var use = new CSUsingPackages(); use.And(new CSUsing("System.Runtime.InteropServices")) .And(new CSUsing("System")) .And(new CSUsing("System.Collections.Generic")) .And(new CSUsing("SwiftRuntimeLibrary")); var csFile = new CSFile(use, new CSNamespace [] { ns }); var csClass = new CSClass(CSVisibility.Internal, $"{fileName}Metadata"); new CSComment(kRobotText).AttachBefore(use); CSConditionalCompilation.If(PlatformToCSCondition(platform)).AttachBefore(use); CSConditionalCompilation.Endif.AttachAfter(ns); ns.Block.Add(csClass); var typeOntoPinvoke = new List <KeyValuePair <CSBaseExpression, CSBaseExpression> > (); var typesToProcess = new List <TypeDefinition> (); typesToProcess.AddRange(types.PublicEnums); typesToProcess.AddRange(types.PublicStructs); // pre-sort by function name typesToProcess.Sort((type1, type2) => String.CompareOrdinal(FuncIDForTypeDefinition(type1), FuncIDForTypeDefinition(type2))); foreach (var type in typesToProcess) { if (type.HasGenericParameters) { continue; } var moduleName = type.Namespace; var name = type.Name; if (TypeAggregator.FilterModuleAndName(platform, moduleName, ref name)) { var pinvoke = PInvokeForType(type, funcs); if (pinvoke != null) { csClass.Methods.Add(pinvoke); use.AddIfNotPresent(type.Namespace); var typeOf = new CSSimpleType(type.FullName).Typeof(); var funcName = pinvoke.Name; typeOntoPinvoke.Add(new KeyValuePair <CSBaseExpression, CSBaseExpression> (typeOf, funcName)); } } } var initializers = typeOntoPinvoke.Select(typeAndFunc => new CSInitializer(new CSBaseExpression [] { typeAndFunc.Key, typeAndFunc.Value }, false)); var bindingExpr = new CSInitializedType(new CSFunctionCall("Dictionary<Type, Func<SwiftMetatype>>", true), new CSInitializer(initializers, true)); var bindingDecl = new CSFieldDeclaration(new CSSimpleType("Dictionary<Type, Func<SwiftMetatype>>"), "ObjCBindingSwiftMetatypes", bindingExpr, CSVisibility.Internal, true); csClass.Fields.Add(new CSLine(bindingDecl)); use.Sort((package1, package2) => String.CompareOrdinal(package1.Package, package2.Package)); return(csFile); }
public static CSFile GenerateTestEntry(CodeElementCollection <ICodeElement> callingCode, string testName, string nameSpace, PlatformName platform, CSClass otherClass = null) { var use = GetTestEntryPointUsings(nameSpace, platform); var ns = new CSNamespace(nameSpace); if (otherClass != null) { ns.Block.Add(otherClass); } var mainBody = new CSCodeBlock(callingCode); mainBody.Add(CaptureSwiftOutputPostlude(testName)); var main = new CSMethod(CSVisibility.Public, CSMethodKind.Static, CSSimpleType.Void, (CSIdentifier)"Main", new CSParameterList(new CSParameter(CSSimpleType.CreateArray("string"), "args")), mainBody); var mainClass = new CSClass(CSVisibility.Public, "NameNotImportant", new CSMethod [] { main }); AddSupportingCode(mainClass, platform); ns.Block.Add(mainClass); return(CSFile.Create(use, ns)); }