public void TestCharacterCreation() { var swiftCode = @" public class CharacterHolder { public var C: Character; public init (c: Character) {C = c } }"; var callingCode = new CodeElementCollection <ICodeElement> (); StringBuilder expected = new StringBuilder(); foreach (string c in TestCases) { CSIdentifier testIdentifier = (CSIdentifier)$@"""{c}"""; Action <ICSExpression> testCharacter = creation => { CSCodeBlock block = new CSCodeBlock(); block.Add(CSVariableDeclaration.VarLine((CSSimpleType)"SwiftCharacter", (CSIdentifier)"Char", creation)); block.Add(CSVariableDeclaration.VarLine((CSSimpleType)"CharacterHolder", (CSIdentifier)"Foo", CSFunctionCall.Ctor("CharacterHolder", (CSIdentifier)"Char"))); block.Add(CSFunctionCall.FunctionLine("Console.Write", (CSIdentifier)"(string)Foo.C")); expected.Append(c); callingCode.Add(block); }; testCharacter(CSFunctionCall.Function("SwiftCharacter.FromCharacter", (testIdentifier))); testCharacter(new CSCastExpression((CSSimpleType)"SwiftCharacter", testIdentifier)); } TestRunning.TestAndExecute(swiftCode, callingCode, expected.ToString()); }
static CodeElementCollection <ICodeElement> CaptureSwiftOutputPostlude(string fileName) { //#if _MAC_TS_TEST_ // string path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), fileName); //#else //NSUrl[] urls = NSFileManager.DefaultManager.GetUrls(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomain.User); //string path = Path.Combine(urls[0].Path, fileName); //#endif //NSUrl[] urls = NSFileManager.DefaultManager.GetUrls(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomain.User); //string path = Path.Combine(urls[0].Path, fileName); //if (File.Exists(path)) //{ // Console.Write(File.ReadAllText(path)); //} CSCodeBlock block = new CSCodeBlock(); CSIdentifier pathID = new CSIdentifier("path"); block.Add(new CSIdentifier("\n#if _MAC_TS_TEST_\n")); block.Add(CSVariableDeclaration.VarLine(CSSimpleType.String, pathID, new CSFunctionCall("Path.Combine", false, new CSIdentifier("Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)") + CSConstant.Val("/Documents/"), CSConstant.Val(fileName)))); block.Add(new CSIdentifier("\n#else\n")); CSIdentifier urlID = new CSIdentifier("urls"); CSLine urlsLine = CSVariableDeclaration.VarLine(new CSSimpleType("NSUrl", true), urlID, new CSFunctionCall("NSFileManager.DefaultManager.GetUrls", false, new CSIdentifier("NSSearchPathDirectory.DocumentDirectory"), new CSIdentifier("NSSearchPathDomain.User"))); block.Add(urlsLine); CSLine pathLine = CSVariableDeclaration.VarLine(CSSimpleType.String, pathID, new CSFunctionCall("Path.Combine", false, new CSArray1D(urlID.Name, CSConstant.Val(0)).Dot(new CSIdentifier("Path")), CSConstant.Val(fileName))); block.Add(pathLine); block.Add(new CSIdentifier("\n#endif\n")); CSCodeBlock ifBlock = new CSCodeBlock(); CSLine writer = CSFunctionCall.FunctionCallLine("Console.Write", false, new CSFunctionCall("File.ReadAllText", false, pathID)); ifBlock.Add(writer); ifBlock.Add(CSFunctionCall.FunctionCallLine("File.Delete", false, pathID)); CSIfElse iftest = new CSIfElse(new CSFunctionCall("File.Exists", false, pathID), ifBlock); block.Add(iftest); return(block); }
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)); }
public void OperatorCompositionNoInvoke() { var swiftCode = "infix operator ∘\n" + " public func ∘<T>(left: @escaping (T) -> (T), right: @escaping (T) -> (T)) -> (T) -> (T) {\n" + " return { (x) in\n" + " left (right(x))\n" + " }\n" + "}\n"; var lbody1 = new CSCodeBlock(); var lid = new CSIdentifier("d"); lbody1.Add(CSReturn.ReturnLine(lid * CSConstant.Val(2.0))); var pl = new CSParameterList(); pl.Add(new CSParameter(CSSimpleType.Double, lid)); var lam1 = new CSLambda(pl, lbody1); var lbody2 = new CSCodeBlock(); lbody2.Add(CSReturn.ReturnLine(lid * CSConstant.Val(3.0))); var lam2 = new CSLambda(pl, lbody2); var compFunc = CSFunctionCall.FunctionCallLine("TopLevelEntities.InfixOperatorRing", false, lam1, lam2); var printIt = CSFunctionCall.ConsoleWriteLine(CSConstant.Val(12.0)); var callingCode = new CodeElementCollection <ICodeElement> { compFunc, printIt }; TestRunning.TestAndExecute(swiftCode, callingCode, "12\n"); }
static CSProperty MakeGetOnlyStringProp(string name, string val) { CSCodeBlock body = new CSCodeBlock(); body.Add(CSReturn.ReturnLine(CSConstant.Val(val))); return(new CSProperty(CSSimpleType.String, CSMethodKind.None, new CSIdentifier(name), CSVisibility.Public, body, CSVisibility.Public, null)); }
void TLExceptionVoid(string toAdd, string output) { string swiftCode = $"public enum MyErrorTLEV{toAdd} : Error {{\ncase itFailed\n}}\n" + $"public func throwItTLEV{toAdd}(doThrow: Bool) throws \n {{\n if doThrow {{\n throw MyErrorTLEV{toAdd}.itFailed\n}}\n}}\n"; CodeElementCollection <ICodeElement> callingCode = new CodeElementCollection <ICodeElement> (); CSCodeBlock tryBlock = new CSCodeBlock(); CSLine call = CSFunctionCall.FunctionCallLine($"TopLevelEntities.ThrowItTLEV{toAdd}", false, new CSIdentifier(toAdd)); CSLine writer = CSFunctionCall.FunctionCallLine("Console.Write", false, CSConstant.Val("no exception")); tryBlock.Add(call); tryBlock.Add(writer); CSCodeBlock catchBlock = new CSCodeBlock(); catchBlock.Add(CSFunctionCall.FunctionCallLine("Console.Write", false, CSConstant.Val("exception thrown"))); CSTryCatch catcher = new CSTryCatch(tryBlock, typeof(SwiftException), null, catchBlock); callingCode.Add(catcher); TestRunning.TestAndExecute(swiftCode, callingCode, output, testName: $"TLExceptionVoid{toAdd}"); }
void VirtualMethodException(string toAdd, string output) { string swiftCode = $"public enum MyErrorVME{toAdd} : Error {{\ncase itFailed\n}}\n" + $"open class FooVME{toAdd} {{\npublic init() {{\n}}\n public final func doIt(doThrow:Bool) throws {{\n let _ = try throwIt(doThrow:doThrow)\n}}\n open func throwIt(doThrow: Bool) throws -> Int\n {{\n if doThrow {{\n throw MyErrorVME{toAdd}.itFailed\n}}\nelse {{\n return 5\n}}\n}}\n}}\n"; CodeElementCollection <ICodeElement> callingCode = new CodeElementCollection <ICodeElement> (); CSClass fooOver = new CSClass(CSVisibility.Public, $"SubFooVME{toAdd}"); fooOver.Inheritance.Add(new CSIdentifier($"FooVME{toAdd}")); CSCodeBlock overBody = new CSCodeBlock(); CSCodeBlock ifblock = new CSCodeBlock(); CSCodeBlock elseblock = new CSCodeBlock(); ifblock.Add(new CSLine(new CSThrow(new CSFunctionCall("ArgumentException", true, CSConstant.Val("gotcha."))))); elseblock.Add(CSReturn.ReturnLine(CSConstant.Val(6))); CSIfElse ifElse = new CSIfElse(new CSIdentifier("doThrow"), ifblock, elseblock); overBody.Add(ifElse); CSMethod myThrowIt = new CSMethod(CSVisibility.Public, CSMethodKind.Override, new CSSimpleType("nint"), new CSIdentifier("ThrowIt"), new CSParameterList(new CSParameter(CSSimpleType.Bool, new CSIdentifier("doThrow"))), overBody); fooOver.Methods.Add(myThrowIt); CSCodeBlock tryBlock = new CSCodeBlock(); CSLine varLine = CSVariableDeclaration.VarLine(new CSSimpleType($"SubFooVME{toAdd}"), "foo", new CSFunctionCall($"SubFooVME{toAdd}", true)); tryBlock.Add(varLine); CSLine call = CSFunctionCall.FunctionCallLine("foo.DoIt", false, new CSIdentifier(toAdd)); tryBlock.Add(call); CSCodeBlock catchBlock = new CSCodeBlock(); catchBlock.Add(CSFunctionCall.FunctionCallLine("Console.Write", false, new CSIdentifier("e").Dot(new CSIdentifier("Message")))); CSTryCatch catcher = new CSTryCatch(tryBlock, typeof(SwiftException), "e", catchBlock); callingCode.Add(catcher); TestRunning.TestAndExecute(swiftCode, callingCode, output, testName: $"VirtualMethodException{toAdd}", otherClass: fooOver, platform: PlatformName.macOS); }
public void TestCharacterReturns() { var swiftCode = @" public class CharacterEcho { var C : Character; public init (c : Character) { C = c } public func GetValue () -> Character { return C } public var Value : Character { get { return C; } } }"; var callingCode = new CodeElementCollection <ICodeElement> (); StringBuilder expected = new StringBuilder(); foreach (string c in TestCases) { CSIdentifier testIdentifier = (CSIdentifier)$@"""{c}"""; CSCodeBlock block = new CSCodeBlock(); var ctorParam = new CSCastExpression((CSSimpleType)"SwiftCharacter", testIdentifier); CSLine instance = CSVariableDeclaration.VarLine((CSSimpleType)"CharacterEcho", (CSIdentifier)"Foo", CSFunctionCall.Ctor("CharacterEcho", ctorParam)); // First the properties var explicitCastProp = (CSIdentifier)"(string)Foo.Value"; var toStringProp = (CSIdentifier)"Foo.Value.ToString ()"; // Then the function returns as well var explicitCastFun = (CSIdentifier)"(string)Foo.GetValue ()"; var toStringFun = (CSIdentifier)"Foo.GetValue ().ToString ()"; block.Add(instance); foreach (var call in new CSBaseExpression [] { explicitCastProp, toStringProp, explicitCastFun, toStringFun }) { CSLine print = CSFunctionCall.FunctionLine("Console.Write", call); block.Add(print); expected.Append(c); } callingCode.Add(block); } TestRunning.TestAndExecute(swiftCode, callingCode, expected.ToString()); }
void VirtualMethodExceptionSimple(string toAdd, string output) { string swiftCode = $"public enum MyErrorVMES{toAdd} : Error {{\ncase itFailed\n}}\n" + $"open class FooVMES{toAdd} {{\npublic init() {{\n}}\n open func throwIt(doThrow: Bool) throws -> Int\n {{\n if doThrow {{\n throw MyErrorVMES{toAdd}.itFailed\n}}\nelse {{\n return 5\n}}\n}}\n}}\n"; CodeElementCollection <ICodeElement> callingCode = new CodeElementCollection <ICodeElement> (); CSCodeBlock tryBlock = new CSCodeBlock(); CSLine varLine = CSVariableDeclaration.VarLine(new CSSimpleType($"FooVMES{toAdd}"), "foo", new CSFunctionCall($"FooVMES{toAdd}", true)); tryBlock.Add(varLine); CSLine call = CSFunctionCall.FunctionCallLine("Console.Write", false, new CSFunctionCall("foo.ThrowIt", false, new CSIdentifier(toAdd))); tryBlock.Add(call); CSCodeBlock catchBlock = new CSCodeBlock(); catchBlock.Add(CSFunctionCall.FunctionCallLine("Console.Write", false, new CSIdentifier("e").Dot(new CSIdentifier("Message")))); CSTryCatch catcher = new CSTryCatch(tryBlock, typeof(SwiftException), "e", catchBlock); callingCode.Add(catcher); TestRunning.TestAndExecute(swiftCode, callingCode, output, testName: $"VirtualMethodExceptionSimple{toAdd}", platform: PlatformName.macOS); }
void MakeCapsuleAccessor(CSClass cl) { CSParameterList pl = new CSParameterList(); pl.Add(new CSParameter(new CSSimpleType(typeof(EventArgs)), "evt")); CSCodeBlock body = new CSCodeBlock(); // System.Reflection.PropertyInfo pi = evt.GetType().GetProperty("Capsule"); // return pi.GetValue(evt); body.Add(CSVariableDeclaration.VarLine(new CSSimpleType("System.Reflection.PropertyInfo"), "pi", new CSFunctionCall("evt.GetType().GetProperty", false, CSConstant.Val("Capsule")))); body.Add(CSReturn.ReturnLine(new CSFunctionCall("pi.GetValue", false, new CSIdentifier("evt")))); CSMethod meth = new CSMethod(CSVisibility.Public, CSMethodKind.None, CSSimpleType.Object, new CSIdentifier("GetCapsule"), pl, body); cl.Methods.Add(meth); }
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 NSObjectSubclassableMethodTest3() { string swiftCode = "import Foundation\n" + "@objc\n" + "open class Subclassable3 : NSObject {\n" + " public override init () { }\n" + " open var returnsTrue:Bool {\n" + " get { return true\n } " + " }\n" + "}\n" + "public func callIt (a: Subclassable3) -> Bool {\n" + " return a.returnsTrue\n" + "}\n"; var theSub = new CSClass(CSVisibility.Public, "TheSub3"); var ctor = new CSMethod(CSVisibility.Public, CSMethodKind.None, null, theSub.Name, new CSParameterList(), new CSBaseExpression [0], true, new CSCodeBlock()); theSub.Constructors.Add(ctor); theSub.Inheritance.Add(new CSIdentifier("Subclassable3")); var theBody = new CSCodeBlock(); theBody.Add(CSReturn.ReturnLine(CSConstant.Val(false))); LineCodeElementCollection <ICodeElement> getCode = new LineCodeElementCollection <ICodeElement> ( new ICodeElement [] { CSReturn.ReturnLine(CSConstant.Val(false)) }, false, true); CSProperty returnsFalse = new CSProperty(CSSimpleType.Bool, CSMethodKind.Override, new CSIdentifier("ReturnsTrue"), CSVisibility.Public, new CSCodeBlock(getCode), CSVisibility.Public, null); theSub.Properties.Add(returnsFalse); var callingCode = new CodeElementCollection <ICodeElement> (); var objID = new CSIdentifier("subTest"); var objDecl = CSVariableDeclaration.VarLine(CSSimpleType.Var, objID, new CSFunctionCall("TheSub3", true)); var call = CSFunctionCall.ConsoleWriteLine(objID.Dot((CSIdentifier)"ReturnsTrue")); var call2 = CSFunctionCall.ConsoleWriteLine(CSFunctionCall.Function("TopLevelEntities.CallIt", objID)); callingCode.Add(objDecl); callingCode.Add(call); callingCode.Add(call2); TestRunning.TestAndExecute(swiftCode, callingCode, "False\nFalse\n", otherClass: theSub, platform: PlatformName.macOS); }
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 ClosureSmokeTest() { string swiftCode = "public func callClosureCST(f:@escaping()->()) {\n" + " f()\n" + "}"; CodeElementCollection <ICodeElement> callingCode = new CodeElementCollection <ICodeElement> (); CSCodeBlock body = new CSCodeBlock(); body.Add(CSFunctionCall.ConsoleWriteLine(CSConstant.Val("C# output"))); CSLine invoker = CSFunctionCall.FunctionCallLine("TopLevelEntities.CallClosureCST", false, new CSLambda(new CSParameterList(), body)); callingCode.Add(invoker); TestRunning.TestAndExecute(swiftCode, callingCode, "C# output\n"); }
public static Tuple <CSNamespace, CSUsingPackages> CreateTestClass(CodeElementCollection <ICodeElement> callingCode, string testName, string expectedOutput, string nameSpace, string testClassName, CSClass otherClass, string skipReason, PlatformName platform) { var use = GetTestClassUsings(nameSpace); // [TomSkip(skipReason)] // public class TomTesttestName : ITomTest // { // public testClassName() { } // public string TestName { get { return testName; } } // public string ExpectedOutput { get { return expectedOuput; } } // public void Run() { // callingCode; // } // } // otherClass CSNamespace ns = new CSNamespace(nameSpace); if (otherClass != null) { ns.Block.Add(otherClass); } CSCodeBlock body = new CSCodeBlock(callingCode); body.Add(CaptureSwiftOutputPostlude(testName)); CSMethod run = new CSMethod(CSVisibility.Public, CSMethodKind.None, CSSimpleType.Void, new CSIdentifier("Run"), new CSParameterList(), body); CSClass testClass = new CSClass(CSVisibility.Public, new CSIdentifier($"TomTest{testName}"), new CSMethod [] { run }); testClass.Inheritance.Add(new CSIdentifier("ITomTest")); testClass.Properties.Add(MakeGetOnlyStringProp("TestName", testName)); testClass.Properties.Add(MakeGetOnlyStringProp("ExpectedOutput", expectedOutput)); ns.Block.Add(testClass); if (skipReason != null) { CSArgumentList al = new CSArgumentList(); al.Add(CSConstant.Val(skipReason)); CSAttribute attr = new CSAttribute("TomSkip", al); attr.AttachBefore(testClass); } return(new Tuple <CSNamespace, CSUsingPackages> (ns, use)); }
void ClosureSumFunc(string swiftType, string csVal1, string csVal2, string output, bool escaping) { string escapingAttribute = escaping ? "@escaping" : ""; string swiftCode = $"public func sumIt{swiftType}{escaping}(a:{swiftType}, b:{swiftType}, f:{escapingAttribute}({swiftType},{swiftType})->{swiftType}) -> {swiftType} {{\n" + " return f(a, b)\n" + "}"; CodeElementCollection <ICodeElement> callingCode = new CodeElementCollection <ICodeElement> (); CSCodeBlock body = new CSCodeBlock(); body.Add(CSReturn.ReturnLine(new CSIdentifier("val1") + new CSIdentifier("val2"))); CSLine invoker = CSFunctionCall.ConsoleWriteLine(CSFunctionCall.Function($"TopLevelEntities.SumIt{swiftType}{escaping}", (CSIdentifier)csVal1, (CSIdentifier)csVal2, new CSLambda(body, "val1", "val2"))); callingCode.Add(invoker); TestRunning.TestAndExecute(swiftCode, callingCode, output, testName: $"ClosureSumFunc{swiftType}{escaping}"); }
void ClosureConstantFunc(string appendage, string swiftType, string csVal, string output, bool escaping) { appendage += escaping.ToString(); string escapingAttribute = escaping ? "@escaping" : ""; string swiftCode = $"public func callClosureCCF{appendage}(f:{escapingAttribute}()->{swiftType}) -> {swiftType} {{\n" + " return f()\n" + "}"; CodeElementCollection <ICodeElement> callingCode = new CodeElementCollection <ICodeElement> (); CSCodeBlock body = new CSCodeBlock(); body.Add(CSReturn.ReturnLine(new CSIdentifier(csVal))); CSLine invoker = CSFunctionCall.ConsoleWriteLine(CSFunctionCall.Function($"TopLevelEntities.CallClosureCCF{appendage}", new CSLambda(body))); callingCode.Add(invoker); TestRunning.TestAndExecute(swiftCode, callingCode, output, testName: $"ClosureConstantFunc{appendage}"); }
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); }
void TLExceptionSimpleOptional(string name, string toAdd, bool toReturn, string output) { string swiftCode = $"public enum MyErrorTLSO{name} : Error {{\ncase itFailed\n}}\n" + $"public func throwItTLSO{name}(doThrow: Bool, doReturn: Bool) throws -> Int?\n {{\n if doThrow {{\n throw MyErrorTLSO{name}.itFailed\n}}\nelse {{\n if doReturn {{\n return 5\n}} else {{\nreturn nil\n}}\n}}\n}}\n"; CodeElementCollection <ICodeElement> callingCode = new CodeElementCollection <ICodeElement> (); CSCodeBlock tryBlock = new CSCodeBlock(); CSLine call = CSFunctionCall.FunctionCallLine("Console.Write", false, new CSFunctionCall($"TopLevelEntities.ThrowItTLSO{name}", false, new CSIdentifier(toAdd), CSConstant.Val(toReturn)).Dot(new CSFunctionCall("ToString", false))); tryBlock.Add(call); CSCodeBlock catchBlock = new CSCodeBlock(); catchBlock.Add(CSFunctionCall.FunctionCallLine("Console.Write", false, CSConstant.Val("exception thrown"))); CSTryCatch catcher = new CSTryCatch(tryBlock, typeof(SwiftException), null, catchBlock); callingCode.Add(catcher); TestRunning.TestAndExecute(swiftCode, callingCode, output, testName: $"TLExceptionSimpleOptional{name}"); }
void ClosureSmokeTest1(string appendage, string swiftType, string csVal, string output) { string swiftCode = $"public func callClosureCST1{appendage}(a:{swiftType}, f:@escaping({swiftType})->()) {{\n" + " f(a)\n" + "}"; CodeElementCollection <ICodeElement> callingCode = new CodeElementCollection <ICodeElement> (); CSCodeBlock body = new CSCodeBlock(); body.Add(CSFunctionCall.ConsoleWriteLine((CSIdentifier)"val")); CSLine invoker = CSFunctionCall.FunctionCallLine($"TopLevelEntities.CallClosureCST1{appendage}", false, new CSIdentifier(csVal), new CSLambda(body, "val")); callingCode.Add(invoker); TestRunning.TestAndExecute(swiftCode, callingCode, output, testName: $"ClosureSmokeTest1{appendage}"); }
void ClosureActionTwofer(string swiftType, string csVal1, string csVal2, string output, bool escaping) { string escapingAttribute = escaping ? "@escaping" : ""; string swiftCode = $"public func callClosureCAT{swiftType}{escaping}(a: {swiftType}, b: {swiftType}, f:{escapingAttribute}({swiftType}, {swiftType})->()) -> () {{\n" + " f(a, b)\n" + "}"; CodeElementCollection <ICodeElement> callingCode = new CodeElementCollection <ICodeElement> (); CSCodeBlock body = new CSCodeBlock(); body.Add(CSFunctionCall.ConsoleWriteLine(CSConstant.Val("{0}, {1}"), (CSIdentifier)"val1", (CSIdentifier)"val2")); CSLine invoker = CSFunctionCall.FunctionCallLine($"TopLevelEntities.CallClosureCAT{swiftType}{escaping}", false, new CSIdentifier(csVal1), new CSIdentifier(csVal2), new CSLambda(body, "val1", "val2")); callingCode.Add(invoker); TestRunning.TestAndExecute(swiftCode, callingCode, output, testName: $"ClosureActionTwofer{swiftType}{escaping}"); }
public void ClosureIdentity() { var swiftCode = "public func closureIdentity(a: @escaping () -> ()) -> () -> () {\n" + " return a\n" + "}\n"; var callingCode = new CodeElementCollection <ICodeElement> (); var body = new CSCodeBlock(); body.Add(CSFunctionCall.ConsoleWriteLine(CSConstant.Val("Success"))); var lambda = new CSLambda(body); callingCode.Add(CSVariableDeclaration.VarLine(new CSSimpleType("Action"), "lam", lambda)); callingCode.Add(CSVariableDeclaration.VarLine(new CSSimpleType("Action"), "lamreturn", new CSFunctionCall("TopLevelEntities.ClosureIdentity", false, new CSIdentifier("lam")))); callingCode.Add(CSFunctionCall.FunctionCallLine("lamreturn", false)); TestRunning.TestAndExecute(swiftCode, callingCode, "Success\n"); }
public void HandlesAutoclosure() { var swiftCode = "public func autoClosureCheck(a: @autoclosure ()->Bool) -> Bool {\n" + " return a()\n" + "}\n"; var callingCode = new CodeElementCollection <ICodeElement> (); var body = new CSCodeBlock(); body.Add(CSReturn.ReturnLine(CSConstant.Val(true))); var lambda = new CSLambda(body); var printer = CSFunctionCall.ConsoleWriteLine(CSFunctionCall.Function("TopLevelEntities.AutoClosureCheck", lambda)); callingCode.Add(printer); TestRunning.TestAndExecute(swiftCode, callingCode, "True\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"); }
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); }
void ClosureEventTest(string swiftType, string csVal, string output, bool escaping) { string escapingAttribute = escaping ? "@escaping" : ""; string swiftCode = $"public func callClosure_{escaping}(a:{swiftType}, f:{escapingAttribute}({swiftType})->()) {{\n" + " f(a)\n" + "}"; var eventerName = $"Eventer_{escaping}"; CSClass eventer = new CSClass(CSVisibility.Public, eventerName); MakeHandler(eventer, "AllocHandler", "AllocArgs"); MakeHandler(eventer, "DeInitHandler", "DeInitArgs"); MakeCapsuleAccessor(eventer); CodeElementCollection <ICodeElement> callingCode = new CodeElementCollection <ICodeElement> (); // SwiftDotNetCapsule.CapsuleTrackArgs allocArgs; // SwiftDotNetCapsule.CapsuleTrackArgs deinitArgs; // EventInfo ei = typeof(SwiftDotNetCapsule).GetEvent("AllocCalled", System.Reflection.BindingFlags.Static); // ei.AddEventHandler(null, et.AllocHandler); // SwiftDotNetCapsule.AllocCalled += (s, e) => { // allocArgs = e; // }; // SwiftDotNetCapsule.DeInitCalled += (s, e) => { // deinitArgs = e; // }; // ... // Console.WriteLine((allocArgs != null) && (allocArgs == deinitArgs)); CSCodeBlock body = new CSCodeBlock(); body.Add(CSFunctionCall.ConsoleWriteLine((CSIdentifier)"val")); callingCode.Add(CSVariableDeclaration.VarLine(new CSSimpleType(eventerName), new CSIdentifier("et"), new CSFunctionCall(eventerName, true))); callingCode.Add(CSVariableDeclaration.VarLine(new CSSimpleType("Action<object, EventArgs>"), "allocDel", new CSIdentifier("et.AllocHandler"))); callingCode.Add(CSVariableDeclaration.VarLine(new CSSimpleType("System.Reflection.EventInfo"), new CSIdentifier("allocEI"), new CSFunctionCall("typeof(SwiftDotNetCapsule).GetEvent", false, CSConstant.Val("AllocCalled"), new CSIdentifier("System.Reflection.BindingFlags.Static") | new CSIdentifier("System.Reflection.BindingFlags.NonPublic")))); callingCode.Add(CSVariableDeclaration.VarLine(new CSSimpleType(typeof(Delegate)), "allocDelCvt", new CSFunctionCall("Delegate.CreateDelegate", false, new CSIdentifier("allocEI.EventHandlerType"), new CSIdentifier("allocDel.Target"), new CSIdentifier("allocDel.Method")))); callingCode.Add(CSVariableDeclaration.VarLine(new CSSimpleType("System.Reflection.MethodInfo"), new CSIdentifier("allocMI"), new CSFunctionCall("allocEI.GetAddMethod", false, CSConstant.Val(true)))); callingCode.Add(CSFunctionCall.FunctionCallLine("allocMI.Invoke", false, CSConstant.Null, new CSArray1DInitialized("object", new CSIdentifier("allocDelCvt")))); //callingCode.Add(FunctionCall.FunctionCallLine("allocEI.AddEventHandler", false, Constant.Null, // new Identifier("allocDelCvt"))); callingCode.Add(CSVariableDeclaration.VarLine(new CSSimpleType("Action<object, EventArgs>"), "deInitDel", new CSIdentifier("et.DeInitHandler"))); callingCode.Add(CSVariableDeclaration.VarLine(new CSSimpleType("System.Reflection.EventInfo"), new CSIdentifier("deInitEI"), new CSFunctionCall("typeof(SwiftDotNetCapsule).GetEvent", false, CSConstant.Val("DeInitCalled"), new CSIdentifier("System.Reflection.BindingFlags.Static") | new CSIdentifier("System.Reflection.BindingFlags.NonPublic")))); callingCode.Add(CSVariableDeclaration.VarLine(new CSSimpleType(typeof(Delegate)), "deInitDelCvt", new CSFunctionCall("Delegate.CreateDelegate", false, new CSIdentifier("deInitEI.EventHandlerType"), new CSIdentifier("deInitDel.Target"), new CSIdentifier("deInitDel.Method")))); callingCode.Add(CSVariableDeclaration.VarLine(new CSSimpleType("System.Reflection.MethodInfo"), new CSIdentifier("deInitMI"), new CSFunctionCall("allocEI.GetAddMethod", false, CSConstant.Val(true)))); callingCode.Add(CSFunctionCall.FunctionCallLine("deInitMI.Invoke", false, CSConstant.Null, new CSArray1DInitialized("object", new CSIdentifier("deInitDelCvt")))); //callingCode.Add(FunctionCall.FunctionCallLine("deInitEI.AddEventHandler", false, Constant.Null, // new Identifier("deInitDelCvt"))); //callingCode.Add(Assignment.Assign("SwiftDotNetCapsule.AllocCalled", AssignmentOp.AddAssign, // new Identifier("et.AllocHandler"))); //callingCode.Add(Assignment.Assign("SwiftDotNetCapsule.DeInitCalled", AssignmentOp.AddAssign, // new Identifier("et.DeInitHandler"))); CSLine invoker = CSFunctionCall.FunctionCallLine($"TopLevelEntities.CallClosure_{escaping}", false, new CSIdentifier(csVal), new CSLambda(body, "val")); callingCode.Add(invoker); callingCode.Add(CSFunctionCall.ConsoleWriteLine((CSIdentifier)"et.GetCapsule(et.AllocArgs)" == (CSIdentifier)"et.GetCapsule(et.DeInitArgs)")); TestRunning.TestAndExecute(swiftCode, callingCode, output, testName: $"ClosureEventTest{escaping}", otherClass: eventer); }