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
path: root/linker
diff options
context:
space:
mode:
authorEugene Rozenfeld <erozen@microsoft.com>2017-03-24 09:07:13 +0300
committerMarek Safar <marek.safar@gmail.com>2017-04-01 09:06:26 +0300
commitd6910ee0d3374b2bb1808d3b4edbf68a47c532c5 (patch)
treedb05be6ebb80e299304309d8653c966af37a5f37 /linker
parent411ef52ceefaa8e08c8f52d0f9644c722b850d81 (diff)
Mark methods and fields needed for types with debugger attributes.
Add an option (-v) to keep members needed for types with debugger attributes: 1. Keep the fields, methods, and properties specified in the string passed to the constructor of DebuggerDisplayAttribute if they can be easily extracted from the string; otherwise, keep all fields and methods in the type and its base types . 2. Keep all fields and methods in proxy types from DebuggerTypeProxyAttribute.
Diffstat (limited to 'linker')
-rw-r--r--linker/Mono.Linker.Steps/MarkStep.cs87
-rw-r--r--linker/Mono.Linker/Driver.cs4
-rw-r--r--linker/Mono.Linker/LinkContext.cs7
3 files changed, 98 insertions, 0 deletions
diff --git a/linker/Mono.Linker.Steps/MarkStep.cs b/linker/Mono.Linker.Steps/MarkStep.cs
index 9b2692588..1e48b68d4 100644
--- a/linker/Mono.Linker.Steps/MarkStep.cs
+++ b/linker/Mono.Linker.Steps/MarkStep.cs
@@ -30,6 +30,7 @@
using System;
using System.Collections;
using System.Linq;
+using System.Text.RegularExpressions;
using Mono.Cecil;
using Mono.Cecil.Cil;
@@ -365,6 +366,19 @@ namespace Mono.Linker.Steps {
return null;
}
+ MethodDefinition GetMethodWithNoParameters (TypeDefinition type, string methodname)
+ {
+ while (type != null) {
+ MethodDefinition method = type.Methods.FirstOrDefault (m => m.Name == methodname && !m.HasParameters);
+ if (method != null)
+ return method;
+
+ type = type.BaseType != null ? ResolveTypeDefinition (type.BaseType) : null;
+ }
+
+ return null;
+ }
+
void MarkCustomAttributeArguments (CustomAttribute ca)
{
if (!ca.HasConstructorArguments)
@@ -596,6 +610,12 @@ namespace Mono.Linker.Steps {
case "System.Xml.Serialization.XmlSchemaProviderAttribute":
MarkXmlSchemaProvider (type, attribute);
break;
+ case "System.Diagnostics.DebuggerDisplayAttribute":
+ MarkTypeWithDebuggerDisplayAttribute (type, attribute);
+ break;
+ case "System.Diagnostics.DebuggerTypeProxyAttribute":
+ MarkTypeWithDebuggerTypeProxyAttribute (type, attribute);
+ break;
}
}
}
@@ -623,6 +643,73 @@ namespace Mono.Linker.Steps {
MarkNamedMethod (type, method_name);
}
+ void MarkTypeWithDebuggerDisplayAttribute (TypeDefinition type, CustomAttribute attribute)
+ {
+ if (_context.KeepMembersForDebuggerAttributes) {
+
+ string displayString = (string) attribute.ConstructorArguments[0].Value;
+
+ Regex regex = new Regex ("{[^{}]+}", RegexOptions.Compiled);
+
+ foreach (Match match in regex.Matches (displayString)) {
+ // Remove '{' and '}'
+ string realMatch = match.Value.Substring (1, match.Value.Length - 2);
+
+ // Remove ",nq" suffix if present
+ // (it asks the expression evaluator to remove the quotes when displaying the final value)
+ if (Regex.IsMatch(realMatch, @".+,\s*nq")) {
+ realMatch = realMatch.Substring (0, realMatch.LastIndexOf (','));
+ }
+
+ if (realMatch.EndsWith ("()")) {
+ string methodName = realMatch.Substring (0, realMatch.Length - 2);
+ MethodDefinition method = GetMethodWithNoParameters (type, methodName);
+ if (method != null) {
+ MarkMethod (method);
+ continue;
+ }
+ } else {
+ FieldDefinition field = GetField (type, realMatch);
+ if (field != null) {
+ MarkField (field);
+ continue;
+ }
+
+ PropertyDefinition property = GetProperty (type, realMatch);
+ if (property != null) {
+ if (property.GetMethod != null) {
+ MarkMethod (property.GetMethod);
+ }
+ if (property.SetMethod != null) {
+ MarkMethod (property.SetMethod);
+ }
+ continue;
+ }
+ }
+
+ while (type != null) {
+ MarkMethods (type);
+ MarkFields (type, includeStatic: true);
+ type = type.BaseType != null ? ResolveTypeDefinition (type.BaseType) : null;
+ }
+ return;
+ }
+ }
+ }
+
+ void MarkTypeWithDebuggerTypeProxyAttribute (TypeDefinition type, CustomAttribute attribute)
+ {
+ if (_context.KeepMembersForDebuggerAttributes) {
+ TypeReference proxyTypeReference = (TypeReference) attribute.ConstructorArguments [0].Value;
+
+ MarkType (proxyTypeReference);
+
+ TypeDefinition proxyType = ResolveTypeDefinition (proxyTypeReference);
+ MarkMethods (proxyType);
+ MarkFields (proxyType, includeStatic: true);
+ }
+ }
+
static bool TryGetStringArgument (CustomAttribute attribute, out string argument)
{
argument = null;
diff --git a/linker/Mono.Linker/Driver.cs b/linker/Mono.Linker/Driver.cs
index d2a32f178..28d8512bf 100644
--- a/linker/Mono.Linker/Driver.cs
+++ b/linker/Mono.Linker/Driver.cs
@@ -163,6 +163,9 @@ namespace Mono.Linker {
if (!bool.Parse (GetParam ()))
p.RemoveStep (typeof (RegenerateGuidStep));
break;
+ case 'v':
+ context.KeepMembersForDebuggerAttributes = bool.Parse (GetParam ());
+ break;
default:
Usage ("Unknown option: `" + token [1] + "'");
break;
@@ -293,6 +296,7 @@ namespace Mono.Linker {
Console.WriteLine (" -d Add a directory where the linker will look for assemblies");
Console.WriteLine (" -b Generate debug symbols for each linked module (true or false)");
Console.WriteLine (" -g Generate a new unique guid for each linked module (true or false)");
+ Console.WriteLine (" -v Keep memebers needed by debugger attributes (true or false)");
Console.WriteLine (" -l List of i18n assemblies to copy to the output directory");
Console.WriteLine (" separated with a comma: none,all,cjk,mideast,other,rare,west");
Console.WriteLine (" default is all");
diff --git a/linker/Mono.Linker/LinkContext.cs b/linker/Mono.Linker/LinkContext.cs
index db7481a37..f5629ed56 100644
--- a/linker/Mono.Linker/LinkContext.cs
+++ b/linker/Mono.Linker/LinkContext.cs
@@ -44,6 +44,7 @@ namespace Mono.Linker {
Hashtable _parameters;
bool _linkSymbols;
bool _keepTypeForwarderOnlyAssemblies;
+ bool _keepMembersForDebuggerAttributes;
AssemblyResolver _resolver;
@@ -82,6 +83,12 @@ namespace Mono.Linker {
set { _keepTypeForwarderOnlyAssemblies = value; }
}
+ public bool KeepMembersForDebuggerAttributes
+ {
+ get { return _keepMembersForDebuggerAttributes; }
+ set { _keepMembersForDebuggerAttributes = value; }
+ }
+
public IDictionary Actions {
get { return _actions; }
}