Esempio n. 1
0
        string GetDelegateCall(Source src, DelegateType dt, List <string> arguments)
        {
            var parameters = dt.Parameters;

            // + 1 for the delegate itself
            if (parameters.Length + 1 != arguments.Count)
            {
                Log.Error(src, ErrorCode.E0000,
                          "Foreign CPlusPlus error: Wrong number of arguments for macro call to delegate " + dt.FullName + ".");
            }

            string[] foreignParamTypes;
            string[] unoArgs;
            ConvertDelegateArguments(src, parameters, out foreignParamTypes, out unoArgs);
            var returnConversion = GetConversion(src, dt.ReturnType);

            using (var sw = new StringWriter())
                using (var tf = new TextFormatter(sw))
                {
                    tf.BeginLine();
                    tf.Write("[] (" + Helpers.CompiledType(dt) + " __unoDelegate");
                    for (var i = 0; i < parameters.Length; ++i)
                    {
                        var p = parameters[i];
                        tf.Write(", " + foreignParamTypes[i] + " " + p.Name);
                    }
                    tf.Write(") -> " + returnConversion.ForeignType);
                    tf.EndLine();
                    tf.Indent("{");

                    var call = Helpers.CallDelegate(
                        Helpers.StringExpr(dt, "__unoDelegate"),
                        parameters.Select((p, i) => Helpers.StringExpr(p.Type, unoArgs[i])).ToArray());
                    tf.WriteLine((dt.ReturnType.IsVoid ? call : "return " + call) + ";");

                    tf.Unindent();
                    tf.Write("} (" + string.Join(", ", arguments) + ")");
                    return(sw.ToString());
                }
        }
Esempio n. 2
0
        string WrapBody(Function f, string body)
        {
            if (!f.IsStatic)
            {
                Log.Error(f.Source, ErrorCode.E0000, "Foreign CPlusPlus functions must be static");
            }
            var paramConversions  = f.Parameters.Select(GetParamConversion).ToArray();
            var paramNames        = f.Parameters.Select((x, i) => "@IL$" + i).ToArray();
            var foreignParamNames = f.Parameters.Select(x => x.UnoName).ToArray();
            var returnConversion  = GetConversion(f.Source, f.ReturnType);
            var arguments         = paramConversions.Select((p, i) => p.FromUno(paramNames[i])).ToArray();

            if (paramConversions.All(x => x.IsIdentity))
            {
                return(body);
            }
            else
            {
                using (var sw = new StringWriter())
                {
                    using (var tf = new TextFormatter(sw))
                    {
                        tf.BeginLine();
                        tf.Write("[] ");
                        tf.Write(ForeignTypeParamList(paramConversions, foreignParamNames));
                        tf.Write(" -> ");
                        tf.Write(returnConversion.ForeignType);
                        tf.EndLine();
                        tf.Indent("{");
                        tf.WriteLines(body);
                        tf.Unindent();
                        tf.Write("} (");
                        tf.Write(string.Join(", ", arguments));
                        tf.Write(")");
                        return(MakeReturnStatement(f.ReturnType, sw.ToString()));
                    }
                }
            }
        }
