~ubuntu-branches/ubuntu/trusty/monodevelop/trusty-proposed

« back to all changes in this revision

Viewing changes to contrib/ICSharpCode.NRefactory.CSharp/Parser/mcs/parameter.cs

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2013-05-12 09:46:03 UTC
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130512094603-mad323bzcxvmcam0
Tags: upstream-4.0.5+dfsg
ImportĀ upstreamĀ versionĀ 4.0.5+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
//
2
 
// parameter.cs: Parameter definition.
3
 
//
4
 
// Author: Miguel de Icaza (miguel@gnu.org)
5
 
//         Marek Safar (marek.safar@seznam.cz)
6
 
//
7
 
// Dual licensed under the terms of the MIT X11 or GNU GPL
8
 
//
9
 
// Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
10
 
// Copyright 2003-2008 Novell, Inc. 
11
 
// Copyright 2011 Xamarin Inc
12
 
//
13
 
//
14
 
using System;
15
 
using System.Text;
16
 
 
17
 
#if STATIC
18
 
using MetaType = IKVM.Reflection.Type;
19
 
using IKVM.Reflection;
20
 
using IKVM.Reflection.Emit;
21
 
#else
22
 
using MetaType = System.Type;
23
 
using System.Reflection;
24
 
using System.Reflection.Emit;
25
 
#endif
26
 
 
27
 
namespace Mono.CSharp {
28
 
 
29
 
        /// <summary>
30
 
        ///   Abstract Base class for parameters of a method.
31
 
        /// </summary>
32
 
        public abstract class ParameterBase : Attributable
33
 
        {
34
 
                protected ParameterBuilder builder;
35
 
 
36
 
                public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
37
 
                {
38
 
#if false
39
 
                        if (a.Type == pa.MarshalAs) {
40
 
                                UnmanagedMarshal marshal = a.GetMarshal (this);
41
 
                                if (marshal != null) {
42
 
                                        builder.SetMarshal (marshal);
43
 
                                }
44
 
                                return;
45
 
                        }
46
 
#endif
47
 
                        if (a.HasSecurityAttribute) {
48
 
                                a.Error_InvalidSecurityParent ();
49
 
                                return;
50
 
                        }
51
 
 
52
 
                        if (a.Type == pa.Dynamic) {
53
 
                                a.Error_MisusedDynamicAttribute ();
54
 
                                return;
55
 
                        }
56
 
 
57
 
                        builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
58
 
                }
59
 
 
60
 
                public ParameterBuilder Builder {
61
 
                        get {
62
 
                                return builder;
63
 
                        }
64
 
                }
65
 
 
66
 
                public override bool IsClsComplianceRequired()
67
 
                {
68
 
                        return false;
69
 
                }
70
 
        }
71
 
 
72
 
        /// <summary>
73
 
        /// Class for applying custom attributes on the return type
74
 
        /// </summary>
75
 
        public class ReturnParameter : ParameterBase
76
 
        {
77
 
                MemberCore method;
78
 
 
79
 
                // TODO: merge method and mb
80
 
                public ReturnParameter (MemberCore method, MethodBuilder mb, Location location)
81
 
                {
82
 
                        this.method = method;
83
 
                        try {
84
 
                                builder = mb.DefineParameter (0, ParameterAttributes.None, "");                 
85
 
                        }
86
 
                        catch (ArgumentOutOfRangeException) {
87
 
                                method.Compiler.Report.RuntimeMissingSupport (location, "custom attributes on the return type");
88
 
                        }
89
 
                }
90
 
 
91
 
                public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
92
 
                {
93
 
                        if (a.Type == pa.CLSCompliant) {
94
 
                                method.Compiler.Report.Warning (3023, 1, a.Location,
95
 
                                        "CLSCompliant attribute has no meaning when applied to return types. Try putting it on the method instead");
96
 
                        }
97
 
 
98
 
                        // This occurs after Warning -28
99
 
                        if (builder == null)
100
 
                                return;
101
 
 
102
 
                        base.ApplyAttributeBuilder (a, ctor, cdata, pa);
103
 
                }
104
 
 
105
 
                public override AttributeTargets AttributeTargets {
106
 
                        get {
107
 
                                return AttributeTargets.ReturnValue;
108
 
                        }
109
 
                }
110
 
 
111
 
                /// <summary>
112
 
                /// Is never called
113
 
                /// </summary>
114
 
                public override string[] ValidAttributeTargets {
115
 
                        get {
116
 
                                return null;
117
 
                        }
118
 
                }
119
 
        }
120
 
 
121
 
        public class ImplicitLambdaParameter : Parameter
122
 
        {
123
 
                public ImplicitLambdaParameter (string name, Location loc)
124
 
                        : base (null, name, Modifier.NONE, null, loc)
125
 
                {
126
 
                }
127
 
 
128
 
                public override TypeSpec Resolve (IMemberContext ec, int index)
129
 
                {
130
 
                        if (parameter_type == null)
131
 
                                throw new InternalErrorException ("A type of implicit lambda parameter `{0}' is not set",
132
 
                                        Name);
133
 
 
134
 
                        base.idx = index;
135
 
                        return parameter_type;
136
 
                }
137
 
 
138
 
                public void SetParameterType (TypeSpec type)
139
 
                {
140
 
                        parameter_type = type;
141
 
                }
142
 
        }
143
 
 
144
 
        public class ParamsParameter : Parameter {
145
 
                public ParamsParameter (FullNamedExpression type, string name, Attributes attrs, Location loc):
146
 
                        base (type, name, Parameter.Modifier.PARAMS, attrs, loc)
147
 
                {
148
 
                }
149
 
 
150
 
                public override TypeSpec Resolve (IMemberContext ec, int index)
151
 
                {
152
 
                        if (base.Resolve (ec, index) == null)
153
 
                                return null;
154
 
 
155
 
                        var ac = parameter_type as ArrayContainer;
156
 
                        if (ac == null || ac.Rank != 1) {
157
 
                                ec.Module.Compiler.Report.Error (225, Location, "The params parameter must be a single dimensional array");
158
 
                                return null;
159
 
                        }
160
 
 
161
 
                        return parameter_type;
162
 
                }
163
 
 
164
 
                public override void ApplyAttributes (MethodBuilder mb, ConstructorBuilder cb, int index, PredefinedAttributes pa)
165
 
                {
166
 
                        base.ApplyAttributes (mb, cb, index, pa);
167
 
                        pa.ParamArray.EmitAttribute (builder);
168
 
                }
169
 
        }
170
 
 
171
 
        public class ArglistParameter : Parameter {
172
 
                // Doesn't have proper type because it's never chosen for better conversion
173
 
                public ArglistParameter (Location loc) :
174
 
                        base (null, String.Empty, Parameter.Modifier.NONE, null, loc)
175
 
                {
176
 
                        parameter_type = InternalType.Arglist;
177
 
                }
178
 
 
179
 
                public override void  ApplyAttributes (MethodBuilder mb, ConstructorBuilder cb, int index, PredefinedAttributes pa)
180
 
                {
181
 
                        // Nothing to do
182
 
                }
183
 
 
184
 
