diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/JniRemapping/JniAssemblyRewriterTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/JniRemapping/JniAssemblyRewriterTests.cs index 21c93763bdc..f05d4f16851 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/JniRemapping/JniAssemblyRewriterTests.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/JniRemapping/JniAssemblyRewriterTests.cs @@ -7,7 +7,6 @@ using System.Reflection.Metadata; using System.Reflection.Metadata.Ecma335; using System.Reflection.PortableExecutable; -using Microsoft.Android.Sdk.TrimmableTypeMap; using Microsoft.Build.Framework; using Microsoft.Build.Utilities; using NUnit.Framework; @@ -891,85 +890,6 @@ public void FailsWhenASharedUtf8DatumNeedsTwoDifferentNames () StringAssert.Contains ("shared", exception.Message.ToLowerInvariant ()); } - [Test] - public void RewritesGeneratedTypeMapWithOwnerSpecificMethodNames () - { - byte [] source = GenerateTypeMapWithSharedMethodName (); - var warnings = new List (); - - JniRewriteResult result = Rewrite (source, Mapping ( - "test.First -> a.b.First:\n" + - " void n_Run() -> a\n" + - "test.Second -> a.b.Second:\n" + - " void n_Run() -> b\n"), warnings); - - CollectionAssert.AreEquivalent (new [] { "a", "b", "()V" }, ReadUtf8Values (result.Image)); - CollectionAssert.DoesNotContain (warnings.Select (warning => warning.Code).ToArray (), "XA4326"); - } - - [Test] - public void RewritesGeneratedTypeMapWithMappedAndUnmappedMethodNames () - { - byte [] source = GenerateTypeMapWithSharedMethodName (); - var warnings = new List (); - - JniRewriteResult result = Rewrite (source, Mapping ( - "test.First -> a.b.First:\n" + - " void n_Run() -> a\n" + - "test.Second -> test.Second:\n"), warnings); - - CollectionAssert.AreEquivalent (new [] { "a", "n_Run", "()V" }, ReadUtf8Values (result.Image)); - CollectionAssert.DoesNotContain (warnings.Select (warning => warning.Code).ToArray (), "XA4326"); - } - - static byte [] GenerateTypeMapWithSharedMethodName () - { - var peers = new [] { - CreatePeer ("test/First", "Test.First"), - CreatePeer ("test/Second", "Test.Second"), - }; - using var stream = new MemoryStream (); - new TypeMapAssemblyGenerator (new Version (11, 0, 0, 0)).Generate (peers, stream, "OwnerSpecificNames"); - return stream.ToArray (); - - static JavaPeerInfo CreatePeer (string javaName, string managedName) - { - int separator = managedName.LastIndexOf ('.'); - return new JavaPeerInfo { - JavaName = javaName, - CompatJniName = javaName, - ManagedTypeName = managedName, - ManagedTypeNamespace = managedName.Substring (0, separator), - ManagedTypeShortName = managedName.Substring (separator + 1), - AssemblyName = "TestAsm", - DoNotGenerateAcw = false, - ActivationCtor = new ActivationCtorInfo { - DeclaringTypeName = managedName, - DeclaringAssemblyName = "TestAsm", - Style = ActivationCtorStyle.XamarinAndroid, - }, - MarshalMethods = [ - new MarshalMethodInfo { - JniName = "run", - NativeCallbackName = "n_Run", - JniSignature = "()V", - ManagedMethodName = "Run", - }, - ], - }; - } - } - - static string [] ReadUtf8Values (byte [] image) - { - using var peReader = new PEReader (ImmutableArray.Create (image)); - MetadataReader reader = peReader.GetMetadataReader (); - return FieldRvaTable.Read (peReader, reader).Entries - .Select (entry => entry.Utf8Value) - .OfType () - .ToArray (); - } - [Test] public void FailsWhenASharedUtf8DatumMustRemainUnmappedForOneProxy () { diff --git a/tests/Microsoft.Android.Sdk.TrimmableTypeMap.IntegrationTests/JniAssemblyRewriterTests.cs b/tests/Microsoft.Android.Sdk.TrimmableTypeMap.IntegrationTests/JniAssemblyRewriterTests.cs new file mode 100644 index 00000000000..a2673ac1535 --- /dev/null +++ b/tests/Microsoft.Android.Sdk.TrimmableTypeMap.IntegrationTests/JniAssemblyRewriterTests.cs @@ -0,0 +1,103 @@ +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.IO; +using System.Linq; +using System.Reflection.Metadata; +using System.Reflection.PortableExecutable; +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; +using Xamarin.Android.Tasks.JniRemapping; +using Xunit; + +namespace Microsoft.Android.Sdk.TrimmableTypeMap.IntegrationTests; + +public class JniAssemblyRewriterTests +{ + [Fact] + public void RewritesGeneratedTypeMapWithOwnerSpecificMethodNames () + { + byte [] source = GenerateTypeMapWithSharedMethodName (); + var warnings = new List (); + + JniRewriteResult result = Rewrite (source, Mapping ( + "test.First -> a.b.First:\n" + + " void n_Run() -> a\n" + + "test.Second -> a.b.Second:\n" + + " void n_Run() -> b\n"), warnings); + + Assert.Equal (new [] { "()V", "a", "b" }, ReadUtf8Values (result.Image).OrderBy (value => value, StringComparer.Ordinal)); + Assert.DoesNotContain (warnings, warning => warning.Code == "XA4326"); + } + + [Fact] + public void RewritesGeneratedTypeMapWithMappedAndUnmappedMethodNames () + { + byte [] source = GenerateTypeMapWithSharedMethodName (); + var warnings = new List (); + + JniRewriteResult result = Rewrite (source, Mapping ( + "test.First -> a.b.First:\n" + + " void n_Run() -> a\n" + + "test.Second -> test.Second:\n"), warnings); + + Assert.Equal (new [] { "()V", "a", "n_Run" }, ReadUtf8Values (result.Image).OrderBy (value => value, StringComparer.Ordinal)); + Assert.DoesNotContain (warnings, warning => warning.Code == "XA4326"); + } + + static JniRewriteResult Rewrite (byte [] sourceImage, R8Mapping mapping, IList warnings) + { + var log = new TaskLoggingHelper (new MockBuildEngine (warnings), nameof (JniAssemblyRewriterTests)); + return JniAssemblyRewriter.Rewrite (sourceImage, mapping, log); + } + + static R8Mapping Mapping (string text) => R8Mapping.Parse (new StringReader (text)); + + static byte [] GenerateTypeMapWithSharedMethodName () + { + var peers = new [] { + CreatePeer ("test/First", "Test.First"), + CreatePeer ("test/Second", "Test.Second"), + }; + using var stream = new MemoryStream (); + new TypeMapAssemblyGenerator (new Version (11, 0, 0, 0)).Generate (peers, stream, "OwnerSpecificNames"); + return stream.ToArray (); + + static JavaPeerInfo CreatePeer (string javaName, string managedName) + { + int separator = managedName.LastIndexOf ('.'); + return new JavaPeerInfo { + JavaName = javaName, + CompatJniName = javaName, + ManagedTypeName = managedName, + ManagedTypeNamespace = managedName.Substring (0, separator), + ManagedTypeShortName = managedName.Substring (separator + 1), + AssemblyName = "TestAsm", + DoNotGenerateAcw = false, + ActivationCtor = new ActivationCtorInfo { + DeclaringTypeName = managedName, + DeclaringAssemblyName = "TestAsm", + Style = ActivationCtorStyle.XamarinAndroid, + }, + MarshalMethods = [ + new MarshalMethodInfo { + JniName = "run", + NativeCallbackName = "n_Run", + JniSignature = "()V", + ManagedMethodName = "Run", + }, + ], + }; + } + } + + static string [] ReadUtf8Values (byte [] image) + { + using var peReader = new PEReader (ImmutableArray.Create (image)); + MetadataReader reader = peReader.GetMetadataReader (); + return FieldRvaTable.Read (peReader, reader).Entries + .Select (entry => entry.Utf8Value) + .OfType () + .ToArray (); + } +} diff --git a/tests/Microsoft.Android.Sdk.TrimmableTypeMap.IntegrationTests/MockBuildEngine.cs b/tests/Microsoft.Android.Sdk.TrimmableTypeMap.IntegrationTests/MockBuildEngine.cs index d6c8c19d1eb..1d53a4603ac 100644 --- a/tests/Microsoft.Android.Sdk.TrimmableTypeMap.IntegrationTests/MockBuildEngine.cs +++ b/tests/Microsoft.Android.Sdk.TrimmableTypeMap.IntegrationTests/MockBuildEngine.cs @@ -1,5 +1,6 @@ using System; using System.Collections; +using System.Collections.Generic; using Microsoft.Build.Framework; namespace Microsoft.Android.Sdk.TrimmableTypeMap.IntegrationTests; @@ -9,6 +10,13 @@ namespace Microsoft.Android.Sdk.TrimmableTypeMap.IntegrationTests; /// sealed class MockBuildEngine : IBuildEngine { + readonly IList? warnings; + + public MockBuildEngine (IList? warnings = null) + { + this.warnings = warnings; + } + public bool ContinueOnError => false; public int LineNumberOfTaskNode => 0; public int ColumnNumberOfTaskNode => 0; @@ -18,5 +26,5 @@ sealed class MockBuildEngine : IBuildEngine public void LogCustomEvent (CustomBuildEventArgs e) { } public void LogErrorEvent (BuildErrorEventArgs e) { } public void LogMessageEvent (BuildMessageEventArgs e) { } - public void LogWarningEvent (BuildWarningEventArgs e) { } + public void LogWarningEvent (BuildWarningEventArgs e) => warnings?.Add (e); }