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:
authorVladislav Rishe <vlados.v10.0@gmail.com>2017-07-28 12:12:47 +0300
committerMarek Safar <marek.safar@gmail.com>2017-08-02 22:30:55 +0300
commitc39f545b10306e5e0420501a0777f7288bbbbf24 (patch)
tree749f2a1d16c1647f2b98d235f5f9c01c8b6673d1 /linker/Tests
parent39b70e7550e38188a6f411d7ec46fc9ac5528cd8 (diff)
Provide 'event' and 'property' elements support with Link XML step.
Diffstat (limited to 'linker/Tests')
-rw-r--r--linker/Tests/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptBackingFieldAttribute.cs5
-rw-r--r--linker/Tests/Mono.Linker.Tests.Cases/LinkXml/UnusedEventPreservedByLinkXmlIsKept.cs23
-rw-r--r--linker/Tests/Mono.Linker.Tests.Cases/LinkXml/UnusedEventPreservedByLinkXmlIsKept.xml8
-rw-r--r--linker/Tests/Mono.Linker.Tests.Cases/LinkXml/UnusedPropertyPreservedByLinkXmlIsKept.cs16
-rw-r--r--linker/Tests/Mono.Linker.Tests.Cases/LinkXml/UnusedPropertyPreservedByLinkXmlIsKept.xml5
-rw-r--r--linker/Tests/Mono.Linker.Tests.Cases/Mono.Linker.Tests.Cases.csproj4
-rw-r--r--linker/Tests/TestCasesRunner/AssemblyChecker.cs54
-rw-r--r--linker/Tests/TestCasesRunner/PeVerifier.cs34
8 files changed, 120 insertions, 29 deletions
diff --git a/linker/Tests/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptBackingFieldAttribute.cs b/linker/Tests/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptBackingFieldAttribute.cs
index a4160490a..b21ce0628 100644
--- a/linker/Tests/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptBackingFieldAttribute.cs
+++ b/linker/Tests/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptBackingFieldAttribute.cs
@@ -1,8 +1,7 @@
using System;
-namespace Mono.Linker.Tests.Cases.Expectations.Assertions
-{
- [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
+namespace Mono.Linker.Tests.Cases.Expectations.Assertions {
+ [AttributeUsage(AttributeTargets.Property | AttributeTargets.Event, AllowMultiple = false, Inherited = false)]
public sealed class KeptBackingFieldAttribute : KeptAttribute {
}
}
diff --git a/linker/Tests/Mono.Linker.Tests.Cases/LinkXml/UnusedEventPreservedByLinkXmlIsKept.cs b/linker/Tests/Mono.Linker.Tests.Cases/LinkXml/UnusedEventPreservedByLinkXmlIsKept.cs
new file mode 100644
index 000000000..c17eedfb6
--- /dev/null
+++ b/linker/Tests/Mono.Linker.Tests.Cases/LinkXml/UnusedEventPreservedByLinkXmlIsKept.cs
@@ -0,0 +1,23 @@
+using System;
+
+using Mono.Linker.Tests.Cases.Expectations.Assertions;
+
+namespace Mono.Linker.Tests.Cases.LinkXml {
+ class UnusedEventPreservedByLinkXmlIsKept {
+ public static void Main ()
+ {
+ }
+
+ [Kept]
+ class Unused {
+ [Kept]
+ [KeptBackingField]
+ public event EventHandler<EventArgs> Preserved;
+
+ [Kept]
+ public event EventHandler<EventArgs> Preserved1 { [Kept] add { } [Kept] remove { } }
+
+ public event EventHandler<EventArgs> NotPreserved;
+ }
+ }
+} \ No newline at end of file
diff --git a/linker/Tests/Mono.Linker.Tests.Cases/LinkXml/UnusedEventPreservedByLinkXmlIsKept.xml b/linker/Tests/Mono.Linker.Tests.Cases/LinkXml/UnusedEventPreservedByLinkXmlIsKept.xml
new file mode 100644
index 000000000..6674d9784
--- /dev/null
+++ b/linker/Tests/Mono.Linker.Tests.Cases/LinkXml/UnusedEventPreservedByLinkXmlIsKept.xml
@@ -0,0 +1,8 @@
+<linker>
+ <assembly fullname="test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
+ <type fullname="Mono.Linker.Tests.Cases.LinkXml.UnusedEventPreservedByLinkXmlIsKept/Unused">
+ <event signature="System.EventHandler`1&lt;System.EventArgs&gt; Preserved" />
+ <event signature="System.EventHandler`1&lt;System.EventArgs&gt; Preserved1" />
+ </type>
+ </assembly>
+</linker> \ No newline at end of file
diff --git a/linker/Tests/Mono.Linker.Tests.Cases/LinkXml/UnusedPropertyPreservedByLinkXmlIsKept.cs b/linker/Tests/Mono.Linker.Tests.Cases/LinkXml/UnusedPropertyPreservedByLinkXmlIsKept.cs
index 65084580f..1dbd59a8a 100644
--- a/linker/Tests/Mono.Linker.Tests.Cases/LinkXml/UnusedPropertyPreservedByLinkXmlIsKept.cs
+++ b/linker/Tests/Mono.Linker.Tests.Cases/LinkXml/UnusedPropertyPreservedByLinkXmlIsKept.cs
@@ -20,6 +20,22 @@ namespace Mono.Linker.Tests.Cases.LinkXml {
[KeptBackingField]
public int PreservedProperty3 { get; [Kept] set; }
+ [Kept]
+ [KeptBackingField]
+ public int PreservedProperty4 { [Kept] get; [Kept] set; }
+
+ [Kept]
+ [KeptBackingField]
+ public int PreservedProperty5 { [Kept] get; [Kept] set; }
+
+ [Kept]
+ [KeptBackingField]
+ public int PreservedProperty6 { [Kept] get; set; }
+
+ [Kept]
+ [KeptBackingField]
+ public int PreservedProperty7 { get; [Kept] set; }
+
public int NotPreservedProperty { get; set; }
}
}
diff --git a/linker/Tests/Mono.Linker.Tests.Cases/LinkXml/UnusedPropertyPreservedByLinkXmlIsKept.xml b/linker/Tests/Mono.Linker.Tests.Cases/LinkXml/UnusedPropertyPreservedByLinkXmlIsKept.xml
index 1e182255d..de3fe0c7e 100644
--- a/linker/Tests/Mono.Linker.Tests.Cases/LinkXml/UnusedPropertyPreservedByLinkXmlIsKept.xml
+++ b/linker/Tests/Mono.Linker.Tests.Cases/LinkXml/UnusedPropertyPreservedByLinkXmlIsKept.xml
@@ -5,6 +5,11 @@
<method signature="System.Void set_PreservedProperty1(System.Int32)" />
<method signature="System.Int32 get_PreservedProperty2()" />
<method signature="System.Void set_PreservedProperty3(System.Int32)" />
+
+ <property signature="System.Int32 PreservedProperty4" />
+ <property signature="System.Int32 PreservedProperty5" accessors="all" />
+ <property signature="System.Int32 PreservedProperty6" accessors="get" />
+ <property signature="System.Int32 PreservedProperty7" accessors="set" />
</type>
</assembly>
</linker> \ No newline at end of file
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 a74c019af..be75f1d64 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
@@ -58,6 +58,7 @@
<Compile Include="Basic\UsedPropertyIsKept.cs" />
<Compile Include="Basic\UsedStructIsKept.cs" />
<Compile Include="LinkXml\UnusedAssemblyWithNoDefinedPreserveHasAllTypesPreserved.cs" />
+ <Compile Include="LinkXml\UnusedEventPreservedByLinkXmlIsKept.cs" />
<Compile Include="LinkXml\UnusedTypeWithNoDefinedPreserveHasAllMembersPreserved.cs" />
<Compile Include="VirtualMethods\ClassUsedFromConcreteTypeHasInterfaceMethodRemoved.cs" />
<Compile Include="VirtualMethods\ClassUsedFromInterfaceHasInterfaceMethodKept.cs" />
@@ -133,6 +134,7 @@
<ItemGroup>
<Content Include="LinkXml\TypeWithPreserveFieldsHasBackingFieldsOfPropertiesRemoved.xml" />
<Content Include="LinkXml\UnusedAssemblyWithNoDefinedPreserveHasAllTypesPreserved.xml" />
+ <Content Include="LinkXml\UnusedEventPreservedByLinkXmlIsKept.xml" />
<Content Include="LinkXml\UnusedFieldPreservedByLinkXmlIsKept.xml" />
<Content Include="LinkXml\UnusedMethodPreservedByLinkXmlIsKept.xml" />
<Content Include="LinkXml\UnusedNestedTypePreservedByLinkXmlIsKept.xml" />
@@ -160,4 +162,4 @@
<Target Name="AfterBuild">
</Target>
-->
-</Project>
+</Project> \ No newline at end of file
diff --git a/linker/Tests/TestCasesRunner/AssemblyChecker.cs b/linker/Tests/TestCasesRunner/AssemblyChecker.cs
index 3d28c7ddf..7a5132b95 100644
--- a/linker/Tests/TestCasesRunner/AssemblyChecker.cs
+++ b/linker/Tests/TestCasesRunner/AssemblyChecker.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -13,6 +13,7 @@ namespace Mono.Linker.Tests.TestCasesRunner {
HashSet<string> linkedMembers;
HashSet<string> verifiedBackingFields = new HashSet<string> ();
+ HashSet<string> verifiedEventMethods = new HashSet<string>();
public AssemblyChecker (AssemblyDefinition original, AssemblyDefinition linked)
{
@@ -96,6 +97,11 @@ namespace Mono.Linker.Tests.TestCasesRunner {
VerifyProperty (p, linked?.Properties.FirstOrDefault (l => p.Name == l.Name), linked);
linkedMembers.Remove (p.FullName);
}
+ // Need to check events before fields so that the KeptBackingFieldAttribute is handled correctly
+ foreach (var e in original.Events) {
+ VerifyEvent (e, linked?.Events.FirstOrDefault (l => e.Name == l.Name), linked);
+ linkedMembers.Remove (e.FullName);
+ }
foreach (var f in original.Fields) {
if (verifiedBackingFields.Contains (f.FullName))
@@ -105,14 +111,11 @@ namespace Mono.Linker.Tests.TestCasesRunner {
}
foreach (var m in original.Methods) {
+ if (verifiedEventMethods.Contains (m.FullName))
+ continue;
VerifyMethod (m, linked?.Methods.FirstOrDefault (l => m.GetSignature () == l.GetSignature ()));
linkedMembers.Remove (m.FullName);
}
-
- foreach (var e in original.Events) {
- VerifyEvent (e, linked?.Events.FirstOrDefault (l => e.Name == l.Name));
- linkedMembers.Remove (e.FullName);
- }
}
void VerifyBaseType (TypeDefinition src, TypeDefinition linked)
@@ -184,7 +187,7 @@ namespace Mono.Linker.Tests.TestCasesRunner {
void VerifyProperty (PropertyDefinition src, PropertyDefinition linked, TypeDefinition linkedType)
{
- VerifyBackingField (src, linkedType);
+ VerifyMemberBackingField (src, linkedType);
bool expectedKept = ShouldBeKept (src);
@@ -204,8 +207,10 @@ namespace Mono.Linker.Tests.TestCasesRunner {
VerifyCustomAttributes (src, linked);
}
- void VerifyEvent (EventDefinition src, EventDefinition linked)
+ void VerifyEvent (EventDefinition src, EventDefinition linked, TypeDefinition linkedType)
{
+ VerifyMemberBackingField (src, linkedType);
+
bool expectedKept = ShouldBeKept (src);
if (!expectedKept) {
@@ -213,6 +218,22 @@ namespace Mono.Linker.Tests.TestCasesRunner {
Assert.Fail ($"Event `{src}' should have been removed");
return;
+ } else {
+ var keptBackingFieldAttribute = src.CustomAttributes
+ .FirstOrDefault (attr => attr.AttributeType.Name == nameof (KeptBackingFieldAttribute));
+
+ // If we have KeepBackingFieldAttribute set,
+ // then we expect having 'add' and 'remove' accessors marked as 'kept' implicitly.
+ if (keptBackingFieldAttribute != null)
+ {
+ VerifyMethodInternal (src.AddMethod, linked.AddMethod, true);
+ verifiedEventMethods.Add (src.AddMethod.FullName);
+ linkedMembers.Remove (src.AddMethod.FullName);
+
+ VerifyMethodInternal (src.RemoveMethod, linked.RemoveMethod, true);
+ verifiedEventMethods.Add (src.RemoveMethod.FullName);
+ linkedMembers.Remove (src.RemoveMethod.FullName);
+ }
}
if (linked == null)
@@ -228,6 +249,12 @@ namespace Mono.Linker.Tests.TestCasesRunner {
var srcSignature = src.GetSignature ();
bool expectedKept = ShouldBeKept (src, srcSignature) || (linked != null && linked.DeclaringType.Module.EntryPoint == linked);
+ VerifyMethodInternal (src, linked, expectedKept);
+ }
+
+
+ void VerifyMethodInternal (MethodDefinition src, MethodDefinition linked, bool expectedKept)
+ {
if (!expectedKept) {
if (linked != null)
Assert.Fail ($"Method `{src.FullName}' should have been removed");
@@ -244,13 +271,14 @@ namespace Mono.Linker.Tests.TestCasesRunner {
VerifyCustomAttributes (src, linked);
}
- void VerifyBackingField (PropertyDefinition src, TypeDefinition linkedType)
+ void VerifyMemberBackingField (IMemberDefinition src, TypeDefinition linkedType)
{
var keptBackingFieldAttribute = src.CustomAttributes.FirstOrDefault (attr => attr.AttributeType.Name == nameof (KeptBackingFieldAttribute));
if (keptBackingFieldAttribute == null)
return;
- var backingFieldName = $"<{src.Name}>k__BackingField";
+ var backingFieldName = src.MetadataToken.TokenType == TokenType.Property
+ ? $"<{src.Name}>k__BackingField" : src.Name;
var srcField = src.DeclaringType.Fields.FirstOrDefault (f => f.Name == backingFieldName);
if (srcField == null) {
@@ -263,7 +291,7 @@ namespace Mono.Linker.Tests.TestCasesRunner {
}
if (srcField == null)
- Assert.Fail ($"Property `{src}', could not locate the expected backing field {backingFieldName}");
+ Assert.Fail ($"{src.MetadataToken.TokenType} `{src}', could not locate the expected backing field {backingFieldName}");
VerifyFieldKept (srcField, linkedType?.Fields.FirstOrDefault (l => srcField.Name == l.Name));
verifiedBackingFields.Add (srcField.FullName);
@@ -317,8 +345,8 @@ namespace Mono.Linker.Tests.TestCasesRunner {
static IEnumerable<T> GetCustomAttributeCtorValues<T> (ICustomAttributeProvider provider, string attributeName) where T : class
{
return provider.CustomAttributes.
- Where (w => w.AttributeType.Name == attributeName && w.Constructor.Parameters.Count == 1).
- Select (l => l.ConstructorArguments [0].Value as T);
+ Where (w => w.AttributeType.Name == attributeName && w.Constructor.Parameters.Count == 1).
+ Select (l => l.ConstructorArguments [0].Value as T);
}
}
}
diff --git a/linker/Tests/TestCasesRunner/PeVerifier.cs b/linker/Tests/TestCasesRunner/PeVerifier.cs
index 388fa1e5d..0d87b63f5 100644
--- a/linker/Tests/TestCasesRunner/PeVerifier.cs
+++ b/linker/Tests/TestCasesRunner/PeVerifier.cs
@@ -9,8 +9,7 @@ using Mono.Linker.Tests.Extensions;
using NUnit.Framework;
namespace Mono.Linker.Tests.TestCasesRunner {
- public class PeVerifier
- {
+ public class PeVerifier {
private readonly string _peExecutable;
public PeVerifier ()
@@ -66,11 +65,11 @@ namespace Mono.Linker.Tests.TestCasesRunner {
skipCheckEntirely = true;
}
else
- throw new ArgumentException($"Unhandled platform and toolchain values of {Environment.OSVersion.Platform} and {skipToolchain}");
+ throw new ArgumentException ($"Unhandled platform and toolchain values of {Environment.OSVersion.Platform} and {skipToolchain}");
} else if (ctorArg.Type.Name == nameof (String)) {
assembliesToSkip.Add ((string)ctorArg.Value);
} else {
- throw new ArgumentException($"Unhandled constructor argument type of {ctorArg.Type} on {nameof (SkipPeVerifyAttribute)}");
+ throw new ArgumentException ($"Unhandled constructor argument type of {ctorArg.Type} on {nameof (SkipPeVerifyAttribute)}");
}
}
}
@@ -101,28 +100,39 @@ namespace Mono.Linker.Tests.TestCasesRunner {
if (Environment.OSVersion.Platform != PlatformID.Win32NT)
throw new InvalidOperationException ("This method should only be called on windows");
- var key = Registry.LocalMachine.OpenSubKey (@"SOFTWARE\Wow6432Node\Microsoft\Microsoft SDKs\Windows");
+ NPath result;
+ if (TryFindPeExecutableFromRegustrySubfolder ("NETFXSDK", out result))
+ return result;
+ if (TryFindPeExecutableFromRegustrySubfolder ("Windows", out result))
+ return result;
+
+ throw new InvalidOperationException ("Could not locate a peverify.exe executable");
+ }
+
+ private static bool TryFindPeExecutableFromRegustrySubfolder (string subfolder, out NPath peVerifyPath)
+ {
+ var keyPath = $"SOFTWARE\\Wow6432Node\\Microsoft\\Microsoft SDKs\\{subfolder}";
+ var key = Registry.LocalMachine.OpenSubKey (keyPath);
+
foreach (var sdkKeyName in key.GetSubKeyNames ().OrderBy (name => new Version (name.TrimStart ('v').TrimEnd ('A'))).Reverse ()) {
- var sdkKey = Registry.LocalMachine.OpenSubKey ($"SOFTWARE\\Wow6432Node\\Microsoft\\Microsoft SDKs\\Windows\\{sdkKeyName}");
+ var sdkKey = Registry.LocalMachine.OpenSubKey ($"{keyPath}\\{sdkKeyName}");
var sdkDir = (string)sdkKey.GetValue ("InstallationFolder");
if (string.IsNullOrEmpty (sdkDir))
continue;
var binDir = sdkDir.ToNPath ().Combine ("bin");
-
if (!binDir.Exists ())
continue;
foreach (var netSdkDirs in binDir.Directories ().OrderBy (dir => dir.FileName)) {
- var peVerifyPath = netSdkDirs.Combine ("PEVerify.exe");
-
+ peVerifyPath = netSdkDirs.Combine ("PEVerify.exe");
if (peVerifyPath.FileExists ())
- return peVerifyPath;
+ return true;
}
}
-
- throw new InvalidOperationException ("Could not locate a peverify.exe executable");
+ peVerifyPath = null;
+ return false;
}
}
}