Skip to content

Commit bd7c60a

Browse files
authored
[generator] Support //interface/@no-alternatives (#601)
Context: #509 In 105d544 we began cleaning up our existing "alternative" hacks for bindings that use the new C#8 DIM features. However, as we add new API interfaces we will continue to generate new `[Obsolete]` "alternative" classes. We do not need to add new already-obsolete API to our bindings. Update `generator` so that Metadata.xml files can now add a `//interface/@no-alternatives` attribute. When this attribute is `true`, the alternative types won't be emitted. This will be used in `Mono.Android.dll` like this: <attr api-since="30" path="/api/package/interface[contains(@merge.SourceFile,'api-30.xml.in')]" name="no-alternatives">true</attr> which will prevent any interfaces added in API-R+ from creating `[Obsolete]` alternative classes.
1 parent 105d544 commit bd7c60a

File tree

4 files changed

+43
-0
lines changed

4 files changed

+43
-0
lines changed

tests/generator-Tests/Unit-Tests/DefaultInterfaceMethodsTests.cs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,5 +363,38 @@ public void ObsoleteInterfaceAlternativeClass ()
363363

364364
Assert.AreEqual (GetTargetedExpected (nameof (ObsoleteInterfaceAlternativeClass)), writer.ToString ().NormalizeLineEndings ());
365365
}
366+
367+
[Test]
368+
public void RespectNoAlternativesForInterfaces ()
369+
{
370+
// If an interface is marked with no-alternatives='true', do
371+
// not generate any legacy alternative classes for it
372+
options.SupportInterfaceConstants = true;
373+
374+
var xml = @"<api>
375+
<package name='java.lang' jni-name='java/lang'>
376+
<class abstract='false' deprecated='not deprecated' final='false' name='Object' static='false' visibility='public' jni-signature='Ljava/lang/EmptyOverrideClass;' />
377+
</package>
378+
<package name='com.xamarin.android' jni-name='com/xamarin/android'>
379+
<interface no-alternatives='true' abstract='true' deprecated='not deprecated' final='false' name='Parent' static='false' visibility='public' jni-signature='Lcom/xamarin/android/Parent;'>
380+
<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>
381+
<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>
382+
<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>
383+
<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' />
384+
<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' />
385+
</interface>
386+
</package>
387+
</api>";
388+
389+
var gens = ParseApiDefinition (xml);
390+
var iface = gens.OfType<InterfaceGen> ().Single ();
391+
392+
iface.Validate (options, new GenericParameterDefinitionList (), new CodeGeneratorContext ());
393+
394+
generator.WriteInterface (iface, string.Empty, new GenerationInfo (string.Empty, string.Empty, "MyAssembly"));
395+
396+
Assert.False (writer.ToString ().Contains ("class ParentConsts"));
397+
Assert.False (writer.ToString ().Contains ("class Parent"));
398+
}
366399
}
367400
}

tools/generator/Java.Interop.Tools.Generator.CodeGeneration/CodeGenerator.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -732,6 +732,11 @@ public void WriteInterfaceImplementedMembersAlternative (InterfaceGen @interface
732732
// in order to maintain backward compatibility.
733733
// If we're creating a binding that supports DIM, we remove the XXXConsts class as they've been
734734
// [Obsolete:iserror] for a long time, and we add [Obsolete] to the interface "class".
735+
736+
// Bail if requested we not produce alternative classes for this interface
737+
if (@interface.NoAlternatives)
738+
return;
739+
735740
var staticMethods = @interface.Methods.Where (m => m.IsStatic);
736741
var should_obsolete = opt.SupportInterfaceConstants && opt.SupportDefaultInterfaceMethods;
737742

tools/generator/Java.Interop.Tools.Generator.Importers/XmlApiImporter.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ public static InterfaceGen CreateInterface (XElement pkg, XElement elem, CodeGen
197197
var iface = new InterfaceGen (CreateGenBaseSupport (pkg, elem, true)) {
198198
ArgsType = elem.XGetAttribute ("argsType"),
199199
HasManagedName = elem.Attribute ("managedName") != null,
200+
NoAlternatives = elem.XGetAttribute ("no-alternatives") == "true",
200201
// Only use an explicitly set XML attribute
201202
Unnest = elem.XGetAttribute ("unnest") == "true" ? true :
202203
elem.XGetAttribute ("unnest") == "false" ? false :

tools/generator/Java.Interop.Tools.Generator.ObjectModel/InterfaceGen.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,10 @@ public bool IsConstSugar {
186186
internal bool NeedsSender =>
187187
Methods.Any (m => (m.RetVal.IsVoid && !m.Parameters.HasSender) || (m.IsEventHandlerWithHandledProperty && !m.Parameters.HasSender));
188188

189+
// If true, we will no longer generate the "interface alternative" legacy classes
190+
// used to hold interface constants/static methods before we had C#8
191+
public bool NoAlternatives { get; set; }
192+
189193
protected override bool OnValidate (CodeGenerationOptions opt, GenericParameterDefinitionList type_params, CodeGeneratorContext context)
190194
{
191195
if (validated)

0 commit comments

Comments
 (0)