                public override bool CheckAccessibility (InterfaceMemberBase member)
185
 
                {
186
 
                        return true;
187
 
                }
188
 
 
189
 
                public override TypeSpec Resolve (IMemberContext ec, int index)
190
 
                {
191
 
                        return parameter_type;
192
 
                }
193
 
        }
194
 
 
195
 
        public interface IParameterData
196
 
        {
197
 
                Expression DefaultValue { get; }
198
 
                bool HasExtensionMethodModifier { get; }
199
 
                bool HasDefaultValue { get; }
200
 
                Parameter.Modifier ModFlags { get; }
201
 
                string Name { get; }
202
 
        }
203
 
 
204
 
        //
205
 
        // Parameter information created by parser
206
 
        //
207
 
        public class Parameter : ParameterBase, IParameterData, ILocalVariable // TODO: INamedBlockVariable
208
 
        {
209
 
                [Flags]
210
 
                public enum Modifier : byte {
211
 
                        NONE    = 0,
212
 
                        PARAMS  = 1 << 0,
213
 
                        REF = 1 << 1,
214
 
                        OUT = 1 << 2,
215
 
                        This = 1 << 3,
216
 
                        CallerMemberName = 1 << 4,
217
 
                        CallerLineNumber = 1 << 5,
218
 
                        CallerFilePath = 1 << 6,
219
 
 
220
 
                        RefOutMask = REF | OUT,
221
 
                        ModifierMask = PARAMS | REF | OUT | This,
222
 
                        CallerMask = CallerMemberName | CallerLineNumber | CallerFilePath
223
 
                }
224
 
 
225
 
                static readonly string[] attribute_targets = new string[] { "param" };
226
 
 
227
 
                FullNamedExpression texpr;
228
 
                Modifier modFlags;
229
 
                string name;
230
 
                Expression default_expr;
231
 
                protected TypeSpec parameter_type;
232
 
                readonly Location loc;
233
 
                protected int idx;
234
 
                public bool HasAddressTaken;
235
 
 
236
 
                TemporaryVariableReference expr_tree_variable;
237
 
 
238
 
                HoistedParameter hoisted_variant;
239
 
 
240
 
                public Parameter (FullNamedExpression type, string name, Modifier mod, Attributes attrs, Location loc)
241
 
                {
242
 
                        this.name = name;
243
 
                        modFlags = mod;
244
 
                        this.loc = loc;
245
 
                        texpr = type;
246
 
 
247
 
                        // Only assign, attributes will be attached during resolve
248
 
                        base.attributes = attrs;
249
 
                }
250
 
 
251
 
                #region Properties
252
 
 
253
 
                public Expression DefaultExpression {
254
 
                        get {
255
 
                                return default_expr;
256
 
                        }
257
 
                }
258
 
 
259
 
                public DefaultParameterValueExpression DefaultValue {
260
 
                        get {
261
 
                                return default_expr as DefaultParameterValueExpression;
262
 
                        }
263
 
                        set {
264
 
                                default_expr = value;
265
 
                        }
266
 
                }
267
 
 
268
 
                Expression IParameterData.DefaultValue {
269
 
                        get {
270
 
                                var expr = default_expr as DefaultParameterValueExpression;
271
 
                                return expr == null ? default_expr : expr.Child;
272
 
                        }
273
 
                }
274
 
 
275
 
                bool HasOptionalExpression {
276
 
                        get {
277
 
                                return default_expr is DefaultParameterValueExpression;
278
 
                        }
279
 
                }
280
 
 
281
 
                public Location Location {
282
 
                        get {
283
 
                                return loc;
284
 
                        }
285
 
                }
286
 
 
287
 
                public Modifier ParameterModifier {
288
 
                        get {
289
 
                                return modFlags;
290
 
                        }
291
 
                }
292
 
 
293
 
                public TypeSpec Type {
294
 
                        get {
295
 
                                return parameter_type;
296
 
                        }
297
 
                        set {
298
 
                                parameter_type = value;
299
 
                        }
300
 
                }
301
 
 
302
 
                public FullNamedExpression TypeExpression  {
303
 
                        get {
304
 
                                return texpr;
305
 
                        }
306
 
                }
307
 
 
308
 
                public override string[] ValidAttributeTargets {
309
 
                        get {
310
 
                                return attribute_targets;
311
 
                        }
312
 
                }
313
 
 
314
 
                #endregion
315
 
 
316
 
                public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
317
 
                {
318
 
                        if (a.Type == pa.In && ModFlags == Modifier.OUT) {
319
 
                                a.Report.Error (36, a.Location, "An out parameter cannot have the `In' attribute");
320
 
                                return;
321
 
                        }
322
 
 
323
 
                        if (a.Type == pa.ParamArray) {
324
 
                                a.Report.Error (674, a.Location, "Do not use `System.ParamArrayAttribute'. Use the `params' keyword instead");
325
 
                                return;
326
 
                        }
327
 
 
328
 
                        if (a.Type == pa.Out && (ModFlags & Modifier.REF) != 0 &&
329
 
                            !OptAttributes.Contains (pa.In)) {
330
 
                                a.Report.Error (662, a.Location,
331
 
                                        "Cannot specify only `Out' attribute on a ref parameter. Use both `In' and `Out' attributes or neither");
332
 
                                return;
333
 
                        }
334
 
 
335
 
                        if (a.Type == pa.CLSCompliant) {
336
 
                                a.Report.Warning (3022, 1, a.Location, "CLSCompliant attribute has no meaning when applied to parameters. Try putting it on the method instead");
337
 
                        } else if (a.Type == pa.DefaultParameterValue || a.Type == pa.OptionalParameter) {
338
 
                                if (HasOptionalExpression) {
339
 
                                        a.Report.Error (1745, a.Location,
340
 
                                                "Cannot specify `{0}' attribute on optional parameter `{1}'",
341
 
                                                TypeManager.CSharpName (a.Type).Replace ("Attribute", ""), Name);
342
 
                                }
343
 
 
344
 
                                if (a.Type == pa.DefaultParameterValue)
345
 
                                        return;
346
 
                        } else if (a.Type == pa.CallerMemberNameAttribute) {
347
 
                                if ((modFlags & Modifier.CallerMemberName) == 0) {
348
 
                                        a.Report.Error (4022, a.Location,
349
 
                                                "The CallerMemberName attribute can only be applied to parameters with default value");
350
 
                                }
351
 
                        } else if (a.Type == pa.CallerLineNumberAttribute) {
352
 
                                if ((modFlags & Modifier.CallerLineNumber) == 0) {
353
 
                                        a.Report.Error (4020, a.Location,
354
 
                                                "The CallerLineNumber attribute can only be applied to parameters with default value");
355
 
                                }
356
 
                        } else if (a.Type == pa.CallerFilePathAttribute) {
357
 
                                if ((modFlags & Modifier.CallerFilePath) == 0) {
358
 
                                        a.Report.Error (4021, a.Location,
359
 
                                                "The CallerFilePath attribute can only be applied to parameters with default value");
360
 
                                }
361
 
                        }
362
 
 
363
 
                        base.ApplyAttributeBuilder (a, ctor, cdata, pa);
364
 
                }
365
 
                
366
 
                public virtual bool CheckAccessibility (InterfaceMemberBase member)
367
 
                {
368
 
                        if (parameter_type == null)
369
 
                                return true;
370
 
 
371
 
                        return member.IsAccessibleAs (parameter_type);
372
 
                }
373
 
 
374
 
                // <summary>
375
 
                //   Resolve is used in method definitions
376
 
                // </summary>
377
 
                public virtual TypeSpec Resolve (IMemberContext rc, int index)
378
 
                {
379
 
                        if (parameter_type != null)
380
 
                                return parameter_type;
381
 
 
382
 
                        if (attributes != null)
383
 
                                attributes.AttachTo (this, rc);
384
 
 
385
 
                        parameter_type = texpr.ResolveAsType (rc);
386
 
                        if (parameter_type == null)
387
 
                                return null;
388
 
 
389
 
                        this.idx = index;
390
 
 
391
 
                        if ((modFlags & Parameter.Modifier.RefOutMask) != 0 && parameter_type.IsSpecialRuntimeType) {
392
 
                                rc.Module.Compiler.Report.Error (1601, Location, "Method or delegate parameter cannot be of type `{0}'",
393
 
                                        GetSignatureForError ());
394
 
                                return null;
395
 
                        }
396
 
 
397
 
                        TypeManager.CheckTypeVariance (parameter_type,
398
 
                                (modFlags & Parameter.Modifier.RefOutMask) != 0 ? Variance.None : Variance.Contravariant,
399
 
                                rc);
400
 
 
401
 
                        if (parameter_type.IsStatic) {
402
 
                                rc.Module.Compiler.Report.Error (721, Location, "`{0}': static types cannot be used as parameters",
403
 
                                        texpr.GetSignatureForError ());
404
 
                                return parameter_type;
405
 
                        }
406
 
 
407
 
                        if ((modFlags & Modifier.This) != 0 && (parameter_type.IsPointer || parameter_type.BuiltinType == BuiltinTypeSpec.Type.Dynamic)) {
408
 
                                rc.Module.Compiler.Report.Error (1103, Location, "The extension method cannot be of type `{0}'",
409
 
                                        TypeManager.CSharpName (parameter_type));
410
 
                        }
411
 
 
412
 
                        return parameter_type;
413
 
                }
414
 
 
415
 
                void ResolveCallerAttributes (ResolveContext rc)
416
 
                {
417
 
                        var pa = rc.Module.PredefinedAttributes;
418
 
                        TypeSpec caller_type;
419
 
 
420
 
                        foreach (var attr in attributes.Attrs) {
421
 
                                var atype = attr.ResolveType ();
422
 
                                if (atype == null)
423
 
                                        continue;
424
 
 
425
 
                                if (atype == pa.CallerMemberNameAttribute) {
426
 
                                        caller_type = rc.BuiltinTypes.String;
427
 
                                        if (caller_type != parameter_type && !Convert.ImplicitReferenceConversionExists (caller_type, parameter_type)) {
428
 
                                                rc.Report.Error (4019, attr.Location,
429
 
                                                        "The CallerMemberName attribute cannot be applied because there is no standard conversion from `{0}' to `{1}'",
430
 
                                                        caller_type.GetSignatureForError (), parameter_type.GetSignatureForError ());
431
 
                                        }
432
 
 
433
 
                                        modFlags |= Modifier.CallerMemberName;
434
 
                                        continue;
435
 
                                }
436
 
 
437
 
                                if (atype == pa.CallerLineNumberAttribute) {
438
 
                                        caller_type = rc.BuiltinTypes.Int;
439
 
                                        if (caller_type != parameter_type && !Convert.ImplicitNumericConversionExists (caller_type, parameter_type)) {
440
 
                                                rc.Report.Error (4017, attr.Location,
441
 
                                                        "The CallerMemberName attribute cannot be applied because there is no standard conversion from `{0}' to `{1}'",
442
 
                                                        caller_type.GetSignatureForError (), parameter_type.GetSignatureForError ());
443
 
                                        }
444
 
 
445
 
                                        modFlags |= Modifier.CallerLineNumber;
446
 
                                        continue;
447
 
                                }
448
 
 
449
 
                                if (atype == pa.CallerFilePathAttribute) {
450
 
                                        caller_type = rc.BuiltinTypes.String;
451
 
                                        if (caller_type != parameter_type && !Convert.ImplicitReferenceConversionExists (caller_type, parameter_type)) {
452
 
                                                rc.Report.Error (4018, attr.Location,
453
 
                                                        "The CallerFilePath attribute cannot be applied because there is no standard conversion from `{0}' to `{1}'",
454
 
                                                        caller_type.GetSignatureForError (), parameter_type.GetSignatureForError ());
455
 
                                        }
456
 
 
457
 
                                        modFlags |= Modifier.CallerFilePath;
458
 
                                        continue;
459
 
                                }
460
 
                        }
461
 
                }
462
 
 
463
 
                public void ResolveDefaultValue (ResolveContext rc)
464
 
                {
465
 
                        //
466
 
                        // Default value was specified using an expression
467
 
                        //
468
 
                        if (default_expr != null) {
469
 
                                ((DefaultParameterValueExpression)default_expr).Resolve (rc, this);
470
 
                                if (attributes != null)
471
 
                                        ResolveCallerAttributes (rc);
472
 
 
473
 
                                return;
474
 
                        }
475
 
 
476
 
                        if (attributes == null)
477
 
                                return;
478
 
 
479
 
                        var pa = rc.Module.PredefinedAttributes;
480
 
                        var def_attr = attributes.Search (pa.DefaultParameterValue);
481
 
                        if (def_attr != null) {
482
 
                                if (def_attr.Resolve () == null)
483
 
                                        return;
484
 
 
485
 
                                var default_expr_attr = def_attr.GetParameterDefaultValue ();
486
 
                                if (default_expr_attr == null)
487
 
                                        return;
488
 
 
489
 
                                var dpa_rc = def_attr.CreateResolveContext ();
490
 
                                default_expr = default_expr_attr.Resolve (dpa_rc);
491
 
 
492
 
                                if (default_expr is BoxedCast)
493
 
                                        default_expr = ((BoxedCast) default_expr).Child;
494
 
 
495
 
                                Constant c = default_expr as Constant;
496
 
                                if (c == null) {
497
 
                                        if (parameter_type.BuiltinType == BuiltinTypeSpec.Type.Object) {
498
 
                                                rc.Report.Error (1910, default_expr.Location,
499
 
                                                        "Argument of type `{0}' is not applicable for the DefaultParameterValue attribute",
500
 
                                                        default_expr.Type.GetSignatureForError ());
501
 
                                        } else {
502
 
                                                rc.Report.Error (1909, default_expr.Location,
503
 
                                                        "The DefaultParameterValue attribute is not applicable on parameters of type `{0}'",
504
 
                                                        default_expr.Type.GetSignatureForError ()); ;
505
 
                                        }
506
 
 
507
 
                                        default_expr = null;
508
 
                                        return;
509
 
                                }
510
 
 
511
 
                                if (TypeSpecComparer.IsEqual (default_expr.Type, parameter_type) ||
512
 
                                        (default_expr is NullConstant && TypeSpec.IsReferenceType (parameter_type) && !parameter_type.IsGenericParameter) ||
513
 
                                        parameter_type.BuiltinType == BuiltinTypeSpec.Type.Object) {
514
 
                                        return;
515
 
                                }
516
 
 
517
 
                                //
518
 
                                // LAMESPEC: Some really weird csc behaviour which we have to mimic
519
 
                                // User operators returning same type as parameter type are considered
520
 
                                // valid for this attribute only
521
 
                                //
522
 
                                // struct S { public static implicit operator S (int i) {} }
523
 
                                //
524
 
                                // void M ([DefaultParameterValue (3)]S s)
525
 
                                //
526
 
                                var expr = Convert.ImplicitUserConversion (dpa_rc, default_expr, parameter_type, loc);
527
 
                                if (expr != null && TypeSpecComparer.IsEqual (expr.Type, parameter_type)) {
528
 
                                        return;
529
 
                                }
530
 
                                
531
 
                                rc.Report.Error (1908, default_expr.Location, "The type of the default value should match the type of the parameter");
532
 
                                return;
533
 
                        }
534
 
 
535
 
                        var opt_attr = attributes.Search (pa.OptionalParameter);
536
 
                        if (opt_attr != null) {
537
 
                                default_expr = EmptyExpression.MissingValue;
538
 
                        }
539
 
                }
540
 
 
541
 
                public bool HasDefaultValue {
542
 
                        get { return default_expr != null; }
543
 
                }
544
 
 
545
 
                public bool HasExtensionMethodModifier {
546
 
                        get { return (modFlags & Modifier.This) != 0; }
547
 
                }
548
 
 
549
 
                //
550
 
                // Hoisted parameter variant
551
 
                //
552
 
                public HoistedParameter HoistedVariant {
553
 
                        get {
554
 
                                return hoisted_variant;
555
 
                        }
556
 
                        set {
557
 
                                hoisted_variant = value;
558
 
                        }
559
 
                }
560
 
 
561
 
                public Modifier ModFlags {
562
 
                        get { return modFlags & ~Modifier.This; }
563
 
                }
564
 
 
565
 
                public string Name {
566
 
                        get { return name; }
567
 
                        set { name = value; }
568
 
                }
569
 
 
570
 
                public override AttributeTargets AttributeTargets {
571
 
                        get {
572
 
                                return AttributeTargets.Parameter;
573
 
                        }
574
 
                }
575
 
 
576
 
                public void Error_DuplicateName (Report r)
577
 
                {
578
 
                        r.Error (100, Location, "The parameter name `{0}' is a duplicate", Name);
579
 
                }
580
 
 
581
 
                public virtual string GetSignatureForError ()
582
 
                {
583
 
                        string type_name;
584
 
                        if (parameter_type != null)
585
 
                                type_name = TypeManager.CSharpName (parameter_type);
586
 
                        else
587
 
                                type_name = texpr.GetSignatureForError ();
588
 
 
589
 
                        string mod = GetModifierSignature (modFlags);
590
 
                        if (mod.Length > 0)
591
 
                                return String.Concat (mod, " ", type_name);
592
 
 
593
 
                        return type_name;
594
 
                }
595
 
 
596
 
                public static string GetModifierSignature (Modifier mod)
597
 
                {
598
 
                        switch (mod) {
599
 
                        case Modifier.OUT:
600
 
                                return "out";
601
 
                        case Modifier.PARAMS:
602
 
                                return "params";
603
 
                        case Modifier.REF:
604
 
                                return "ref";
605
 
                        case Modifier.This:
606
 
                                return "this";
607
 
                        default:
608
 
                                return "";
609
 
                        }
610
 
                }
611
 
 
612
 
                public void IsClsCompliant (IMemberContext ctx)
613
 
                {
614
 
                        if (parameter_type.IsCLSCompliant ())
615
 
                                return;
616
 
 
617
 
                        ctx.Module.Compiler.Report.Warning (3001, 1, Location,
618
 
                                "Argument type `{0}' is not CLS-compliant", parameter_type.GetSignatureForError ());
619
 
                }
620
 
 
621
 
                public virtual void ApplyAttributes (MethodBuilder mb, ConstructorBuilder cb, int index, PredefinedAttributes pa)
622
 
                {
623
 
                        if (builder != null)
624
 
                                throw new InternalErrorException ("builder already exists");
625
 
 
626
 
                        var pattrs = ParametersCompiled.GetParameterAttribute (modFlags);
627
 
                        if (HasOptionalExpression)
628
 
                                pattrs |= ParameterAttributes.Optional;
629
 
 
630
 
                        if (mb == null)
631
 
                                builder = cb.DefineParameter (index, pattrs, Name);
632
 
                        else
633
 
                                builder = mb.DefineParameter (index, pattrs, Name);
634
 
 
635
 
                        if (OptAttributes != null)
636
 
                                OptAttributes.Emit ();
637
 
 
638
 
                        if (HasDefaultValue) {
639
 
                                //
640
 
                                // Emit constant values for true constants only, the other
641
 
                                // constant-like expressions will rely on default value expression
642
 
                                //
643
 
                                var def_value = DefaultValue;
644
 
                                Constant c = def_value != null ? def_value.Child as Constant : default_expr as Constant;
645
 
                                if (c != null) {
646
 
                                        if (c.Type.BuiltinType == BuiltinTypeSpec.Type.Decimal) {
647
 
                                                pa.DecimalConstant.EmitAttribute (builder, (decimal) c.GetValue (), c.Location);
648
 
                                        } else {
649
 
                                                builder.SetConstant (c.GetValue ());
650
 
                                        }
651
 
                                } else if (default_expr.Type.IsStruct) {
652
 
                                        //
653
 
                                        // Handles special case where default expression is used with value-type
654
 
                                        //
655
 
                                        // void Foo (S s = default (S)) {}
656
 
                                        //
657
 
                                        builder.SetConstant (null);
658
 
                                }
659
 
                        }
660
 
 
661
 
                        if (parameter_type != null) {
662
 
                                if (parameter_type.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
663
 
                                        pa.Dynamic.EmitAttribute (builder);
664
 
                                } else if (parameter_type.HasDynamicElement) {
665
 
                                        pa.Dynamic.EmitAttribute (builder, parameter_type, Location);
666
 
                                }
667
 
                        }
668
 
                }
669
 
 
670
 
                public Parameter Clone ()
671
 
                {
672
 
                        Parameter p = (Parameter) MemberwiseClone ();
673
 
                        if (attributes != null)
674
 
                                p.attributes = attributes.Clone ();
675
 
 
676
 
                        return p;
677
 
                }
678
 
 
679
 
                public ExpressionStatement CreateExpressionTreeVariable (BlockContext ec)
680
 
                {
681
 
                        if ((modFlags & Modifier.RefOutMask) != 0)
682
 
                                ec.Report.Error (1951, Location, "An expression tree parameter cannot use `ref' or `out' modifier");
683
 
 
684
 
                        expr_tree_variable = TemporaryVariableReference.Create (ResolveParameterExpressionType (ec, Location).Type, ec.CurrentBlock.ParametersBlock, Location);
685
 
                        expr_tree_variable = (TemporaryVariableReference) expr_tree_variable.Resolve (ec);
686
 
 
687
 
                        Arguments arguments = new Arguments (2);
688
 
                        arguments.Add (new Argument (new TypeOf (parameter_type, Location)));
689
 
                        arguments.Add (new Argument (new StringConstant (ec.BuiltinTypes, Name, Location)));
690
 
                        return new SimpleAssign (ExpressionTreeVariableReference (),
691
 
                                Expression.CreateExpressionFactoryCall (ec, "Parameter", null, arguments, Location));
692
 
                }
693
 
 
694
 
                public void Emit (EmitContext ec)
695
 
                {
696
 
                        ec.EmitArgumentLoad (idx);
697
 
                }
698
 
 
699
 
                public void EmitAssign (EmitContext ec)
700
 
                {
701
 
                        ec.EmitArgumentStore (idx);
702
 
                }
703
 
 
704
 
                public void EmitAddressOf (EmitContext ec)
705
 
                {
706
 
                        if ((ModFlags & Modifier.RefOutMask) != 0) {
707
 
                                ec.EmitArgumentLoad (idx);
708
 
                        } else {
709
 
                                ec.EmitArgumentAddress (idx);
710
 
                        }
711
 
                }
712
 
 
713
 
                public TemporaryVariableReference ExpressionTreeVariableReference ()
714
 
                {
715
 
                        return expr_tree_variable;
716
 
                }
717
 
 
718
 
                //
719
 
                // System.Linq.Expressions.ParameterExpression type
720
 
                //
721
 
                public static TypeExpr ResolveParameterExpressionType (IMemberContext ec, Location location)
722
 
                {
723
 
                        TypeSpec p_type = ec.Module.PredefinedTypes.ParameterExpression.Resolve ();
724
 
                        return new TypeExpression (p_type, location);
725
 
                }
726
 
 
727
 
                public void Warning_UselessOptionalParameter (Report Report)
728
 
                {
729
 
                        Report.Warning (1066, 1, Location,
730
 
                                "The default value specified for optional parameter `{0}' will never be used",
731
 
                                Name);
732
 
                }
733
 
        }
734
 
 
735
 
