diff --git a/tools/generator/Java.Interop.Tools.Generator.CodeGeneration/CodeGenerator.cs b/tools/generator/Java.Interop.Tools.Generator.CodeGeneration/CodeGenerator.cs index f6b9a7807..3ced2cef6 100644 --- a/tools/generator/Java.Interop.Tools.Generator.CodeGeneration/CodeGenerator.cs +++ b/tools/generator/Java.Interop.Tools.Generator.CodeGeneration/CodeGenerator.cs @@ -1470,8 +1470,13 @@ public void WriteProperty (Property property, GenBase gen, string indent, bool w if ((property.Getter ?? property.Setter).IsStatic) virtual_override = " static"; // It should be using AdjustedName instead of Name, but ICharSequence ("Formatted") properties are not caught by this... - else if (gen.BaseSymbol != null && gen.BaseSymbol.GetPropertyByName (property.Name, true) != null) - virtual_override = " override"; + else if (gen.BaseSymbol != null) { + var base_prop = gen.BaseSymbol.GetPropertyByName (property.Name, true); + + // If the matching base getter we found is a DIM, we do not override it, it should stay virtual + if (base_prop != null && !base_prop.Getter.IsInterfaceDefaultMethod) + virtual_override = " override"; + } WriteMethodIdField (property.Getter, indent); if (property.Setter != null) diff --git a/tools/generator/Tests/Unit-Tests/CodeGeneratorTestBase.cs b/tools/generator/Tests/Unit-Tests/CodeGeneratorTestBase.cs index 1fd31f7c3..2b2cb4b01 100644 --- a/tools/generator/Tests/Unit-Tests/CodeGeneratorTestBase.cs +++ b/tools/generator/Tests/Unit-Tests/CodeGeneratorTestBase.cs @@ -1,7 +1,10 @@ using System; +using System.Collections.Generic; using System.IO; +using System.Linq; using System.Reflection; using System.Text; +using System.Xml.Linq; using MonoDroid.Generation; using NUnit.Framework; @@ -55,5 +58,25 @@ protected string GetTargetedExpected (string testName) return File.ReadAllText (Path.Combine (root, "Unit-Tests", "CodeGeneratorExpectedResults", target, $"{testName}.txt")).NormalizeLineEndings (); } + + protected List ParseApiDefinition (string xml) + { + var doc = XDocument.Parse (xml); + var gens = new Parser (options).Parse (doc, Enumerable.Empty (), "29", 7); + + foreach (var gen in gens) + options.SymbolTable.AddType (gen); + + foreach (var gen in gens) + gen.Validate (options, new GenericParameterDefinitionList (), generator.Context); + + foreach (var gen in gens) + gen.FillProperties (); + + foreach (var gen in gens) + gen.FixupMethodOverrides (options); + + return gens; + } } } diff --git a/tools/generator/Tests/Unit-Tests/DefaultInterfaceMethodsTests.cs b/tools/generator/Tests/Unit-Tests/DefaultInterfaceMethodsTests.cs index 142fbae9b..d60f047bc 100644 --- a/tools/generator/Tests/Unit-Tests/DefaultInterfaceMethodsTests.cs +++ b/tools/generator/Tests/Unit-Tests/DefaultInterfaceMethodsTests.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using MonoDroid.Generation; using NUnit.Framework; using Xamarin.Android.Binder; @@ -149,6 +150,48 @@ public void WriteSealedOverriddenDefaultMethod () Assert.False (writer.ToString ().Contains ("virtual sealed")); } + [Test] + public void WriteInterfaceRedeclaredChainDefaultMethod () + { + // Fix a case where a property declared in this hierarchy was generated as "override" instead of "virtual" + // public interface MyInterface { default int getValue () { return 0; } } + // public class MyClass implements MyInterface { } + // public class MySecondClass extends MyClass { @Override public int getValue () { return 1; } } + var gens = ParseApiDefinition (@" + + + + + + + + + + + + + + + + + + + + + + + + "); + + var klass = (ClassGen)gens.First (g => g.Name == "ImplementedChainOverrideClass"); + + generator.Context.ContextTypes.Push (klass); + generator.WriteClass (klass, string.Empty, new GenerationInfo (string.Empty, string.Empty, "MyAssembly")); + generator.Context.ContextTypes.Pop (); + + Assert.True (writer.ToString ().Contains ("public virtual unsafe int Bar")); + } + [Test] public void WriteStaticInterfaceMethod () {