bcdd58c14c2c01bc4c0db72ce1490be238eaf93e
[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 Mono.CSharp {
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                                         if (a.Length != 0)
41                                                 last_arg_is_params = true;
42                         } 
43                 }
44                        
45                 public Type ParameterType (int pos)
46                 {
47                         return pi [pos].ParameterType;
48                 }
49
50                 public string ParameterDesc (int pos)
51                 {
52                         StringBuilder sb = new StringBuilder ();
53
54                         if (pi [pos].IsOut)
55                                 sb.Append ("out ");
56
57                         if (pi [pos].IsIn)
58                                 sb.Append ("in ");
59
60                         if (pos == pi.Length - 1)
61                                 sb.Append ("params ");
62                         
63                         sb.Append (TypeManager.CSharpName (ParameterType (pos)));
64
65                         return sb.ToString ();
66                         
67                 }
68
69                 public Parameter.Modifier ParameterModifier (int pos)
70                 {
71                         if (pi [pos].IsOut)
72                                 return Parameter.Modifier.OUT;
73
74                         if (pos == pi.Length-1) 
75                                 if (last_arg_is_params)
76                                         return Parameter.Modifier.PARAMS;
77
78                         return Parameter.Modifier.NONE;
79                 }
80
81                 public int Count {
82                         get {
83                                 return pi.Length;
84                         }
85                 }
86                 
87         }
88
89         public class InternalParameters : ParameterData {
90                 Type [] param_types;
91
92                 Parameters parameters;
93                 
94                 public InternalParameters (TypeContainer tc, Parameters parameters)
95                 {
96                         this.param_types = parameters.GetParameterInfo (tc);
97                         this.parameters = parameters;
98                 }
99
100                 public int Count {
101                         get {
102                                 if (param_types == null)
103                                         return 0;
104
105                                 return param_types.Length;
106                         }
107                 }
108
109                 public Type ParameterType (int pos)
110                 {
111                         if (param_types == null)
112                                 return null;
113
114                         int len = parameters.FixedParameters.Length;
115                         Parameter p;
116
117                         if (pos == len)
118                                 p = parameters.ArrayParameter;
119                         else if (pos < len)
120                                 p = parameters.FixedParameters [pos];
121                         else {
122                                 p = parameters.ArrayParameter;
123                                 pos = len;
124                         }
125
126                         //
127                         // Return the internal type.
128                         //
129                         return p.ParameterType;
130                 }
131
132                 public string ParameterDesc (int pos)
133                 {
134                         string tmp = null;
135                         Parameter p;
136
137                         if (pos >= parameters.FixedParameters.Length)
138                                 p = parameters.ArrayParameter;
139                         else
140                                 p = parameters.FixedParameters [pos];
141                         
142                         if (p.ModFlags == Parameter.Modifier.REF)
143                                 tmp = "ref ";
144                         else if (p.ModFlags == Parameter.Modifier.OUT)
145                                 tmp = "out ";
146                         else if (p.ModFlags == Parameter.Modifier.PARAMS)
147                                 tmp = "params ";
148
149                         Type t = ParameterType (pos);
150
151                         return tmp + TypeManager.CSharpName (t);
152                 }
153
154                 public Parameter.Modifier ParameterModifier (int pos)
155                 {
156                         if (pos >= parameters.FixedParameters.Length)
157                                 return parameters.ArrayParameter.ModFlags;
158                         else
159                                 return parameters.FixedParameters [pos].ModFlags;
160                 }
161                 
162         }
163 }