diff options
26 files changed, 183 insertions, 58 deletions
diff --git a/src/linker/Linker.Steps/SweepStep.cs b/src/linker/Linker.Steps/SweepStep.cs index 02054c45b..c42fea927 100644 --- a/src/linker/Linker.Steps/SweepStep.cs +++ b/src/linker/Linker.Steps/SweepStep.cs @@ -65,11 +65,14 @@ namespace Mono.Linker.Steps // Update scopes before removing any type forwarder. foreach (var assembly in assemblies) { - switch (Annotations.GetAction (assembly)) { + var action = Annotations.GetAction (assembly); + switch (action) { case AssemblyAction.CopyUsed: case AssemblyAction.Link: case AssemblyAction.Save: - SweepAssemblyReferences (assembly); + bool changed = SweepAssemblyReferences (assembly); + if (changed && action == AssemblyAction.CopyUsed) + Annotations.SetAction (assembly, AssemblyAction.Save); break; } } @@ -183,8 +186,11 @@ namespace Mono.Linker.Steps case AssemblyAction.CopyUsed: AssemblyAction assemblyAction = AssemblyAction.Copy; - if (!Context.KeepTypeForwarderOnlyAssemblies && SweepTypeForwarders (assembly)) + if (!Context.KeepTypeForwarderOnlyAssemblies && SweepTypeForwarders (assembly)) { + // Need to sweep references, in case sweeping type forwarders removed any + SweepAssemblyReferences (assembly); assemblyAction = AssemblyAction.Save; + } Annotations.SetAction (assembly, assemblyAction); break; @@ -197,7 +203,10 @@ namespace Mono.Linker.Steps break; case AssemblyAction.Save: - SweepTypeForwarders (assembly); + if (!Context.KeepTypeForwarderOnlyAssemblies && SweepTypeForwarders (assembly)) { + // Need to sweep references, in case sweeping type forwarders removed any + SweepAssemblyReferences (assembly); + } break; } } @@ -247,7 +256,7 @@ namespace Mono.Linker.Steps SweepAssemblyReferences (assembly); } - static void SweepAssemblyReferences (AssemblyDefinition assembly) + static bool SweepAssemblyReferences (AssemblyDefinition assembly) { // // We used to run over list returned by GetTypeReferences but @@ -258,7 +267,7 @@ namespace Mono.Linker.Steps assembly.MainModule.AssemblyReferences.Clear (); var ars = new AssemblyReferencesCorrector (assembly); - ars.Process (); + return ars.Process (); } bool IsUsedAssembly (AssemblyDefinition assembly) @@ -561,6 +570,7 @@ namespace Mono.Linker.Steps readonly DefaultMetadataImporter importer; HashSet<TypeReference> updated; + bool changedAnyScopes; public AssemblyReferencesCorrector (AssemblyDefinition assembly) { @@ -568,9 +578,10 @@ namespace Mono.Linker.Steps this.importer = new DefaultMetadataImporter (assembly.MainModule); updated = null; + changedAnyScopes = false; } - public void Process () + public bool Process () { updated = new HashSet<TypeReference> (); @@ -591,6 +602,10 @@ namespace Mono.Linker.Steps UpdateTypeScope (mmodule.ExportedTypes); updated = null; + var ret = changedAnyScopes; + changedAnyScopes = false; + + return ret; } void UpdateScopes (TypeDefinition typeDefinition) @@ -696,12 +711,17 @@ namespace Mono.Linker.Steps if (td == null) { // Forwarded type cannot be resolved but it was marked // linker is running in --skip-unresolved true mode + var anr = (AssemblyNameReference) f.Scope; + f.Scope = importer.ImportReference (anr); continue; } var tr = assembly.MainModule.ImportReference (td); - if (f.Scope != tr.Scope) - f.Scope = tr.Scope; + if (f.Scope == tr.Scope) + continue; + + f.Scope = tr.Scope; + changedAnyScopes = true; } } @@ -869,11 +889,9 @@ namespace Mono.Linker.Steps if (type == null) return; - if (updated.Contains (type)) + if (!updated.Add (type)) return; - updated.Add (type); - // Can't update the scope of windows runtime projections if (type.IsWindowsRuntimeProjection) return; @@ -918,8 +936,11 @@ namespace Mono.Linker.Steps } var tr = assembly.MainModule.ImportReference (td); - if (type.Scope != tr.Scope) - type.Scope = tr.Scope; + if (type.Scope == tr.Scope) + return; + + type.Scope = tr.Scope; + changedAnyScopes = true; } } } diff --git a/test/Mono.Linker.Tests.Cases/Mono.Linker.Tests.Cases.csproj b/test/Mono.Linker.Tests.Cases/Mono.Linker.Tests.Cases.csproj index 63b87f3f3..71a33ea86 100644 --- a/test/Mono.Linker.Tests.Cases/Mono.Linker.Tests.Cases.csproj +++ b/test/Mono.Linker.Tests.Cases/Mono.Linker.Tests.Cases.csproj @@ -19,6 +19,7 @@ <Compile Remove="TypeForwarding\Dependencies\ForwarderLibrary.cs" /> <Compile Remove="TypeForwarding\Dependencies\ForwarderLibrary_2.cs" /> <Compile Remove="TypeForwarding\Dependencies\ForwarderLibrary_3.cs" /> + <Compile Remove="TypeForwarding\Dependencies\ForwarderLibraryWithUnusedReference.cs" /> <Compile Remove="TypeForwarding\Dependencies\ImplementationLibrary_3.cs" /> <Compile Remove="TypeForwarding\Dependencies\MyEnumForwarder.cs" /> <Compile Remove="TypeForwarding\Dependencies\TypeForwardedIsUpdatedForMissingTypeFwd.cs" /> diff --git a/test/Mono.Linker.Tests.Cases/TypeForwarding/AttributeArgumentForwarded.cs b/test/Mono.Linker.Tests.Cases/TypeForwarding/AttributeArgumentForwarded.cs index 6e740e717..b0efefb6a 100644 --- a/test/Mono.Linker.Tests.Cases/TypeForwarding/AttributeArgumentForwarded.cs +++ b/test/Mono.Linker.Tests.Cases/TypeForwarding/AttributeArgumentForwarded.cs @@ -17,8 +17,8 @@ namespace Mono.Linker.Tests.Cases.TypeForwarding [SetupCompileAfter ("Forwarder.dll", new[] { "Dependencies/ForwarderLibrary.cs" }, references: new[] { "Implementation.dll" })] [RemovedAssembly ("Forwarder.dll")] - [KeptMemberInAssembly ("Implementation.dll", typeof (ImplementationLibrary))] - [KeptMemberInAssembly ("Implementation.dll", typeof (ImplementationStruct))] + [KeptTypeInAssembly ("Implementation.dll", typeof (ImplementationLibrary))] + [KeptTypeInAssembly ("Implementation.dll", typeof (ImplementationStruct))] class AttributeArgumentForwarded { static void Main () diff --git a/test/Mono.Linker.Tests.Cases/TypeForwarding/AttributeArgumentForwardedWithCopyAction.cs b/test/Mono.Linker.Tests.Cases/TypeForwarding/AttributeArgumentForwardedWithCopyAction.cs index 0c5d01131..71e154036 100644 --- a/test/Mono.Linker.Tests.Cases/TypeForwarding/AttributeArgumentForwardedWithCopyAction.cs +++ b/test/Mono.Linker.Tests.Cases/TypeForwarding/AttributeArgumentForwardedWithCopyAction.cs @@ -23,8 +23,8 @@ namespace Mono.Linker.Tests.Cases.TypeForwarding [SetupCompileAfter ("Implementation.dll", new[] { "Dependencies/ImplementationLibrary.cs" })] [SetupCompileAfter ("Forwarder.dll", new[] { "Dependencies/ForwarderLibrary.cs" }, references: new[] { "Implementation.dll" })] - [KeptMemberInAssembly ("Forwarder.dll", typeof (ImplementationLibrary))] - [KeptMemberInAssembly ("Implementation.dll", typeof (ImplementationLibrary))] + [KeptTypeInAssembly ("Forwarder.dll", typeof (ImplementationLibrary))] + [KeptTypeInAssembly ("Implementation.dll", typeof (ImplementationLibrary))] static class AttributeArgumentForwardedWithCopyAction { static void Main () diff --git a/test/Mono.Linker.Tests.Cases/TypeForwarding/AttributesScopeUpdated.cs b/test/Mono.Linker.Tests.Cases/TypeForwarding/AttributesScopeUpdated.cs index 1e01403be..f1be225b9 100644 --- a/test/Mono.Linker.Tests.Cases/TypeForwarding/AttributesScopeUpdated.cs +++ b/test/Mono.Linker.Tests.Cases/TypeForwarding/AttributesScopeUpdated.cs @@ -19,8 +19,8 @@ namespace Mono.Linker.Tests.Cases.TypeForwarding [SetupCompileAfter ("Implementation.dll", new[] { "Dependencies/ImplementationLibrary.cs" })] [SetupCompileAfter ("Forwarder.dll", new[] { "Dependencies/ForwarderLibrary.cs" }, references: new[] { "Implementation.dll" })] - [KeptMemberInAssembly ("Forwarder.dll", typeof (ImplementationLibrary))] - [KeptMemberInAssembly ("Implementation.dll", typeof (ImplementationLibrary))] + [KeptTypeInAssembly ("Forwarder.dll", typeof (ImplementationLibrary))] + [KeptTypeInAssembly ("Implementation.dll", typeof (ImplementationLibrary))] static class AttributesScopeUpdated { static void Main () diff --git a/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ForwarderLibraryWithUnusedReference.cs b/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ForwarderLibraryWithUnusedReference.cs new file mode 100644 index 000000000..b6037e99b --- /dev/null +++ b/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ForwarderLibraryWithUnusedReference.cs @@ -0,0 +1,4 @@ +using System; + +[assembly: System.Runtime.CompilerServices.TypeForwardedTo (typeof (Mono.Linker.Tests.Cases.TypeForwarding.Dependencies.ImplementationLibrary))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo (typeof (Mono.Linker.Tests.Cases.TypeForwarding.Dependencies.UnusedImplementationLibrary))]
\ No newline at end of file diff --git a/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ReferenceImplementationUsedAndUnusedLibrary.cs b/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ReferenceImplementationUsedAndUnusedLibrary.cs new file mode 100644 index 000000000..6f0b48228 --- /dev/null +++ b/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ReferenceImplementationUsedAndUnusedLibrary.cs @@ -0,0 +1,13 @@ +namespace Mono.Linker.Tests.Cases.TypeForwarding.Dependencies +{ +#if INCLUDE_REFERENCE_IMPL + public class ImplementationLibrary + { + public string GetSomeValue () => null; + } + + public class UnusedImplementationLibrary + { + } +#endif +}
\ No newline at end of file diff --git a/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/UnusedImplementationLibrary.cs b/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/UnusedImplementationLibrary.cs new file mode 100644 index 000000000..a719d0bb9 --- /dev/null +++ b/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/UnusedImplementationLibrary.cs @@ -0,0 +1,6 @@ +namespace Mono.Linker.Tests.Cases.TypeForwarding.Dependencies +{ + public class UnusedImplementationLibrary + { + } +}
\ No newline at end of file diff --git a/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedAndUnusedForwarderWithAssemblyCopy.cs b/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedAndUnusedForwarderWithAssemblyCopy.cs index fdd75a7f8..c1b63ce8c 100644 --- a/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedAndUnusedForwarderWithAssemblyCopy.cs +++ b/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedAndUnusedForwarderWithAssemblyCopy.cs @@ -21,8 +21,8 @@ namespace Mono.Linker.Tests.Cases.TypeForwarding [KeptMemberInAssembly ("Implementation.dll", typeof (ImplementationLibrary), "GetSomeValue()")] // The whole assembly is kept as is, since it is marked with the `copy` action. - [KeptMemberInAssembly ("Forwarder.dll", typeof (ImplementationLibrary))] - [KeptMemberInAssembly ("Forwarder.dll", "Mono.Linker.Tests.Cases.TypeForwarding.Dependencies.AnotherLibrary`1")] + [KeptTypeInAssembly ("Forwarder.dll", typeof (ImplementationLibrary))] + [KeptTypeInAssembly ("Forwarder.dll", "Mono.Linker.Tests.Cases.TypeForwarding.Dependencies.AnotherLibrary`1")] [KeptReferencesInAssembly ("Forwarder.dll", new[] { "System.Private.CoreLib", "Implementation", "Unused" })] // Even though `Forwarder` references this assembly, none of its members are marked (none is used) and, since `Unused` // has `link` action, it is removed. diff --git a/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderInCopyAssemblyKeptByPreserveDependency.cs b/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderInCopyAssemblyKeptByPreserveDependency.cs index 4abfabc66..e9ad4d5c4 100644 --- a/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderInCopyAssemblyKeptByPreserveDependency.cs +++ b/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderInCopyAssemblyKeptByPreserveDependency.cs @@ -16,8 +16,8 @@ namespace Mono.Linker.Tests.Cases.TypeForwarding [SetupCompileAfter ("Implementation.dll", new[] { "Dependencies/ImplementationLibrary.cs" })] [SetupCompileAfter ("Forwarder.dll", new[] { "Dependencies/ForwarderLibrary.cs" }, references: new[] { "Implementation.dll" })] - [KeptMemberInAssembly ("Forwarder.dll", typeof (ImplementationLibrary))] - [KeptMemberInAssembly ("Implementation.dll", typeof (ImplementationLibrary))] + [KeptTypeInAssembly ("Forwarder.dll", typeof (ImplementationLibrary))] + [KeptTypeInAssembly ("Implementation.dll", typeof (ImplementationLibrary))] [Kept] [KeptMember (".ctor()")] diff --git a/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderInCopyAssemblyKeptByUsedCustomAttribute.cs b/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderInCopyAssemblyKeptByUsedCustomAttribute.cs index 5c1230cd6..5c342a666 100644 --- a/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderInCopyAssemblyKeptByUsedCustomAttribute.cs +++ b/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderInCopyAssemblyKeptByUsedCustomAttribute.cs @@ -15,8 +15,8 @@ namespace Mono.Linker.Tests.Cases.TypeForwarding [SetupCompileAfter ("Implementation.dll", new[] { "Dependencies/ImplementationLibrary.cs" })] [SetupCompileAfter ("Forwarder.dll", new[] { "Dependencies/ForwarderLibrary.cs" }, references: new[] { "Implementation.dll" })] - [KeptMemberInAssembly ("Forwarder.dll", typeof (ImplementationLibraryAttribute))] - [KeptMemberInAssembly ("Implementation.dll", typeof (ImplementationLibraryAttribute))] + [KeptTypeInAssembly ("Forwarder.dll", typeof (ImplementationLibraryAttribute))] + [KeptTypeInAssembly ("Implementation.dll", typeof (ImplementationLibraryAttribute))] [Kept] [KeptMember (".ctor()")] diff --git a/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderInCopyAssemblyKeptByUsedField.cs b/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderInCopyAssemblyKeptByUsedField.cs index 961cf64f8..678cb3e2d 100644 --- a/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderInCopyAssemblyKeptByUsedField.cs +++ b/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderInCopyAssemblyKeptByUsedField.cs @@ -15,9 +15,9 @@ namespace Mono.Linker.Tests.Cases.TypeForwarding [SetupCompileAfter ("Forwarder.dll", new[] { "Dependencies/ForwarderLibrary.cs" }, references: new[] { "Implementation.dll" })] [KeptAssembly ("Forwarder.dll")] - [KeptMemberInAssembly ("Implementation.dll", typeof (ImplementationLibrary))] + [KeptTypeInAssembly ("Implementation.dll", typeof (ImplementationLibrary))] [KeptMemberInAssembly ("Implementation.dll", typeof (ImplementationLibrary), "someField")] - [KeptMemberInAssembly ("Forwarder.dll", typeof (ImplementationLibrary))] + [KeptTypeInAssembly ("Forwarder.dll", typeof (ImplementationLibrary))] [Kept] [KeptMember (".ctor()")] diff --git a/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderInCopyAssemblyKeptByUsedInterface.cs b/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderInCopyAssemblyKeptByUsedInterface.cs index 8b87e16a2..712dfde88 100644 --- a/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderInCopyAssemblyKeptByUsedInterface.cs +++ b/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderInCopyAssemblyKeptByUsedInterface.cs @@ -15,10 +15,10 @@ namespace Mono.Linker.Tests.Cases.TypeForwarding [SetupCompileAfter ("Implementation.dll", new[] { "Dependencies/ImplementationLibrary.cs" })] [SetupCompileAfter ("Forwarder.dll", new[] { "Dependencies/ForwarderLibrary.cs" }, references: new[] { "Implementation.dll" })] - [KeptMemberInAssembly ("Forwarder.dll", typeof (ImplementationLibraryImp))] - [KeptMemberInAssembly ("Forwarder.dll", typeof (ImplementationLibraryInterface))] - [KeptMemberInAssembly ("Implementation.dll", typeof (ImplementationLibraryImp))] - [KeptMemberInAssembly ("Implementation.dll", typeof (ImplementationLibraryInterface))] + [KeptTypeInAssembly ("Forwarder.dll", typeof (ImplementationLibraryImp))] + [KeptTypeInAssembly ("Forwarder.dll", typeof (ImplementationLibraryInterface))] + [KeptTypeInAssembly ("Implementation.dll", typeof (ImplementationLibraryImp))] + [KeptTypeInAssembly ("Implementation.dll", typeof (ImplementationLibraryInterface))] [Kept] [KeptMember (".ctor()")] diff --git a/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderInCopyAssemblyKeptByUsedMethod.cs b/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderInCopyAssemblyKeptByUsedMethod.cs index 7f574762a..714dabdee 100644 --- a/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderInCopyAssemblyKeptByUsedMethod.cs +++ b/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderInCopyAssemblyKeptByUsedMethod.cs @@ -15,9 +15,9 @@ namespace Mono.Linker.Tests.Cases.TypeForwarding [SetupCompileAfter ("Forwarder.dll", new[] { "Dependencies/ForwarderLibrary.cs" }, references: new[] { "Implementation.dll" })] [KeptAssembly ("Forwarder.dll")] - [KeptMemberInAssembly ("Implementation.dll", typeof (ImplementationLibrary))] + [KeptTypeInAssembly ("Implementation.dll", typeof (ImplementationLibrary))] [KeptMemberInAssembly ("Implementation.dll", typeof (ImplementationLibrary), "GetSomeValue()")] - [KeptMemberInAssembly ("Forwarder.dll", typeof (ImplementationLibrary))] + [KeptTypeInAssembly ("Forwarder.dll", typeof (ImplementationLibrary))] [Kept] [KeptMember (".ctor()")] diff --git a/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderInCopyAssemblyKeptByUsedNestedType.cs b/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderInCopyAssemblyKeptByUsedNestedType.cs index 56e952b25..c9c90e6b7 100644 --- a/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderInCopyAssemblyKeptByUsedNestedType.cs +++ b/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderInCopyAssemblyKeptByUsedNestedType.cs @@ -16,8 +16,8 @@ namespace Mono.Linker.Tests.Cases.TypeForwarding [SetupCompileAfter ("Forwarder.dll", new[] { "Dependencies/ForwarderLibrary.cs" }, references: new[] { "Implementation.dll" })] [KeptAssembly ("Forwarder.dll")] - [KeptMemberInAssembly ("Implementation.dll", typeof (ImplementationLibrary.ImplementationLibraryNestedType))] - [KeptMemberInAssembly ("Forwarder.dll", typeof (ImplementationLibrary.ImplementationLibraryNestedType))] + [KeptTypeInAssembly ("Implementation.dll", typeof (ImplementationLibrary.ImplementationLibraryNestedType))] + [KeptTypeInAssembly ("Forwarder.dll", typeof (ImplementationLibrary.ImplementationLibraryNestedType))] [Kept] [KeptMember (".ctor()")] diff --git a/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderInCopyAssemblyKeptByUsedProperty.cs b/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderInCopyAssemblyKeptByUsedProperty.cs index e92f5e716..a748b8bbe 100644 --- a/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderInCopyAssemblyKeptByUsedProperty.cs +++ b/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderInCopyAssemblyKeptByUsedProperty.cs @@ -15,10 +15,10 @@ namespace Mono.Linker.Tests.Cases.TypeForwarding [SetupCompileAfter ("Implementation.dll", new[] { "Dependencies/ImplementationLibrary.cs" })] [SetupCompileAfter ("Forwarder.dll", new[] { "Dependencies/ForwarderLibrary.cs" }, references: new[] { "Implementation.dll" })] - [KeptMemberInAssembly ("Forwarder.dll", typeof (ImplementationLibrary))] - [KeptMemberInAssembly ("Forwarder.dll", typeof (ImplementationLibrary.ImplementationLibraryNestedType))] - [KeptMemberInAssembly ("Implementation.dll", typeof (ImplementationLibrary))] - [KeptMemberInAssembly ("Implementation.dll", typeof (ImplementationLibrary.ImplementationLibraryNestedType))] + [KeptTypeInAssembly ("Forwarder.dll", typeof (ImplementationLibrary))] + [KeptTypeInAssembly ("Forwarder.dll", typeof (ImplementationLibrary.ImplementationLibraryNestedType))] + [KeptTypeInAssembly ("Implementation.dll", typeof (ImplementationLibrary))] + [KeptTypeInAssembly ("Implementation.dll", typeof (ImplementationLibrary.ImplementationLibraryNestedType))] [Kept] [KeptMember (".ctor()")] diff --git a/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderInCopyAssemblyKeptByUsedTypeAsGenericArg.cs b/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderInCopyAssemblyKeptByUsedTypeAsGenericArg.cs index 1693a506e..9981fe87f 100644 --- a/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderInCopyAssemblyKeptByUsedTypeAsGenericArg.cs +++ b/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderInCopyAssemblyKeptByUsedTypeAsGenericArg.cs @@ -16,8 +16,8 @@ namespace Mono.Linker.Tests.Cases.TypeForwarding [SetupCompileAfter ("Forwarder.dll", new[] { "Dependencies/ForwarderLibrary.cs" }, references: new[] { "Implementation.dll" })] [KeptAssembly ("Forwarder.dll")] - [KeptMemberInAssembly ("Implementation.dll", typeof (ImplementationLibrary))] - [KeptMemberInAssembly ("Forwarder.dll", typeof (ImplementationLibrary))] + [KeptTypeInAssembly ("Implementation.dll", typeof (ImplementationLibrary))] + [KeptTypeInAssembly ("Forwarder.dll", typeof (ImplementationLibrary))] [Kept] [KeptMember (".ctor()")] diff --git a/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderInGenericIsDynamicallyAccessedWithAssemblyCopyUsed.cs b/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderInGenericIsDynamicallyAccessedWithAssemblyCopyUsed.cs index 9895151b8..9f167aef2 100644 --- a/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderInGenericIsDynamicallyAccessedWithAssemblyCopyUsed.cs +++ b/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderInGenericIsDynamicallyAccessedWithAssemblyCopyUsed.cs @@ -21,7 +21,7 @@ namespace Mono.Linker.Tests.Cases.TypeForwarding // https://github.com/mono/linker/issues/1536 //[KeptMemberInAssembly ("Forwarder.dll", typeof (ImplementationLibrary))] - [KeptMemberInAssembly ("Implementation.dll", typeof (ImplementationLibrary))] + [KeptTypeInAssembly ("Implementation.dll", typeof (ImplementationLibrary))] class UsedForwarderInGenericIsDynamicallyAccessedWithAssemblyCopyUsed { static void Main () diff --git a/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderIsDynamicallyAccessedWithAssemblyCopyUsed.cs b/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderIsDynamicallyAccessedWithAssemblyCopyUsed.cs index 963d22da9..e50edd190 100644 --- a/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderIsDynamicallyAccessedWithAssemblyCopyUsed.cs +++ b/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderIsDynamicallyAccessedWithAssemblyCopyUsed.cs @@ -19,8 +19,8 @@ namespace Mono.Linker.Tests.Cases.TypeForwarding [SetupCompileAfter ("Implementation.dll", new[] { "Dependencies/ImplementationLibrary.cs" })] [SetupCompileAfter ("Forwarder.dll", new[] { "Dependencies/ForwarderLibrary.cs" }, references: new[] { "Implementation.dll" })] - [KeptMemberInAssembly ("Forwarder.dll", typeof (ImplementationLibrary))] - [KeptMemberInAssembly ("Implementation.dll", typeof (ImplementationLibrary))] + [KeptTypeInAssembly ("Forwarder.dll", typeof (ImplementationLibrary))] + [KeptTypeInAssembly ("Implementation.dll", typeof (ImplementationLibrary))] class UsedForwarderIsDynamicallyAccessedWithAssemblyCopyUsed { static void Main () diff --git a/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderWithAssemblyCopy.cs b/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderWithAssemblyCopy.cs index 925816023..7067abe6a 100644 --- a/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderWithAssemblyCopy.cs +++ b/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderWithAssemblyCopy.cs @@ -19,7 +19,7 @@ namespace Mono.Linker.Tests.Cases.TypeForwarding [KeptAssembly ("Forwarder.dll")] [KeptMemberInAssembly ("Implementation.dll", typeof (ImplementationLibrary), "GetSomeValue()")] - [KeptMemberInAssembly ("Forwarder.dll", typeof (ImplementationLibrary))] + [KeptTypeInAssembly ("Forwarder.dll", typeof (ImplementationLibrary))] class UsedForwarderWithAssemblyCopy { static void Main () diff --git a/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderWithAssemblyCopyUsedAndFacadesKept.cs b/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderWithAssemblyCopyUsedAndFacadesKept.cs index 7698bc70c..6aa2e75bf 100644 --- a/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderWithAssemblyCopyUsedAndFacadesKept.cs +++ b/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderWithAssemblyCopyUsedAndFacadesKept.cs @@ -18,7 +18,7 @@ namespace Mono.Linker.Tests.Cases.TypeForwarding [SetupCompileAfter ("Implementation.dll", new[] { "Dependencies/ImplementationLibrary.cs" })] [SetupCompileAfter ("Forwarder.dll", new[] { "Dependencies/ForwarderLibrary.cs" }, references: new[] { "Implementation.dll" })] - [KeptMemberInAssembly ("Forwarder.dll", typeof (ImplementationLibrary))] + [KeptTypeInAssembly ("Forwarder.dll", typeof (ImplementationLibrary))] [KeptMemberInAssembly ("Implementation.dll", typeof (ImplementationLibrary), "GetSomeValue()")] [RemovedAssemblyReference ("test", "Forwarder")] class UsedForwarderWithAssemblyCopyUsedAndFacadesKept diff --git a/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderWithAssemblyCopyUsedAndFacadesKeptAndUnusedReference.cs b/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderWithAssemblyCopyUsedAndFacadesKeptAndUnusedReference.cs new file mode 100644 index 000000000..c3c6e19ef --- /dev/null +++ b/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderWithAssemblyCopyUsedAndFacadesKeptAndUnusedReference.cs @@ -0,0 +1,34 @@ +using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Metadata; +using Mono.Linker.Tests.Cases.TypeForwarding.Dependencies; + +namespace Mono.Linker.Tests.Cases.TypeForwarding +{ + // Actions: + // link - This assembly + // copyused - Forwarder.dll, Implementation.dll, and UnusedImplementation.dll + // --keep-facades + [SetupLinkerAction ("link", "test")] + [SetupLinkerDefaultAction ("copyused")] + [KeepTypeForwarderOnlyAssemblies ("true")] + + [SetupCompileBefore ("Forwarder.dll", new[] { "Dependencies/ReferenceImplementationUsedAndUnusedLibrary.cs" }, defines: new[] { "INCLUDE_REFERENCE_IMPL" })] + + // After compiling the test case we then replace the reference impl with implementation + type forwarder + [SetupCompileAfter ("Implementation.dll", new[] { "Dependencies/ImplementationLibrary.cs" })] + [SetupCompileAfter ("UnusedImplementation.dll", new[] { "Dependencies/UnusedImplementationLibrary.cs" })] + [SetupCompileAfter ("Forwarder.dll", new[] { "Dependencies/ForwarderLibraryWithUnusedReference.cs" }, references: new[] { "Implementation.dll", "UnusedImplementation.dll" })] + + [KeptTypeInAssembly ("Forwarder.dll", typeof (ImplementationLibrary))] + [KeptTypeInAssembly ("Forwarder.dll", typeof (UnusedImplementationLibrary))] + [KeptMemberInAssembly ("Implementation.dll", typeof (ImplementationLibrary), "GetSomeValue()")] + [RemovedAssemblyReference ("test", "Forwarder")] + [RemovedAssembly ("UnusedImplementation.dll")] + class UsedForwarderWithAssemblyCopyUsedAndFacadesKeptAndUnusedReference + { + static void Main () + { + new ImplementationLibrary ().GetSomeValue (); + } + } +} diff --git a/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderWithAssemblyCopyUsedAndForwarderLibraryKept.cs b/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderWithAssemblyCopyUsedAndForwarderLibraryKept.cs new file mode 100644 index 000000000..e4e750c3d --- /dev/null +++ b/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderWithAssemblyCopyUsedAndForwarderLibraryKept.cs @@ -0,0 +1,44 @@ +using System; +using System.Reflection; +using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Metadata; +using Mono.Linker.Tests.Cases.TypeForwarding.Dependencies; + +namespace Mono.Linker.Tests.Cases.TypeForwarding +{ + [SetupLinkerDefaultAction ("copyused")] + [KeepTypeForwarderOnlyAssemblies ("false")] + + [SetupCompileBefore ("Forwarder.dll", new[] { "Dependencies/ReferenceImplementationLibrary.cs" }, defines: new[] { "INCLUDE_REFERENCE_IMPL" })] + + // After compiling the test case we then replace the reference impl with implementation + type forwarder + [SetupCompileAfter ("Implementation.dll", new[] { "Dependencies/ImplementationLibrary.cs" })] + [SetupCompileAfter ("Forwarder.dll", new[] { "Dependencies/ForwarderLibrary.cs" }, references: new[] { "Implementation.dll" })] + + // The typeref to the type forwarder is updated, so the type forwarder is removed (and the assemblyref along with it) + [RemovedTypeInAssembly ("Forwarder.dll", typeof (ImplementationLibrary))] + [RemovedAssemblyReference ("test", "Forwarder")] + // But other members of the forwarder assembly are kept + [KeptTypeInAssembly ("Forwarder.dll", typeof (ImplementationStruct))] + + [KeptMemberInAssembly ("Implementation.dll", typeof (ImplementationLibrary), "GetSomeValue()")] + [KeptMember (".ctor()")] + class UsedForwarderWithAssemblyCopyUsedAndForwarderLibraryKept + { + static void Main () + { + // Preserve a member of the forwarder library to ensure the forwarder assembly is kept + var t1 = Type.GetType ("Mono.Linker.Tests.Cases.TypeForwarding.Dependencies.ImplementationStruct, Forwarder"); + + // Include a direct typeref to the forwarder that will get its scope updated + var t = typeof (ReferencesForwarder); + } + + [Kept] + [KeptMember (".ctor()")] + [KeptBaseType (typeof (ImplementationLibrary))] + public class ReferencesForwarder : ImplementationLibrary + { + } + } +} diff --git a/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedTransitiveForwarderInCopyAssemblyIsDynamicallyAccessed.cs b/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedTransitiveForwarderInCopyAssemblyIsDynamicallyAccessed.cs index 4ba936ae6..bc0041039 100644 --- a/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedTransitiveForwarderInCopyAssemblyIsDynamicallyAccessed.cs +++ b/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedTransitiveForwarderInCopyAssemblyIsDynamicallyAccessed.cs @@ -17,10 +17,10 @@ namespace Mono.Linker.Tests.Cases.TypeForwarding [SetupCompileAfter ("SecondForwarder.dll", new[] { "Dependencies/ForwarderLibrary.cs" }, references: new[] { "Implementation.dll" })] [SetupLinkerAction ("copy", "FirstForwarder")] - [KeptMemberInAssembly ("FirstForwarder.dll", typeof (ImplementationLibrary))] + [KeptTypeInAssembly ("FirstForwarder.dll", typeof (ImplementationLibrary))] // Dynamically accessing a type forwarder will cause the linker to mark the scope // of type pointed to as well as the resolved type. - [KeptMemberInAssembly ("SecondForwarder.dll", typeof (ImplementationLibrary))] + [KeptTypeInAssembly ("SecondForwarder.dll", typeof (ImplementationLibrary))] [KeptMemberInAssembly ("Implementation.dll", typeof (ImplementationLibrary), "GetSomeValue()")] class UsedTransitiveForwarderInCopyAssemblyIsDynamicallyAccessed { diff --git a/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedTransitiveForwarderInCopyUsedAssemblyIsDynamicallyAccessed.cs b/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedTransitiveForwarderInCopyUsedAssemblyIsDynamicallyAccessed.cs index 9f6b74c0d..3c3249280 100644 --- a/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedTransitiveForwarderInCopyUsedAssemblyIsDynamicallyAccessed.cs +++ b/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedTransitiveForwarderInCopyUsedAssemblyIsDynamicallyAccessed.cs @@ -19,7 +19,7 @@ namespace Mono.Linker.Tests.Cases.TypeForwarding [SetupCompileAfter ("SecondForwarder.dll", new[] { "Dependencies/ForwarderLibrary.cs" }, references: new[] { "Implementation.dll" })] [SetupLinkerAction ("copyused", "FirstForwarder")] - [KeptMemberInAssembly ("FirstForwarder.dll", typeof (ImplementationLibrary))] + [KeptTypeInAssembly ("FirstForwarder.dll", typeof (ImplementationLibrary))] [KeptMemberInAssembly ("Implementation.dll", typeof (ImplementationLibrary), "GetSomeValue()")] [RemovedAssemblyReference ("FirstForwarder.dll", "SecondForwarder.dll")] [RemovedForwarder ("FirstForwarder.dll", nameof (ImplementationStruct))] diff --git a/test/Mono.Linker.Tests/TestCasesRunner/ResultChecker.cs b/test/Mono.Linker.Tests/TestCasesRunner/ResultChecker.cs index 18a32880d..7319df57b 100644 --- a/test/Mono.Linker.Tests/TestCasesRunner/ResultChecker.cs +++ b/test/Mono.Linker.Tests/TestCasesRunner/ResultChecker.cs @@ -220,19 +220,19 @@ namespace Mono.Linker.Tests.TestCasesRunner using (var linkedAssembly = ResolveLinkedAssembly (assemblyName)) { foreach (var checkAttrInAssembly in checks[assemblyName]) { var attributeTypeName = checkAttrInAssembly.AttributeType.Name; - if (attributeTypeName == nameof (KeptAllTypesAndMembersInAssemblyAttribute)) { + + switch (attributeTypeName) { + case nameof (KeptAllTypesAndMembersInAssemblyAttribute): VerifyKeptAllTypesAndMembersInAssembly (linkedAssembly); continue; - } - - if (attributeTypeName == nameof (KeptAttributeInAssemblyAttribute)) { + case nameof (KeptAttributeInAssemblyAttribute): VerifyKeptAttributeInAssembly (checkAttrInAssembly, linkedAssembly); continue; - } - - if (attributeTypeName == nameof (RemovedAttributeInAssembly)) { + case nameof (RemovedAttributeInAssembly): VerifyRemovedAttributeInAssembly (checkAttrInAssembly, linkedAssembly); continue; + default: + break; } var expectedTypeName = checkAttrInAssembly.ConstructorArguments[1].Value.ToString (); @@ -539,7 +539,9 @@ namespace Mono.Linker.Tests.TestCasesRunner void VerifyKeptMemberInAssembly (CustomAttribute inAssemblyAttribute, TypeDefinition linkedType) { var originalType = GetOriginalTypeFromInAssemblyAttribute (inAssemblyAttribute); - foreach (var memberNameAttr in (CustomAttributeArgument[]) inAssemblyAttribute.ConstructorArguments[2].Value) { + var memberNames = (CustomAttributeArgument[]) inAssemblyAttribute.ConstructorArguments[2].Value; + Assert.IsTrue (memberNames.Length > 0, "Invalid KeptMemberInAssemblyAttribute. Expected member names."); + foreach (var memberNameAttr in memberNames) { string memberName = (string) memberNameAttr.Value; // We will find the matching type from the original assembly first that way we can confirm |