        //
736
 
        // Imported or resolved parameter information
737
 
        //
738
 
        public class ParameterData : IParameterData
739
 
        {
740
 
                readonly string name;
741
 
                readonly Parameter.Modifier modifiers;
742
 
                readonly Expression default_value;
743
 
 
744
 
                public ParameterData (string name, Parameter.Modifier modifiers)
745
 
                {
746
 
                        this.name = name;
747
 
                        this.modifiers = modifiers;
748
 
                }
749
 
 
750
 
                public ParameterData (string name, Parameter.Modifier modifiers, Expression defaultValue)
751
 
                        : this (name, modifiers)
752
 
                {
753
 
                        this.default_value = defaultValue;
754
 
                }
755
 
 
756
 
                #region IParameterData Members
757
 
 
758
 
                public Expression DefaultValue {
759
 
                        get { return default_value; }
760
 
                }
761
 
 
762
 
                public bool HasExtensionMethodModifier {
763
 
                        get { return (modifiers & Parameter.Modifier.This) != 0; }
764
 
                }
765
 
 
766
 
                public bool HasDefaultValue {
767
 
                        get { return default_value != null; }
768
 
                }
769
 
 
770
 
                public Parameter.Modifier ModFlags {
771
 
                        get { return modifiers; }
772
 
                }
773
 
 
774
 
                public string Name {
775
 
                        get { return name; }
776
 
                }
777
 
 
778
 
                #endregion
779
 
        }
780
 
 
781
 
