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");
        }
Esempio n. 4
0
        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");
        }
Esempio n. 13
0
        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);
        }
Esempio n. 16
0
        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));
        }