(DISTFILES): Comment out a few missing files.
[mono-project.git] / mcs / mbas / parameter.cs
blobea81f6b3dd8c052f31090cb49af80b7005dd1f6b
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 //
12 using System;
13 using System.Reflection;
14 using System.Reflection.Emit;
15 using System.Collections;
17 namespace Mono.MonoBASIC {
20 /// <summary>
21 /// Represents a single method parameter
22 /// </summary>
23 public class Parameter : Attributable {
24 [Flags]
25 public enum Modifier : byte {
26 NONE = 0,
27 VAL = 0,
28 REF = 1,
29 OUT = 2,
30 PARAMS = 4,
31 // This is a flag which says that it's either REF or OUT.
32 ISBYREF = 8,
33 OPTIONAL = 16
36 public readonly Expression TypeName;
37 public readonly Modifier ModFlags;
38 public readonly string Name;
39 public Type parameter_type;
40 public readonly Expression ParameterInitializer;
41 public readonly bool IsOptional;
43 public Parameter (Expression type, string name, Modifier mod, Attributes attrs)
44 : base (attrs)
46 Name = name;
47 ModFlags = mod;
48 TypeName = type;
49 ParameterInitializer = null;
50 IsOptional = false;
53 public Parameter (Expression type, string name, Modifier mod, Attributes attrs, Expression pi)
54 : base (attrs)
56 Name = name;
57 ModFlags = mod;
58 TypeName = type;
59 ParameterInitializer = pi;
60 IsOptional = false;
63 public Parameter (Expression type, string name, Modifier mod, Attributes attrs, Expression pi, bool opt)
64 : base (attrs)
66 Name = name;
67 ModFlags = mod;
68 TypeName = type;
69 ParameterInitializer = pi;
70 IsOptional = opt;
73 public override AttributeTargets AttributeTargets {
74 get {
75 return AttributeTargets.Parameter;
79 // <summary>
80 // Resolve is used in method definitions
81 // </summary>
82 public bool Resolve (DeclSpace ds, Location l)
84 parameter_type = ds.ResolveType (TypeName, false, l);
86 if (parameter_type == TypeManager.void_type){
87 Report.Error (1536, l, "`void' parameter is not permitted");
88 return false;
91 return parameter_type != null;
94 public Type ExternalType (DeclSpace ds, Location l)
96 if ((ModFlags & Parameter.Modifier.ISBYREF) != 0){
97 string n = parameter_type.FullName + "&";
99 Type t = RootContext.LookupType (ds, n, false, l);
101 return t;
104 return parameter_type;
107 public Type ParameterType {
108 get {
109 return parameter_type;
113 public ParameterAttributes Attributes {
114 get {
115 int flags = ((int) ModFlags) & ~((int) Parameter.Modifier.ISBYREF);
116 switch ((Modifier) flags) {
117 case Modifier.NONE:
118 return ParameterAttributes.None;
119 case Modifier.REF:
120 return ParameterAttributes.None;
121 case Modifier.OUT:
122 return ParameterAttributes.Out;
123 case Modifier.OPTIONAL:
124 return ParameterAttributes.Optional;
125 case Modifier.PARAMS:
126 return 0;
129 return ParameterAttributes.None;
133 /// <summary>
134 /// Returns the signature for this parameter evaluating it on the
135 /// @tc context
136 /// </summary>
137 public string GetSignature (DeclSpace ds, Location loc)
139 if (parameter_type == null){
140 if (!Resolve (ds, loc))
141 return null;
144 return ExternalType (ds, loc).FullName;
148 /// <summary>
149 /// Represents the methods parameters
150 /// </summary>
151 public class Parameters {
152 public Parameter [] FixedParameters;
153 public readonly Parameter ArrayParameter;
154 string signature;
155 Type [] types;
156 Location loc;
158 static Parameters empty_parameters;
160 public Parameters (Parameter [] fixed_parameters, Parameter array_parameter, Location l)
162 FixedParameters = fixed_parameters;
163 ArrayParameter = array_parameter;
164 loc = l;
167 /// <summary>
168 /// This is used to reuse a set of empty parameters, because they
169 /// are common
170 /// </summary>
171 public static Parameters EmptyReadOnlyParameters {
172 get {
173 if (empty_parameters == null)
174 empty_parameters = new Parameters (null, null, Location.Null);
176 return empty_parameters;
180 public bool HasOptional()
182 bool res = false;
184 foreach (Parameter p in FixedParameters)
186 if (p.IsOptional)
188 res = true;
189 break;
192 return (res);
195 /// <summary>
196 /// Returns the number of standard (i.e. non-optional) parameters
197 /// </summary>
198 public int CountStandardParams()
200 int res = 0;
201 if (FixedParameters == null)
202 return 0;
204 foreach (Parameter p in FixedParameters) {
205 if (!p.IsOptional)
206 res++;
208 return (res);
211 /// <summary>
212 /// Returns the number of optional parameters
213 /// </summary>
214 public int CountOptionalParams()
216 int res = 0;
217 if (FixedParameters == null)
218 return 0;
220 foreach (Parameter p in FixedParameters) {
221 if (p.IsOptional)
222 res++;
224 return (res);
227 public Expression GetDefaultValue (int i)
229 Parameter p = FixedParameters[i];
230 if (p.IsOptional)
231 return p.ParameterInitializer;
232 else
233 return null;
236 public void AppendParameter (Parameter p)
238 if (FixedParameters != null)
240 Parameter [] pa = new Parameter [FixedParameters.Length+1];
241 FixedParameters.CopyTo (pa, 0);
242 pa[FixedParameters.Length] = p;
243 FixedParameters = pa;
245 else
247 FixedParameters = new Parameter [1];
248 FixedParameters[0] = p;
252 public void PrependParameter (Parameter p)
254 Parameter [] pa = new Parameter [FixedParameters.Length+1];
255 FixedParameters.CopyTo (pa, 1);
256 pa[0] = p;
257 FixedParameters = pa;
260 public Parameters Copy (Location l)
262 Parameters p = new Parameters (null, null, l);
263 p.FixedParameters = new Parameter[this.FixedParameters.Length];
264 this.FixedParameters.CopyTo (p.FixedParameters, 0);
266 return (p);
270 public bool Empty {
271 get {
272 return (FixedParameters == null) && (ArrayParameter == null);
276 public void ComputeSignature (DeclSpace ds)
278 signature = "";
279 if (FixedParameters != null){
280 for (int i = 0; i < FixedParameters.Length; i++){
281 Parameter par = FixedParameters [i];
283 signature += par.GetSignature (ds, loc);
287 // Note: as per the spec, the `params' arguments (ArrayParameter)
288 // are not used in the signature computation for a method
292 static void Error_DuplicateParameterName (string name)
294 Report.Error (
295 100, "The parameter name `" + name + "' is a duplicate");
298 public bool VerifyArgs ()
300 int count;
301 int i, j;
303 if (FixedParameters == null)
304 return true;
306 count = FixedParameters.Length;
307 string array_par_name = ArrayParameter != null ? ArrayParameter.Name : null;
308 for (i = 0; i < count; i++){
309 string base_name = FixedParameters [i].Name;
311 for (j = i + 1; j < count; j++){
312 if (base_name != FixedParameters [j].Name)
313 continue;
314 Error_DuplicateParameterName (base_name);
315 return false;
318 if (base_name == array_par_name){
319 Error_DuplicateParameterName (base_name);
320 return false;
323 return true;
326 /// <summary>
327 /// Returns the signature of the Parameters evaluated in
328 /// the @tc environment
329 /// </summary>
330 public string GetSignature (DeclSpace ds)
332 if (signature == null){
333 VerifyArgs ();
334 ComputeSignature (ds);
337 return signature;
340 /// <summary>
341 /// Returns the paramenter information based on the name
342 /// </summary>
343 public Parameter GetParameterByName (string name, out int idx)
345 idx = 0;
346 int i = 0;
348 if (FixedParameters != null){
349 foreach (Parameter par in FixedParameters){
350 if (par.Name == name){
351 idx = i;
352 return par;
354 i++;
358 if (ArrayParameter != null){
359 if (name == ArrayParameter.Name){
360 idx = i;
361 return ArrayParameter;
365 return null;
368 bool ComputeParameterTypes (DeclSpace ds)
370 int extra = (ArrayParameter != null) ? 1 : 0;
371 int i = 0;
372 int pc;
374 if (FixedParameters == null)
375 pc = extra;
376 else
377 pc = extra + FixedParameters.Length;
379 types = new Type [pc];
381 if (!VerifyArgs ()){
382 FixedParameters = null;
383 return false;
386 bool failed = false;
387 if (FixedParameters != null){
388 foreach (Parameter p in FixedParameters){
389 Type t = null;
391 if (p.Resolve (ds, loc))
392 t = p.ExternalType (ds, loc);
393 else
394 failed = true;
396 types [i] = t;
397 i++;
401 if (extra > 0){
402 if (ArrayParameter.Resolve (ds, loc))
403 types [i] = ArrayParameter.ExternalType (ds, loc);
404 else
405 failed = true;
408 if (failed){
409 types = null;
410 return false;
413 return true;
417 // This variant is used by Delegates, because they need to
418 // resolve/define names, instead of the plain LookupType
420 public bool ComputeAndDefineParameterTypes (DeclSpace ds)
422 int extra = (ArrayParameter != null) ? 1 : 0;
423 int i = 0;
424 int pc;
426 if (FixedParameters == null)
427 pc = extra;
428 else
429 pc = extra + FixedParameters.Length;
431 types = new Type [pc];
433 if (!VerifyArgs ()){
434 FixedParameters = null;
435 return false;
438 bool ok_flag = true;
440 if (FixedParameters != null){
441 foreach (Parameter p in FixedParameters){
442 Type t = null;
444 if (p.Resolve (ds, loc))
445 t = p.ExternalType (ds, loc);
446 else
447 ok_flag = false;
449 types [i] = t;
450 i++;
454 if (extra > 0){
455 if (ArrayParameter.Resolve (ds, loc))
456 types [i] = ArrayParameter.ExternalType (ds, loc);
457 else
458 ok_flag = false;
462 // invalidate the cached types
464 if (!ok_flag){
465 types = null;
468 return ok_flag;
471 /// <summary>
472 /// Returns the argument types as an array
473 /// </summary>
474 static Type [] no_types = new Type [0];
476 public Type [] GetParameterInfo (DeclSpace ds)
478 if (types != null)
479 return types;
481 if (FixedParameters == null && ArrayParameter == null)
482 return no_types;
484 if (ComputeParameterTypes (ds) == false){
485 types = null;
486 return null;
489 return types;
492 /// <summary>
493 /// Returns the type of a given parameter, and stores in the `is_out'
494 /// boolean whether this is an out or ref parameter.
496 /// Note that the returned type will not contain any dereference in this
497 /// case (ie, you get "int" for a ref int instead of "int&"
498 /// </summary>
499 public Type GetParameterInfo (DeclSpace ds, int idx, out Parameter.Modifier mod)
501 mod = Parameter.Modifier.NONE;
503 if (!VerifyArgs ()){
504 FixedParameters = null;
505 return null;
508 if (FixedParameters == null && ArrayParameter == null)
509 return null;
511 if (types == null)
512 if (ComputeParameterTypes (ds) == false)
513 return null;
516 // If this is a request for the variable lenght arg.
518 int array_idx = (FixedParameters != null ? FixedParameters.Length : 0);
519 if (idx == array_idx)
520 return types [idx];
523 // Otherwise, it is a fixed parameter
525 Parameter p = FixedParameters [idx];
526 mod = p.ModFlags;
528 if ((mod & (Parameter.Modifier.REF | Parameter.Modifier.OUT)) != 0)
529 mod |= Parameter.Modifier.ISBYREF;
531 return p.ParameterType;
534 public CallingConventions GetCallingConvention ()
536 // For now this is the only correc thing to do
537 return CallingConventions.Standard;