diff options
author | Mike Voorhees <michaelv@unity3d.com> | 2017-05-09 22:24:18 +0300 |
---|---|---|
committer | Marek Safar <marek.safar@gmail.com> | 2017-05-11 22:21:05 +0300 |
commit | 98d8cffc84cdc3101267587f158b17467cb21ee5 (patch) | |
tree | c6d8334e8bfb329e72f16b2266ca57d3e8a02500 /linker/Tests | |
parent | cbb4fe809fab5684ecb5302ae1f01a28db418f42 (diff) |
Implement Kept & Removed attributes for TypeInAssembly.
This allowed for the core link test to be implemented
Diffstat (limited to 'linker/Tests')
5 files changed, 103 insertions, 2 deletions
diff --git a/linker/Tests/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptTypeInAssemblyAttribute.cs b/linker/Tests/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptTypeInAssemblyAttribute.cs new file mode 100644 index 000000000..f4725f9b9 --- /dev/null +++ b/linker/Tests/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptTypeInAssemblyAttribute.cs @@ -0,0 +1,17 @@ +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Delegate, AllowMultiple = true, Inherited = false)] + public class KeptTypeInAssemblyAttribute : BaseExpectedLinkedBehaviorAttribute + { + public readonly string AssemblyFileName; + public readonly Type Type; + + public KeptTypeInAssemblyAttribute(string assemblyFileName, Type type) + { + AssemblyFileName = assemblyFileName; + Type = type; + } + } +} diff --git a/linker/Tests/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedTypeInAssemblyAttribute.cs b/linker/Tests/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedTypeInAssemblyAttribute.cs new file mode 100644 index 000000000..04bc9c132 --- /dev/null +++ b/linker/Tests/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedTypeInAssemblyAttribute.cs @@ -0,0 +1,16 @@ +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Delegate, AllowMultiple = true, Inherited = false)] + public class RemovedTypeInAssemblyAttribute : BaseExpectedLinkedBehaviorAttribute { + public readonly string AssemblyFileName; + public readonly Type Type; + + public RemovedTypeInAssemblyAttribute (string assemblyFileName, Type type) + { + AssemblyFileName = assemblyFileName; + Type = type; + } + } +} diff --git a/linker/Tests/Mono.Linker.Tests.Cases.Expectations/Mono.Linker.Tests.Cases.Expectations.csproj b/linker/Tests/Mono.Linker.Tests.Cases.Expectations/Mono.Linker.Tests.Cases.Expectations.csproj index dfb15ba2a..a9ba2d50b 100644 --- a/linker/Tests/Mono.Linker.Tests.Cases.Expectations/Mono.Linker.Tests.Cases.Expectations.csproj +++ b/linker/Tests/Mono.Linker.Tests.Cases.Expectations/Mono.Linker.Tests.Cases.Expectations.csproj @@ -43,7 +43,9 @@ <Compile Include="Assertions\BaseExpectedLinkedBehaviorAttribute.cs" /> <Compile Include="Assertions\KeptBackingFieldAttribute.cs" /> <Compile Include="Assertions\KeptMemberAttribute.cs" /> + <Compile Include="Assertions\KeptTypeInAssemblyAttribute.cs" /> <Compile Include="Assertions\RemovedAssemblyAttribute.cs" /> + <Compile Include="Assertions\RemovedTypeInAssemblyAttribute.cs" /> <Compile Include="Metadata\BaseMetadataAttribute.cs" /> <Compile Include="Metadata\CoreLinkAttribute.cs" /> <Compile Include="Metadata\NotATestCaseAttribute.cs" /> diff --git a/linker/Tests/Mono.Linker.Tests.Cases/CoreLink/LinkingOfCoreLibrariesRemovesUnusedTypes.cs b/linker/Tests/Mono.Linker.Tests.Cases/CoreLink/LinkingOfCoreLibrariesRemovesUnusedTypes.cs index c7bb5aae4..b9a4c1f88 100644 --- a/linker/Tests/Mono.Linker.Tests.Cases/CoreLink/LinkingOfCoreLibrariesRemovesUnusedTypes.cs +++ b/linker/Tests/Mono.Linker.Tests.Cases/CoreLink/LinkingOfCoreLibrariesRemovesUnusedTypes.cs @@ -1,15 +1,30 @@ -using Mono.Linker.Tests.Cases.Expectations.Assertions; +using System; +using Mono.Linker.Tests.Cases.Expectations.Assertions; using Mono.Linker.Tests.Cases.Expectations.Metadata; namespace Mono.Linker.Tests.Cases.CoreLink { [CoreLink ("link")] + [Reference("System.dll")] + [KeptAssembly ("mscorlib.dll")] + [KeptAssembly("System.dll")] // We can't check everything that should be removed, but we should be able to check a few niche things that // we known should be removed which will at least verify that the core library was processed - // TODO by Mike : List a few types + [KeptTypeInAssembly ("mscorlib.dll", typeof (System.Collections.Generic.IEnumerable<>))] + [KeptTypeInAssembly ("System.dll", typeof (Uri))] + + [RemovedTypeInAssembly ("mscorlib.dll", typeof (System.Resources.ResourceWriter))] + [RemovedTypeInAssembly ("System.dll", typeof (System.CodeDom.Compiler.CodeCompiler))] class LinkingOfCoreLibrariesRemovesUnusedTypes { public static void Main () { + // Use something from system that would normally be removed if we didn't use it + OtherMethods2 (new Uri ("dont care")); + } + + [Kept] + static void OtherMethods2 (Uri uri) + { } } }
\ No newline at end of file diff --git a/linker/Tests/TestCasesRunner/ResultChecker.cs b/linker/Tests/TestCasesRunner/ResultChecker.cs index df66381fd..259a53588 100644 --- a/linker/Tests/TestCasesRunner/ResultChecker.cs +++ b/linker/Tests/TestCasesRunner/ResultChecker.cs @@ -1,6 +1,8 @@ using System; +using System.Collections.Generic; using System.Linq; using Mono.Cecil; +using Mono.Linker.Tests.Cases.Expectations.Assertions; using Mono.Linker.Tests.Extensions; using NUnit.Framework; @@ -18,6 +20,8 @@ namespace Mono.Linker.Tests.TestCasesRunner { var checker = new AssemblyChecker (original.Definition, linked.Definition); checker.Verify (); } + + VerifyLinkingOfOtherAssemblies (original.Definition, linkResult.OutputAssemblyPath.Parent); } } @@ -41,6 +45,53 @@ namespace Mono.Linker.Tests.TestCasesRunner { } } + void VerifyLinkingOfOtherAssemblies (AssemblyDefinition original, NPath outputDirectory) + { + var checks = BuildOtherAssemblyCheckTable (original); + + foreach (var assemblyName in checks.Keys) { + using (var linkedAssembly = ReadAssembly (outputDirectory.Combine (assemblyName))) { + foreach (var checkAttrInAssembly in checks [assemblyName]) { + var expectedTypeName = checkAttrInAssembly.ConstructorArguments [1].Value.ToString (); + var linkedType = linkedAssembly.Definition.MainModule.GetType (expectedTypeName); + + if (checkAttrInAssembly.AttributeType.Name == nameof (RemovedTypeInAssemblyAttribute)) { + if (linkedType != null) + Assert.Fail ($"Type `{expectedTypeName}' should have been removed"); + } else if (checkAttrInAssembly.AttributeType.Name == nameof (KeptTypeInAssemblyAttribute)) { + if (linkedType == null) + Assert.Fail ($"Type `{expectedTypeName}' should have been kept"); + } else { + throw new NotImplementedException ($"Type {original}, has an unknown other assembly attribute of type {checkAttrInAssembly.AttributeType}"); + } + } + } + } + } + + static Dictionary<string, List<CustomAttribute>> BuildOtherAssemblyCheckTable (AssemblyDefinition original) + { + var checks = new Dictionary<string, List<CustomAttribute>> (); + + foreach (var typeWithRemoveInAssembly in original.AllDefinedTypes ()) { + foreach (var attr in typeWithRemoveInAssembly.CustomAttributes.Where (IsTypeInOtherAssemblyAssertion)) { + var assemblyName = (string) attr.ConstructorArguments [0].Value; + List<CustomAttribute> checksForAssembly; + if (!checks.TryGetValue (assemblyName, out checksForAssembly)) + checks [assemblyName] = checksForAssembly = new List<CustomAttribute> (); + + checksForAssembly.Add (attr); + } + } + + return checks; + } + + static bool IsTypeInOtherAssemblyAssertion (CustomAttribute attr) + { + return attr.AttributeType.Name == nameof (RemovedTypeInAssemblyAttribute) || attr.AttributeType.Name == nameof (KeptTypeInAssemblyAttribute); + } + struct AssemblyContainer : IDisposable { public readonly AssemblyResolver Resolver; |