示例#1
0
        public void GenerateNativeDeclarations(TranslationUnit unit)
        {
            // Since the native declarations are targetting the generated C bindings,
            // we need to modify the AST to match the one generated by the C target.

            var passes = new PassBuilder <TranslationUnitPass>(Context);

            CGenerator.SetupPasses(passes);

            Context.Options.GeneratorKind = GeneratorKind.C;

            passes.RunPasses(pass =>
            {
                pass.Context = Context;
                pass.VisitASTContext(Context.ASTContext);
            });

            Context.Options.GeneratorKind = GeneratorKind.Java;

            var nativeGen = new JavaNative(Context, unit);

            Generators.Add(nativeGen);
        }
        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 = ");

            var unit = method.TranslationUnit;
            var package = string.Join(".", GetPackageNames(unit));
            Write($"{package}.{JavaNative.GetNativeLibClassName(unit)}.INSTANCE.{JavaNative.GetCMethodIdentifier(method)}(");

            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};");
            }
        }