public void ObjCReturnProto()
        {
            var swiftCode =
                "import Foundation\n" +
                "@objc\n" +
                "public protocol Picker {\n" +
                "    @objc func pick () -> Int\n" +
                "}\n" +
                "@objc\n" +
                "private class hiddenPicker : NSObject, Picker {\n" +
                "    @objc public func pick () -> Int {\n" +
                "        return 42\n" +
                "    }\n" +
                "}\n" +
                "public func getPicker () -> Picker {\n" +
                "    return hiddenPicker ()\n" +
                "}\n";

            var varDecl     = CSVariableDeclaration.VarLine(CSSimpleType.Var, "picker", new CSFunctionCall("TopLevelEntities.GetPicker", false));
            var printIt     = CSFunctionCall.ConsoleWriteLine(new CSFunctionCall("picker.Pick", false));
            var callingCode = CSCodeBlock.Create(varDecl, printIt);

            TestRunning.TestAndExecute(swiftCode, callingCode, "42\n", platform: PlatformName.macOS);
        }
Пример #2
0
        public void ConvenienceCtor()
        {
            var swiftCode = @"
open class InconvenienceClass {
	private var x: Double
	public init (f: Double) {
		x = f
	}
	public convenience init (g: Int) {
		self.init (f: Double(g))
	}
	public func getX () -> Double {
		return x
	}
}
";

            var declID      = new CSIdentifier("cl");
            var decl        = CSVariableDeclaration.VarLine(CSSimpleType.Var, declID, new CSFunctionCall("InconvenienceClass", true, CSConstant.Val(3.14)));
            var printer     = CSFunctionCall.ConsoleWriteLine(new CSFunctionCall($"{declID.Name}.GetX", false));
            var callingCode = CSCodeBlock.Create(decl, printer);

            TestRunning.TestAndExecute(swiftCode, callingCode, "3.14\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}");
        }