Esempio n. 3
0
        TypeConversion GetDelegateConversion(Source src, DelegateType dt)
        {
            var paramConversions = dt.Parameters.Select(GetParamConversion).ToArray();
            var returnConversion = GetConversion(src, dt.ReturnType);
            var compiledType     = Helpers.CompiledType(dt);

            var foreignType = "::uObjC::Function<" +
                              returnConversion.ForeignType +
                              ((paramConversions.Length > 0) ? ", " : "") +
                              ForeignTypes(paramConversions) + ">";

            Func <string, string> fromUno = (string x) =>
            {
                var convertedArguments = paramConversions.Select((p, i) => p.ToUno(dt.Parameters[i].Name)).ToList();
                var preStatements      = convertedArguments.SelectMany(a => a.PreStatements).ToList();
                var arguments          = convertedArguments.Select((arg, i) => Helpers.StringExpr(dt.Parameters[i].Type, arg.Expression)).ToArray();
                var postStatements     = convertedArguments.SelectMany(a => a.PostStatements).ToList();

                using (var tw = new StringWriter())
                {
                    using (var ftw = new TextFormatter(tw))
                    {
                        ftw.WriteLine("[] (id<UnoObject> __delegateRef) -> " + foreignType);
                        ftw.Indent("{");
                        ftw.WriteLine("return __delegateRef == nil ? (" + foreignType + ")nil : (^ " + returnConversion.ForeignType + " " +
                                      ForeignTypeParamList(paramConversions, dt.Parameters.Select(p => p.Name).ToArray()));
                        ftw.Indent("{");
                        ftw.WriteLine("::uForeignPool __foreignPool;");
                        ftw.WriteLine(compiledType + " __unoDelegate = (" + compiledType + ")__delegateRef.unoObject;");
                        ftw.WriteLines(ReturnWithPrePostStatements(
                                           dt.ReturnType,
                                           preStatements,
                                           returnConversion.FromUno(Helpers.CallDelegate(Helpers.StringExpr(dt, "__unoDelegate"), arguments)),
                                           postStatements));
                        ftw.Unindent("});");
                        ftw.Unindent();
                        ftw.Write("} ([::StrongUnoObject strongUnoObjectWithUnoObject: " + x + "])");
                        return(tw.ToString());
                    }
                }
            };

            Func <string, string> toUno = (string x) =>
            {
                var convertedArguments = paramConversions.Select((p, i) => p.FromUno(GetDelegateArgumentString(dt.Parameters[i]))).ToList();
                var preStatements      = convertedArguments.SelectMany(a => a.PreStatements).ToList();
                var arguments          = convertedArguments.Select(a => a.Expression).ToList();
                var postStatements     = convertedArguments.SelectMany(a => a.PostStatements).ToList();

                using (var tw = new StringWriter())
                {
                    using (var ftw = new TextFormatter(tw))
                    {
                        ftw.Write("::uObjC::NewUnoDelegate(" + Helpers.TypeOf(dt) + ", ");
                        string fptrType = "::uObjC::RawFunction<void, " + Helpers.CompiledType(Essentials.Object) +
                                          ((paramConversions.Length) > 0 ? ", " : "") +
                                          string.Join(", ", paramConversions.Select(GetDelegateParameterType)) +
                                          (dt.ReturnType.IsVoid ? "" : (", " + Helpers.CompiledType(returnConversion.UnoType) + "*")) +
                                          ">";
                        ftw.Write("(void*) (" + fptrType + ") [] (");
                        ftw.Write(Helpers.CompiledType(Essentials.Object) + " __this" +
                                  ((paramConversions.Length > 0) ? ", " : "") +
                                  string.Join(", ", paramConversions.Select((p, i) => GetDelegateParameterType(p) + " " + dt.Parameters[i].Name)) +
                                  (dt.ReturnType.IsVoid ? "" : (", " + GetDelegateReturnType(returnConversion) + " __ret")));
                        ftw.Write(")");
                        ftw.EndLine();
                        ftw.Indent("{");
                        ftw.WriteLine(Helpers.CompiledType(_objCObject) + " __thisObj = (" + Helpers.CompiledType(_objCObject) + ")__this;");
                        preStatements.ForEach(ftw.WriteLine);
                        ftw.BeginLine();
                        if (!dt.ReturnType.IsVoid)
                        {
                            ftw.Write(GetDelegateReturnString(returnConversion, "__ret") + " = ");
                        }
                        ftw.Write(returnConversion.ToUno("((" + foreignType + ")" + Helpers.CallStatic(_getHandle, Helpers.StringExpr(_objCObject, "__thisObj")) +
                                                         ")(" + string.Join(", ", arguments) + ")") + ";");
                        ftw.EndLine();
                        postStatements.ForEach(ftw.WriteLine);
                        ftw.Unindent();
                        ftw.Write("}, " + Helpers.CallStatic(_newObjCObject, Helpers.StringExpr(_objCID, x)) + ")");
                        return(tw.ToString());
                    }
                }
            };

            return(TypeConversion.Boxed(
                       dt,
                       foreignType,
                       fromUno,
                       toUno));
        }
Esempio n. 4
0
        string WrapBody(Function f, string body)
        {
            var paramConversions  = new List <ParamTypeConversion>();
            var paramNames        = new List <string>();
            var foreignParamNames = new List <string>();

            if (!f.IsStatic && body.Contains("_this"))
            {
                paramConversions.Add(
                    GetParamConversion(
                        new Parameter(
                            f.Source,
                            new NewObject[0],
                            ParameterModifier.This,
                            f.DeclaringType,
                            "@IL$$",
                            null)));
                paramNames.Add("@IL$$");
                foreignParamNames.Add("_this");
            }

            paramConversions.AddRange(f.Parameters.Select(GetParamConversion));
            paramNames.AddRange(f.Parameters.Select((x, i) => "@IL$" + i));
            foreignParamNames.AddRange(f.Parameters.Select(x => x.UnoName));

            var returnConversion = GetConversion(f.Source, f.ReturnType);

            var convertedArguments = paramConversions.Select((p, i) => p.FromUno(paramNames[i])).ToList();
            var preStatements      = convertedArguments.SelectMany(x => x.PreStatements).ToList();
            var arguments          = convertedArguments.Select(x => x.Expression).ToList();
            var postStatements     = convertedArguments.SelectMany(x => x.PostStatements).ToList();

            if (paramConversions.All(x => x.IsIdentity) &&
                returnConversion.IsIdentity &&
                preStatements.Count == 0 &&
                postStatements.Count == 0 &&
                f.Parameters.All(p => p.Name == p.UnoName))
            {
                return(WithObjCAutoreleasePool(body));
            }
            else
            {
                using (var tw = new StringWriter())
                {
                    using (var ftw = new TextFormatter(tw))
                    {
                        ftw.BeginLine();
                        ftw.Write("[] ");
                        ftw.Write(ForeignTypeParamList(paramConversions, foreignParamNames.ToArray()));
                        ftw.Write(" -> ");
                        ftw.Write(returnConversion.ForeignType);
                        ftw.EndLine();
                        ftw.Indent("{");
                        ftw.WriteLines(body);
                        ftw.Unindent();
                        ftw.Write("} (");
                        ftw.Write(string.Join(", ", arguments));
                        ftw.Write(")");
                        return(WithObjCAutoreleasePool(ReturnWithPrePostStatements(f.ReturnType, preStatements, returnConversion.ToUno(tw.ToString()), postStatements)));
                    }
                }
            }
        }