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
35 changes: 35 additions & 0 deletions tests/generator-Tests/Unit-Tests/DefaultInterfaceMethodsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -396,5 +396,40 @@ public void RespectNoAlternativesForInterfaces ()
Assert.False (writer.ToString ().Contains ("class ParentConsts"));
Assert.False (writer.ToString ().Contains ("class Parent"));
}

[Test]
public void DontInvalidateInterfaceDueToStaticOrDefaultMethods ()
{
// This interface contains a static and a default interface method that cannot
// be bound due to an unknown return type. However the user doesn't have to
// provide an implementation for these methods, so it's ok to bind the interface.

var xml = @"<api>
<package name='com.xamarin.android' jni-name='com/xamarin/android'>
<interface abstract='true' deprecated='not deprecated' final='false' name='Parent' static='false' visibility='public' jni-signature='Lcom/xamarin/android/Parent;'>
<method abstract='true' deprecated='not deprecated' name='normalMethod' jni-signature='()I' return='int' static='false' transient='false' visibility='public' volatile='false'></method>
<method abstract='false' deprecated='not deprecated' name='staticMethod' jni-signature='()Lfoo/bar/baz;' return='Lfoo/bar/baz;' static='true' transient='false' visibility='public' volatile='false'></method>
<method abstract='false' deprecated='not deprecated' name='defaultMethod' jni-signature='()Lfoo/bar/baz;' return='Lfoo/bar/baz;' static='false' transient='false' visibility='public' volatile='false'></method>
</interface>
</package>
</api>";

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

var result = iface.Validate (options, new GenericParameterDefinitionList (), new CodeGeneratorContext ());

// Inteface should pass validation despite invalid static/default methods
Assert.True (result);

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

var generated = writer.ToString ();

Assert.True (generated.Contains ("interface IParent"));
Assert.True (generated.Contains ("NormalMethod"));
Assert.False (generated.Contains ("StaticMethod"));
Assert.False (generated.Contains ("DefaultMethod"));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -677,11 +677,11 @@ protected virtual bool OnValidate (CodeGenerationOptions opt, GenericParameterDe
}
Fields = valid_fields;

// If we can't validate a default interface method it's ok to ignore it and still bind the interface
var method_cnt = Methods.Where (m => !m.IsInterfaceDefaultMethod).Count ();
// If we can't validate a static or default interface method it's ok to ignore it and still bind the interface
var method_cnt = Methods.Where (m => !m.IsInterfaceDefaultMethod && !m.IsStatic).Count ();

Methods = Methods.Where (m => ValidateMethod (opt, m, context)).ToList ();
MethodValidationFailed = method_cnt != Methods.Where (m => !m.IsInterfaceDefaultMethod).Count ();
MethodValidationFailed = method_cnt != Methods.Where (m => !m.IsInterfaceDefaultMethod && !m.IsStatic).Count ();

foreach (Method m in Methods) {
if (m.IsVirtual)
Expand Down