        public abstract class AParametersCollection
782
 
        {
783
 
                protected bool has_arglist;
784
 
                protected bool has_params;
785
 
 
786
 
                // Null object pattern
787
 
                protected IParameterData [] parameters;
788
 
                protected TypeSpec [] types;
789
 
 
790
 
                public CallingConventions CallingConvention {
791
 
                        get {
792
 
                                return has_arglist ?
793
 
                                        CallingConventions.VarArgs :
794
 
                                        CallingConventions.Standard;
795
 
                        }
796
 
                }
797
 
 
798
 
                public int Count {
799
 
                        get { return parameters.Length; }
800
 
                }
801
 
 
802
 
                public TypeSpec ExtensionMethodType {
803
 
                        get {
804
 
                                if (Count == 0)
805
 
                                        return null;
806
 
 
807
 
                                return FixedParameters [0].HasExtensionMethodModifier ?
808
 
                                        types [0] : null;
809
 
                        }
810
 
                }
811
 
 
812
 
                public IParameterData [] FixedParameters {
813
 
                        get {
814
 
                                return parameters;
815
 
                        }
816
 
                }
817
 
 
818
 
                public static ParameterAttributes GetParameterAttribute (Parameter.Modifier modFlags)
819
 
                {
820
 
                        return (modFlags & Parameter.Modifier.OUT) != 0 ?
821
 
                                ParameterAttributes.Out : ParameterAttributes.None;
822
 
                }
823
 
 
824
 
                // Very expensive operation
825
 
                public MetaType[] GetMetaInfo ()
826
 
                {
827
 
                        MetaType[] types;
828
 
                        if (has_arglist) {
829
 
                                if (Count == 1)
830
 
                                        return MetaType.EmptyTypes;
831
 
 
832
 
                                types = new MetaType[Count - 1];
833
 
                        } else {
834
 
                                if (Count == 0)
835
 
                                        return MetaType.EmptyTypes;
836
 
 
837
 
                                types = new MetaType[Count];
838
 
                        }
839
 
 
840
 
                        for (int i = 0; i < types.Length; ++i) {
841
 
                                types[i] = Types[i].GetMetaInfo ();
842
 
 
843
 
                                if ((FixedParameters[i].ModFlags & Parameter.Modifier.RefOutMask) == 0)
844
 
                                        continue;
845
 
 
846
 
                                // TODO MemberCache: Should go to MetaInfo getter
847
 
                                types [i] = types [i].MakeByRefType ();
848
 
                        }
849
 
 
850
 
                        return types;
851
 
                }
852
 
 
853
 
                //
854
 
                // Returns the parameter information based on the name
855
 
                //
856
 
                public int GetParameterIndexByName (string name)
857
 
                {
858
 
                        for (int idx = 0; idx < Count; ++idx) {
859
 
                                if (parameters [idx].Name == name)
860
 
                                        return idx;
861
 
                        }
862
 
 
863
 
                        return -1;
864
 
                }
865
 
 
866
 
                public string GetSignatureForDocumentation ()
867
 
                {
868
 
                        if (IsEmpty)
869
 
                                return string.Empty;
870
 
 
871
 
                        StringBuilder sb = new StringBuilder ("(");
872
 
                        for (int i = 0; i < Count; ++i) {
873
 
                                if (i != 0)
874
 
                                        sb.Append (",");
875
 
 
876
 
                                sb.Append (types [i].GetSignatureForDocumentation ());
877
 
 
878
 
                                if ((parameters[i].ModFlags & Parameter.Modifier.RefOutMask) != 0)
879
 
                                        sb.Append ("@");
880
 
                        }
881
 
                        sb.Append (")");
882
 
 
883
 
                        return sb.ToString ();
884
 
                }
885
 
 
886
 
                public string GetSignatureForError ()
887
 
                {
888
 
                        return GetSignatureForError ("(", ")", Count);
889
 
                }
890
 
 
891
 
                public string GetSignatureForError (string start, string end, int count)
892
 
                {
893
 
                        StringBuilder sb = new StringBuilder (start);
894
 
                        for (int i = 0; i < count; ++i) {
895
 
                                if (i != 0)
896
 
                                        sb.Append (", ");
897
 
                                sb.Append (ParameterDesc (i));
898
 
                        }
899
 
                        sb.Append (end);
900
 
                        return sb.ToString ();
901
 
                }
902
 
 
903
 
                public bool HasArglist {
904
 
                        get { return has_arglist; }
905
 
                }
906
 
 
907
 
                public bool HasExtensionMethodType {
908
 
                        get {
909
 
                                if (Count == 0)
910
 
                                        return false;
911
 
 
912
 
                                return FixedParameters [0].HasExtensionMethodModifier;
913
 
                        }
914
 
                }
915
 
 
916
 
                public bool HasParams {
917
 
                        get { return has_params; }
918
 
                }
919
 
 
920
 
                public bool IsEmpty {
921
 
                        get { return parameters.Length == 0; }
922
 
                }
923
 
 
924
 
                public AParametersCollection Inflate (TypeParameterInflator inflator)
925
 
                {
926
 
                        TypeSpec[] inflated_types = null;
927
 
                        bool default_value = false;
928
 
 
929
 
                        for (int i = 0; i < Count; ++i) {
930
 
                                var inflated_param = inflator.Inflate (types[i]);
931
 
                                if (inflated_types == null) {
932
 
                                        if (inflated_param == types[i])
933
 
                                                continue;
934
 
 
935
 
                                        default_value |= FixedParameters[i] is DefaultValueExpression;
936
 
                                        inflated_types = new TypeSpec[types.Length];
937
 
                                        Array.Copy (types, inflated_types, types.Length);       
938
 
                                }
939
 
 
940
 
                                inflated_types[i] = inflated_param;
941
 
                        }
942
 
 
943
 
                        if (inflated_types == null)
944
 
                                return this;
945
 
 
946
 
                        var clone = (AParametersCollection) MemberwiseClone ();
947
 
                        clone.types = inflated_types;
948
 
                        if (default_value) {
949
 
                                for (int i = 0; i < Count; ++i) {
950
 
                                        var dve = clone.FixedParameters[i] as DefaultValueExpression;
951
 
                                        if (dve != null) {
952
 
                                                throw new NotImplementedException ("net");
953
 
                                                //      clone.FixedParameters [i].DefaultValue = new DefaultValueExpression ();
954
 
                                        }
955
 
                                }
956
 
                        }
957
 
 
958
 
                        return clone;
959
 
                }
960
 
 
961
 
                public string ParameterDesc (int pos)
962
 
                {
963
 
                        if (types == null || types [pos] == null)
964
 
                                return ((Parameter)FixedParameters [pos]).GetSignatureForError ();
965
 
 
966
 
                        string type = TypeManager.CSharpName (types [pos]);
967
 
                        if (FixedParameters [pos].HasExtensionMethodModifier)
968
 
                                return "this " + type;
969
 
 
970
 
                        Parameter.Modifier mod = FixedParameters [pos].ModFlags;
971
 
                        if (mod == 0)
972
 
                                return type;
973
 
 
974
 
                        return Parameter.GetModifierSignature (mod) + " " + type;
975
 
                }
976
 
 
977
 
                public TypeSpec[] Types {
978
 
                        get { return types; }
979
 
                        set { types = value; }
980
 
                }
981
 
        }
982
 
 
983
 
