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 var bs = substep as BaseSubStep;
187 bs.Annotations.Push (substep);
188 substep.ProcessAssembly (assembly);
190 bs.Annotations.Pop ();
194 void DispatchType (TypeDefinition type)
196 foreach (var substep in on_types) {
197 var bs = substep as BaseSubStep;
199 bs.Annotations.Push (substep);
200 substep.ProcessType (type);
202 bs.Annotations.Pop ();
206 void DispatchField (FieldDefinition field)
208 foreach (var substep in on_fields)
209 substep.ProcessField (field);
212 void DispatchMethod (MethodDefinition method)
214 foreach (var substep in on_methods)
215 substep.ProcessMethod (method);
218 void DispatchProperty (PropertyDefinition property)
220 foreach (var substep in on_properties)
221 substep.ProcessProperty (property);
224 void DispatchEvent (EventDefinition @event)
226 foreach (var substep in on_events)
227 substep.ProcessEvent (@event);
230 void InitializeSubSteps (LinkContext context)
232 foreach (var substep in substeps)
233 substep.Initialize (context);
236 void CategorizeSubSteps (AssemblyDefinition assembly)
238 on_assemblies = null;
242 on_properties = null;
245 foreach (var substep in substeps)
246 CategorizeSubStep (substep, assembly);
249 void CategorizeSubStep (ISubStep substep, AssemblyDefinition assembly)
251 if (!substep.IsActiveFor (assembly))
254 CategorizeTarget (substep, SubStepTargets.Assembly, ref on_assemblies);
255 CategorizeTarget (substep, SubStepTargets.Type, ref on_types);
256 CategorizeTarget (substep, SubStepTargets.Field, ref on_fields);
257 CategorizeTarget (substep, SubStepTargets.Method, ref on_methods);
258 CategorizeTarget (substep, SubStepTargets.Property, ref on_properties);
259 CategorizeTarget (substep, SubStepTargets.Event, ref on_events);
262 static void CategorizeTarget (ISubStep substep, SubStepTargets target, ref List<ISubStep> list)
264 if (!Targets (substep, target))
268 list = new List<ISubStep> ();
273 static bool Targets (ISubStep substep, SubStepTargets target)
275 return (substep.Targets & target) == target;
278 IEnumerator IEnumerable.GetEnumerator ()
280 return GetEnumerator ();
283 public IEnumerator<ISubStep> GetEnumerator ()
285 return substeps.GetEnumerator ();