2001-11-22 Miguel de Icaza <miguel@ximian.com>
[mono.git] / mcs / mcs / parameter.cs
1 //
2 // parameter.cs: Parameter definition.
3 //
4 // Author: Miguel de Icaza (miguel@gnu.org)
5 //
6 // Licensed under the terms of the GNU GPL
7 //
8 // (C) 2001 Ximian, Inc (http://www.ximian.com)
9 //
10 //
11 //
12
13 namespace Mono.CSharp {
14
15         using System;
16         using System.Reflection;
17         using System.Collections;
18
19         /// <summary>
20         ///   Represents a single method parameter
21         /// </summary>
22         public class Parameter {
23                 public enum Modifier : byte {
24                         NONE,
25                         REF,
26                         OUT,
27                         PARAMS,
28                 }
29
30                 public readonly string   Type;
31                 public readonly string   Name;
32                 public readonly Modifier ModFlags;
33                 public Attributes OptAttributes;
34                 
35                 public Parameter (string type, string name, Modifier mod, Attributes attrs)
36                 {
37                         Name = name;
38                         ModFlags = mod;
39                         Type = type = type;
40                         OptAttributes = attrs;
41                 }
42
43                 public ParameterAttributes Attributes {
44                         get {
45                                 switch (ModFlags){
46                                 case Modifier.NONE:
47                                         return ParameterAttributes.None;
48                                 case Modifier.REF:
49                                         return ParameterAttributes.None;
50                                 case Modifier.OUT:
51                                         return ParameterAttributes.Out;
52                                 case Modifier.PARAMS:
53                                         return 0;
54                                 }
55                                 
56                                 return ParameterAttributes.None;
57                         }
58                 }
59                 
60                 string ModSignature ()
61                 {
62                         switch (ModFlags){
63                         case Modifier.NONE:
64                                 return "";
65                         case Modifier.REF:
66                                 return "&";
67                         case Modifier.OUT:
68                                 return ">";
69                         case Modifier.PARAMS:
70                                 return "";
71                         }
72                         // This should not happen.
73                         return (string) null;
74                 }
75
76                 /// <summary>
77                 ///   Returns the signature for this parameter evaluating it on the
78                 ///   @tc context
79                 /// </summary>
80                 public string GetSignature (TypeContainer tc)
81                 {
82                         Type t = tc.LookupType (Type, false);
83
84                         if (t == null)
85                                 return "";
86                         
87                         return ModSignature () + t.FullName;
88                 }
89         }
90
91         /// <summary>
92         ///   Represents the methods parameters
93         /// </summary>
94         public class Parameters {
95                 public Parameter [] FixedParameters;
96                 public readonly Parameter ArrayParameter;
97                 string signature;
98                 Type [] types;
99
100                 static Parameters empty_parameters;
101                 
102                 public Parameters (Parameter [] fixed_parameters, Parameter array_parameter)
103                 {
104                         FixedParameters = fixed_parameters;
105                         ArrayParameter  = array_parameter;
106                 }
107
108                 /// <summary>
109                 ///   This is used to reuse a set of empty parameters, because they
110                 ///   are common
111                 /// </summary>
112                 public static Parameters GetEmptyReadOnlyParameters ()
113                 {
114                         if (empty_parameters == null)
115                                 empty_parameters = new Parameters (null, null);
116                         
117                         return empty_parameters;
118                 }
119                 
120                 public bool Empty {
121                         get {
122                                 return (FixedParameters == null) && (ArrayParameter == null);
123                         }
124                 }
125                 
126                 public void ComputeSignature (TypeContainer tc)
127                 {
128                         signature = "";
129                         if (FixedParameters != null){
130                                 for (int i = 0; i < FixedParameters.Length; i++){
131                                         Parameter par = FixedParameters [i];
132                                         
133                                         signature += par.GetSignature (tc);
134                                 }
135                         }
136                         //
137                         // Note: as per the spec, the `params' arguments (ArrayParameter)
138                         // are not used in the signature computation for a method
139                         //
140                 }
141
142                 public bool VerifyArgs (TypeContainer tc)
143                 {
144                         int count;
145                         int i, j;
146
147                         if (FixedParameters == null)
148                                 return true;
149                         
150                         count = FixedParameters.Length;
151                         for (i = 0; i < count; i++){
152                                 for (j = i + 1; j < count; j++){
153                                         if (FixedParameters [i].Name != FixedParameters [j].Name)
154                                                 continue;
155                                         Report.Error (
156                                                 100, "The parameter name `" + FixedParameters [i].Name +
157                                                 "' is a duplicate");
158                                         return false;
159                                 }
160                         }
161                         return true;
162                 }
163                 
164                 /// <summary>
165                 ///    Returns the signature of the Parameters evaluated in
166                 ///    the @tc environment
167                 /// </summary>
168                 public string GetSignature (TypeContainer tc)
169                 {
170                         if (signature == null){
171                                 VerifyArgs (tc);
172                                 ComputeSignature (tc);
173                         }
174                         
175                         return signature;
176                 }
177                 
178                 /// <summary>
179                 ///    Returns the paramenter information based on the name
180                 /// </summary>
181                 public Parameter GetParameterByName (string name, out int idx)
182                 {
183                         idx = 0;
184
185                         if (FixedParameters == null)
186                                 return null;
187
188                         int i = 0;
189                         foreach (Parameter par in FixedParameters){
190                                 if (par.Name == name){
191                                         idx = i;
192                                         return par;
193                                 }
194                                 i++;
195                         }
196
197                         if (ArrayParameter != null)
198                                 if (name == ArrayParameter.Name){
199                                         idx = i;
200                                         return ArrayParameter;
201                                 }
202                         
203                         return null;
204                 }
205
206                 
207                 /// <summary>
208                 ///   Returns the argument types as an array
209                 /// </summary>
210                 public Type [] GetParameterInfo (TypeContainer tc)
211                 {
212                         if (types != null)
213                                 return types;
214                         
215                         if (FixedParameters == null)
216                                 return null;
217                         
218                         int extra = (ArrayParameter != null) ? 1 : 0;
219                         int i = 0;
220                         int pc = FixedParameters.Length + extra;
221                         
222                         types = new Type [pc];
223
224                         if (!VerifyArgs (tc)){
225                                 FixedParameters = null;
226                                 return null;
227                         }
228                         
229                         foreach (Parameter p in FixedParameters){
230                                 Type t = tc.LookupType (p.Type, false);
231
232                                 if ((p.ModFlags & (Parameter.Modifier.REF | Parameter.Modifier.OUT)) != 0){
233                                         t = Type.GetType (t.FullName + "&");
234                                 }
235                                 types [i] = t;
236                                 i++;
237                         }
238
239                         if (extra > 0)
240                                 types [i] = tc.LookupType (ArrayParameter.Type, false);
241                         
242                         return types;
243                 }
244
245                 public CallingConventions GetCallingConvention ()
246                 {
247                         if (ArrayParameter != null)
248                                 return CallingConventions.VarArgs;
249                         else
250                                 return CallingConventions.Standard;
251                 }
252         }
253 }
254                 
255         
256