2 using System.Collections;
3 using System.Collections.Generic;
7 using Mono.Linker.Steps;
11 namespace Mono.Tuner {
13 public abstract class ApplyPreserveAttributeBase : BaseSubStep {
15 protected abstract string PreserveAttribute { get; }
17 public override SubStepTargets Targets {
19 return SubStepTargets.Type
20 | SubStepTargets.Field
21 | SubStepTargets.Method
22 | SubStepTargets.Property
23 | SubStepTargets.Event;
27 public override bool IsActiveFor (AssemblyDefinition assembly)
29 return !Profile.IsSdkAssembly (assembly) && Annotations.GetAction (assembly) == AssemblyAction.Link;
32 public override void ProcessType (TypeDefinition type)
34 TryApplyPreserveAttribute (type);
37 public override void ProcessField (FieldDefinition field)
39 var attribute = GetPreserveAttribute (field);
40 if (attribute == null)
43 Mark (field, attribute);
46 public override void ProcessMethod (MethodDefinition method)
48 MarkMethodIfPreserved (method);
51 public override void ProcessProperty (PropertyDefinition property)
53 var attribute = GetPreserveAttribute (property);
54 if (attribute == null)
57 MarkMethod (property.GetMethod, attribute);
58 MarkMethod (property.SetMethod, attribute);
61 public override void ProcessEvent (EventDefinition @event)
63 var attribute = GetPreserveAttribute (@event);
64 if (attribute == null)
67 MarkMethod (@event.AddMethod, attribute);
68 MarkMethod (@event.InvokeMethod, attribute);
69 MarkMethod (@event.RemoveMethod, attribute);
72 void MarkMethodIfPreserved (MethodDefinition method)
74 var attribute = GetPreserveAttribute (method);
75 if (attribute == null)
78 MarkMethod (method, attribute);
81 void MarkMethod (MethodDefinition method, CustomAttribute preserve_attribute)
86 Mark (method, preserve_attribute);
87 Annotations.SetAction (method, MethodAction.Parse);
90 void Mark (IMetadataTokenProvider provider, CustomAttribute preserve_attribute)
92 if (IsConditionalAttribute (preserve_attribute)) {
93 PreserveConditional (provider);
97 PreserveUnconditional (provider);
100 void PreserveConditional (IMetadataTokenProvider provider)
102 var method = provider as MethodDefinition;
106 Annotations.AddPreservedMethod (method.DeclaringType, method);
109 static bool IsConditionalAttribute (CustomAttribute attribute)
111 if (attribute == null)
114 foreach (var named_argument in attribute.Fields)
115 if (named_argument.Name == "Conditional")
116 return (bool) named_argument.Argument.Value;
121 void PreserveUnconditional (IMetadataTokenProvider provider)
123 Annotations.Mark (provider);
125 var member = provider as IMemberDefinition;
126 if (member == null || member.DeclaringType == null)
129 Mark (member.DeclaringType, null);
132 void TryApplyPreserveAttribute (TypeDefinition type)
134 var attribute = GetPreserveAttribute (type);
135 if (attribute == null)
138 Annotations.Mark (type);
140 foreach (var named_argument in attribute.Fields)
141 if (named_argument.Name == "AllMembers" && (bool) named_argument.Argument.Value)
142 Annotations.SetPreserve (type, TypePreserve.All);
145 CustomAttribute GetPreserveAttribute (ICustomAttributeProvider provider)
147 if (!provider.HasCustomAttributes)
150 var attributes = provider.CustomAttributes;
152 for (int i = 0; i < attributes.Count; i++) {
153 var attribute = attributes [i];
155 if (attribute.Constructor.DeclaringType.FullName != PreserveAttribute)
158 attributes.RemoveAt (i);