void AddInheritedInterfaces(InterfaceGen iface, CodeGenerationOptions opt) { foreach (var isym in iface.Interfaces) { var igen = (isym is GenericSymbol ? (isym as GenericSymbol).Gen : isym) as InterfaceGen; // igen *should not* be null here because we *should* only be inheriting interfaces, but // in the case of constants on that interface we create a C# *class* that is registered for the // Java *interface*. Thus when we do type resolution, we are actually pointed to the // Foo abstract class instead of the IFoo interface. if (igen is null || igen.IsConstSugar(opt) || igen.RawVisibility != "public") { continue; } Implements.Add(opt.GetOutputName(isym.FullName)); } if (Implements.Count == 0 && !iface.IsConstSugar(opt)) { if (opt.CodeGenerationTarget != CodeGenerationTarget.JavaInterop1) { Implements.Add("IJavaObject"); } Implements.Add("IJavaPeerable"); } }
void AddInheritedInterfaces(InterfaceGen iface, CodeGenerationOptions opt) { foreach (var isym in iface.Interfaces) { var igen = (isym is GenericSymbol ? (isym as GenericSymbol).Gen : isym) as InterfaceGen; if (igen.IsConstSugar(opt) || igen.RawVisibility != "public") { continue; } Implements.Add(opt.GetOutputName(isym.FullName)); } if (Implements.Count == 0 && !iface.IsConstSugar(opt)) { Implements.AddRange(new [] { "IJavaObject", "IJavaPeerable" }); } }
public BoundInterface(InterfaceGen iface, CodeGenerationOptions opt, CodeGeneratorContext context, GenerationInfo genInfo) { context.ContextTypes.Push(iface); Name = iface.Name; AddNestedSiblingTypes(iface, opt, context, genInfo); AddAlternativesClass(iface, opt, context); // If this interface is just fields and we can't generate any of them // then we don't need to write the interface. We still keep this type // because it may have nested types or need an InterfaceMemberAlternativeClass. if (iface.IsConstSugar(opt) && iface.GetGeneratableFields(opt).Count() == 0) { dont_generate = true; return; } IsPartial = true; UsePriorityOrder = true; SetVisibility(iface.Visibility); iface.JavadocInfo?.AddJavadocs(Comments); Comments.Add($"// Metadata.xml XPath interface reference: path=\"{iface.MetadataXPathReference}\""); if (iface.IsDeprecated) { Attributes.Add(new ObsoleteAttr(iface.DeprecatedComment) { WriteAttributeSuffix = true, WriteEmptyString = true }); } if (!iface.IsConstSugar(opt)) { var signature = string.IsNullOrWhiteSpace(iface.Namespace) ? iface.FullName.Replace('.', '/') : iface.Namespace + "." + iface.FullName.Substring(iface.Namespace.Length + 1).Replace('.', '/'); if (opt.CodeGenerationTarget == CodeGenerationTarget.JavaInterop1) { Attributes.Add(new JniTypeSignatureAttr(iface.RawJniName, false)); } else { Attributes.Add(new RegisterAttr(iface.RawJniName, string.Empty, signature + "Invoker", additionalProperties: iface.AdditionalAttributeString())); } } if (iface.TypeParameters != null && iface.TypeParameters.Any()) { Attributes.Add(new CustomAttr(iface.TypeParameters.ToGeneratedAttributeString())); } AddInheritedInterfaces(iface, opt); AddClassHandle(iface, opt); AddFields(iface, opt, context); AddProperties(iface, opt); AddMethods(iface, opt); AddNestedTypes(iface, opt, context, genInfo); // If this interface is just constant fields we don't need to add all the invoker bits if (iface.IsConstSugar(opt)) { return; } if (!iface.AssemblyQualifiedName.Contains('/')) { if (iface.Methods.Any(m => m.CanHaveStringOverload) || iface.Methods.Any(m => m.Asyncify)) { post_sibling_types.Add(new InterfaceExtensionsClass(iface, null, opt)); } } if (opt.CodeGenerationTarget != CodeGenerationTarget.JavaInterop1) { // Worry about later; https://github.com/xamarin/java.interop/issues/910 post_sibling_types.Add(new InterfaceInvokerClass(iface, opt, context)); } AddInterfaceEventHandler(iface, opt, context); context.ContextTypes.Pop(); }