예제 #1
0
        public override bool VisitClassDecl(Class @class)
        {
            var @object   = IsByRefParameter ? $"{ArgName}.get()" : ArgName;
            var objectRef = @class.IsInterface ? "__getObject()" : "__object";

            if (IsByRefParameter)
            {
                CheckRefOutParameter(Parameter.IsInOut);

                TypePrinter.PushContext(TypePrinterContextKind.Native);
                var typeName = Parameter.Visit(TypePrinter);
                TypePrinter.PopContext();

                var varName = JavaGenerator.GeneratedIdentifier(ArgName);
                var marshal = Parameter.IsInOut ?
                              $"new {typeName}({@object}.{objectRef})" : $"new {typeName}()";
                Before.WriteLine($"{typeName} {varName} = {marshal};");

                var marshaler = new JavaMarshalNativeToManaged(Context)
                {
                    Parameter     = Parameter,
                    ReturnVarName = $"{varName}.getValue()"
                };

                @class.Visit(marshaler);

                After.WriteLine($"{ArgName}.set({marshaler.Return});");

                Return.Write(varName);
                return(true);
            }

            Return.Write($"{ArgName} == null ? null : {ArgName}.{objectRef}");
            return(true);
        }
        public void GenerateMethodInvocation(Method method)
        {
            var marshalers = new List <Marshaler>();
            var @params    = new List <string>();

            if (!method.IsStatic && !(method.IsConstructor || method.IsDestructor))
            {
                @params.Add("__object");
            }

            int paramIndex = 0;

            foreach (var param in method.Parameters.Where(m => !m.IsImplicit))
            {
                var marshal = new JavaMarshalManagedToNative(Context)
                {
                    ArgName        = param.Name,
                    Parameter      = param,
                    ParameterIndex = paramIndex++
                };
                marshalers.Add(marshal);

                param.Visit(marshal);

                if (!string.IsNullOrWhiteSpace(marshal.Before))
                {
                    Write(marshal.Before);
                }

                @params.Add(marshal.Return);
            }

            PrimitiveType primitive;

            method.ReturnType.Type.IsPrimitiveType(out primitive);

            var hasReturn = primitive != PrimitiveType.Void && !(method.IsConstructor || method.IsDestructor);

            if (hasReturn)
            {
                TypePrinter.PushContext(TypePrinterContextKind.Native);
                var typeName = method.ReturnType.Visit(TypePrinter);
                TypePrinter.PopContext();
                Write($"{typeName.Type} __ret = ");
            }

            if (method.IsConstructor)
            {
                Write("__object = ");
            }

            // Get the effective method for synthetized interface method implementations.
            var effectiveMethod = method.CompleteDeclaration as Method ?? method;
            var unit            = effectiveMethod.TranslationUnit;
            var package         = string.Join(".", GetPackageNames(unit));
            var nativeMethodId  = JavaNative.GetCMethodIdentifier(effectiveMethod);

            Write($"{package}.{JavaNative.GetNativeLibClassName(unit)}.INSTANCE.{nativeMethodId}(");

            Write(string.Join(", ", @params));
            WriteLine(");");

            WriteLine("mono.embeddinator.Runtime.checkExceptions();");

            foreach (var marshal in marshalers)
            {
                if (!string.IsNullOrWhiteSpace(marshal.After))
                {
                    Write(marshal.After);
                }
            }

            if (hasReturn)
            {
                var marshal = new JavaMarshalNativeToManaged(Context)
                {
                    ReturnType    = method.ReturnType,
                    ReturnVarName = "__ret"
                };

                method.ReturnType.Visit(marshal);

                if (marshal.Return.ToString().Length == 0)
                {
                    throw new System.Exception();
                }

                if (!string.IsNullOrWhiteSpace(marshal.Before))
                {
                    Write(marshal.Before);
                }

                WriteLine($"return {marshal.Return};");
            }
        }