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