6f7641cd1efed203f907a162d46928961a89a151
[mono.git] / mcs / mcs / support.cs
1 //
2 // support.cs: Support routines to work around the fact that System.Reflection.Emit
3 // can not introspect types that are being constructed
4 //
5 // Author:
6 //   Miguel de Icaza (miguel@ximian.com)
7 //
8 // (C) 2001 Ximian, Inc (http://www.ximian.com)
9 //
10
11 using System.Reflection.Emit;
12 using System.Reflection;
13 using System;
14 using System.Text;
15
16 namespace CIR {
17
18         public interface ParameterData {
19                 Type ParameterType (int pos);
20                 int  Count { get; }
21                 string ParameterDesc (int pos);
22                 Parameter.Modifier ParameterModifier (int pos);
23         }
24
25         public class ReflectionParameters : ParameterData {
26                 ParameterInfo [] pi;
27                 bool last_arg_is_params;
28                 
29                 public ReflectionParameters (ParameterInfo [] pi)
30                 {
31                         object a;
32                         
33                         this.pi = pi;
34
35                         int count = pi.Length-1;
36                         if (count > 0){
37                                 a = pi [count-1].GetCustomAttributes (TypeManager.param_array_type, false);
38                         
39                                 if (a != null)
40                                         last_arg_is_params = true;
41                         } 
42                 }
43                        
44                 public Type ParameterType (int pos)
45                 {
46                         return pi [pos].ParameterType;
47                 }
48
49                 public string ParameterDesc (int pos)
50                 {
51                         StringBuilder sb = new StringBuilder ();
52
53                         if (pi [pos].IsOut)
54                                 sb.Append ("out ");
55
56                         if (pi [pos].IsIn)
57                                 sb.Append ("in ");
58
59                         if (pos == pi.Length - 1)
60                                 sb.Append ("params ");
61                         
62                         sb.Append (TypeManager.CSharpName (ParameterType (pos)));
63
64                         return sb.ToString ();
65                         
66                 }
67
68                 public Parameter.Modifier ParameterModifier (int pos)
69                 {
70                         if (pi [pos].IsOut)
71                                 return Parameter.Modifier.OUT;
72
73                         if (pos == pi.Length-1)
74                                 if (last_arg_is_params)
75                                         return Parameter.Modifier.PARAMS;
76                         
77                         return Parameter.Modifier.NONE;
78                 }
79
80                 public int Count {
81                         get {
82                                 return pi.Length;
83                         }
84                 }
85                 
86         }
87
88         public class InternalParameters : ParameterData {
89                 Type [] param_types;
90
91                 Parameters parameters;
92                 
93                 public InternalParameters (TypeContainer tc, Parameters parameters)
94                 {
95                         this.param_types = parameters.GetParameterInfo (tc);
96                         this.parameters = parameters;
97                 }
98
99                 public int Count {
100                         get {
101                                 if (param_types == null)
102                                         return 0;
103
104                                 return param_types.Length;
105                         }
106                 }
107
108                 public Type ParameterType (int pos)
109                 {
110                         if (param_types == null)
111                                 return null;
112
113                         int len = parameters.FixedParameters.Length;
114                         Parameter p;
115
116                         if (pos == len)
117                                 p = parameters.ArrayParameter;
118                         else if (pos < len)
119                                 p = parameters.FixedParameters [pos];
120                         else {
121                                 p = parameters.ArrayParameter;
122                                 pos = len;
123                         }
124
125                         Type t = param_types [pos];
126                         string name = t.FullName;
127                         
128                         if (p.ModFlags == Parameter.Modifier.REF ||
129                             p.ModFlags == Parameter.Modifier.OUT)
130                                 t = Type.GetType (name.Substring (0, name.Length - 1));
131                         
132                         return t;
133                 }
134
135                 public string ParameterDesc (int pos)
136                 {
137                         string tmp = null;
138                         Parameter p;
139
140                         if (pos == parameters.FixedParameters.Length)
141                                 p = parameters.ArrayParameter;
142                         else
143                                 p = parameters.FixedParameters [pos];
144                         
145                         if (p.ModFlags == Parameter.Modifier.REF)
146                                 tmp = "ref ";
147                         else if (p.ModFlags == Parameter.Modifier.OUT)
148                                 tmp = "out ";
149                         else if (p.ModFlags == Parameter.Modifier.PARAMS)
150                                 tmp = "params ";
151
152                         Type t = ParameterType (pos);
153
154                         return tmp + TypeManager.CSharpName (t);
155                 }
156
157                 public Parameter.Modifier ParameterModifier (int pos)
158                 {
159                         if (pos == parameters.FixedParameters.Length)
160                                 return parameters.ArrayParameter.ModFlags;
161                         else
162                                 return parameters.FixedParameters [pos].ModFlags;
163                 }
164                 
165         }
166 }