Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/linker.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Voorhees <michaelv@unity3d.com>2017-05-10 00:20:26 +0300
committerMarek Safar <marek.safar@gmail.com>2017-05-11 22:21:05 +0300
commit7fadbac85790cde18d7daed6ab38fd8b205b127f (patch)
tree12a1a6799777b63c697bdb1b7da057691a1ada4c /linker/Tests
parent98d8cffc84cdc3101267587f158b17467cb21ee5 (diff)
Implement Kept & Removed Member in assembly
Diffstat (limited to 'linker/Tests')
-rw-r--r--linker/Tests/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptMemberInAssemblyAttribute.cs18
-rw-r--r--linker/Tests/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedMemberInAssemblyAttribute.cs17
-rw-r--r--linker/Tests/Mono.Linker.Tests.Cases.Expectations/Mono.Linker.Tests.Cases.Expectations.csproj2
-rw-r--r--linker/Tests/Mono.Linker.Tests.Cases/CoreLink/LinkingOfCoreLibrariesRemovesUnusedMethods.cs24
-rw-r--r--linker/Tests/Mono.Linker.Tests.Cases/Mono.Linker.Tests.Cases.csproj1
-rw-r--r--linker/Tests/TestCasesRunner/ResultChecker.cs95
6 files changed, 155 insertions, 2 deletions
diff --git a/linker/Tests/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptMemberInAssemblyAttribute.cs b/linker/Tests/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptMemberInAssemblyAttribute.cs
new file mode 100644
index 000000000..31dd5131d
--- /dev/null
+++ b/linker/Tests/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptMemberInAssemblyAttribute.cs
@@ -0,0 +1,18 @@
+using System;
+
+
+namespace Mono.Linker.Tests.Cases.Expectations.Assertions {
+ [AttributeUsage (AttributeTargets.Class | AttributeTargets.Delegate, AllowMultiple = true, Inherited = false)]
+ public class KeptMemberInAssemblyAttribute : BaseExpectedLinkedBehaviorAttribute {
+ public readonly string AssemblyFileName;
+ public readonly Type Type;
+ public readonly string [] MemberNames;
+
+ public KeptMemberInAssemblyAttribute (string assemblyFileName, Type type, params string [] memberNames)
+ {
+ AssemblyFileName = assemblyFileName;
+ Type = type;
+ MemberNames = memberNames;
+ }
+ }
+}
diff --git a/linker/Tests/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedMemberInAssemblyAttribute.cs b/linker/Tests/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedMemberInAssemblyAttribute.cs
new file mode 100644
index 000000000..3bcd63b9d
--- /dev/null
+++ b/linker/Tests/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedMemberInAssemblyAttribute.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 RemovedMemberInAssemblyAttribute : BaseExpectedLinkedBehaviorAttribute {
+ public readonly string AssemblyFileName;
+ public readonly Type Type;
+ public readonly string [] MemberNames;
+
+ public RemovedMemberInAssemblyAttribute (string assemblyFileName, Type type, params string [] memberNames)
+ {
+ AssemblyFileName = assemblyFileName;
+ Type = type;
+ MemberNames = memberNames;
+ }
+ }
+}
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 a9ba2d50b..d330e6c40 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,8 +43,10 @@
<Compile Include="Assertions\BaseExpectedLinkedBehaviorAttribute.cs" />
<Compile Include="Assertions\KeptBackingFieldAttribute.cs" />
<Compile Include="Assertions\KeptMemberAttribute.cs" />
+ <Compile Include="Assertions\KeptMemberInAssemblyAttribute.cs" />
<Compile Include="Assertions\KeptTypeInAssemblyAttribute.cs" />
<Compile Include="Assertions\RemovedAssemblyAttribute.cs" />
+ <Compile Include="Assertions\RemovedMemberInAssemblyAttribute.cs" />
<Compile Include="Assertions\RemovedTypeInAssemblyAttribute.cs" />
<Compile Include="Metadata\BaseMetadataAttribute.cs" />
<Compile Include="Metadata\CoreLinkAttribute.cs" />
diff --git a/linker/Tests/Mono.Linker.Tests.Cases/CoreLink/LinkingOfCoreLibrariesRemovesUnusedMethods.cs b/linker/Tests/Mono.Linker.Tests.Cases/CoreLink/LinkingOfCoreLibrariesRemovesUnusedMethods.cs
new file mode 100644
index 000000000..78b460939
--- /dev/null
+++ b/linker/Tests/Mono.Linker.Tests.Cases/CoreLink/LinkingOfCoreLibrariesRemovesUnusedMethods.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections;
+using System.IO;
+using Mono.Linker.Tests.Cases.Expectations.Assertions;
+using Mono.Linker.Tests.Cases.Expectations.Metadata;
+
+namespace Mono.Linker.Tests.Cases.CoreLink
+{
+ [CoreLink ("link")]
+
+ [KeptAssembly ("mscorlib.dll")]
+ [KeptMemberInAssembly ("mscorlib.dll", typeof (Stack), ".ctor(System.Int32)", "Pop()", "Push(System.Object)")]
+ // 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
+ [RemovedMemberInAssembly ("mscorlib.dll", typeof (Stack), ".ctor(System.Collections.ICollection)")]
+ class LinkingOfCoreLibrariesRemovesUnusedMethods {
+ public static void Main()
+ {
+ Stack stack = new Stack (2);
+ stack.Push (1);
+ var val = stack.Pop ();
+ }
+ }
+}
diff --git a/linker/Tests/Mono.Linker.Tests.Cases/Mono.Linker.Tests.Cases.csproj b/linker/Tests/Mono.Linker.Tests.Cases/Mono.Linker.Tests.Cases.csproj
index 49463ed70..74325a8ac 100644
--- a/linker/Tests/Mono.Linker.Tests.Cases/Mono.Linker.Tests.Cases.csproj
+++ b/linker/Tests/Mono.Linker.Tests.Cases/Mono.Linker.Tests.Cases.csproj
@@ -56,6 +56,7 @@
<Compile Include="Basic\UnusedPropertyGetsRemoved.cs" />
<Compile Include="Basic\UnusedPropertySetterRemoved.cs" />
<Compile Include="Basic\UsedPropertyIsKept.cs" />
+ <Compile Include="CoreLink\LinkingOfCoreLibrariesRemovesUnusedMethods.cs" />
<Compile Include="CoreLink\LinkingOfCoreLibrariesRemovesUnusedTypes.cs" />
<Compile Include="Advanced\DeadCodeElimination1.cs" />
<Compile Include="Advanced\FieldThatOnlyGetsSetIsRemoved.cs" />
diff --git a/linker/Tests/TestCasesRunner/ResultChecker.cs b/linker/Tests/TestCasesRunner/ResultChecker.cs
index 259a53588..8ced27196 100644
--- a/linker/Tests/TestCasesRunner/ResultChecker.cs
+++ b/linker/Tests/TestCasesRunner/ResultChecker.cs
@@ -61,14 +61,102 @@ namespace Mono.Linker.Tests.TestCasesRunner {
} else if (checkAttrInAssembly.AttributeType.Name == nameof (KeptTypeInAssemblyAttribute)) {
if (linkedType == null)
Assert.Fail ($"Type `{expectedTypeName}' should have been kept");
+ } else if (checkAttrInAssembly.AttributeType.Name == nameof (RemovedMemberInAssemblyAttribute)) {
+ if (linkedType == null)
+ continue;
+
+ VerifyRemovedMemberInAssembly (checkAttrInAssembly, linkedType);
+ } else if (checkAttrInAssembly.AttributeType.Name == nameof (KeptMemberInAssemblyAttribute)) {
+ if (linkedType == null)
+ Assert.Fail ($"Type `{expectedTypeName}' should have been kept");
+
+ VerifyKeptMemberInAssembly (checkAttrInAssembly, linkedType);
} else {
- throw new NotImplementedException ($"Type {original}, has an unknown other assembly attribute of type {checkAttrInAssembly.AttributeType}");
+ throw new NotImplementedException ($"Type {expectedTypeName}, has an unknown other assembly attribute of type {checkAttrInAssembly.AttributeType}");
}
}
}
}
}
+ static void VerifyRemovedMemberInAssembly (CustomAttribute inAssemblyAttribute, TypeDefinition linkedType)
+ {
+ var originalType = ((TypeReference) inAssemblyAttribute.ConstructorArguments [1].Value).Resolve ();
+ foreach (var memberNameAttr in (CustomAttributeArgument[]) inAssemblyAttribute.ConstructorArguments [2].Value) {
+ string memberName = (string) memberNameAttr.Value;
+
+ // We will find the matching type from the original assembly first that way we can confirm
+ // that the name defined in the attribute corresponds to a member that actually existed
+ var originalFieldMember = originalType.Fields.FirstOrDefault (m => m.Name == memberName);
+ if (originalFieldMember != null) {
+ var linkedField = linkedType.Fields.FirstOrDefault (m => m.Name == memberName);
+ if (linkedField != null)
+ Assert.Fail ($"Field `{memberName}` on Type `{originalType}` should have been removed");
+
+ continue;
+ }
+
+ var originalPropertyMember = originalType.Properties.FirstOrDefault (m => m.Name == memberName);
+ if (originalPropertyMember != null) {
+ var linkedProperty = linkedType.Properties.FirstOrDefault (m => m.Name == memberName);
+ if (linkedProperty != null)
+ Assert.Fail ($"Property `{memberName}` on Type `{originalType}` should have been removed");
+
+ continue;
+ }
+
+ var originalMethodMember = originalType.Methods.FirstOrDefault (m => m.GetSignature () == memberName);
+ if (originalMethodMember != null) {
+ var linkedMethod = linkedType.Methods.FirstOrDefault (m => m.GetSignature () == memberName);
+ if (linkedMethod != null)
+ Assert.Fail ($"Method `{memberName}` on Type `{originalType}` should have been removed");
+
+ continue;
+ }
+
+ Assert.Fail ($"Invalid test assertion. No member named `{memberName}` exists on the original type `{originalType}`");
+ }
+ }
+
+ static void VerifyKeptMemberInAssembly (CustomAttribute inAssemblyAttribute, TypeDefinition linkedType)
+ {
+ var originalType = ((TypeReference) inAssemblyAttribute.ConstructorArguments [1].Value).Resolve ();
+ foreach (var memberNameAttr in (CustomAttributeArgument[]) inAssemblyAttribute.ConstructorArguments [2].Value) {
+ string memberName = (string) memberNameAttr.Value;
+
+ // We will find the matching type from the original assembly first that way we can confirm
+ // that the name defined in the attribute corresponds to a member that actually existed
+ var originalFieldMember = originalType.Fields.FirstOrDefault (m => m.Name == memberName);
+ if (originalFieldMember != null) {
+ var linkedField = linkedType.Fields.FirstOrDefault (m => m.Name == memberName);
+ if (linkedField == null)
+ Assert.Fail ($"Field `{memberName}` on Type `{originalType}` should have been kept");
+
+ continue;
+ }
+
+ var originalPropertyMember = originalType.Properties.FirstOrDefault (m => m.Name == memberName);
+ if (originalPropertyMember != null) {
+ var linkedProperty = linkedType.Properties.FirstOrDefault (m => m.Name == memberName);
+ if (linkedProperty == null)
+ Assert.Fail ($"Property `{memberName}` on Type `{originalType}` should have been kept");
+
+ continue;
+ }
+
+ var originalMethodMember = originalType.Methods.FirstOrDefault (m => m.GetSignature () == memberName);
+ if (originalMethodMember != null) {
+ var linkedMethod = linkedType.Methods.FirstOrDefault (m => m.GetSignature () == memberName);
+ if (linkedMethod == null)
+ Assert.Fail ($"Method `{memberName}` on Type `{originalType}` should have been kept");
+
+ continue;
+ }
+
+ Assert.Fail ($"Invalid test assertion. No member named `{memberName}` exists on the original type `{originalType}`");
+ }
+ }
+
static Dictionary<string, List<CustomAttribute>> BuildOtherAssemblyCheckTable (AssemblyDefinition original)
{
var checks = new Dictionary<string, List<CustomAttribute>> ();
@@ -89,7 +177,10 @@ namespace Mono.Linker.Tests.TestCasesRunner {
static bool IsTypeInOtherAssemblyAssertion (CustomAttribute attr)
{
- return attr.AttributeType.Name == nameof (RemovedTypeInAssemblyAttribute) || attr.AttributeType.Name == nameof (KeptTypeInAssemblyAttribute);
+ return attr.AttributeType.Name == nameof (RemovedTypeInAssemblyAttribute)
+ || attr.AttributeType.Name == nameof (KeptTypeInAssemblyAttribute)
+ || attr.AttributeType.Name == nameof (RemovedMemberInAssemblyAttribute)
+ || attr.AttributeType.Name == nameof (KeptMemberInAssemblyAttribute);
}
struct AssemblyContainer : IDisposable