From b7a4d86ff9bed295af9a6a8a42771a5223f45729 Mon Sep 17 00:00:00 2001 From: Jonathan Pobst Date: Wed, 7 Aug 2019 13:29:59 -0500 Subject: [PATCH] [Tuner] Don't generate AbstractMethodErrors for default interface methods. --- .../MonoDroid.Tuner/FixAbstractMethodsStep.cs | 3 +- .../Tasks/LinkerTests.cs | 72 +++++++++++++++++++ .../Xamarin.Android.Build.Tests.csproj | 1 + 3 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/LinkerTests.cs diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs index 101ecc5052b..32e582c0eef 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using Mono.Cecil; @@ -163,7 +164,7 @@ bool FixAbstractMethods (TypeDefinition type) if (ifaceDef.HasGenericParameters) continue; - foreach (var iMethod in ifaceDef.Methods) { + foreach (var iMethod in ifaceDef.Methods.Where (m => m.IsAbstract)) { bool exists = false; foreach (var tMethod in typeMethods) { diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/LinkerTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/LinkerTests.cs new file mode 100644 index 00000000000..3b8417a2c47 --- /dev/null +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/LinkerTests.cs @@ -0,0 +1,72 @@ +using System; +using System.Linq; +using Mono.Cecil; +using Mono.Linker; +using MonoDroid.Tuner; +using NUnit.Framework; + +namespace Xamarin.Android.Build.Tests +{ + public class LinkerTests : BaseTest + { + [Test] + public void FixAbstractMethodsStep_SkipDimMembers () + { + var step = new FixAbstractMethodsStep (); + var pipeline = new Pipeline (); + var context = new LinkContext (pipeline); + + var android = CreateFauxMonoAndroidAssembly (); + var jlo = android.MainModule.GetType ("Java.Lang.Object"); + + context.Resolver.CacheAssembly (android); + + var assm = AssemblyDefinition.CreateAssembly (new AssemblyNameDefinition ("DimTest", new Version ()), "DimTest", ModuleKind.Dll); + var void_type = assm.MainModule.ImportReference (typeof (void)); + + // Create interface + var iface = new TypeDefinition ("MyNamespace", "IMyInterface", TypeAttributes.Interface); + + var abstract_method = new MethodDefinition ("MyAbstractMethod", MethodAttributes.Abstract, void_type); + var default_method = new MethodDefinition ("MyDefaultMethod", MethodAttributes.Public, void_type); + + iface.Methods.Add (abstract_method); + iface.Methods.Add (default_method); + + assm.MainModule.Types.Add (iface); + + // Create implementing class + var impl = new TypeDefinition ("MyNamespace", "MyClass", TypeAttributes.Public, jlo); + impl.Interfaces.Add (new InterfaceImplementation (iface)); + + assm.MainModule.Types.Add (impl); + + context.Resolver.CacheAssembly (assm); + + step.Process (context); + + // We should have generated an override for MyAbstractMethod + Assert.IsTrue (impl.Methods.Any (m => m.Name == "MyAbstractMethod")); + + // We should not have generated an override for MyDefaultMethod + Assert.IsFalse (impl.Methods.Any (m => m.Name == "MyDefaultMethod")); + } + + static AssemblyDefinition CreateFauxMonoAndroidAssembly () + { + var assm = AssemblyDefinition.CreateAssembly (new AssemblyNameDefinition ("Mono.Android", new Version ()), "DimTest", ModuleKind.Dll); + var void_type = assm.MainModule.ImportReference (typeof (void)); + + // Create fake JLO type + var jlo = new TypeDefinition ("Java.Lang", "Object", TypeAttributes.Public); + assm.MainModule.Types.Add (jlo); + + // Create fake Java.Lang.AbstractMethodError type + var ame = new TypeDefinition ("Java.Lang", "AbstractMethodError", TypeAttributes.Public); + ame.Methods.Add (new MethodDefinition (".ctor", MethodAttributes.Public, void_type)); + assm.MainModule.Types.Add (ame); + + return assm; + } + } +} diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Xamarin.Android.Build.Tests.csproj b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Xamarin.Android.Build.Tests.csproj index a292ab67f34..2f62792424e 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Xamarin.Android.Build.Tests.csproj +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Xamarin.Android.Build.Tests.csproj @@ -94,6 +94,7 @@ +