        //
984
 
        // A collection of imported or resolved parameters
985
 
        //
986
 
        public class ParametersImported : AParametersCollection
987
 
        {
988
 
                public ParametersImported (IParameterData [] parameters, TypeSpec [] types, bool hasArglist, bool hasParams)
989
 
                {
990
 
                        this.parameters = parameters;
991
 
                        this.types = types;
992
 
                        this.has_arglist = hasArglist;
993
 
                        this.has_params = hasParams;
994
 
                }
995
 
 
996
 
                public ParametersImported (IParameterData[] param, TypeSpec[] types, bool hasParams)
997
 
                {
998
 
                        this.parameters = param;
999
 
                        this.types = types;
1000
 
                        this.has_params = hasParams;
1001
 
                }
1002
 
        }
1003
 
 
1004
 
        /// <summary>
1005
 
        ///   Represents the methods parameters
1006
 
        /// </summary>
1007
 
        public class ParametersCompiled : AParametersCollection
1008
 
        {
1009
 
                public static readonly ParametersCompiled EmptyReadOnlyParameters = new ParametersCompiled ();
1010
 
                
1011
 
                // Used by C# 2.0 delegates
1012
 
                public static readonly ParametersCompiled Undefined = new ParametersCompiled ();
1013
 
 
1014
 
                private ParametersCompiled ()
1015
 
                {
1016
 
                        parameters = new Parameter [0];
1017
 
                        types = TypeSpec.EmptyTypes;
1018
 
                }
1019
 
 
1020
 
                private ParametersCompiled (IParameterData[] parameters, TypeSpec[] types)
1021
 
                {
1022
 
                        this.parameters = parameters;
1023
 
                    this.types = types;
1024
 
                }
1025
 
                
1026
 
                public ParametersCompiled (params Parameter[] parameters)
1027
 
                {
1028
 
                        if (parameters == null || parameters.Length == 0)
1029
 
                                throw new ArgumentException ("Use EmptyReadOnlyParameters");
1030
 
 
1031
 
                        this.parameters = parameters;
1032
 
                        int count = parameters.Length;
1033
 
 
1034
 
                        for (int i = 0; i < count; i++){
1035
 
                                has_params |= (parameters [i].ModFlags & Parameter.Modifier.PARAMS) != 0;
1036
 
                        }
1037
 
                }
1038
 
 
1039
 
                public ParametersCompiled (Parameter [] parameters, bool has_arglist) :
1040
 
                        this (parameters)
1041
 
                {
1042
 
                        this.has_arglist = has_arglist;
1043
 
                }
1044
 
                
1045
 
                public static ParametersCompiled CreateFullyResolved (Parameter p, TypeSpec type)
1046
 
                {
1047
 
                        return new ParametersCompiled (new Parameter [] { p }, new TypeSpec [] { type });
1048
 
                }
1049
 
                
1050
 
                public static ParametersCompiled CreateFullyResolved (Parameter[] parameters, TypeSpec[] types)
1051
 
                {
1052
 
                        return new ParametersCompiled (parameters, types);
1053
 
                }
1054
 
 
1055
 
                //
1056
 
                // TODO: This does not fit here, it should go to different version of AParametersCollection
1057
 
                // as the underlying type is not Parameter and some methods will fail to cast
1058
 
                //
1059
 
                public static AParametersCollection CreateFullyResolved (params TypeSpec[] types)
1060
 
                {
1061
 
                        var pd = new ParameterData [types.Length];
1062
 
                        for (int i = 0; i < pd.Length; ++i)
1063
 
                                pd[i] = new ParameterData (null, Parameter.Modifier.NONE, null);
1064
 
 
1065
 
                        return new ParametersCompiled (pd, types);
1066
 
                }
1067
 
 
1068
 
                public static ParametersCompiled CreateImplicitParameter (FullNamedExpression texpr, Location loc)
1069
 
                {
1070
 
                        return new ParametersCompiled (
1071
 
                                new[] { new Parameter (texpr, "value", Parameter.Modifier.NONE, null, loc) },
1072
 
                                null);
1073
 
                }
1074
 
 
1075
 
                public void CheckConstraints (IMemberContext mc)
1076
 
                {
1077
 
                        foreach (Parameter p in parameters) {
1078
 
                                //
1079
 
                                // It's null for compiler generated types or special types like __arglist
1080
 
                                //
1081
 
                                if (p.TypeExpression != null)
1082
 
                                        ConstraintChecker.Check (mc, p.Type, p.TypeExpression.Location);
1083
 
                        }
1084
 
                }
1085
 
 
1086
 
                //
1087
 
                // Returns non-zero value for equal CLS parameter signatures
1088
 
                //
1089
 
                public static int IsSameClsSignature (AParametersCollection a, AParametersCollection b)
1090
 
                {
1091
 
                        int res = 0;
1092
 
 
1093
 
                        for (int i = 0; i < a.Count; ++i) {
1094
 
                                var a_type = a.Types[i];
1095
 
                                var b_type = b.Types[i];
1096
 
                                if (TypeSpecComparer.Override.IsEqual (a_type, b_type)) {
1097
 
                                        if ((a.FixedParameters[i].ModFlags & Parameter.Modifier.RefOutMask) != (b.FixedParameters[i].ModFlags & Parameter.Modifier.RefOutMask))
1098
 
                                                res |= 1;
1099
 
 
1100
 
                                        continue;
1101
 
                                }
1102
 
 
1103
 
                                var ac_a = a_type as ArrayContainer;
1104
 
                                if (ac_a == null)
1105
 
                                        return 0;
1106
 
 
1107
 
                                var ac_b = b_type as ArrayContainer;
1108
 
                                if (ac_b == null)
1109
 
                                        return 0;
1110
 
 
1111
 
                                if (ac_a.Element is ArrayContainer || ac_b.Element is ArrayContainer) {
1112
 
                                        res |= 2;
1113
 
                                        continue;
1114
 
                                }
1115
 
 
1116
 
                                if (ac_a.Rank != ac_b.Rank && TypeSpecComparer.Override.IsEqual (ac_a.Element, ac_b.Element)) {
1117
 
                                        res |= 1;
1118
 
                                        continue;
1119
 
                                }
1120
 
 
1121
 
                                return 0;
1122
 
                        }
1123
 
 
1124
 
                        return res;
1125
 
                }
1126
 
 
1127
 
                public static ParametersCompiled MergeGenerated (CompilerContext ctx, ParametersCompiled userParams, bool checkConflicts, Parameter compilerParams, TypeSpec compilerTypes)
1128
 
                {
1129
 
                        return MergeGenerated (ctx, userParams, checkConflicts,
1130
 
                                new Parameter [] { compilerParams },
1131
 
                                new TypeSpec [] { compilerTypes });
1132
 
                }
1133
 
 
1134
 
                //
1135
 
                // Use this method when you merge compiler generated parameters with user parameters
1136
 
                //
1137
 
                public static ParametersCompiled MergeGenerated (CompilerContext ctx, ParametersCompiled userParams, bool checkConflicts, Parameter[] compilerParams, TypeSpec[] compilerTypes)
1138
 
                {
1139
 
                        Parameter[] all_params = new Parameter [userParams.Count + compilerParams.Length];
1140
 
                        userParams.FixedParameters.CopyTo(all_params, 0);
1141
 
 
1142
 
                        TypeSpec [] all_types;
1143
 
                        if (userParams.types != null) {
1144
 
                                all_types = new TypeSpec [all_params.Length];
1145
 
                                userParams.Types.CopyTo (all_types, 0);
1146
 
                        } else {
1147
 
                                all_types = null;
1148
 
                        }
1149
 
 
1150
 
                        int last_filled = userParams.Count;
1151
 
                        int index = 0;
1152
 
                        foreach (Parameter p in compilerParams) {
1153
 
                                for (int i = 0; i < last_filled; ++i) {
1154
 
                                        while (p.Name == all_params [i].Name) {
1155
 
                                                if (checkConflicts && i < userParams.Count) {
1156
 
                                                        ctx.Report.Error (316, userParams[i].Location,
1157
 
                                                                "The parameter name `{0}' conflicts with a compiler generated name", p.Name);
1158
 
                                                }
1159
 
                                                p.Name = '_' + p.Name;
1160
 
                                        }
1161
 
                                }
1162
 
                                all_params [last_filled] = p;
1163
 
                                if (all_types != null)
1164
 
                                        all_types [last_filled] = compilerTypes [index++];
1165
 
                                ++last_filled;
1166
 
                        }
1167
 
                        
1168
 
                        ParametersCompiled parameters = new ParametersCompiled (all_params, all_types);
1169
 
                        parameters.has_params = userParams.has_params;
1170
 
                        return parameters;
1171
 
                }
1172
 
 
1173
 
                //
1174
 
                // Parameters checks for members which don't have a block
1175
 
                //
1176
 
                public void CheckParameters (MemberCore member)
1177
 
                {
1178
 
                        for (int i = 0; i < parameters.Length; ++i) {
1179
 
                                var name = parameters[i].Name;
1180
 
                                for (int ii = i + 1; ii < parameters.Length; ++ii) {
1181
 
                                        if (parameters[ii].Name == name)
1182
 
                                                this[ii].Error_DuplicateName (member.Compiler.Report);
1183
 
                                }
1184
 
                        }
1185
 
                }
1186
 
 
1187
 
                public bool Resolve (IMemberContext ec)
1188
 
                {
1189
 
                        if (types != null)
1190
 
                                return true;
1191
 
                        
1192
 
                        types = new TypeSpec [Count];
1193
 
                        
1194
 
                        bool ok = true;
1195
 
                        Parameter p;
1196
 
                        for (int i = 0; i < FixedParameters.Length; ++i) {
1197
 
                                p = this [i];
1198
 
                                TypeSpec t = p.Resolve (ec, i);
1199
 
                                if (t == null) {
1200
 
                                        ok = false;
1201
 
                                        continue;
1202
 
                                }
1203
 
 
1204
 
                                types [i] = t;
1205
 
                        }
1206
 
 
1207
 
                        return ok;
1208
 
                }
1209
 
 
1210
 
                public void ResolveDefaultValues (MemberCore m)
1211
 
                {
1212
 
                        ResolveContext rc = null;
1213
 
                        for (int i = 0; i < parameters.Length; ++i) {
1214
 
                                Parameter p = (Parameter) parameters [i];
1215
 
 
1216
 
                                //
1217
 
                                // Try not to enter default values resolution if there are is not any default value possible
1218
 
                                //
1219
 
                                if (p.HasDefaultValue || p.OptAttributes != null) {
1220
 
                                        if (rc == null)
1221
 
                                                rc = new ResolveContext (m);
1222
 
 
1223
 
                                        p.ResolveDefaultValue (rc);
1224
 
                                }
1225
 
                        }
1226
 
                }
1227
 
 
1228
 
                // Define each type attribute (in/out/ref) and
1229
 
                // the argument names.
1230
 
                public void ApplyAttributes (IMemberContext mc, MethodBase builder)
1231
 
                {
1232
 
                        if (Count == 0)
1233
 
                                return;
1234
 
 
1235
 
                        MethodBuilder mb = builder as MethodBuilder;
1236
 
                        ConstructorBuilder cb = builder as ConstructorBuilder;
1237
 
                        var pa = mc.Module.PredefinedAttributes;
1238
 
 
1239
 
                        for (int i = 0; i < Count; i++) {
1240
 
                                this [i].ApplyAttributes (mb, cb, i + 1, pa);
1241
 
                        }
1242
 
                }
1243
 
 
1244
 
                public void VerifyClsCompliance (IMemberContext ctx)
1245
 
                {
1246
 
                        foreach (Parameter p in FixedParameters)
1247
 
                                p.IsClsCompliant (ctx);
1248
 
                }
1249
 
 
1250
 
                public Parameter this [int pos] {
1251
 
                        get { return (Parameter) parameters [pos]; }
1252
 
                }
1253
 
 
1254
 
                public Expression CreateExpressionTree (BlockContext ec, Location loc)
1255
 
                {
1256
 
                        var initializers = new ArrayInitializer (Count, loc);
1257
 
                        foreach (Parameter p in FixedParameters) {
1258
 
                                //
1259
 
                                // Each parameter expression is stored to local variable
1260
 
                                // to save some memory when referenced later.
1261
 
                                //
1262
 
                                StatementExpression se = new StatementExpression (p.CreateExpressionTreeVariable (ec), Location.Null);
1263
 
                                if (se.Resolve (ec)) {
1264
 
                                        ec.CurrentBlock.AddScopeStatement (new TemporaryVariableReference.Declarator (p.ExpressionTreeVariableReference ()));
1265
 
                                        ec.CurrentBlock.AddScopeStatement (se);
1266
 
                                }
1267
 
                                
1268
 
                                initializers.Add (p.ExpressionTreeVariableReference ());
1269
 
                        }
1270
 
 
1271
 
                        return new ArrayCreation (
1272
 
                                Parameter.ResolveParameterExpressionType (ec, loc),
1273
 
                                initializers, loc);
1274
 
                }
1275
 
 
1276
 
                public ParametersCompiled Clone ()
1277
 
                {
1278
 
                        ParametersCompiled p = (ParametersCompiled) MemberwiseClone ();
1279
 
 
1280
 
                        p.parameters = new IParameterData [parameters.Length];
1281
 
                        for (int i = 0; i < Count; ++i)
1282
 
                                p.parameters [i] = this [i].Clone ();
1283
 
 
1284
 
                        return p;
1285
 
                }
1286
 
        }
1287
 
 
1288
 
