2 using System.Collections;
3 using System.Collections.Generic;
6 using Mono.Linker.Steps;
10 namespace Mono.Tuner {
13 public enum SubStepTargets {
24 public interface ISubStep {
26 SubStepTargets Targets { get; }
28 void Initialize (LinkContext context);
29 bool IsActiveFor (AssemblyDefinition assembly);
31 void ProcessAssembly (AssemblyDefinition assembly);
32 void ProcessType (TypeDefinition type);
33 void ProcessField (FieldDefinition field);
34 void ProcessMethod (MethodDefinition method);
35 void ProcessProperty (PropertyDefinition property);
36 void ProcessEvent (EventDefinition @event);
39 public abstract class BaseSubStep : ISubStep {
41 protected LinkContext context;
43 public AnnotationStore Annotations {
44 get { return context.Annotations; }
47 public abstract SubStepTargets Targets { get; }
49 public virtual void Initialize (LinkContext context)
51 this.context = context;
54 public virtual bool IsActiveFor (AssemblyDefinition assembly)
59 public virtual void ProcessAssembly (AssemblyDefinition assembly)
63 public virtual void ProcessType (TypeDefinition type)
67 public virtual void ProcessField (FieldDefinition field)
71 public virtual void ProcessMethod (MethodDefinition method)
75 public virtual void ProcessProperty (PropertyDefinition property)
79 public virtual void ProcessEvent (EventDefinition @event)
84 public class SubStepDispatcher : IStep, IEnumerable<ISubStep> {
86 List<ISubStep> substeps = new List<ISubStep> ();
88 List<ISubStep> on_assemblies;
89 List<ISubStep> on_types;
90 List<ISubStep> on_fields;
91 List<ISubStep> on_methods;
92 List<ISubStep> on_properties;
93 List<ISubStep> on_events;
95 public void Add (ISubStep substep)
97 substeps.Add (substep);
100 public void Process (LinkContext context)
102 InitializeSubSteps (context);
104 BrowseAssemblies (context.GetAssemblies ());
107 static bool HasSubSteps (List<ISubStep> substeps)
109 return substeps != null && substeps.Count > 0;
112 void BrowseAssemblies (IEnumerable<AssemblyDefinition> assemblies)
114 foreach (var assembly in assemblies) {
115 CategorizeSubSteps (assembly);
117 if (HasSubSteps (on_assemblies))
118 DispatchAssembly (assembly);
120 if (!ShouldDispatchTypes ())
123 BrowseTypes (assembly.MainModule.Types);
127 bool ShouldDispatchTypes ()
129 return HasSubSteps (on_types)
130 || HasSubSteps (on_fields)
131 || HasSubSteps (on_methods)
132 || HasSubSteps (on_properties)
133 || HasSubSteps (on_events);
136 void BrowseTypes (ICollection types)
138 foreach (TypeDefinition type in types) {
141 if (type.HasFields && HasSubSteps (on_fields))
142 BrowseFields (type.Fields);
144 if (type.HasMethods && HasSubSteps (on_methods))
145 BrowseMethods (type.Methods);
147 if (type.HasProperties && HasSubSteps (on_properties))
148 BrowseProperties (type.Properties);
150 if (type.HasEvents && HasSubSteps (on_events))
151 BrowseEvents (type.Events);
153 if (type.HasNestedTypes)
154 BrowseTypes (type.NestedTypes);
158 void BrowseFields (ICollection fields)
160 foreach (FieldDefinition field in fields)
161 DispatchField (field);
164 void BrowseMethods (ICollection methods)
166 foreach (MethodDefinition method in methods)
167 DispatchMethod (method);
170 void BrowseProperties (ICollection properties)
172 foreach (PropertyDefinition property in properties)
173 DispatchProperty (property);
176 void BrowseEvents (ICollection events)
178 foreach (EventDefinition @event in events)
179 DispatchEvent (@event);
182 void DispatchAssembly (AssemblyDefinition assembly)
184 foreach (var substep in on_assemblies)
185 substep.ProcessAssembly (assembly);
188 void DispatchType (TypeDefinition type)
190 foreach (var substep in on_types)
191 substep.ProcessType (type);
194 void DispatchField (FieldDefinition field)
196 foreach (var substep in on_fields)
197 substep.ProcessField (field);
200 void DispatchMethod (MethodDefinition method)
202 foreach (var substep in on_methods)
203 substep.ProcessMethod (method);
206 void DispatchProperty (PropertyDefinition property)
208 foreach (var substep in on_properties)
209 substep.ProcessProperty (property);
212 void DispatchEvent (EventDefinition @event)
214 foreach (var substep in on_events)
215 substep.ProcessEvent (@event);
218 void InitializeSubSteps (LinkContext context)
220 foreach (var substep in substeps)
221 substep.Initialize (context);
224 void CategorizeSubSteps (AssemblyDefinition assembly)
226 on_assemblies = null;
230 on_properties = null;
233 foreach (var substep in substeps)
234 CategorizeSubStep (substep, assembly);
237 void CategorizeSubStep (ISubStep substep, AssemblyDefinition assembly)
239 if (!substep.IsActiveFor (assembly))
242 CategorizeTarget (substep, SubStepTargets.Assembly, ref on_assemblies);
243 CategorizeTarget (substep, SubStepTargets.Type, ref on_types);
244 CategorizeTarget (substep, SubStepTargets.Field, ref on_fields);
245 CategorizeTarget (substep, SubStepTargets.Method, ref on_methods);
246 CategorizeTarget (substep, SubStepTargets.Property, ref on_properties);
247 CategorizeTarget (substep, SubStepTargets.Event, ref on_events);
250 static void CategorizeTarget (ISubStep substep, SubStepTargets target, ref List<ISubStep> list)
252 if (!Targets (substep, target))
256 list = new List<ISubStep> ();
261 static bool Targets (ISubStep substep, SubStepTargets target)
263 return (substep.Targets & target) == target;
266 IEnumerator IEnumerable.GetEnumerator ()
268 return GetEnumerator ();
271 public IEnumerator<ISubStep> GetEnumerator ()
273 return substeps.GetEnumerator ();