void GenerateEventHandlerImpl(StreamWriter sw, string indent, CodeGenerationOptions opt) { string jniClass = "mono/" + RawJniName.Replace('$', '_') + "Implementor"; sw.WriteLine("{0}[global::Android.Runtime.Register (\"{1}\"{2})]", indent, jniClass, this.AdditionalAttributeString()); sw.WriteLine("{0}internal sealed partial class {1}Implementor : global::Java.Lang.Object, {1} {{", indent, Name); bool needs_sender = NeedsSender; if (needs_sender) { sw.WriteLine(); sw.WriteLine("{0}\tobject sender;", indent); } sw.WriteLine(); sw.WriteLine("{0}\tpublic {1}Implementor ({2})", indent, Name, needs_sender ? "object sender" : ""); sw.WriteLine("{0}\t\t: base (", indent); sw.WriteLine("{0}\t\t\tglobal::Android.Runtime.JNIEnv.StartCreateInstance (\"{1}\", \"()V\"),", indent, jniClass); sw.WriteLine("{0}\t\t\tJniHandleOwnership.TransferLocalRef)", indent); sw.WriteLine("{0}\t{{", indent); sw.WriteLine("{0}\t\tglobal::Android.Runtime.JNIEnv.FinishCreateInstance ({1}, \"()V\");", indent, GetObjectHandleProperty("this")); if (needs_sender) { sw.WriteLine("{0}\t\tthis.sender = sender;", indent); } sw.WriteLine("{0}\t}}", indent); sw.WriteLine(); var handlers = new List <string> (); foreach (var m in Methods) { GenerateEventHandlerImplContent(m, sw, indent, opt, needs_sender, jniClass, handlers); } sw.WriteLine(); sw.WriteLine("{0}\tinternal static bool __IsEmpty ({1}Implementor value)", indent, Name); sw.WriteLine("{0}\t{{", indent); if (!Methods.Any(m => m.EventName != string.Empty) || handlers.Count == 0) { sw.WriteLine("{0}\t\treturn true;", indent); } else { sw.WriteLine("{0}\t\treturn {1};", indent, string.Join(" && ", handlers.Select(e => string.Format("value.{0}Handler == null", e)))); } sw.WriteLine("{0}\t}}", indent); sw.WriteLine("{0}}}", indent); sw.WriteLine(); }
public override void Generate(StreamWriter sw, string indent, CodeGenerationOptions opt, GenerationInfo gen_info) { opt.ContextTypes.Push(this); gen_info.TypeRegistrations.Add(new KeyValuePair <string, string>(RawJniName, AssemblyQualifiedName)); bool is_enum = base_symbol != null && base_symbol.FullName == "Java.Lang.Enum"; if (is_enum) { gen_info.Enums.Add(RawJniName.Replace('/', '.') + ":" + Namespace + ":" + JavaSimpleName); } StringBuilder sb = new StringBuilder(); foreach (ISymbol isym in Interfaces) { GenericSymbol gs = isym as GenericSymbol; InterfaceGen gen = (gs == null ? isym : gs.Gen) as InterfaceGen; if (gen != null && gen.IsConstSugar) { continue; } if (sb.Length > 0) { sb.Append(", "); } sb.Append(opt.GetOutputName(isym.FullName)); } string obj_type = null; if (base_symbol != null) { GenericSymbol gs = base_symbol as GenericSymbol; obj_type = gs != null && gs.IsConcrete ? gs.GetGenericType(null) : opt.GetOutputName(base_symbol.FullName); } sw.WriteLine("{0}// Metadata.xml XPath class reference: path=\"{1}\"", indent, MetadataXPathReference); if (this.IsDeprecated) { sw.WriteLine("{0}[ObsoleteAttribute (@\"{1}\")]", indent, this.DeprecatedComment); } sw.WriteLine("{0}[global::Android.Runtime.Register (\"{1}\", DoNotGenerateAcw=true{2})]", indent, RawJniName, this.AdditionalAttributeString()); if (this.TypeParameters != null && this.TypeParameters.Any()) { sw.WriteLine("{0}{1}", indent, TypeParameters.ToGeneratedAttributeString()); } string inherits = ""; if (inherits_object && obj_type != null) { inherits = ": " + obj_type; } if (sb.Length > 0) { if (string.IsNullOrEmpty(inherits)) { inherits = ": "; } else { inherits += ", "; } } sw.WriteLine("{0}{1} {2}{3}{4}partial class {5} {6}{7} {{", indent, Visibility, needs_new ? "new " : String.Empty, IsAbstract ? "abstract " : String.Empty, IsFinal ? "sealed " : String.Empty, Name, inherits, sb.ToString()); sw.WriteLine(); var seen = new HashSet <string> (); GenFields(sw, indent + "\t", opt, seen); bool haveNested = false; foreach (var iface in GetAllImplementedInterfaces() .Except(BaseGen == null ? new InterfaceGen[0] : BaseGen.GetAllImplementedInterfaces()) .Where(i => i.Fields.Count > 0)) { if (!haveNested) { sw.WriteLine(); sw.WriteLine("{0}\tpublic static class InterfaceConsts {{", indent); haveNested = true; } sw.WriteLine(); sw.WriteLine("{0}\t\t// The following are fields from: {1}", indent, iface.JavaName); iface.GenFields(sw, indent + "\t\t", opt, seen); } if (haveNested) { sw.WriteLine("{0}\t}}\n", indent); } foreach (GenBase nest in NestedTypes) { if (BaseGen != null && BaseGen.ContainsNestedType(nest)) { if (nest is ClassGen) { (nest as ClassGen).needs_new = true; } } nest.Generate(sw, indent + "\t", opt, gen_info); sw.WriteLine(); } if (HasClassHandle) { bool requireNew = false; for (var bg = BaseGen; bg != null && bg is XmlClassGen; bg = bg.BaseGen) { if (bg.HasClassHandle) { requireNew = true; break; } } opt.CodeGenerator.WriteClassHandle(this, sw, indent, opt, requireNew); } GenConstructors(sw, indent + "\t", opt); GenProperties(sw, indent + "\t", opt); GenMethods(sw, indent + "\t", opt); if (IsAbstract) { GenerateAbstractMembers(sw, indent + "\t", opt); } bool is_char_seq = false; foreach (ISymbol isym in Interfaces) { if (isym is GenericSymbol) { GenericSymbol gs = isym as GenericSymbol; if (gs.IsConcrete) { // FIXME: not sure if excluding default methods is a valid idea... foreach (Method m in gs.Gen.Methods.Where(m => !m.IsInterfaceDefaultMethod && !m.IsStatic)) { if (m.IsGeneric) { m.GenerateExplicitIface(sw, indent + "\t", opt, gs); } } } } else if (isym.FullName == "Java.Lang.ICharSequence") { is_char_seq = true; } } if (is_char_seq) { GenCharSequenceEnumerator(sw, indent + "\t", opt); } sw.WriteLine(indent + "}"); if (!AssemblyQualifiedName.Contains('/')) { foreach (InterfaceExtensionInfo nestedIface in GetNestedInterfaceTypes()) { nestedIface.Type.GenerateExtensionsDeclaration(sw, indent, opt, nestedIface.DeclaringType); } } if (IsAbstract) { sw.WriteLine(); GenerateInvoker(sw, indent, opt); } opt.ContextTypes.Pop(); }