void AddMethods(ClassGen klass, CodeGenerationOptions opt, CodeGeneratorContext context) { var methodsToDeclare = klass.Methods.AsEnumerable(); // This does not exclude overrides (unlike virtual methods) because we're not sure // if calling the base interface default method via JNI expectedly dispatches to // the derived method. var defaultMethods = klass.GetAllDerivedInterfaces() .SelectMany(i => i.Methods) .Where(m => m.IsInterfaceDefaultMethod) .Where(m => !klass.ContainsMethod(m, false, false)); var overrides = defaultMethods.Where(m => m.OverriddenInterfaceMethod != null); var overridens = defaultMethods.Where(m => overrides.Where(_ => _.Name == m.Name && _.JniSignature == m.JniSignature) .Any(mm => mm.DeclaringType.GetAllDerivedInterfaces().Contains(m.DeclaringType))); methodsToDeclare = opt.SupportDefaultInterfaceMethods ? methodsToDeclare : methodsToDeclare.Concat(defaultMethods.Except(overridens)).Where(m => m.DeclaringType.IsGeneratable); foreach (var m in methodsToDeclare) { var virt = m.IsVirtual; m.IsVirtual = !klass.IsFinal && virt; if (m.IsAbstract && m.OverriddenInterfaceMethod == null && (opt.SupportDefaultInterfaceMethods || !m.IsInterfaceDefaultMethod)) { AddAbstractMethodDeclaration(klass, m, null); } else { AddMethod(klass, m, opt); } context.ContextGeneratedMethods.Add(m); m.IsVirtual = virt; } var methods = klass.Methods.Concat(klass.Properties.Where(p => p.Setter != null).Select(p => p.Setter)); foreach (var type in methods.Where(m => m.IsListenerConnector && m.EventName != string.Empty).Select(m => m.ListenerType).Distinct()) { AddInlineComment($"#region \"Event implementation for {type.FullName}\""); SourceWriterExtensions.AddInterfaceListenerEventsAndProperties(this, type, klass, opt); AddInlineComment("#endregion"); } }