Example #1
0
        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");
            }
        }