void AddProperties(Method method, CodeGenerationOptions opt) { foreach (var p in method.Parameters) { if (p.IsSender) { continue; } // We've already added this property from a different overload if (Properties.Any(prop => prop.Name == p.PropertyName)) { continue; } Fields.Add(new FieldWriter { Name = opt.GetSafeIdentifier(p.Name), Type = new TypeReferenceWriter(opt.GetTypeReferenceName(p)) }); var prop = new PropertyWriter { Name = p.PropertyName, PropertyType = new TypeReferenceWriter(opt.GetTypeReferenceName(p)), IsPublic = true, HasGet = true }; prop.GetBody.Add($"return {opt.GetSafeIdentifier (p.Name)};"); Properties.Add(prop); } }
void AddConstructor(InterfaceGen iface, Method method, CodeGenerationOptions opt) { var ctor = new ConstructorWriter { Name = iface.GetArgsName(method), IsPublic = true }; if (method.IsEventHandlerWithHandledProperty) { ctor.Parameters.Add(new MethodParameterWriter("handled", TypeReferenceWriter.Bool)); ctor.Body.Add("this.handled = handled;"); } foreach (var p in method.Parameters) { if (p.IsSender) { continue; } ctor.Parameters.Add(new MethodParameterWriter(p.Name, new TypeReferenceWriter(opt.GetTypeReferenceName(p)))); ctor.Body.Add($"this.{opt.GetSafeIdentifier (p.Name)} = {opt.GetSafeIdentifier (p.Name)};"); } Constructors.Add(ctor); }
protected override void WriteSetterBody(CodeWriter writer) { writer.WriteLine($"const string __id = \"{field.JavaName}.{field.Symbol.JniName}\";"); writer.WriteLine(); var invokeType = SourceWriterExtensions.GetInvokeType(field.GetMethodPrefix); var indirect = field.IsStatic ? "StaticFields" : "InstanceFields"; string arg; bool have_prep = false; if (field.Symbol.IsArray) { arg = opt.GetSafeIdentifier(TypeNameUtilities.GetNativeName("value")); writer.WriteLine($"IntPtr {arg} = global::Android.Runtime.JavaArray<{opt.GetOutputName (field.Symbol.ElementType)}>.ToLocalJniHandle (value);"); } else { foreach (var prep in field.SetParameters.GetCallPrep(opt)) { have_prep = true; writer.WriteLine(prep); } arg = field.SetParameters [0].ToNative(opt); if (field.SetParameters.HasCleanup && !have_prep) { arg = opt.GetSafeIdentifier(TypeNameUtilities.GetNativeName("value")); writer.WriteLine($"IntPtr {arg} = global::Android.Runtime.JNIEnv.ToLocalJniHandle (value);"); } } writer.WriteLine("try {"); writer.WriteLine($"\t_members.{indirect}.SetValue (__id{(field.IsStatic ? "" : ", this")}, {(invokeType != "Object" ? arg : "new JniObjectReference (" + arg + ")")});"); writer.WriteLine("} finally {"); writer.Indent(); if (field.Symbol.IsArray) { writer.WriteLine($"global::Android.Runtime.JNIEnv.DeleteLocalRef ({arg});"); } else { foreach (var cleanup in field.SetParameters.GetCallCleanup(opt)) { writer.WriteLine(cleanup); } if (field.SetParameters.HasCleanup && !have_prep) { writer.WriteLine($"global::Android.Runtime.JNIEnv.DeleteLocalRef ({arg});"); } } writer.Unindent(); writer.WriteLine("}"); }
public static void AddInterfaceListenerEventOrProperty(TypeWriter tw, InterfaceGen iface, Method method, ClassGen target, string name, string connector_fmt, string add, string remove, CodeGenerationOptions opt) { if (method.EventName == string.Empty) { return; } var nameSpec = iface.Methods.Count > 1 ? method.AdjustedName : string.Empty; var idx = iface.FullName.LastIndexOf("."); var start = iface.Name.StartsWith("IOn") ? 3 : 1; var full_delegate_name = iface.FullName.Substring(0, idx + 1) + iface.Name.Substring(start, iface.Name.Length - start - 8) + nameSpec; if (method.IsSimpleEventHandler) { full_delegate_name = "EventHandler"; } else if (method.RetVal.IsVoid || method.IsEventHandlerWithHandledProperty) { full_delegate_name = "EventHandler<" + iface.FullName.Substring(0, idx + 1) + iface.GetArgsName(method) + ">"; } else { full_delegate_name += "Handler"; } if (method.RetVal.IsVoid || method.IsEventHandlerWithHandledProperty) { if (opt.GetSafeIdentifier(name) != name) { Report.LogCodedWarning(0, Report.WarningInvalidEventName2, method, iface.FullName, name); return; } else { var mt = target.Methods.Where(method => string.Compare(method.Name, connector_fmt, StringComparison.OrdinalIgnoreCase) == 0 && method.IsListenerConnector).FirstOrDefault(); var hasHandlerArgument = mt != null && mt.IsListenerConnector && mt.Parameters.Count == 2 && mt.Parameters [1].Type == "Android.OS.Handler"; tw.Events.Add(new InterfaceListenerEvent(iface, name, nameSpec, full_delegate_name, connector_fmt, add, remove, hasHandlerArgument, opt)); } } else { if (opt.GetSafeIdentifier(name) != name) { Report.LogCodedWarning(0, Report.WarningInvalidEventPropertyName, method, iface.FullName, name); return; } tw.Properties.Add(new InterfaceListenerPropertyImplementor(iface, name, opt)); tw.Properties.Add(new InterfaceListenerProperty(iface, name, nameSpec, method.AdjustedName, full_delegate_name, opt)); } }
protected override void WriteBody(CodeWriter writer) { writer.WriteLine("{0}string __id = \"{1}\";", constructor.IsNonStaticNestedType ? "" : "const ", constructor.IsNonStaticNestedType ? "(" + constructor.Parameters.GetJniNestedDerivedSignature(opt) + ")V" : constructor.JniSignature); writer.WriteLine(); if (opt.CodeGenerationTarget == CodeGenerationTarget.JavaInterop1) { writer.WriteLine($"if (PeerReference.IsValid)"); writer.WriteLine("\treturn;"); } else { writer.WriteLine($"if ({context_this} != IntPtr.Zero)"); writer.WriteLine("\treturn;"); } writer.WriteLine(); foreach (var prep in constructor.Parameters.GetCallPrep(opt)) { writer.WriteLine(prep); } writer.WriteLine("try {"); writer.Indent(); WriteParamterListCallArgs(writer, constructor.Parameters, false, opt); writer.WriteLine("var __r = _members.InstanceMethods.StartCreateInstance (__id, ((object) this).GetType (){0});", constructor.Parameters.GetCallArgs(opt, invoker: false)); if (opt.CodeGenerationTarget == CodeGenerationTarget.JavaInterop1) { writer.WriteLine("Construct (ref __r, JniObjectReferenceOptions.CopyAndDispose);"); } else { writer.WriteLine("SetHandle (__r.Handle, JniHandleOwnership.TransferLocalRef);"); } writer.WriteLine("_members.InstanceMethods.FinishCreateInstance (__id, this{0});", constructor.Parameters.GetCallArgs(opt, invoker: false)); writer.Unindent(); writer.WriteLine("} finally {"); writer.Indent(); var call_cleanup = constructor.Parameters.GetCallCleanup(opt); foreach (string cleanup in call_cleanup) { writer.WriteLine(cleanup); } foreach (var p in constructor.Parameters.Where(para => para.ShouldGenerateKeepAlive())) { writer.WriteLine($"global::System.GC.KeepAlive ({opt.GetSafeIdentifier (p.Name)});"); } writer.Unindent(); writer.WriteLine("}"); }
// static sbyte n_ByteValueExact (IntPtr jnienv, IntPtr native__this) // { // var __this = global::Java.Lang.Object.GetObject<Android.Icu.Math.BigDecimal> (jnienv, native__this, JniHandleOwnership.DoNotTransfer); // return __this.ByteValueExact (); // } public MethodCallback(GenBase type, Method method, CodeGenerationOptions options, string propertyName, bool isFormatted) { this.type = type; this.method = method; property_name = propertyName; is_formatted = isFormatted; opt = options; delegate_field = new MethodCallbackDelegateField(method, options); delegate_getter = new GetDelegateHandlerMethod(method, options); Name = "n_" + method.Name + method.IDSignature; ReturnType = new TypeReferenceWriter(method.RetVal.NativeType); IsStatic = true; IsPrivate = method.IsInterfaceDefaultMethod; if (!string.IsNullOrWhiteSpace(method.Deprecated)) { Attributes.Add(new ObsoleteAttr()); } SourceWriterExtensions.AddSupportedOSPlatform(Attributes, method, opt); Parameters.Add(new MethodParameterWriter("jnienv", TypeReferenceWriter.IntPtr)); Parameters.Add(new MethodParameterWriter("native__this", TypeReferenceWriter.IntPtr)); foreach (var p in method.Parameters) { Parameters.Add(new MethodParameterWriter(options.GetSafeIdentifier(p.UnsafeNativeName), new TypeReferenceWriter(p.NativeType))); } }
// This replaces any `Java.Lang.ICharSequence` parameters with `string`. public static void AddMethodParametersStringOverloads(this MethodWriter method, ParameterList parameters, CodeGenerationOptions opt) { foreach (var p in parameters) { var para = new MethodParameterWriter(opt.GetSafeIdentifier(p.Name), new TypeReferenceWriter(opt.GetTypeReferenceName(p).Replace("Java.Lang.ICharSequence", "string").Replace("global::string", "string"))); if (p.IsEnumified) { para.Attributes.Add(new GeneratedEnumAttr()); } if (p.Annotation != null) { para.Attributes.Add(new CustomAttr(p.Annotation)); } method.Parameters.Add(para); } }
public static void AddMethodParameters(this ITakeParameters method, ParameterList parameters, CodeGenerationOptions opt) { foreach (var p in parameters) { var para = new MethodParameterWriter(opt.GetSafeIdentifier(p.Name), new TypeReferenceWriter(opt.GetTypeReferenceName(p))); if (p.IsEnumified) { para.Attributes.Add(new GeneratedEnumAttr()); } if (p.Annotation != null) { para.Attributes.Add(new CustomAttr(p.Annotation)); } method.Parameters.Add(para); } }
public static void AddInterfaceListenerEventsAndProperties(TypeWriter tw, InterfaceGen iface, ClassGen target, CodeGenerationOptions opt) { var methods = target.Methods.Concat(target.Properties.Where(p => p.Setter != null).Select(p => p.Setter)); var props = new HashSet <string> (); var refs = new HashSet <string> (); var eventMethods = methods.Where(m => m.IsListenerConnector && m.EventName != string.Empty && m.ListenerType == iface).OrderBy(m => m.Parameters.Count).GroupBy(m => m.Name).Select(g => g.First()).Distinct(); foreach (var method in eventMethods) { var name = method.CalculateEventName(target.ContainsName); if (string.IsNullOrEmpty(name)) { Report.LogCodedWarning(0, Report.WarningEmptyEventName, method, iface.FullName, method.Name); continue; } if (opt.GetSafeIdentifier(name) != name) { Report.LogCodedWarning(0, Report.WarningInvalidEventName, method, iface.FullName, method.Name); continue; } var prop = target.Properties.FirstOrDefault(p => p.Setter == method); if (prop != null) { var setter = "__Set" + prop.Name; props.Add(prop.Name); refs.Add(setter); AddInterfaceListenerEventsAndProperties(tw, iface, target, name, setter, string.Format("__v => {0} = __v", prop.Name), string.Format("__v => {0} = null", prop.Name), opt); } else { refs.Add(method.Name); string rm = null; string remove; if (method.Name.StartsWith("Set")) { remove = string.Format("__v => {0} (null)", method.Name); } else if (method.Name.StartsWith("Add") && (rm = "Remove" + method.Name.Substring("Add".Length)) != null && methods.Where(m => m.Name == rm).Any()) { remove = string.Format("__v => {0} (__v)", rm); } else { remove = string.Format("__v => {{throw new NotSupportedException (\"Cannot unregister from {0}.{1}\");}}", iface.FullName, method.Name); } AddInterfaceListenerEventsAndProperties(tw, iface, target, name, method.Name, method.Name, remove, opt); } } foreach (var r in refs) { tw.Fields.Add(new WeakImplementorField(r, opt)); } tw.Methods.Add(new CreateImplementorMethod(iface, opt)); }