Пример #4
0
        public void TestVariadiacInOpenClass()
        {
            string swiftCode  = @"open class OpenVarArr {
    public init () { }
    open func intsAsArray (a:Int32 ...) -> [Int32] {
        return a
    }
}
";
            var    arrId      = new CSIdentifier("arr");
            var    otherarrId = new CSIdentifier("otherarr");
            var    varArrId   = new CSIdentifier("vararr");
            var    arrDecl    = CSVariableDeclaration.VarLine(CSSimpleType.Var, arrId,
                                                              new CSFunctionCall("SwiftArray<int>", true, CSConstant.Val(1), CSConstant.Val(2), CSConstant.Val(3)));
            var varArrDecl   = CSVariableDeclaration.VarLine(CSSimpleType.Var, varArrId, new CSFunctionCall("OpenVarArr", true));
            var otherArrDecl = CSVariableDeclaration.VarLine(CSSimpleType.Var, otherarrId, new CSFunctionCall($"{varArrId.Name}.IntsAsArray", false, arrId));
            var feach        = new CSForEach(CSSimpleType.Var, "x", otherarrId, null);

            feach.Body.Add(CSFunctionCall.FunctionCallLine("Console.Write", false, feach.Ident));

            var callingCode = CSCodeBlock.Create(arrDecl, varArrDecl, otherArrDecl, feach);

            TestRunning.TestAndExecute(swiftCode, callingCode, "123", platform: PlatformName.macOS);
        }
        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);
        }
        public void ClassEquals()
        {
            // Note for future Steve
            // If an argument is a protocol with associated types, the calling conventions are different.
            // Typically, if a function accepts a protocol type as its argument it gets passed in as an existential
            // container.
            // It appears that if a function is generic with a protocol constraint then the argument gets
            // passed in as a pointer to the type then with the attendant metadata and protocol witness table
            // As a result, this code crashes since we're passing in the wrong type as far as I can tell.
            // This clearly needs more investigation

            // note to current or future Steve:
            // The calling conventions for this are:
            // rdi - pointer to value containing a
            // rsi - pointer to value containing b
            // rdx - metadata for type T
            // rcx - protocol witness table for T
            //
            // in pinvoke terms, this is
            // extern static void areEqualClass(IntPtr a, IntPtr b, SwiftMetatype mt, IntPtr protowitness);

            var swiftCode =
                $"public func areEqualClass<T:Equatable>(a: T, b: T) -> Bool {{\n" +
                "    return a == b\n" +
                "}\n" +
                "public protocol XXEquals {\n" +
                "    func Equals() -> Bool\n" +
                "}\n"
            ;

            var eqClass = new CSClass(CSVisibility.Public, "EqClass");
            var field   = CSVariableDeclaration.VarLine(CSSimpleType.Int, "X");

            eqClass.Fields.Add(field);
            var ctorParms = new CSParameterList();

            ctorParms.Add(new CSParameter(CSSimpleType.Int, new CSIdentifier("x")));
            var assignLine = CSAssignment.Assign("X", new CSIdentifier("x"));
            var ctor       = new CSMethod(CSVisibility.Public, CSMethodKind.None, null, new CSIdentifier("EqClass"), ctorParms,
                                          CSCodeBlock.Create(assignLine));

            eqClass.Constructors.Add(ctor);
            eqClass.Inheritance.Add(typeof(ISwiftEquatable));

            var eqParms = new CSParameterList();

            eqParms.Add(new CSParameter(new CSSimpleType("ISwiftEquatable"), new CSIdentifier("other")));
            var castLine = CSVariableDeclaration.VarLine(new CSSimpleType("EqClass"), "otherEqClass",
                                                         new CSBinaryExpression(CSBinaryOperator.As, new CSIdentifier("other"), new CSIdentifier("EqClass")));
            var nonNull    = new CSBinaryExpression(CSBinaryOperator.NotEqual, new CSIdentifier("otherEqClass"), CSConstant.Null);
            var valsEq     = new CSBinaryExpression(CSBinaryOperator.Equal, new CSIdentifier("otherEqClass.X"), new CSIdentifier("X"));
            var returnLine = CSReturn.ReturnLine(new CSBinaryExpression(CSBinaryOperator.And, nonNull, valsEq));
            var opEquals   = new CSMethod(CSVisibility.Public, CSMethodKind.None, CSSimpleType.Bool, new CSIdentifier("OpEquals"), eqParms,
                                          CSCodeBlock.Create(castLine, returnLine));

            eqClass.Methods.Add(opEquals);


            var newClass    = new CSFunctionCall("EqClass", true, CSConstant.Val(5));
            var isEqual     = new CSFunctionCall($"TopLevelEntities.AreEqualClass", false, newClass, newClass);
            var printer     = CSFunctionCall.ConsoleWriteLine(isEqual);
            var callingCode = CSCodeBlock.Create(printer);

            TestRunning.TestAndExecute(swiftCode, callingCode, "True\n", otherClass: eqClass, platform: PlatformName.macOS);
        }
		public void SimpleProtocolProGetSetIndexer ()
		{
			var swiftCode = @"
public protocol Simplest5 {
	associatedtype Item
	subscript (index: Int) -> Item {
		get set
	}
}
public func doSetIt<T:Simplest5> (a: inout T, i: Int, v: T.Item) {
	a[i] = v
}
";
			var altClass = new CSClass (CSVisibility.Public, "Simple5Impl");
			altClass.Inheritance.Add (new CSIdentifier ("ISimplest5<SwiftString>"));

			var fieldName = new CSIdentifier ("v");
			altClass.Fields.Add (CSFieldDeclaration.FieldLine (new CSSimpleType ("SwiftString"), fieldName));
			var getBlock = CSCodeBlock.Create (CSReturn.ReturnLine (fieldName));
			var setBlock = CSCodeBlock.Create (CSAssignment.Assign (fieldName, new CSIdentifier ("value")));

			var parameters = new CSParameterList (new CSParameter (new CSSimpleType ("nint"), new CSIdentifier ("index")));
			var thingIndex = new CSProperty (new CSSimpleType ("SwiftString"), CSMethodKind.None,
				CSVisibility.Public, getBlock, CSVisibility.Public, setBlock, parameters);
			altClass.Properties.Add (thingIndex);

			var ctor = new CSMethod (CSVisibility.Public, CSMethodKind.None, null, altClass.Name, new CSParameterList (), CSCodeBlock.Create ());
			altClass.Methods.Add (ctor);
			var instID = new CSIdentifier ("inst");
			var instDecl = CSVariableDeclaration.VarLine (instID, new CSFunctionCall ("Simple5Impl", true));
			var callSetter = CSFunctionCall.FunctionCallLine ("TopLevelEntities.DoSetIt", false, instID, CSConstant.Val (3), new CSFunctionCall ("SwiftString.FromString", false, CSConstant.Val ("Got here!")));
			var printer = CSFunctionCall.ConsoleWriteLine (new CSIdentifier ($"{instID.Name}[3]"));
			var callingCode = CSCodeBlock.Create (instDecl, callSetter, printer);
			TestRunning.TestAndExecute (swiftCode, callingCode, "Got here!\n", otherClass: altClass, platform: PlatformName.macOS);
		}
		public void SimpleProtocolProGetIndexer ()
		{
			var swiftCode = @"
public protocol Simplest4 {
	associatedtype Item
	subscript (index: Int) -> Item {
		get
	}
}
public func doGetIt<T:Simplest4> (a: T, i: Int) -> T.Item {
	return a[i]
}
";
			var altClass = new CSClass (CSVisibility.Public, "Simple4Impl");
			altClass.Inheritance.Add (new CSIdentifier ("ISimplest4<SwiftString>"));

			var getBlock = CSCodeBlock.Create (CSReturn.ReturnLine (new CSFunctionCall ("SwiftString.FromString", false, CSConstant.Val ("Got here!"))));
			var parameters = new CSParameterList (new CSParameter (new CSSimpleType ("nint"), new CSIdentifier ("index")));
			var thingIndex = new CSProperty (new CSSimpleType ("SwiftString"), CSMethodKind.None,
				CSVisibility.Public, getBlock, CSVisibility.Public, null, parameters);
			altClass.Properties.Add (thingIndex);

			var ctor = new CSMethod (CSVisibility.Public, CSMethodKind.None, null, altClass.Name, new CSParameterList (), CSCodeBlock.Create ());
			altClass.Methods.Add (ctor);
			var instID = new CSIdentifier ("inst");
			var instDecl = CSVariableDeclaration.VarLine (instID, new CSFunctionCall ("Simple4Impl", true));
			var resultID = new CSIdentifier ("result");
			var resultDecl = CSVariableDeclaration.VarLine (resultID, new CSFunctionCall ("TopLevelEntities.DoGetIt<Simple4Impl, SwiftString>", false, instID, CSConstant.Val (3)));
			var printer = CSFunctionCall.ConsoleWriteLine (resultID);
			var callingCode = CSCodeBlock.Create (instDecl, resultDecl, printer);
			TestRunning.TestAndExecute (swiftCode, callingCode, "Got here!\n", otherClass: altClass, platform: PlatformName.macOS);
		}
		public void SimpleProtocolProGetSetAssocTestAltSyntax ()
		{
			var swiftCode = @"
public protocol Simplest3 {
	associatedtype Item
	var thing: Item { get set }
}
public func doSetProp<T> (a: inout T, b:T.Item) where T:Simplest3 {
	a.thing = b
}
";
			var altClass = new CSClass (CSVisibility.Public, "Simple3Impl");
			altClass.Inheritance.Add (new CSIdentifier ("ISimplest3<SwiftString>"));
			var thingProp = CSProperty.PublicGetSet (new CSSimpleType ("SwiftString"), "Thing");
			altClass.Properties.Add (thingProp);

			var ctor = new CSMethod (CSVisibility.Public, CSMethodKind.None, null, altClass.Name, new CSParameterList (), CSCodeBlock.Create ());
			altClass.Methods.Add (ctor);

			var instID = new CSIdentifier ("inst");
			var instDecl = CSVariableDeclaration.VarLine (instID, new CSFunctionCall ("Simple3Impl", true));
			var doSetProp = CSFunctionCall.FunctionCallLine ("TopLevelEntities.DoSetProp<Simple3Impl, SwiftString>", false, instID,
				new CSFunctionCall ("SwiftString.FromString", false, CSConstant.Val ("Got here!")));
			var printer = CSFunctionCall.ConsoleWriteLine (new CSIdentifier ($"{instID.Name}.Thing"));
			var callingCode = CSCodeBlock.Create (instDecl, doSetProp, printer);
			TestRunning.TestAndExecute (swiftCode, callingCode, "Got here!\n", otherClass: altClass, platform: PlatformName.macOS);
		}
		public void SimplestProtocolPropGetAssocTest ()
		{
			var swiftCode = @"
public protocol Simplest1 {
	associatedtype Item
	var printThing: Item { get }
}
public func doPrint<T>(a:T) where T:Simplest1 {
	let _ = a.printThing
}
";
			var altClass = new CSClass (CSVisibility.Public, "Simple1Impl");
			altClass.Inheritance.Add (new CSIdentifier ("ISimplest1<SwiftString>"));
			var strID = new CSIdentifier ("theStr");
			var strDecl = CSVariableDeclaration.VarLine (strID, CSConstant.Val ("Got here!"));
			var printPart = CSFunctionCall.ConsoleWriteLine (strID);
			var returnPart = CSReturn.ReturnLine (new CSFunctionCall ("SwiftString.FromString", false, strID));
			var printBody = CSCodeBlock.Create (strDecl, printPart, returnPart);
			var speak = new CSProperty (new CSSimpleType ("SwiftString"), CSMethodKind.None, new CSIdentifier ("PrintThing"),
				CSVisibility.Public, printBody, CSVisibility.Public, null);
			altClass.Properties.Add (speak);

			var ctor = new CSMethod (CSVisibility.Public, CSMethodKind.None, null, altClass.Name, new CSParameterList (), CSCodeBlock.Create ());
			altClass.Methods.Add (ctor);

			var instID = new CSIdentifier ("inst");
			var instDecl = CSVariableDeclaration.VarLine (instID, new CSFunctionCall ("Simple1Impl", true));
			var doPrint = CSFunctionCall.FunctionCallLine ("TopLevelEntities.DoPrint<Simple1Impl, SwiftString>", false, instID);
			var callingCode = CSCodeBlock.Create (instDecl, doPrint);
			TestRunning.TestAndExecute (swiftCode, callingCode, "Got here!\n", otherClass: altClass, platform: PlatformName.macOS);
		}