コード例 #1
0
        public void GenerateMethodInvocation(Method method)
        {
            var contexts = new List <MarshalContext>();
            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 ctx = new MarshalContext(Context)
                {
                    ArgName        = param.Name,
                    Parameter      = param,
                    ParameterIndex = paramIndex++
                };
                contexts.Add(ctx);

                var marshal = new JavaMarshalManagedToNative(ctx);
                param.Visit(marshal);

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

                @params.Add(marshal.Context.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 contexts)
            {
                if (!string.IsNullOrWhiteSpace(marshal.SupportAfter))
                {
                    Write(marshal.SupportAfter);
                }
            }

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

                var marshal = new JavaMarshalNativeToManaged(ctx);
                method.ReturnType.Visit(marshal);

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

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

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