        //
1289
 
        // Default parameter value expression. We need this wrapper to handle
1290
 
        // default parameter values of folded constants (e.g. indexer parameters).
1291
 
        // The expression is resolved only once but applied to two methods which
1292
 
        // both share reference to this expression and we ensure that resolving
1293
 
        // this expression always returns same instance
1294
 
        //
1295
 
        public class DefaultParameterValueExpression : CompositeExpression
1296
 
        {
1297
 
                public DefaultParameterValueExpression (Expression expr)
1298
 
                        : base (expr)
1299
 
                {
1300
 
                }
1301
 
 
1302
 
                protected override Expression DoResolve (ResolveContext rc)
1303
 
                {
1304
 
                        return base.DoResolve (rc);
1305
 
                }
1306
 
 
1307
 
                public void Resolve (ResolveContext rc, Parameter p)
1308
 
                {
1309
 
                        var expr = Resolve (rc);
1310
 
                        if (expr == null)
1311
 
                                return;
1312
 
 
1313
 
                        expr = Child;
1314
 
 
1315
 
                        if (!(expr is Constant || expr is DefaultValueExpression || (expr is New && ((New) expr).IsDefaultStruct))) {
1316
 
                                rc.Report.Error (1736, Location,
1317
 
                                        "The expression being assigned to optional parameter `{0}' must be a constant or default value",
1318
 
                                        p.Name);
1319
 
 
1320
 
                                return;
1321
 
                        }
1322
 
 
1323
 
                        var parameter_type = p.Type;
1324
 
                        if (type == parameter_type)
1325
 
                                return;
1326
 
 
1327
 
                        var res = Convert.ImplicitConversionStandard (rc, expr, parameter_type, Location);
1328
 
                        if (res != null) {
1329
 
                                if (parameter_type.IsNullableType && res is Nullable.Wrap) {
1330
 
                                        Nullable.Wrap wrap = (Nullable.Wrap) res;
1331
 
                                        res = wrap.Child;
1332
 
                                        if (!(res is Constant)) {
1333
 
                                                rc.Report.Error (1770, Location,
1334
 
                                                        "The expression being assigned to nullable optional parameter `{0}' must be default value",
1335
 
                                                        p.Name);
1336
 
                                                return;
1337
 
                                        }
1338
 
                                }
1339
 
 
1340
 
                                if (!expr.IsNull && TypeSpec.IsReferenceType (parameter_type) && parameter_type.BuiltinType != BuiltinTypeSpec.Type.String) {
1341
 
                                        rc.Report.Error (1763, Location,
1342
 
                                                "Optional parameter `{0}' of type `{1}' can only be initialized with `null'",
1343
 
                                                p.Name, parameter_type.GetSignatureForError ());
1344
 
 
1345
 
                                        return;
1346
 
                                }
1347
 
 
1348
 
                                this.expr = res;
1349
 
                                return;
1350
 
                        }
1351
 
 
1352
 
                        rc.Report.Error (1750, Location,
1353
 
                                "Optional parameter expression of type `{0}' cannot be converted to parameter type `{1}'",
1354
 
                                type.GetSignatureForError (), parameter_type.GetSignatureForError ());
1355
 
                }
1356
 
                
1357
 
                public override object Accept (StructuralVisitor visitor)
1358
 
                {
1359
 
                        return visitor.Visit (this);
1360
 
                }
1361
 
        }
1362
 
}