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