7ae07d24f1e4a2bd9d0d6c07e3972b2dd500d58c
[mono.git] / mcs / tools / linker / Mono.Linker / Pipeline.cs
1 //
2 // Pipeline.cs
3 //
4 // Author:
5 //   Jb Evain (jbevain@gmail.com)
6 //
7 // (C) 2006 Jb Evain
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28
29 using System;
30 using System.Collections;
31 using System.Diagnostics;
32
33 using Mono.Linker.Steps;
34
35 namespace Mono.Linker {
36
37         public class Pipeline {
38
39                 ArrayList _steps;
40
41                 public Pipeline ()
42                 {
43                         _steps = new ArrayList();
44                 }
45
46                 public void PrependStep (IStep step)
47                 {
48                         _steps.Insert (0, step);
49                 }
50
51                 public void AppendStep (IStep step)
52                 {
53                         _steps.Add (step);
54                 }
55
56                 public void AddStepBefore (Type target, IStep step)
57                 {
58                         for (int i = 0; i < _steps.Count; i++) {
59                                 if (target.IsInstanceOfType (_steps [i])) {
60                                         _steps.Insert (i, step);
61                                         return;
62                                 }
63                         }
64                         string msg = String.Format ("Step {0} could not be inserted before (not found) {1}", step, target);
65                         throw new InvalidOperationException (msg);
66                 }
67
68                 public void ReplaceStep (Type target, IStep step)
69                 {
70                         AddStepBefore (target, step);
71                         RemoveStep (target);
72                 }
73
74                 public void AddStepAfter (Type target, IStep step)
75                 {
76                         for (int i = 0; i < _steps.Count; i++) {
77                                 if (target.IsInstanceOfType (_steps [i])) {
78                                         if (i == _steps.Count - 1)
79                                                 _steps.Add (step);
80                                         else
81                                                 _steps.Insert (i + 1, step);
82                                         return;
83                                 }
84                         }
85                         string msg = String.Format ("Step {0} could not be inserted after (not found) {1}", step, target);
86                         throw new InvalidOperationException (msg);
87                 }
88
89                 public void AddStepAfter (IStep target, IStep step)
90                 {
91                         for (int i = 0; i < _steps.Count; i++) {
92                                 if (_steps [i] == target) {
93                                         if (i == _steps.Count - 1)
94                                                 _steps.Add (step);
95                                         else
96                                                 _steps.Insert (i + 1, step);
97                                         return;
98                                 }
99                         }
100                 }
101
102                 public void RemoveStep (Type target)
103                 {
104                         for (int i = 0; i < _steps.Count; i++) {
105                                 if (_steps [i].GetType () != target)
106                                         continue;
107
108                                 _steps.RemoveAt (i);
109                                 break;
110                         }
111                 }
112
113                 public void Process (LinkContext context)
114                 {
115                         while (_steps.Count > 0) {
116                                 IStep step = (IStep) _steps [0];
117                                 context.Annotations.Push (step);
118                                 step.Process (context);
119                                 context.Annotations.Pop ();
120                                 _steps.Remove (step);
121                         }
122                 }
123
124                 public IStep [] GetSteps ()
125                 {
126                         return (IStep []) _steps.ToArray (typeof (IStep));
127                 }
128
129                 public bool ContainsStep (Type type)
130                 {
131                         foreach (IStep step in _steps)
132                                 if (step.GetType () == type)
133                                         return true;
134
135                         return false;
136                 }
137         }
138 }