Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions tests/generator-Tests/Unit-Tests/DefaultInterfaceMethodsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -363,5 +363,38 @@ public void ObsoleteInterfaceAlternativeClass ()

Assert.AreEqual (GetTargetedExpected (nameof (ObsoleteInterfaceAlternativeClass)), writer.ToString ().NormalizeLineEndings ());
}

[Test]
public void RespectNoAlternativesForInterfaces ()
{
// If an interface is marked with no-alternatives='true', do
// not generate any legacy alternative classes for it
options.SupportInterfaceConstants = true;

var xml = @"<api>
<package name='java.lang' jni-name='java/lang'>
<class abstract='false' deprecated='not deprecated' final='false' name='Object' static='false' visibility='public' jni-signature='Ljava/lang/EmptyOverrideClass;' />
</package>
<package name='com.xamarin.android' jni-name='com/xamarin/android'>
<interface no-alternatives='true' abstract='true' deprecated='not deprecated' final='false' name='Parent' static='false' visibility='public' jni-signature='Lcom/xamarin/android/Parent;'>
<field deprecated='not deprecated' final='true' name='ACCEPT_HANDOVER' jni-signature='Ljava/lang/String;' static='true' transient='false' type='java.lang.String' type-generic-aware='java.lang.String' value='&quot;android.permission.ACCEPT_HANDOVER&quot;' visibility='public' volatile='false'></field>
<field deprecated='deprecated' final='true' name='ALREADY_OBSOLETE' jni-signature='Ljava/lang/String;' static='true' transient='false' type='java.lang.String' type-generic-aware='java.lang.String' value='&quot;android.permission.ACCEPT_HANDOVER&quot;' visibility='public' volatile='false'></field>
<field deprecated='not deprecated' final='true' name='API_NAME' jni-signature='Ljava/lang/String;' static='true' transient='false' type='java.lang.String' type-generic-aware='java.lang.String' visibility='public' volatile='false'></field>
<method abstract='false' deprecated='not deprecated' final='false' name='comparing' jni-signature='()I' bridge='false' native='false' return='int' jni-return='I' static='true' synchronized='false' synthetic='false' visibility='public' />
<method abstract='false' deprecated='deprecated' final='false' name='comparingOld' jni-signature='()I' bridge='false' native='false' return='int' jni-return='I' static='true' synchronized='false' synthetic='false' visibility='public' />
</interface>
</package>
</api>";

var gens = ParseApiDefinition (xml);
var iface = gens.OfType<InterfaceGen> ().Single ();

iface.Validate (options, new GenericParameterDefinitionList (), new CodeGeneratorContext ());

generator.WriteInterface (iface, string.Empty, new GenerationInfo (string.Empty, string.Empty, "MyAssembly"));

Assert.False (writer.ToString ().Contains ("class ParentConsts"));
Assert.False (writer.ToString ().Contains ("class Parent"));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -732,6 +732,11 @@ public void WriteInterfaceImplementedMembersAlternative (InterfaceGen @interface
// in order to maintain backward compatibility.
// If we're creating a binding that supports DIM, we remove the XXXConsts class as they've been
// [Obsolete:iserror] for a long time, and we add [Obsolete] to the interface "class".

// Bail if requested we not produce alternative classes for this interface
if (@interface.NoAlternatives)
return;

var staticMethods = @interface.Methods.Where (m => m.IsStatic);
var should_obsolete = opt.SupportInterfaceConstants && opt.SupportDefaultInterfaceMethods;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ public static InterfaceGen CreateInterface (XElement pkg, XElement elem, CodeGen
var iface = new InterfaceGen (CreateGenBaseSupport (pkg, elem, true)) {
ArgsType = elem.XGetAttribute ("argsType"),
HasManagedName = elem.Attribute ("managedName") != null,
NoAlternatives = elem.XGetAttribute ("no-alternatives") == "true",
// Only use an explicitly set XML attribute
Unnest = elem.XGetAttribute ("unnest") == "true" ? true :
elem.XGetAttribute ("unnest") == "false" ? false :
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,10 @@ public bool IsConstSugar {
internal bool NeedsSender =>
Methods.Any (m => (m.RetVal.IsVoid && !m.Parameters.HasSender) || (m.IsEventHandlerWithHandledProperty && !m.Parameters.HasSender));

// If true, we will no longer generate the "interface alternative" legacy classes
// used to hold interface constants/static methods before we had C#8
public bool NoAlternatives { get; set; }

protected override bool OnValidate (CodeGenerationOptions opt, GenericParameterDefinitionList type_params, CodeGeneratorContext context)
{
if (validated)
Expand Down