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

« back to all changes in this revision

Viewing changes to contrib/ICSharpCode.NRefactory.CSharp/Parser/mcs/method.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
 
// method.cs: Method based declarations
3
 
//
4
 
// Authors: Miguel de Icaza (miguel@gnu.org)
5
 
//          Martin Baulig (martin@ximian.com)
6
 
//          Marek Safar (marek.safar@gmail.com)
7
 
//
8
 
// Dual licensed under the terms of the MIT X11 or GNU GPL
9
 
//
10
 
// Copyright 2001, 2002, 2003 Ximian, Inc (http://www.ximian.com)
11
 
// Copyright 2004-2008 Novell, Inc
12
 
// Copyright 2011 Xamarin Inc.
13
 
//
14
 
 
15
 
using System;
16
 
using System.Collections.Generic;
17
 
using System.Security;
18
 
using System.Security.Permissions;
19
 
using System.Text;
20
 
using System.Linq;
21
 
using Mono.CompilerServices.SymbolWriter;
22
 
using System.Runtime.CompilerServices;
23
 
 
24
 
#if NET_2_1
25
 
using XmlElement = System.Object;
26
 
#else
27
 
using System.Xml;
28
 
#endif
29
 
 
30
 
#if STATIC
31
 
using MetaType = IKVM.Reflection.Type;
32
 
using SecurityType = System.Collections.Generic.List<IKVM.Reflection.Emit.CustomAttributeBuilder>;
33
 
using IKVM.Reflection;
34
 
using IKVM.Reflection.Emit;
35
 
#else
36
 
using MetaType = System.Type;
37
 
using SecurityType = System.Collections.Generic.Dictionary<System.Security.Permissions.SecurityAction, System.Security.PermissionSet>;
38
 
using System.Reflection;
39
 
using System.Reflection.Emit;
40
 
#endif
41
 
 
42
 
namespace Mono.CSharp {
43
 
 
44
 
        public abstract class MethodCore : InterfaceMemberBase, IParametersMember
45
 
        {
46
 
                protected ParametersCompiled parameters;
47
 
                protected ToplevelBlock block;
48
 
                protected MethodSpec spec;
49
 
 
50
 
                public MethodCore (TypeDefinition parent, FullNamedExpression type, Modifiers mod, Modifiers allowed_mod,
51
 
                        MemberName name, Attributes attrs, ParametersCompiled parameters)
52
 
                        : base (parent, type, mod, allowed_mod, name, attrs)
53
 
                {
54
 
                        this.parameters = parameters;
55
 
                }
56
 
 
57
 
                public override Variance ExpectedMemberTypeVariance {
58
 
                        get {
59
 
                                return Variance.Covariant;
60
 
                        }
61
 
                }
62
 
 
63
 
                //
64
 
                //  Returns the System.Type array for the parameters of this method
65
 
                //
66
 
                public TypeSpec [] ParameterTypes {
67
 
                        get {
68
 
                                return parameters.Types;
69
 
                        }
70
 
                }
71
 
 
72
 
                public ParametersCompiled ParameterInfo {
73
 
                        get {
74
 
                                return parameters;
75
 
                        }
76
 
                }
77
 
 
78
 
                AParametersCollection IParametersMember.Parameters {
79
 
                        get { return parameters; }
80
 
                }
81
 
                
82
 
                public ToplevelBlock Block {
83
 
                        get {
84
 
                                return block;
85
 
                        }
86
 
 
87
 
                        set {
88
 
                                block = value;
89
 
                        }
90
 
                }
91
 
 
92
 
                public CallingConventions CallingConventions {
93
 
                        get {
94
 
                                CallingConventions cc = parameters.CallingConvention;
95
 
                                if (!IsInterface)
96
 
                                        if ((ModFlags & Modifiers.STATIC) == 0)
97
 
                                                cc |= CallingConventions.HasThis;
98
 
 
99
 
                                // FIXME: How is `ExplicitThis' used in C#?
100
 
                        
101
 
                                return cc;
102
 
                        }
103
 
                }
104
 
 
105
 
                protected override bool CheckOverrideAgainstBase (MemberSpec base_member)
106
 
                {
107
 
                        bool res = base.CheckOverrideAgainstBase (base_member);
108
 
 
109
 
                        //
110
 
                        // Check that the permissions are not being changed
111
 
                        //
112
 
                        if (!CheckAccessModifiers (this, base_member)) {
113
 
                                Error_CannotChangeAccessModifiers (this, base_member);
114
 
                                res = false;
115
 
                        }
116
 
 
117
 
                        return res;
118
 
                }
119
 
 
120
 
                protected override bool CheckBase ()
121
 
                {
122
 
                        // Check whether arguments were correct.
123
 
                        if (!DefineParameters (parameters))
124
 
                                return false;
125
 
 
126
 
                        return base.CheckBase ();
127
 
                }
128
 
 
129
 
                //
130
 
                //   Represents header string for documentation comment.
131
 
                //
132
 
                public override string DocCommentHeader 
133
 
                {
134
 
                        get { return "M:"; }
135
 
                }
136
 
 
137
 
                public override void Emit ()
138
 
                {
139
 
                        if ((ModFlags & Modifiers.COMPILER_GENERATED) == 0) {
140
 
                                parameters.CheckConstraints (this);
141
 
                        }
142
 
 
143
 
                        base.Emit ();
144
 
                }
145
 
 
146
 
                public override bool EnableOverloadChecks (MemberCore overload)
147
 
                {
148
 
                        if (overload is MethodCore) {
149
 
                                caching_flags |= Flags.MethodOverloadsExist;
150
 
                                return true;
151
 
                        }
152
 
 
153
 
                        if (overload is AbstractPropertyEventMethod)
154
 
                                return true;
155
 
 
156
 
                        return base.EnableOverloadChecks (overload);
157
 
                }
158
 
 
159
 
                public override string GetSignatureForDocumentation ()
160
 
                {
161
 
                        string s = base.GetSignatureForDocumentation ();
162
 
                        if (MemberName.Arity > 0)
163
 
                                s += "``" + MemberName.Arity.ToString ();
164
 
 
165
 
                        return s + parameters.GetSignatureForDocumentation ();
166
 
                }
167
 
 
168
 
                public MethodSpec Spec {
169
 
                        get { return spec; }
170
 
                }
171
 
 
172
 
                protected override bool VerifyClsCompliance ()
173
 
                {
174
 
                        if (!base.VerifyClsCompliance ())
175
 
                                return false;
176
 
 
177
 
                        if (parameters.HasArglist) {
178
 
                                Report.Warning (3000, 1, Location, "Methods with variable arguments are not CLS-compliant");
179
 
                        }
180
 
 
181
 
                        if (member_type != null && !member_type.IsCLSCompliant ()) {
182
 
                                Report.Warning (3002, 1, Location, "Return type of `{0}' is not CLS-compliant",
183
 
                                        GetSignatureForError ());
184
 
                        }
185
 
 
186
 
                        parameters.VerifyClsCompliance (this);
187
 
                        return true;
188
 
                }
189
 
        }
190
 
 
191
 
        public interface IGenericMethodDefinition : IMemberDefinition
192
 
        {
193
 
                TypeParameterSpec[] TypeParameters { get; }
194
 
                int TypeParametersCount { get; }
195
 
 
196
 
//              MethodInfo MakeGenericMethod (TypeSpec[] targs);
197
 
        }
198
 
 
199
 
        public sealed class MethodSpec : MemberSpec, IParametersMember
200
 
        {
201
 
                MethodBase metaInfo, inflatedMetaInfo;
202
 
                AParametersCollection parameters;
203
 
                TypeSpec returnType;
204
 
 
205
 
                TypeSpec[] targs;
206
 
                TypeParameterSpec[] constraints;
207
 
 
208
 
                public MethodSpec (MemberKind kind, TypeSpec declaringType, IMemberDefinition details, TypeSpec returnType,
209
 
                        MethodBase info, AParametersCollection parameters, Modifiers modifiers)
210
 
                        : base (kind, declaringType, details, modifiers)
211
 
                {
212
 
                        this.metaInfo = info;
213
 
                        this.parameters = parameters;
214
 
                        this.returnType = returnType;
215
 
                }
216
 
 
217
 
                #region Properties
218
 
 
219
 
                public override int Arity {
220
 
                        get {
221
 
                                return IsGeneric ? GenericDefinition.TypeParametersCount : 0;
222
 
                        }
223
 
                }
224
 
 
225
 
                public TypeParameterSpec[] Constraints {
226
 
                        get {
227
 
                                if (constraints == null && IsGeneric)
228
 
                                        constraints = GenericDefinition.TypeParameters;
229
 
 
230
 
                                return constraints;
231
 
                        }
232
 
                }
233
 
 
234
 
                public bool IsConstructor {
235
 
                        get {
236
 
                                return Kind == MemberKind.Constructor;
237
 
                        }
238
 
                }
239
 
 
240
 
                public IGenericMethodDefinition GenericDefinition {
241
 
                        get {
242
 
                                return (IGenericMethodDefinition) definition;
243
 
                        }
244
 
                }
245
 
 
246
 
                public bool IsExtensionMethod {
247
 
                        get {
248
 
                                return IsStatic && parameters.HasExtensionMethodType;
249
 
                        }
250
 
                }
251
 
 
252
 
                public bool IsSealed {
253
 
                        get {
254
 
                                return (Modifiers & Modifiers.SEALED) != 0;
255
 
                        }
256
 
                }
257
 
 
258
 
                // When is virtual or abstract
259
 
                public bool IsVirtual {
260
 
                        get {
261
 
                                return (Modifiers & (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE)) != 0;
262
 
                        }
263
 
                }
264
 
 
265
 
                public bool IsReservedMethod {
266
 
                        get {
267
 
                                return Kind == MemberKind.Operator || IsAccessor;
268
 
                        }
269
 
                }
270
 
 
271
 
                TypeSpec IInterfaceMemberSpec.MemberType {
272
 
                        get {
273
 
                                return returnType;
274
 
                        }
275
 
                }
276
 
 
277
 
                public AParametersCollection Parameters {
278
 
                        get { 
279
 
                                return parameters;
280
 
                        }
281
 
                }
282
 
 
283
 
                public TypeSpec ReturnType {
284
 
                        get {
285
 
                                return returnType;
286
 
                        }
287
 
                }
288
 
 
289
 
                public TypeSpec[] TypeArguments {
290
 
                        get {
291
 
                                return targs;
292
 
                        }
293
 
                }
294
 
 
295
 
                #endregion
296
 
 
297
 
                public MethodSpec GetGenericMethodDefinition ()
298
 
                {
299
 
                        if (!IsGeneric && !DeclaringType.IsGeneric)
300
 
                                return this;
301
 
 
302
 
                        return MemberCache.GetMember (declaringType, this);
303
 
                }
304
 
 
305
 
                public MethodBase GetMetaInfo ()
306
 
                {
307
 
                        //
308
 
                        // inflatedMetaInfo is extra field needed for cases where we
309
 
                        // inflate method but another nested type can later inflate
310
 
                        // again (the cache would be build with inflated metaInfo) and
311
 
                        // TypeBuilder can work with method definitions only
312
 
                        //
313
 
                        if (inflatedMetaInfo == null) {
314
 
                                if ((state & StateFlags.PendingMetaInflate) != 0) {
315
 
                                        var dt_meta = DeclaringType.GetMetaInfo ();
316
 
 
317
 
                                        if (DeclaringType.IsTypeBuilder) {
318
 
                                                if (IsConstructor)
319
 
                                                        inflatedMetaInfo = TypeBuilder.GetConstructor (dt_meta, (ConstructorInfo) metaInfo);
320
 
                                                else
321
 
                                                        inflatedMetaInfo = TypeBuilder.GetMethod (dt_meta, (MethodInfo) metaInfo);
322
 
                                        } else {
323
 
#if STATIC
324
 
                                                // it should not be reached
325
 
                                                throw new NotImplementedException ();
326
 
#else
327
 
                                                inflatedMetaInfo = MethodInfo.GetMethodFromHandle (metaInfo.MethodHandle, dt_meta.TypeHandle);
328
 
#endif
329
 
                                        }
330
 
 
331
 
                                        state &= ~StateFlags.PendingMetaInflate;
332
 
                                } else {
333
 
                                        inflatedMetaInfo = metaInfo;
334
 
                                }
335
 
                        }
336
 
 
337
 
                        if ((state & StateFlags.PendingMakeMethod) != 0) {
338
 
                                var sre_targs = new MetaType[targs.Length];
339
 
                                for (int i = 0; i < sre_targs.Length; ++i)
340
 
                                        sre_targs[i] = targs[i].GetMetaInfo ();
341
 
 
342
 
                                inflatedMetaInfo = ((MethodInfo) inflatedMetaInfo).MakeGenericMethod (sre_targs);
343
 
                                state &= ~StateFlags.PendingMakeMethod;
344
 
                        }
345
 
 
346
 
                        return inflatedMetaInfo;
347
 
                }
348
 
 
349
 
                public override string GetSignatureForDocumentation ()
350
 
                {
351
 
                        string name;
352
 
                        switch (Kind) {
353
 
                        case MemberKind.Constructor:
354
 
                                name = "#ctor";
355
 
                                break;
356
 
                        case MemberKind.Method:
357
 
                                if (Arity > 0)
358
 
                                        name = Name + "``" + Arity.ToString ();
359
 
                                else
360
 
                                        name = Name;
361
 
 
362
 
                                break;
363
 
                        default:
364
 
                                name = Name;
365
 
                                break;
366
 
                        }
367
 
 
368
 
                        name = DeclaringType.GetSignatureForDocumentation () + "." + name + parameters.GetSignatureForDocumentation ();
369
 
                        if (Kind == MemberKind.Operator) {
370
 
                                var op = Operator.GetType (Name).Value;
371
 
                                if (op == Operator.OpType.Explicit || op == Operator.OpType.Implicit) {
372
 
                                        name += "~" + ReturnType.GetSignatureForDocumentation ();
373
 
                                }
374
 
                        }
375
 
 
376
 
                        return name;
377
 
                }
378
 
 
379
 
                public override string GetSignatureForError ()
380
 
                {
381
 
                        string name;
382
 
                        if (IsConstructor) {
383
 
                                name = DeclaringType.GetSignatureForError () + "." + DeclaringType.Name;
384
 
                        } else if (Kind == MemberKind.Operator) {
385
 
                                var op = Operator.GetType (Name).Value;
386
 
                                if (op == Operator.OpType.Implicit || op == Operator.OpType.Explicit) {
387
 
                                        name = DeclaringType.GetSignatureForError () + "." + Operator.GetName (op) + " operator " + returnType.GetSignatureForError ();
388
 
                                } else {
389
 
                                        name = DeclaringType.GetSignatureForError () + ".operator " + Operator.GetName (op);
390
 
                                }
391
 
                        } else if (IsAccessor) {
392
 
                                int split = Name.IndexOf ('_');
393
 
                                name = Name.Substring (split + 1);
394
 
                                var postfix = Name.Substring (0, split);
395
 
                                if (split == 3) {
396
 
                                        var pc = parameters.Count;
397
 
                                        if (pc > 0 && postfix == "get") {
398
 
                                                name = "this" + parameters.GetSignatureForError ("[", "]", pc);
399
 
                                        } else if (pc > 1 && postfix == "set") {
400
 
                                                name = "this" + parameters.GetSignatureForError ("[", "]", pc - 1);
401
 
                                        }
402
 
                                }
403
 
 
404
 
                                return DeclaringType.GetSignatureForError () + "." + name + "." + postfix;
405
 
                        } else {
406
 
                                name = base.GetSignatureForError ();
407
 
                                if (targs != null)
408
 
                                        name += "<" + TypeManager.CSharpName (targs) + ">";
409
 
                                else if (IsGeneric)
410
 
                                        name += "<" + TypeManager.CSharpName (GenericDefinition.TypeParameters) + ">";
411
 
                        }
412
 
 
413
 
                        return name + parameters.GetSignatureForError ();
414
 
                }
415
 
 
416
 
                public override MemberSpec InflateMember (TypeParameterInflator inflator)
417
 
                {
418
 
                        var ms = (MethodSpec) base.InflateMember (inflator);
419
 
                        ms.inflatedMetaInfo = null;
420
 
                        ms.returnType = inflator.Inflate (returnType);
421
 
                        ms.parameters = parameters.Inflate (inflator);
422
 
                        if (IsGeneric)
423
 
                                ms.constraints = TypeParameterSpec.InflateConstraints (inflator, Constraints);
424
 
 
425
 
                        return ms;
426
 
                }
427
 
 
428
 
                public MethodSpec MakeGenericMethod (IMemberContext context, params TypeSpec[] targs)
429
 
                {
430
 
                        if (targs == null)
431
 
                                throw new ArgumentNullException ();
432
 
// TODO MemberCache
433
 
//                      if (generic_intances != null && generic_intances.TryGetValue (targs, out ginstance))
434
 
//                              return ginstance;
435
 
 
436
 
                        //if (generic_intances == null)
437
 
                        //    generic_intances = new Dictionary<TypeSpec[], Method> (TypeSpecArrayComparer.Default);
438
 
 
439
 
                        var inflator = new TypeParameterInflator (context, DeclaringType, GenericDefinition.TypeParameters, targs);
440
 
 
441
 
                        var inflated = (MethodSpec) MemberwiseClone ();
442
 
                        inflated.declaringType = inflator.TypeInstance;
443
 
                        inflated.returnType = inflator.Inflate (returnType);
444
 
                        inflated.parameters = parameters.Inflate (inflator);
445
 
                        inflated.targs = targs;
446
 
                        inflated.constraints = TypeParameterSpec.InflateConstraints (inflator, constraints ?? GenericDefinition.TypeParameters);
447
 
                        inflated.state |= StateFlags.PendingMakeMethod;
448
 
 
449
 
                        //                      if (inflated.parent == null)
450
 
                        //                              inflated.parent = parent;
451
 
 
452
 
                        //generic_intances.Add (targs, inflated);
453
 
                        return inflated;
454
 
                }
455
 
 
456
 
                public MethodSpec Mutate (TypeParameterMutator mutator)
457
 
                {
458
 
                        var targs = TypeArguments;
459
 
                        if (targs != null)
460
 
                                targs = mutator.Mutate (targs);
461
 
 
462
 
                        var decl = DeclaringType;
463
 
                        if (DeclaringType.IsGenericOrParentIsGeneric) {
464
 
                                decl = mutator.Mutate (decl);
465
 
                        }
466
 
 
467
 
                        if (targs == TypeArguments && decl == DeclaringType)
468
 
                                return this;
469
 
 
470
 
                        var ms = (MethodSpec) MemberwiseClone ();
471
 
                        if (decl != DeclaringType) {
472
 
                                ms.inflatedMetaInfo = null;
473
 
                                ms.declaringType = decl;
474
 
                                ms.state |= StateFlags.PendingMetaInflate;
475
 
                        }
476
 
 
477
 
                        if (targs != null) {
478
 
                                ms.targs = targs;
479
 
                                ms.state |= StateFlags.PendingMakeMethod;
480
 
                        }
481
 
 
482
 
                        return ms;
483
 
                }
484
 
 
485
 
                public override List<TypeSpec> ResolveMissingDependencies ()
486
 
                {
487
 
                        var missing = returnType.ResolveMissingDependencies ();
488
 
                        foreach (var pt in parameters.Types) {
489
 
                                var m = pt.GetMissingDependencies ();
490
 
                                if (m == null)
491
 
                                        continue;
492
 
 
493
 
                                if (missing == null)
494
 
                                        missing = new List<TypeSpec> ();
495
 
 
496
 
                                missing.AddRange (m);
497
 
                        }
498
 
 
499
 
                        if (Arity > 0) {
500
 
                                foreach (var tp in GenericDefinition.TypeParameters) {
501
 
                                        var m = tp.GetMissingDependencies ();
502
 
 
503
 
                                        if (m == null)
504
 
                                                continue;
505
 
 
506
 
                                        if (missing == null)
507
 
                                                missing = new List<TypeSpec> ();
508
 
 
509
 
                                        missing.AddRange (m);
510
 
                                }
511
 
                        }
512
 
 
513
 
                        return missing;                 
514
 
                }
515
 
 
516
 
                public void SetMetaInfo (MethodInfo info)
517
 
                {
518
 
                        if (this.metaInfo != null)
519
 
                                throw new InternalErrorException ("MetaInfo reset");
520
 
 
521
 
                        this.metaInfo = info;
522
 
                }
523
 
        }
524
 
 
525
 
        public abstract class MethodOrOperator : MethodCore, IMethodData
526
 
        {
527
 
                public MethodBuilder MethodBuilder;
528
 
                ReturnParameter return_attributes;
529
 
                SecurityType declarative_security;
530
 
                protected MethodData MethodData;
531
 
 
532
 
                static readonly string[] attribute_targets = new string [] { "method", "return" };
533
 
 
534
 
                protected MethodOrOperator (TypeDefinition parent, FullNamedExpression type, Modifiers mod, Modifiers allowed_mod, MemberName name,
535
 
                                Attributes attrs, ParametersCompiled parameters)
536
 
                        : base (parent, type, mod, allowed_mod, name, attrs, parameters)
537
 
                {
538
 
                }
539
 
 
540
 
                public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
541
 
                {
542
 
                        if (a.Target == AttributeTargets.ReturnValue) {
543
 
                                if (return_attributes == null)
544
 
                                        return_attributes = new ReturnParameter (this, MethodBuilder, Location);
545
 
 
546
 
                                return_attributes.ApplyAttributeBuilder (a, ctor, cdata, pa);
547
 
                                return;
548
 
                        }
549
 
 
550
 
                        if (a.Type == pa.MethodImpl) {
551
 
                                if ((ModFlags & Modifiers.ASYNC) != 0 && (a.GetMethodImplOptions () & MethodImplOptions.Synchronized) != 0) {
552
 
                                        Report.Error (4015, a.Location, "`{0}': Async methods cannot use `MethodImplOptions.Synchronized'",
553
 
                                                GetSignatureForError ());
554
 
                                }
555
 
 
556
 
                                is_external_implementation = a.IsInternalCall ();
557
 
                        } else if (a.Type == pa.DllImport) {
558
 
                                const Modifiers extern_static = Modifiers.EXTERN | Modifiers.STATIC;
559
 
                                if ((ModFlags & extern_static) != extern_static) {
560
 
                                        Report.Error (601, a.Location, "The DllImport attribute must be specified on a method marked `static' and `extern'");
561
 
                                }
562
 
                                is_external_implementation = true;
563
 
                        }
564
 
 
565
 
                        if (a.IsValidSecurityAttribute ()) {
566
 
                                a.ExtractSecurityPermissionSet (ctor, ref declarative_security);
567
 
                                return;
568
 
                        }
569
 
 
570
 
                        if (MethodBuilder != null)
571
 
                                MethodBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
572
 
                }
573
 
 
574
 
                public override AttributeTargets AttributeTargets {
575
 
                        get {
576
 
                                return AttributeTargets.Method; 
577
 
                        }
578
 
                }
579
 
 
580
 
                protected override bool CheckForDuplications ()
581
 
                {
582
 
                        return Parent.MemberCache.CheckExistingMembersOverloads (this, parameters);
583
 
                }
584
 
 
585
 
                public virtual EmitContext CreateEmitContext (ILGenerator ig, SourceMethodBuilder sourceMethod)
586
 
                {
587
 
                        return new EmitContext (this, ig, MemberType, sourceMethod);
588
 
                }
589
 
 
590
 
                public override bool Define ()
591
 
                {
592
 
                        if (!base.Define ())
593
 
                                return false;
594
 
 
595
 
                        if (!CheckBase ())
596
 
                                return false;
597
 
 
598
 
                        MemberKind kind;
599
 
                        if (this is Operator)
600
 
                                kind = MemberKind.Operator;
601
 
                        else if (this is Destructor)
602
 
                                kind = MemberKind.Destructor;
603
 
                        else
604
 
                                kind = MemberKind.Method;
605
 
 
606
 
                        if (IsPartialDefinition) {
607
 
                                caching_flags &= ~Flags.Excluded_Undetected;
608
 
                                caching_flags |= Flags.Excluded;
609
 
 
610
 
                                // Add to member cache only when a partial method implementation has not been found yet
611
 
                                if ((caching_flags & Flags.PartialDefinitionExists) == 0) {
612
 
//                                      MethodBase mb = new PartialMethodDefinitionInfo (this);
613
 
 
614
 
                                        spec = new MethodSpec (kind, Parent.Definition, this, ReturnType, null, parameters, ModFlags);
615
 
                                        if (MemberName.Arity > 0) {
616
 
                                                spec.IsGeneric = true;
617
 
 
618
 
                                                // TODO: Have to move DefineMethod after Define (ideally to Emit)
619
 
                                                throw new NotImplementedException ("Generic partial methods");
620
 
                                        }
621
 
 
622
 
                                        Parent.MemberCache.AddMember (spec);
623
 
                                }
624
 
 
625
 
                                return true;
626
 
                        }
627
 
 
628
 
                        MethodData = new MethodData (
629
 
                                this, ModFlags, flags, this, MethodBuilder, base_method);
630
 
 
631
 
                        if (!MethodData.Define (Parent.PartialContainer, GetFullName (MemberName)))
632
 
                                return false;
633
 
                                        
634
 
                        MethodBuilder = MethodData.MethodBuilder;
635
 
 
636
 
                        spec = new MethodSpec (kind, Parent.Definition, this, ReturnType, MethodBuilder, parameters, ModFlags);
637
 
                        if (MemberName.Arity > 0)
638
 
                                spec.IsGeneric = true;
639
 
                        
640
 
                        Parent.MemberCache.AddMember (this, MethodBuilder.Name, spec);
641
 
 
642
 
                        return true;
643
 
                }
644
 
 
645
 
                protected override void DoMemberTypeIndependentChecks ()
646
 
                {
647
 
                        base.DoMemberTypeIndependentChecks ();
648
 
 
649
 
                        CheckAbstractAndExtern (block != null);
650
 
 
651
 
                        if ((ModFlags & Modifiers.PARTIAL) != 0) {
652
 
                                for (int i = 0; i < parameters.Count; ++i) {
653
 
                                        IParameterData p = parameters.FixedParameters [i];
654
 
                                        if ((p.ModFlags & Parameter.Modifier.OUT) != 0) {
655
 
                                                Report.Error (752, Location, "`{0}': A partial method parameters cannot use `out' modifier",
656
 
                                                        GetSignatureForError ());
657
 
                                        }
658
 
 
659
 
                                        if (p.HasDefaultValue && IsPartialImplementation)
660
 
                                                ((Parameter) p).Warning_UselessOptionalParameter (Report);
661
 
                                }
662
 
                        }
663
 
                }
664
 
 
665
 
                protected override void DoMemberTypeDependentChecks ()
666
 
                {
667
 
                        base.DoMemberTypeDependentChecks ();
668
 
 
669
 
                        if (MemberType.IsStatic) {
670
 
                                Error_StaticReturnType ();
671
 
                        }
672
 
                }
673
 
 
674
 
                public override void Emit ()
675
 
                {
676
 
                        if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0 && !Parent.IsCompilerGenerated)
677
 
                                Module.PredefinedAttributes.CompilerGenerated.EmitAttribute (MethodBuilder);
678
 
                        if ((ModFlags & Modifiers.DEBUGGER_HIDDEN) != 0)
679
 
                                Module.PredefinedAttributes.DebuggerHidden.EmitAttribute (MethodBuilder);
680
 
 
681
 
                        if (ReturnType.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
682
 
                                return_attributes = new ReturnParameter (this, MethodBuilder, Location);
683
 
                                Module.PredefinedAttributes.Dynamic.EmitAttribute (return_attributes.Builder);
684
 
                        } else if (ReturnType.HasDynamicElement) {
685
 
                                return_attributes = new ReturnParameter (this, MethodBuilder, Location);
686
 
                                Module.PredefinedAttributes.Dynamic.EmitAttribute (return_attributes.Builder, ReturnType, Location);
687
 
                        }
688
 
 
689
 
                        if (OptAttributes != null)
690
 
                                OptAttributes.Emit ();
691
 
 
692
 
                        if (declarative_security != null) {
693
 
                                foreach (var de in declarative_security) {
694
 
#if STATIC
695
 
                                        MethodBuilder.__AddDeclarativeSecurity (de);
696
 
#else
697
 
                                        MethodBuilder.AddDeclarativeSecurity (de.Key, de.Value);
698
 
#endif
699
 
                                }
700
 
                        }
701
 
 
702
 
                        if (type_expr != null)
703
 
                                ConstraintChecker.Check (this, member_type, type_expr.Location);
704
 
 
705
 
                        base.Emit ();
706
 
 
707
 
                        if (MethodData != null)
708
 
                                MethodData.Emit (Parent);
709
 
 
710
 
                        Block = null;
711
 
                }
712
 
 
713
 
                protected void Error_ConditionalAttributeIsNotValid ()
714
 
                {
715
 
                        Report.Error (577, Location,
716
 
                                "Conditional not valid on `{0}' because it is a constructor, destructor, operator or explicit interface implementation",
717
 
                                GetSignatureForError ());
718
 
                }
719
 
 
720
 
                public bool IsPartialDefinition {
721
 
                        get {
722
 
                                return (ModFlags & Modifiers.PARTIAL) != 0 && Block == null;
723
 
                        }
724
 
                }
725
 
 
726
 
                public bool IsPartialImplementation {
727
 
                        get {
728
 
                                return (ModFlags & Modifiers.PARTIAL) != 0 && Block != null;
729
 
                        }
730
 
                }
731
 
 
732
 
                public override string[] ValidAttributeTargets {
733
 
                        get {
734
 
                                return attribute_targets;
735
 
                        }
736
 
                }
737
 
 
738
 
                #region IMethodData Members
739
 
 
740
 
                bool IMethodData.IsAccessor {
741
 
                        get {
742
 
                                return false;
743
 
                        }
744
 
                }
745
 
 
746
 
                public TypeSpec ReturnType {
747
 
                        get {
748
 
                                return MemberType;
749
 
                        }
750
 
                }
751
 
 
752
 
                public MemberName MethodName {
753
 
                        get {
754
 
                                return MemberName;
755
 
                        }
756
 
                }
757
 
 
758
 
                /// <summary>
759
 
                /// Returns true if method has conditional attribute and the conditions is not defined (method is excluded).
760
 
                /// </summary>
761
 
                public override string[] ConditionalConditions ()
762
 
                {
763
 
                        if ((caching_flags & (Flags.Excluded_Undetected | Flags.Excluded)) == 0)
764
 
                                return null;
765
 
 
766
 
                        if ((ModFlags & Modifiers.PARTIAL) != 0 && (caching_flags & Flags.Excluded) != 0)
767
 
                                return new string [0];
768
 
 
769
 
                        caching_flags &= ~Flags.Excluded_Undetected;
770
 
                        string[] conditions;
771
 
 
772
 
                        if (base_method == null) {
773
 
                                if (OptAttributes == null)
774
 
                                        return null;
775
 
 
776
 
                                Attribute[] attrs = OptAttributes.SearchMulti (Module.PredefinedAttributes.Conditional);
777
 
                                if (attrs == null)
778
 
                                        return null;
779
 
 
780
 
                                conditions = new string[attrs.Length];
781
 
                                for (int i = 0; i < conditions.Length; ++i)
782
 
                                        conditions[i] = attrs[i].GetConditionalAttributeValue ();
783
 
                        } else {
784
 
                                conditions = base_method.MemberDefinition.ConditionalConditions();
785
 
                        }
786
 
 
787
 
                        if (conditions != null)
788
 
                                caching_flags |= Flags.Excluded;
789
 
 
790
 
                        return conditions;
791
 
                }
792
 
 
793
 
                #endregion
794
 
 
795
 
                public override void WriteDebugSymbol (MonoSymbolFile file)
796
 
                {
797
 
                        if (MethodData != null)
798
 
                                MethodData.WriteDebugSymbol (file);
799
 
                }
800
 
        }
801
 
 
802
 
        public class Method : MethodOrOperator, IGenericMethodDefinition
803
 
        {
804
 
                Method partialMethodImplementation;
805
 
 
806
 
                public Method (TypeDefinition parent, FullNamedExpression return_type, Modifiers mod, MemberName name, ParametersCompiled parameters, Attributes attrs)
807
 
                        : base (parent, return_type, mod,
808
 
                                parent.PartialContainer.Kind == MemberKind.Interface ? AllowedModifiersInterface :
809
 
                                parent.PartialContainer.Kind == MemberKind.Struct ? AllowedModifiersStruct | Modifiers.ASYNC :
810
 
                                AllowedModifiersClass | Modifiers.ASYNC,
811
 
                                name, attrs, parameters)
812
 
                {
813
 
                }
814
 
 
815
 
                protected Method (TypeDefinition parent, FullNamedExpression return_type, Modifiers mod, Modifiers amod,
816
 
                                        MemberName name, ParametersCompiled parameters, Attributes attrs)
817
 
                        : base (parent, return_type, mod, amod, name, attrs, parameters)
818
 
                {
819
 
                }
820
 
 
821
 
                #region Properties
822
 
 
823
 
                public override TypeParameters CurrentTypeParameters {
824
 
                        get {
825
 
                                return MemberName.TypeParameters;
826
 
                        }
827
 
                }
828
 
 
829
 
                public TypeParameterSpec[] TypeParameters {
830
 
                        get {
831
 
                                return CurrentTypeParameters.Types;
832
 
                        }
833
 
                }
834
 
 
835
 
                public int TypeParametersCount {
836
 
                        get {
837
 
                                return CurrentTypeParameters == null ? 0 : CurrentTypeParameters.Count;
838
 
                        }
839
 
                }
840
 
 
841
 
#endregion
842
 
 
843
 
                public override void Accept (StructuralVisitor visitor)
844
 
                {
845
 
                        visitor.Visit (this);
846
 
                }
847
 
 
848
 
                public static Method Create (TypeDefinition parent, FullNamedExpression returnType, Modifiers mod,
849
 
                                   MemberName name, ParametersCompiled parameters, Attributes attrs, bool hasConstraints)
850
 
                {
851
 
                        var m = new Method (parent, returnType, mod, name, parameters, attrs);
852
 
 
853
 
                        if (hasConstraints && ((mod & Modifiers.OVERRIDE) != 0 || m.IsExplicitImpl)) {
854
 
                                m.Report.Error (460, m.Location,
855
 
                                        "`{0}': Cannot specify constraints for overrides and explicit interface implementation methods",
856
 
                                        m.GetSignatureForError ());
857
 
                        }
858
 
 
859
 
                        if ((mod & Modifiers.PARTIAL) != 0) {
860
 
                                const Modifiers invalid_partial_mod = Modifiers.AccessibilityMask | Modifiers.ABSTRACT | Modifiers.EXTERN |
861
 
                                        Modifiers.NEW | Modifiers.OVERRIDE | Modifiers.SEALED | Modifiers.VIRTUAL;
862
 
 
863
 
                                if ((mod & invalid_partial_mod) != 0) {
864
 
                                        m.Report.Error (750, m.Location,
865
 
                                                "A partial method cannot define access modifier or any of abstract, extern, new, override, sealed, or virtual modifiers");
866
 
                                        mod &= ~invalid_partial_mod;
867
 
                                }
868
 
 
869
 
                                if ((parent.ModFlags & Modifiers.PARTIAL) == 0) {
870
 
                                        m.Report.Error (751, m.Location, 
871
 
                                                "A partial method must be declared within a partial class or partial struct");
872
 
                                }
873
 
                        }
874
 
 
875
 
                        if ((mod & Modifiers.STATIC) == 0 && parameters.HasExtensionMethodType) {
876
 
                                m.Report.Error (1105, m.Location, "`{0}': Extension methods must be declared static",
877
 
                                        m.GetSignatureForError ());
878
 
                        }
879
 
 
880
 
 
881
 
                        return m;
882
 
                }
883
 
 
884
 
                public override string GetSignatureForError()
885
 
                {
886
 
                        return base.GetSignatureForError () + parameters.GetSignatureForError ();
887
 
                }
888
 
 
889
 
                void Error_DuplicateEntryPoint (Method b)
890
 
                {
891
 
                        Report.Error (17, b.Location,
892
 
                                "Program `{0}' has more than one entry point defined: `{1}'",
893
 
                                b.Module.Builder.ScopeName, b.GetSignatureForError ());
894
 
                }
895
 
 
896
 
                bool IsEntryPoint ()
897
 
                {
898
 
                        if (ReturnType.Kind != MemberKind.Void && ReturnType.BuiltinType != BuiltinTypeSpec.Type.Int)
899
 
                                return false;
900
 
 
901
 
                        if (parameters.IsEmpty)
902
 
                                return true;
903
 
 
904
 
                        if (parameters.Count > 1)
905
 
                                return false;
906
 
 
907
 
                        var ac = parameters.Types [0] as ArrayContainer;
908
 
                        return ac != null && ac.Rank == 1 && ac.Element.BuiltinType == BuiltinTypeSpec.Type.String &&
909
 
                                        (parameters[0].ModFlags & Parameter.Modifier.RefOutMask) == 0;
910
 
                }
911
 
 
912
 
                public override FullNamedExpression LookupNamespaceOrType (string name, int arity, LookupMode mode, Location loc)
913
 
                {
914
 
                        if (arity == 0) {
915
 
                                var tp = CurrentTypeParameters;
916
 
                                if (tp != null) {
917
 
                                        TypeParameter t = tp.Find (name);
918
 
                                        if (t != null)
919
 
                                                return new TypeParameterExpr (t, loc);
920
 
                                }
921
 
                        }
922
 
 
923
 
                        return base.LookupNamespaceOrType (name, arity, mode, loc);
924
 
                }
925
 
 
926
 
                public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
927
 
                {
928
 
                        if (a.Type == pa.Conditional) {
929
 
                                if (IsExplicitImpl) {
930
 
                                        Error_ConditionalAttributeIsNotValid ();
931
 
                                        return;
932
 
                                }
933
 
 
934
 
                                if ((ModFlags & Modifiers.OVERRIDE) != 0) {
935
 
                                        Report.Error (243, Location, "Conditional not valid on `{0}' because it is an override method", GetSignatureForError ());
936
 
                                        return;
937
 
                                }
938
 
 
939
 
                                if (ReturnType.Kind != MemberKind.Void) {
940
 
                                        Report.Error (578, Location, "Conditional not valid on `{0}' because its return type is not void", GetSignatureForError ());
941
 
                                        return;
942
 
                                }
943
 
 
944
 
                                if (IsInterface) {
945
 
                                        Report.Error (582, Location, "Conditional not valid on interface members");
946
 
                                        return;
947
 
                                }
948
 
 
949
 
                                if (MethodData.implementing != null) {
950
 
                                        Report.SymbolRelatedToPreviousError (MethodData.implementing.DeclaringType);
951
 
                                        Report.Error (629, Location, "Conditional member `{0}' cannot implement interface member `{1}'",
952
 
                                                GetSignatureForError (), TypeManager.CSharpSignature (MethodData.implementing));
953
 
                                        return;
954
 
                                }
955
 
 
956
 
                                for (int i = 0; i < parameters.Count; ++i) {
957
 
                                        if ((parameters.FixedParameters [i].ModFlags & Parameter.Modifier.OUT) != 0) {
958
 
                                                Report.Error (685, Location, "Conditional method `{0}' cannot have an out parameter", GetSignatureForError ());
959
 
                                                return;
960
 
                                        }
961
 
                                }
962
 
                        }
963
 
 
964
 
                        if (a.Type == pa.Extension) {
965
 
                                a.Error_MisusedExtensionAttribute ();
966
 
                                return;
967
 
                        }
968
 
 
969
 
                        base.ApplyAttributeBuilder (a, ctor, cdata, pa);
970
 
                }
971
 
 
972
 
                void CreateTypeParameters ()
973
 
                {
974
 
                        var tparams = MemberName.TypeParameters;
975
 
                        string[] snames = new string[MemberName.Arity];
976
 
                        var parent_tparams = Parent.TypeParametersAll;
977
 
 
978
 
                        for (int i = 0; i < snames.Length; i++) {
979
 
                                string type_argument_name = tparams[i].MemberName.Name;
980
 
 
981
 
                                if (block == null) {
982
 
                                        int idx = parameters.GetParameterIndexByName (type_argument_name);
983
 
                                        if (idx >= 0) {
984
 
                                                var b = block;
985
 
                                                if (b == null)
986
 
                                                        b = new ToplevelBlock (Compiler, Location);
987
 
 
988
 
                                                b.Error_AlreadyDeclaredTypeParameter (type_argument_name, parameters[i].Location);
989
 
                                        }
990
 
                                } else {
991
 
                                        INamedBlockVariable variable = null;
992
 
                                        block.GetLocalName (type_argument_name, block, ref variable);
993
 
                                        if (variable != null)
994
 
                                                variable.Block.Error_AlreadyDeclaredTypeParameter (type_argument_name, variable.Location);
995
 
                                }
996
 
 
997
 
                                if (parent_tparams != null) {
998
 
                                        var tp = parent_tparams.Find (type_argument_name);
999
 
                                        if (tp != null) {
1000
 
                                                tparams[i].WarningParentNameConflict (tp);
1001
 
                                        }
1002
 
                                }
1003
 
 
1004
 
                                snames[i] = type_argument_name;
1005
 
                        }
1006
 
 
1007
 
                        GenericTypeParameterBuilder[] gen_params = MethodBuilder.DefineGenericParameters (snames);
1008
 
                        tparams.Define (gen_params, null, 0, Parent);
1009
 
                }
1010
 
 
1011
 
                protected virtual void DefineTypeParameters ()
1012
 
                {
1013
 
                        var tparams = CurrentTypeParameters;
1014
 
 
1015
 
                        TypeParameterSpec[] base_tparams = null;
1016
 
                        TypeParameterSpec[] base_decl_tparams = TypeParameterSpec.EmptyTypes;
1017
 
                        TypeSpec[] base_targs = TypeSpec.EmptyTypes;
1018
 
                        if (((ModFlags & Modifiers.OVERRIDE) != 0 || IsExplicitImpl)) {
1019
 
                                if (base_method != null) {
1020
 
                                        base_tparams = base_method.GenericDefinition.TypeParameters;
1021
 
                                
1022
 
                                        if (base_method.DeclaringType.IsGeneric) {
1023
 
                                                base_decl_tparams = base_method.DeclaringType.MemberDefinition.TypeParameters;
1024
 
 
1025
 
                                                var base_type_parent = CurrentType;
1026
 
                                                while (base_type_parent.BaseType != base_method.DeclaringType) {
1027
 
                                                        base_type_parent = base_type_parent.BaseType;
1028
 
                                                }
1029
 
 
1030
 
                                                base_targs = base_type_parent.BaseType.TypeArguments;
1031
 
                                        }
1032
 
 
1033
 
                                        if (base_method.IsGeneric) {
1034
 
                                                ObsoleteAttribute oa;
1035
 
                                                foreach (var base_tp in base_tparams) {
1036
 
                                                        oa = base_tp.BaseType.GetAttributeObsolete ();
1037
 
                                                        if (oa != null) {
1038
 
                                                                AttributeTester.Report_ObsoleteMessage (oa, base_tp.BaseType.GetSignatureForError (), Location, Report);
1039
 
                                                        }
1040
 
 
1041
 
                                                        if (base_tp.InterfacesDefined != null) {
1042
 
                                                                foreach (var iface in base_tp.InterfacesDefined) {
1043
 
                                                                        oa = iface.GetAttributeObsolete ();
1044
 
                                                                        if (oa != null) {
1045
 
                                                                                AttributeTester.Report_ObsoleteMessage (oa, iface.GetSignatureForError (), Location, Report);
1046
 
                                                                        }
1047
 
                                                                }
1048
 
                                                        }
1049
 
                                                }
1050
 
 
1051
 
                                                if (base_decl_tparams.Length != 0) {
1052
 
                                                        base_decl_tparams = base_decl_tparams.Concat (base_tparams).ToArray ();
1053
 
                                                        base_targs = base_targs.Concat (tparams.Types).ToArray ();
1054
 
                                                } else {
1055
 
                                                        base_decl_tparams = base_tparams;
1056
 
                                                        base_targs = tparams.Types;
1057
 
                                                }
1058
 
                                        }
1059
 
                                } else if (MethodData.implementing != null) {
1060
 
                                        base_tparams = MethodData.implementing.GenericDefinition.TypeParameters;
1061
 
                                        if (MethodData.implementing.DeclaringType.IsGeneric) {
1062
 
                                                base_decl_tparams = MethodData.implementing.DeclaringType.MemberDefinition.TypeParameters;
1063
 
                                                foreach (var iface in Parent.CurrentType.Interfaces) {
1064
 
                                                        if (iface == MethodData.implementing.DeclaringType) {
1065
 
                                                                base_targs = iface.TypeArguments;
1066
 
                                                                break;
1067
 
                                                        }
1068
 
                                                }
1069
 
                                        }
1070
 
                                }
1071
 
                        }
1072
 
 
1073
 
                        for (int i = 0; i < tparams.Count; ++i) {
1074
 
                                var tp = tparams[i];
1075
 
 
1076
 
                                if (!tp.ResolveConstraints (this))
1077
 
                                        continue;
1078
 
 
1079
 
                                //
1080
 
                                // Copy base constraints for override/explicit methods
1081
 
                                //
1082
 
                                if (base_tparams != null) {
1083
 
                                        var base_tparam = base_tparams[i];
1084
 
                                        var local_tparam = tp.Type;
1085
 
                                        local_tparam.SpecialConstraint = base_tparam.SpecialConstraint;
1086
 
 
1087
 
                                        var inflator = new TypeParameterInflator (this, CurrentType, base_decl_tparams, base_targs);
1088
 
                                        base_tparam.InflateConstraints (inflator, local_tparam);
1089
 
 
1090
 
                                        //
1091
 
                                        // Check all type argument constraints for possible collision or unification
1092
 
                                        // introduced by inflating inherited constraints in this context
1093
 
                                        //
1094
 
                                        // Conflict example:
1095
 
                                        //
1096
 
                                        // class A<T> { virtual void Foo<U> () where U : class, T {} }
1097
 
                                        // class B : A<int> { override void Foo<U> {} }
1098
 
                                        //
1099
 
                                        var local_tparam_targs = local_tparam.TypeArguments;
1100
 
                                        if (local_tparam_targs != null) {
1101
 
                                                for (int ii = 0; ii < local_tparam_targs.Length; ++ii) {
1102
 
                                                        var ta = local_tparam_targs [ii];
1103
 
                                                        if (!ta.IsClass && !ta.IsStruct)
1104
 
                                                                continue;
1105
 
 
1106
 
                                                        TypeSpec[] unique_tparams = null;
1107
 
                                                        for (int iii = ii + 1; iii < local_tparam_targs.Length; ++iii) {
1108
 
                                                                //
1109
 
                                                                // Remove any identical or unified constraint types
1110
 
                                                                //
1111
 
                                                                var tparam_checked = local_tparam_targs[iii];
1112
 
                                                                if (TypeSpecComparer.IsEqual (ta, tparam_checked) || TypeSpec.IsBaseClass (ta, tparam_checked, false)) {
1113
 
                                                                        unique_tparams = new TypeSpec[local_tparam_targs.Length - 1];
1114
 
                                                                        Array.Copy (local_tparam_targs, 0, unique_tparams, 0, iii);
1115
 
                                                                        Array.Copy (local_tparam_targs, iii + 1, unique_tparams, iii, local_tparam_targs.Length - iii - 1);
1116
 
                                                                } else if (!TypeSpec.IsBaseClass (tparam_checked, ta, false)) {
1117
 
                                                                        Constraints.Error_ConflictingConstraints (this, local_tparam, ta, tparam_checked, Location);
1118
 
                                                                }
1119
 
                                                        }
1120
 
 
1121
 
                                                        if (unique_tparams != null) {
1122
 
                                                                local_tparam_targs = unique_tparams;
1123
 
                                                                local_tparam.TypeArguments = local_tparam_targs;
1124
 
                                                                continue;
1125
 
                                                        }
1126
 
 
1127
 
                                                        Constraints.CheckConflictingInheritedConstraint (local_tparam, ta, this, Location);
1128
 
                                                }
1129
 
                                        }
1130
 
 
1131
 
                                        continue;
1132
 
                                }
1133
 
                        }
1134
 
 
1135
 
                        if (base_tparams == null && MethodData != null && MethodData.implementing != null) {
1136
 
                                CheckImplementingMethodConstraints (Parent, spec, MethodData.implementing);
1137
 
                        }
1138
 
                }
1139
 
 
1140
 
                public static bool CheckImplementingMethodConstraints (TypeContainer container, MethodSpec method, MethodSpec baseMethod)
1141
 
                {
1142
 
                        var tparams = method.Constraints;
1143
 
                        var base_tparams = baseMethod.Constraints;
1144
 
                        for (int i = 0; i < tparams.Length; ++i) {
1145
 
                                if (!tparams[i].HasSameConstraintsImplementation (base_tparams[i])) {
1146
 
                                        container.Compiler.Report.SymbolRelatedToPreviousError (method);
1147
 
                                        container.Compiler.Report.SymbolRelatedToPreviousError (baseMethod);
1148
 
 
1149
 
                                        // Using container location because the interface can be implemented
1150
 
                                        // by base class
1151
 
                                        container.Compiler.Report.Error (425, container.Location,
1152
 
                                                "The constraints for type parameter `{0}' of method `{1}' must match the constraints for type parameter `{2}' of interface method `{3}'. Consider using an explicit interface implementation instead",
1153
 
                                                tparams[i].GetSignatureForError (), method.GetSignatureForError (),
1154
 
                                                base_tparams[i].GetSignatureForError (), baseMethod.GetSignatureForError ());
1155
 
 
1156
 
                                        return false;
1157
 
                                }
1158
 
                        }
1159
 
 
1160
 
                        return true;
1161
 
                }
1162
 
 
1163
 
                //
1164
 
                // Creates the type
1165
 
                //
1166
 
                public override bool Define ()
1167
 
                {
1168
 
                        if (!base.Define ())
1169
 
                                return false;
1170
 
 
1171
 
                        if (member_type.Kind == MemberKind.Void && parameters.IsEmpty && MemberName.Arity == 0 && MemberName.Name == Destructor.MetadataName) {
1172
 
                                Report.Warning (465, 1, Location,
1173
 
                                        "Introducing `Finalize' method can interfere with destructor invocation. Did you intend to declare a destructor?");
1174
 
                        }
1175
 
 
1176
 
                        if (partialMethodImplementation != null && IsPartialDefinition)
1177
 
                                MethodBuilder = partialMethodImplementation.MethodBuilder;
1178
 
 
1179
 
                        if (Compiler.Settings.StdLib && ReturnType.IsSpecialRuntimeType) {
1180
 
                                Error1599 (Location, ReturnType, Report);
1181
 
                                return false;
1182
 
                        }
1183
 
 
1184
 
                        if (CurrentTypeParameters == null) {
1185
 
                                if (base_method != null && !IsExplicitImpl) {
1186
 
                                        if (parameters.Count == 1 && ParameterTypes[0].BuiltinType == BuiltinTypeSpec.Type.Object && MemberName.Name == "Equals")
1187
 
                                                Parent.PartialContainer.Mark_HasEquals ();
1188
 
                                        else if (parameters.IsEmpty && MemberName.Name == "GetHashCode")
1189
 
                                                Parent.PartialContainer.Mark_HasGetHashCode ();
1190
 
                                }
1191
 
                                        
1192
 
                        } else {
1193
 
                                DefineTypeParameters ();
1194
 
                        }
1195
 
 
1196
 
                        if (block != null) {
1197
 
                                if (block.IsIterator) {
1198
 
                                        //
1199
 
                                        // Current method is turned into automatically generated
1200
 
                                        // wrapper which creates an instance of iterator
1201
 
                                        //
1202
 
                                        Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags);
1203
 
                                        ModFlags |= Modifiers.DEBUGGER_HIDDEN;
1204
 
                                }
1205
 
 
1206
 
                                if ((ModFlags & Modifiers.ASYNC) != 0) {
1207
 
                                        if (ReturnType.Kind != MemberKind.Void &&
1208
 
                                                ReturnType != Module.PredefinedTypes.Task.TypeSpec &&
1209
 
                                                !ReturnType.IsGenericTask) {
1210
 
                                                Report.Error (1983, Location, "The return type of an async method must be void, Task, or Task<T>");
1211
 
                                        }
1212
 
 
1213
 
                                        block = (ToplevelBlock) block.ConvertToAsyncTask (this, Parent.PartialContainer, parameters, ReturnType, Location);
1214
 
                                        ModFlags |= Modifiers.DEBUGGER_HIDDEN;
1215
 
                                }
1216
 
                        }
1217
 
 
1218
 
                        if ((ModFlags & Modifiers.STATIC) == 0)
1219
 
                                return true;
1220
 
 
1221
 
                        if (parameters.HasExtensionMethodType) {
1222
 
                                if (Parent.PartialContainer.IsStatic && !Parent.IsGenericOrParentIsGeneric) {
1223
 
                                        if (!Parent.IsTopLevel)
1224
 
                                                Report.Error (1109, Location, "`{0}': Extension methods cannot be defined in a nested class",
1225
 
                                                        GetSignatureForError ());
1226
 
 
1227
 
                                        PredefinedAttribute pa = Module.PredefinedAttributes.Extension;
1228
 
                                        if (!pa.IsDefined) {
1229
 
                                                Report.Error (1110, Location,
1230
 
                                                        "`{0}': Extension methods require `System.Runtime.CompilerServices.ExtensionAttribute' type to be available. Are you missing an assembly reference?",
1231
 
                                                        GetSignatureForError ());
1232
 
                                        }
1233
 
 
1234
 
                                        ModFlags |= Modifiers.METHOD_EXTENSION;
1235
 
                                        Parent.PartialContainer.ModFlags |= Modifiers.METHOD_EXTENSION;
1236
 
                                        Spec.DeclaringType.SetExtensionMethodContainer ();
1237
 
                                        Parent.Module.HasExtensionMethod = true;
1238
 
                                } else {
1239
 
                                        Report.Error (1106, Location, "`{0}': Extension methods must be defined in a non-generic static class",
1240
 
                                                GetSignatureForError ());
1241
 
                                }
1242
 
                        }
1243
 
 
1244
 
                        //
1245
 
                        // This is used to track the Entry Point,
1246
 
                        //
1247
 
                        var settings = Compiler.Settings;
1248
 
                        if (settings.NeedsEntryPoint && MemberName.Name == "Main" && (settings.MainClass == null || settings.MainClass == Parent.TypeBuilder.FullName)) {
1249
 
                                if (IsEntryPoint ()) {
1250
 
                                        if (Parent.DeclaringAssembly.EntryPoint == null) {
1251
 
                                                if (Parent.IsGenericOrParentIsGeneric || MemberName.IsGeneric) {
1252
 
                                                        Report.Warning (402, 4, Location, "`{0}': an entry point cannot be generic or in a generic type",
1253
 
                                                                GetSignatureForError ());
1254
 
                                                } else if ((ModFlags & Modifiers.ASYNC) != 0) {
1255
 
                                                        Report.Error (4009, Location, "`{0}': an entry point cannot be async method",
1256
 
                                                                GetSignatureForError ());
1257
 
                                                } else {
1258
 
                                                        SetIsUsed ();
1259
 
                                                        Parent.DeclaringAssembly.EntryPoint = this;
1260
 
                                                }
1261
 
                                        } else {
1262
 
                                                Error_DuplicateEntryPoint (Parent.DeclaringAssembly.EntryPoint);
1263
 
                                                Error_DuplicateEntryPoint (this);
1264
 
                                        }
1265
 
                                } else {
1266
 
                                        Report.Warning (28, 4, Location, "`{0}' has the wrong signature to be an entry point",
1267
 
                                                GetSignatureForError ());
1268
 
                                }
1269
 
                        }
1270
 
 
1271
 
                        return true;
1272
 
                }
1273
 
 
1274
 
                //
1275
 
                // Emits the code
1276
 
                // 
1277
 
                public override void Emit ()
1278
 
                {
1279
 
                        try {
1280
 
                                if (IsPartialDefinition) {
1281
 
                                        //
1282
 
                                        // Use partial method implementation builder for partial method declaration attributes
1283
 
                                        //
1284
 
                                        if (partialMethodImplementation != null) {
1285
 
                                                MethodBuilder = partialMethodImplementation.MethodBuilder;
1286
 
                                        }
1287
 
 
1288
 
                                        return;
1289
 
                                }
1290
 
                                
1291
 
                                if ((ModFlags & Modifiers.PARTIAL) != 0 && (caching_flags & Flags.PartialDefinitionExists) == 0) {
1292
 
                                        Report.Error (759, Location, "A partial method `{0}' implementation is missing a partial method declaration",
1293
 
                                                GetSignatureForError ());
1294
 
                                }
1295
 
 
1296
 
                                if (CurrentTypeParameters != null) {
1297
 
                                        for (int i = 0; i < CurrentTypeParameters.Count; ++i) {
1298
 
                                                var tp = CurrentTypeParameters [i];
1299
 
                                                tp.CheckGenericConstraints (false);
1300
 
                                                tp.Emit ();
1301
 
                                        }
1302
 
                                }
1303
 
 
1304
 
                                base.Emit ();
1305
 
                                
1306
 
                                if ((ModFlags & Modifiers.METHOD_EXTENSION) != 0)
1307
 
                                        Module.PredefinedAttributes.Extension.EmitAttribute (MethodBuilder);
1308
 
                        } catch {
1309
 
                                Console.WriteLine ("Internal compiler error at {0}: exception caught while emitting {1}",
1310
 
                                                   Location, MethodBuilder);
1311
 
                                throw;
1312
 
                        }
1313
 
                }
1314
 
 
1315
 
                public override bool EnableOverloadChecks (MemberCore overload)
1316
 
                {
1317
 
                        if (overload is Indexer)
1318
 
                                return false;
1319
 
 
1320
 
                        return base.EnableOverloadChecks (overload);
1321
 
                }
1322
 
 
1323
 
                public static void Error1599 (Location loc, TypeSpec t, Report Report)
1324
 
                {
1325
 
                        Report.Error (1599, loc, "Method or delegate cannot return type `{0}'", TypeManager.CSharpName (t));
1326
 
                }
1327
 
 
1328
 
                protected override bool ResolveMemberType ()
1329
 
                {
1330
 
                        if (CurrentTypeParameters != null) {
1331
 
                                MethodBuilder = Parent.TypeBuilder.DefineMethod (GetFullName (MemberName), flags);
1332
 
                                CreateTypeParameters ();
1333
 
                        }
1334
 
 
1335
 
                        return base.ResolveMemberType ();
1336
 
                }
1337
 
 
1338
 
                public void SetPartialDefinition (Method methodDefinition)
1339
 
                {
1340
 
                        caching_flags |= Flags.PartialDefinitionExists;
1341
 
                        methodDefinition.partialMethodImplementation = this;
1342
 
 
1343
 
                        // Ensure we are always using method declaration parameters
1344
 
                        for (int i = 0; i < methodDefinition.parameters.Count; ++i ) {
1345
 
                                parameters [i].Name = methodDefinition.parameters [i].Name;
1346
 
                                parameters [i].DefaultValue = methodDefinition.parameters [i].DefaultValue;
1347
 
                        }
1348
 
 
1349
 
                        if (methodDefinition.attributes == null)
1350
 
                                return;
1351
 
 
1352
 
                        if (attributes == null) {
1353
 
                                attributes = methodDefinition.attributes;
1354
 
                        } else {
1355
 
                                attributes.Attrs.AddRange (methodDefinition.attributes.Attrs);
1356
 
                        }
1357
 
                }
1358
 
        }
1359
 
 
1360
 
        public abstract class ConstructorInitializer : ExpressionStatement
1361
 
        {
1362
 
                Arguments argument_list;
1363
 
                MethodSpec base_ctor;
1364
 
 
1365
 
                public ConstructorInitializer (Arguments argument_list, Location loc)
1366
 
                {
1367
 
                        this.argument_list = argument_list;
1368
 
                        this.loc = loc;
1369
 
                }
1370
 
 
1371
 
                public Arguments Arguments {
1372
 
                        get {
1373
 
                                return argument_list;
1374
 
                        }
1375
 
                }
1376
 
 
1377
 
                public override bool ContainsEmitWithAwait ()
1378
 
                {
1379
 
                        throw new NotSupportedException ();
1380
 
                }
1381
 
 
1382
 
                public override Expression CreateExpressionTree (ResolveContext ec)
1383
 
                {
1384
 
                        throw new NotSupportedException ("ET");
1385
 
                }
1386
 
 
1387
 
                protected override Expression DoResolve (ResolveContext ec)
1388
 
                {
1389
 
                        eclass = ExprClass.Value;
1390
 
 
1391
 
                        // FIXME: Hack
1392
 
                        var caller_builder = (Constructor) ec.MemberContext;
1393
 
 
1394
 
                        //
1395
 
                        // Spec mandates that constructor initializer will not have `this' access
1396
 
                        //
1397
 
                        using (ec.Set (ResolveContext.Options.BaseInitializer)) {
1398
 
                                if (argument_list != null) {
1399
 
                                        bool dynamic;
1400
 
                                        argument_list.Resolve (ec, out dynamic);
1401
 
 
1402
 
                                        if (dynamic) {
1403
 
                                                ec.Report.Error (1975, loc,
1404
 
                                                        "The constructor call cannot be dynamically dispatched within constructor initializer");
1405
 
 
1406
 
                                                return null;
1407
 
                                        }
1408
 
                                }
1409
 
 
1410
 
                                type = ec.CurrentType;
1411
 
                                if (this is ConstructorBaseInitializer) {
1412
 
                                        if (ec.CurrentType.BaseType == null)
1413
 
                                                return this;
1414
 
 
1415
 
                                        type = ec.CurrentType.BaseType;
1416
 
                                        if (ec.CurrentType.IsStruct) {
1417
 
                                                ec.Report.Error (522, loc,
1418
 
                                                        "`{0}': Struct constructors cannot call base constructors", caller_builder.GetSignatureForError ());
1419
 
                                                return this;
1420
 
                                        }
1421
 
                                } else {
1422
 
                                        //
1423
 
                                        // It is legal to have "this" initializers that take no arguments
1424
 
                                        // in structs, they are just no-ops.
1425
 
                                        //
1426
 
                                        // struct D { public D (int a) : this () {}
1427
 
                                        //
1428
 
                                        if (ec.CurrentType.IsStruct && argument_list == null)
1429
 
                                                return this;
1430
 
                                }
1431
 
 
1432
 
                                base_ctor = ConstructorLookup (ec, type, ref argument_list, loc);
1433
 
                        }
1434
 
        
1435
 
                        if (base_ctor.MemberDefinition == caller_builder.Spec.MemberDefinition) {
1436
 
                                ec.Report.Error (516, loc, "Constructor `{0}' cannot call itself",
1437
 
                                        caller_builder.GetSignatureForError ());
1438
 
                        }
1439
 
 
1440
 
                        return this;
1441
 
                }
1442
 
 
1443
 
                public override void Emit (EmitContext ec)
1444
 
                {
1445
 
                        // It can be null for static initializers
1446
 
                        if (base_ctor == null)
1447
 
                                return;
1448
 
                        
1449
 
                        var call = new CallEmitter ();
1450
 
                        call.InstanceExpression = new CompilerGeneratedThis (type, loc); 
1451
 
                        call.EmitPredefined (ec, base_ctor, argument_list);
1452
 
                }
1453
 
 
1454
 
                public override void EmitStatement (EmitContext ec)
1455
 
                {
1456
 
                        Emit (ec);
1457
 
                }
1458
 
        }
1459
 
 
1460
 
        public class ConstructorBaseInitializer : ConstructorInitializer {
1461
 
                public ConstructorBaseInitializer (Arguments argument_list, Location l) :
1462
 
                        base (argument_list, l)
1463
 
                {
1464
 
                }
1465
 
        }
1466
 
 
1467
 
        class GeneratedBaseInitializer: ConstructorBaseInitializer {
1468
 
                public GeneratedBaseInitializer (Location loc):
1469
 
                        base (null, loc)
1470
 
                {
1471
 
                }
1472
 
        }
1473
 
 
1474
 
        public class ConstructorThisInitializer : ConstructorInitializer {
1475
 
                public ConstructorThisInitializer (Arguments argument_list, Location l) :
1476
 
                        base (argument_list, l)
1477
 
                {
1478
 
                }
1479
 
        }
1480
 
        
1481
 
        public class Constructor : MethodCore, IMethodData
1482
 
        {
1483
 
                public ConstructorBuilder ConstructorBuilder;
1484
 
                public ConstructorInitializer Initializer;
1485
 
                SecurityType declarative_security;
1486
 
                bool has_compliant_args;
1487
 
                SourceMethodBuilder debug_builder;
1488
 
 
1489
 
                // <summary>
1490
 
                //   Modifiers allowed for a constructor.
1491
 
                // </summary>
1492
 
                public const Modifiers AllowedModifiers =
1493
 
                        Modifiers.PUBLIC |
1494
 
                        Modifiers.PROTECTED |
1495
 
                        Modifiers.INTERNAL |
1496
 
                        Modifiers.STATIC |
1497
 
                        Modifiers.UNSAFE |
1498
 
                        Modifiers.EXTERN |              
1499
 
                        Modifiers.PRIVATE;
1500
 
 
1501
 
                static readonly string[] attribute_targets = new string [] { "method" };
1502
 
 
1503
 
                public static readonly string ConstructorName = ".ctor";
1504
 
                public static readonly string TypeConstructorName = ".cctor";
1505
 
 
1506
 
                public Constructor (TypeDefinition parent, string name, Modifiers mod, Attributes attrs, ParametersCompiled args, Location loc)
1507
 
                        : base (parent, null, mod, AllowedModifiers, new MemberName (name, loc), attrs, args)
1508
 
                {
1509
 
                }
1510
 
 
1511
 
                public bool HasCompliantArgs {
1512
 
                        get {
1513
 
                                return has_compliant_args;
1514
 
                        }
1515
 
                }
1516
 
 
1517
 
                public override AttributeTargets AttributeTargets {
1518
 
                        get {
1519
 
                                return AttributeTargets.Constructor;
1520
 
                        }
1521
 
                }
1522
 
 
1523
 
                bool IMethodData.IsAccessor {
1524
 
                    get {
1525
 
                        return false;
1526
 
                    }
1527
 
                }
1528
 
 
1529
 
                //
1530
 
                // Returns true if this is a default constructor
1531
 
                //
1532
 
                public bool IsDefault ()
1533
 
                {
1534
 
                        if ((ModFlags & Modifiers.STATIC) != 0)
1535
 
                                return parameters.IsEmpty;
1536
 
 
1537
 
                        return parameters.IsEmpty &&
1538
 
                                        (Initializer is ConstructorBaseInitializer) &&
1539
 
                                        (Initializer.Arguments == null);
1540
 
                }
1541
 
 
1542
 
                public override void Accept (StructuralVisitor visitor)
1543
 
                {
1544
 
                        visitor.Visit (this);
1545
 
                }
1546
 
 
1547
 
                public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
1548
 
                {
1549
 
                        if (a.IsValidSecurityAttribute ()) {
1550
 
                                a.ExtractSecurityPermissionSet (ctor, ref declarative_security);
1551
 
                                return;
1552
 
                        }
1553
 
 
1554
 
                        if (a.Type == pa.MethodImpl) {
1555
 
                                is_external_implementation = a.IsInternalCall ();
1556
 
                        }
1557
 
 
1558
 
                        ConstructorBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
1559
 
                }
1560
 
 
1561
 
                protected override bool CheckBase ()
1562
 
                {
1563
 
                        if ((ModFlags & Modifiers.STATIC) != 0) {
1564
 
                                if (!parameters.IsEmpty) {
1565
 
                                        Report.Error (132, Location, "`{0}': The static constructor must be parameterless",
1566
 
                                                GetSignatureForError ());
1567
 
                                        return false;
1568
 
                                }
1569
 
 
1570
 
                                if ((caching_flags & Flags.MethodOverloadsExist) != 0)
1571
 
                                        Parent.MemberCache.CheckExistingMembersOverloads (this, parameters);
1572
 
 
1573
 
                                // the rest can be ignored
1574
 
                                return true;
1575
 
                        }
1576
 
 
1577
 
                        // Check whether arguments were correct.
1578
 
                        if (!DefineParameters (parameters))
1579
 
                                return false;
1580
 
 
1581
 
                        if ((caching_flags & Flags.MethodOverloadsExist) != 0)
1582
 
                                Parent.MemberCache.CheckExistingMembersOverloads (this, parameters);
1583
 
 
1584
 
                        if (Parent.PartialContainer.Kind == MemberKind.Struct && parameters.IsEmpty) {
1585
 
                                Report.Error (568, Location, 
1586
 
                                        "Structs cannot contain explicit parameterless constructors");
1587
 
                                return false;
1588
 
                        }
1589
 
 
1590
 
                        CheckProtectedModifier ();
1591
 
                        
1592
 
                        return true;
1593
 
                }
1594
 
                
1595
 
                //
1596
 
                // Creates the ConstructorBuilder
1597
 
                //
1598
 
                public override bool Define ()
1599
 
                {
1600
 
                        if (ConstructorBuilder != null)
1601
 
                                return true;
1602
 
 
1603
 
                        if (!CheckAbstractAndExtern (block != null))
1604
 
                                return false;
1605
 
                        
1606
 
                        // Check if arguments were correct.
1607
 
                        if (!CheckBase ())
1608
 
                                return false;
1609
 
 
1610
 
                        var ca = ModifiersExtensions.MethodAttr (ModFlags) | MethodAttributes.RTSpecialName | MethodAttributes.SpecialName;
1611
 
 
1612
 
                        ConstructorBuilder = Parent.TypeBuilder.DefineConstructor (
1613
 
                                ca, CallingConventions,
1614
 
                                parameters.GetMetaInfo ());
1615
 
 
1616
 
                        spec = new MethodSpec (MemberKind.Constructor, Parent.Definition, this, Compiler.BuiltinTypes.Void, ConstructorBuilder, parameters, ModFlags);
1617
 
                        
1618
 
                        Parent.MemberCache.AddMember (spec);
1619
 
                        
1620
 
                        // It's here only to report an error
1621
 
                        if (block != null && block.IsIterator) {
1622
 
                                member_type = Compiler.BuiltinTypes.Void;
1623
 
                                Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags);
1624
 
                        }
1625
 
 
1626
 
                        return true;
1627
 
                }
1628
 
 
1629
 
                //
1630
 
                // Emits the code
1631
 
                //
1632
 
                public override void Emit ()
1633
 
                {
1634
 
                        if (Parent.PartialContainer.IsComImport) {
1635
 
                                if (!IsDefault ()) {
1636
 
                                        Report.Error (669, Location, "`{0}': A class with the ComImport attribute cannot have a user-defined constructor",
1637
 
                                                Parent.GetSignatureForError ());
1638
 
                                }
1639
 
 
1640
 
                                // Set as internal implementation and reset block data
1641
 
                                // to ensure no IL is generated
1642
 
                                ConstructorBuilder.SetImplementationFlags (MethodImplAttributes.InternalCall);
1643
 
                                block = null;
1644
 
                        }
1645
 
 
1646
 
                        if ((ModFlags & Modifiers.DEBUGGER_HIDDEN) != 0)
1647
 
                                Module.PredefinedAttributes.DebuggerHidden.EmitAttribute (ConstructorBuilder);
1648
 
 
1649
 
                        if (OptAttributes != null)
1650
 
                                OptAttributes.Emit ();
1651
 
 
1652
 
                        base.Emit ();
1653
 
                        parameters.ApplyAttributes (this, ConstructorBuilder);
1654
 
 
1655
 
 
1656
 
                        BlockContext bc = new BlockContext (this, block, Compiler.BuiltinTypes.Void);
1657
 
                        bc.Set (ResolveContext.Options.ConstructorScope);
1658
 
 
1659
 
                        //
1660
 
                        // If we use a "this (...)" constructor initializer, then
1661
 
                        // do not emit field initializers, they are initialized in the other constructor
1662
 
                        //
1663
 
                        if (!(Initializer is ConstructorThisInitializer))
1664
 
                                Parent.PartialContainer.ResolveFieldInitializers (bc);
1665
 
 
1666
 
                        if (block != null) {
1667
 
                                if (!IsStatic) {
1668
 
                                        if (Initializer == null) {
1669
 
                                                if (Parent.PartialContainer.Kind == MemberKind.Struct) {
1670
 
                                                        //
1671
 
                                                        // If this is a non-static `struct' constructor and doesn't have any
1672
 
                                                        // initializer, it must initialize all of the struct's fields.
1673
 
                                                        //
1674
 
                                                        block.AddThisVariable (bc);
1675
 
                                                } else if (Parent.PartialContainer.Kind == MemberKind.Class) {
1676
 
                                                        Initializer = new GeneratedBaseInitializer (Location);
1677
 
                                                }
1678
 
                                        }
1679
 
 
1680
 
                                        if (Initializer != null) {
1681
 
                                                //
1682
 
                                                // mdb format does not support reqions. Try to workaround this by emitting the
1683
 
                                                // sequence point at initializer. Any breakpoint at constructor header should
1684
 
                                                // be adjusted to this sequence point as it's the next one which follows.
1685
 
                                                //
1686
 
                                                block.AddScopeStatement (new StatementExpression (Initializer));
1687
 
                                        }
1688
 
                                }
1689
 
 
1690
 
                                if (block.Resolve (null, bc, this)) {
1691
 
                                        debug_builder = Parent.CreateMethodSymbolEntry ();
1692
 
                                        EmitContext ec = new EmitContext (this, ConstructorBuilder.GetILGenerator (), bc.ReturnType, debug_builder);
1693
 
                                        ec.With (EmitContext.Options.ConstructorScope, true);
1694
 
 
1695
 
                                        block.Emit (ec);
1696
 
                                }
1697
 
                        }
1698
 
 
1699
 
                        if (declarative_security != null) {
1700
 
                                foreach (var de in declarative_security) {
1701
 
#if STATIC
1702
 
                                        ConstructorBuilder.__AddDeclarativeSecurity (de);
1703
 
#else
1704
 
                                        ConstructorBuilder.AddDeclarativeSecurity (de.Key, de.Value);
1705
 
#endif
1706
 
                                }
1707
 
                        }
1708
 
 
1709
 
                        block = null;
1710
 
                }
1711
 
 
1712
 
                protected override MemberSpec FindBaseMember (out MemberSpec bestCandidate, ref bool overrides)
1713
 
                {
1714
 
                        // Is never override
1715
 
                        bestCandidate = null;
1716
 
                        return null;
1717
 
                }
1718
 
 
1719
 
                public override string GetCallerMemberName ()
1720
 
                {
1721
 
                        return IsStatic ? TypeConstructorName : ConstructorName;
1722
 
                }
1723
 
 
1724
 
                public override string GetSignatureForDocumentation ()
1725
 
                {
1726
 
                        return Parent.GetSignatureForDocumentation () + ".#ctor" + parameters.GetSignatureForDocumentation ();
1727
 
                }
1728
 
 
1729
 
                public override string GetSignatureForError()
1730
 
                {
1731
 
                        return base.GetSignatureForError () + parameters.GetSignatureForError ();
1732
 
                }
1733
 
 
1734
 
                public override string[] ValidAttributeTargets {
1735
 
                        get {
1736
 
                                return attribute_targets;
1737
 
                        }
1738
 
                }
1739
 
 
1740
 
                protected override bool VerifyClsCompliance ()
1741
 
                {
1742
 
                        if (!base.VerifyClsCompliance () || !IsExposedFromAssembly ()) {
1743
 
                                return false;
1744
 
                        }
1745
 
 
1746
 
                        if (!parameters.IsEmpty && Parent.Definition.IsAttribute) {
1747
 
                                foreach (TypeSpec param in parameters.Types) {
1748
 
                                        if (param.IsArray) {
1749
 
                                                return true;
1750
 
                                        }
1751
 
                                }
1752
 
                        }
1753
 
 
1754
 
                        has_compliant_args = true;
1755
 
                        return true;
1756
 
                }
1757
 
 
1758
 
                public override void WriteDebugSymbol (MonoSymbolFile file)
1759
 
                {
1760
 
                        if (debug_builder == null)
1761
 
                                return;
1762
 
 
1763
 
                        var token = ConstructorBuilder.GetToken ();
1764
 
                        int t = token.Token;
1765
 
#if STATIC
1766
 
                        if (token.IsPseudoToken)
1767
 
                                t = Module.Builder.ResolvePseudoToken (t);
1768
 
#endif
1769
 
 
1770
 
                        debug_builder.DefineMethod (file, t);
1771
 
                }
1772
 
 
1773
 
                #region IMethodData Members
1774
 
 
1775
 
                public MemberName MethodName {
1776
 
                        get {
1777
 
                                return MemberName;
1778
 
                        }
1779
 
                }
1780
 
 
1781
 
                public TypeSpec ReturnType {
1782
 
                        get {
1783
 
                                return MemberType;
1784
 
                        }
1785
 
                }
1786
 
 
1787
 
                EmitContext IMethodData.CreateEmitContext (ILGenerator ig, SourceMethodBuilder sourceMethod)
1788
 
                {
1789
 
                        throw new NotImplementedException ();
1790
 
                }
1791
 
 
1792
 
                #endregion
1793
 
        }
1794
 
 
1795
 
        /// <summary>
1796
 
        /// Interface for MethodData class. Holds links to parent members to avoid member duplication.
1797
 
        /// </summary>
1798
 
        public interface IMethodData : IMemberContext
1799
 
        {
1800
 
                CallingConventions CallingConventions { get; }
1801
 
                Location Location { get; }
1802
 
                MemberName MethodName { get; }
1803
 
                TypeSpec ReturnType { get; }
1804
 
                ParametersCompiled ParameterInfo { get; }
1805
 
                MethodSpec Spec { get; }
1806
 
                bool IsAccessor { get; }
1807
 
 
1808
 
                Attributes OptAttributes { get; }
1809
 
                ToplevelBlock Block { get; set; }
1810
 
 
1811
 
                EmitContext CreateEmitContext (ILGenerator ig, SourceMethodBuilder sourceMethod);
1812
 
        }
1813
 
 
1814
 
        //
1815
 
        // Encapsulates most of the Method's state
1816
 
        //
1817
 
        public class MethodData
1818
 
        {
1819
 
#if !STATIC
1820
 
                static FieldInfo methodbuilder_attrs_field;
1821
 
#endif
1822
 
 
1823
 
                public readonly IMethodData method;
1824
 
 
1825
 
                //
1826
 
                // Are we implementing an interface ?
1827
 
                //
1828
 
                public MethodSpec implementing;
1829
 
 
1830
 
                //
1831
 
                // Protected data.
1832
 
                //
1833
 
                protected InterfaceMemberBase member;
1834
 
                protected Modifiers modifiers;
1835
 
                protected MethodAttributes flags;
1836
 
                protected TypeSpec declaring_type;
1837
 
                protected MethodSpec parent_method;
1838
 
                SourceMethodBuilder debug_builder;
1839
 
 
1840
 
                MethodBuilder builder;
1841
 
                public MethodBuilder MethodBuilder {
1842
 
                        get {
1843
 
                                return builder;
1844
 
                        }
1845
 
                }
1846
 
 
1847
 
                public TypeSpec DeclaringType {
1848
 
                        get {
1849
 
                                return declaring_type;
1850
 
                        }
1851
 
                }
1852
 
 
1853
 
                public MethodData (InterfaceMemberBase member,
1854
 
                                   Modifiers modifiers, MethodAttributes flags, IMethodData method)
1855
 
                {
1856
 
                        this.member = member;
1857
 
                        this.modifiers = modifiers;
1858
 
                        this.flags = flags;
1859
 
 
1860
 
                        this.method = method;
1861
 
                }
1862
 
 
1863
 
                public MethodData (InterfaceMemberBase member,
1864
 
                                   Modifiers modifiers, MethodAttributes flags, 
1865
 
                                   IMethodData method, MethodBuilder builder,
1866
 
                                   MethodSpec parent_method)
1867
 
                        : this (member, modifiers, flags, method)
1868
 
                {
1869
 
                        this.builder = builder;
1870
 
                        this.parent_method = parent_method;
1871
 
                }
1872
 
 
1873
 
                public bool Define (TypeDefinition container, string method_full_name)
1874
 
                {
1875
 
                        PendingImplementation pending = container.PendingImplementations;
1876
 
                        MethodSpec ambig_iface_method;
1877
 
                        bool optional = false;
1878
 
 
1879
 
                        if (pending != null) {
1880
 
                                implementing = pending.IsInterfaceMethod (method.MethodName, member.InterfaceType, this, out ambig_iface_method, ref optional);
1881
 
 
1882
 
                                if (member.InterfaceType != null) {
1883
 
                                        if (implementing == null) {
1884
 
                                                if (member is PropertyBase) {
1885
 
                                                        container.Compiler.Report.Error (550, method.Location,
1886
 
                                                                "`{0}' is an accessor not found in interface member `{1}{2}'",
1887
 
                                                                          method.GetSignatureForError (), TypeManager.CSharpName (member.InterfaceType),
1888
 
                                                                          member.GetSignatureForError ().Substring (member.GetSignatureForError ().LastIndexOf ('.')));
1889
 
 
1890
 
                                                } else {
1891
 
                                                        container.Compiler.Report.Error (539, method.Location,
1892
 
                                                                          "`{0}.{1}' in explicit interface declaration is not a member of interface",
1893
 
                                                                          TypeManager.CSharpName (member.InterfaceType), member.ShortName);
1894
 
                                                }
1895
 
                                                return false;
1896
 
                                        }
1897
 
                                        if (implementing.IsAccessor && !method.IsAccessor) {
1898
 
                                                container.Compiler.Report.SymbolRelatedToPreviousError (implementing);
1899
 
                                                container.Compiler.Report.Error (683, method.Location,
1900
 
                                                        "`{0}' explicit method implementation cannot implement `{1}' because it is an accessor",
1901
 
                                                        member.GetSignatureForError (), TypeManager.CSharpSignature (implementing));
1902
 
                                                return false;
1903
 
                                        }
1904
 
                                } else {
1905
 
                                        if (implementing != null) {
1906
 
                                                if (!method.IsAccessor) {
1907
 
                                                        if (implementing.IsAccessor) {
1908
 
                                                                container.Compiler.Report.SymbolRelatedToPreviousError (implementing);
1909
 
                                                                container.Compiler.Report.Error (470, method.Location,
1910
 
                                                                        "Method `{0}' cannot implement interface accessor `{1}'",
1911
 
                                                                        method.GetSignatureForError (), TypeManager.CSharpSignature (implementing));
1912
 
                                                        }
1913
 
                                                } else if (implementing.DeclaringType.IsInterface) {
1914
 
                                                        if (!implementing.IsAccessor) {
1915
 
                                                                container.Compiler.Report.SymbolRelatedToPreviousError (implementing);
1916
 
                                                                container.Compiler.Report.Error (686, method.Location,
1917
 
                                                                        "Accessor `{0}' cannot implement interface member `{1}' for type `{2}'. Use an explicit interface implementation",
1918
 
                                                                        method.GetSignatureForError (), TypeManager.CSharpSignature (implementing), container.GetSignatureForError ());
1919
 
                                                        } else {
1920
 
                                                                PropertyBase.PropertyMethod pm = method as PropertyBase.PropertyMethod;
1921
 
                                                                if (pm != null && pm.HasCustomAccessModifier && (pm.ModFlags & Modifiers.PUBLIC) == 0) {
1922
 
                                                                        container.Compiler.Report.SymbolRelatedToPreviousError (implementing);
1923
 
                                                                        container.Compiler.Report.Error (277, method.Location,
1924
 
                                                                                "Accessor `{0}' must be declared public to implement interface member `{1}'",
1925
 
                                                                                method.GetSignatureForError (), implementing.GetSignatureForError ());
1926
 
                                                                }
1927
 
                                                        }
1928
 
                                                }
1929
 
                                        }
1930
 
                                }
1931
 
                        } else {
1932
 
                                ambig_iface_method = null;
1933
 
                        }
1934
 
 
1935
 
                        //
1936
 
                        // For implicit implementations, make sure we are public, for
1937
 
                        // explicit implementations, make sure we are private.
1938
 
                        //
1939
 
                        if (implementing != null){
1940
 
                                if (member.IsExplicitImpl) {
1941
 
                                        if (method.ParameterInfo.HasParams && !implementing.Parameters.HasParams) {
1942
 
                                                container.Compiler.Report.SymbolRelatedToPreviousError (implementing);
1943
 
                                                container.Compiler.Report.Error (466, method.Location,
1944
 
                                                        "`{0}': the explicit interface implementation cannot introduce the params modifier",
1945
 
                                                        method.GetSignatureForError ());
1946
 
                                        }
1947
 
 
1948
 
                                        if (ambig_iface_method != null) {
1949
 
                                                container.Compiler.Report.SymbolRelatedToPreviousError (ambig_iface_method);
1950
 
                                                container.Compiler.Report.SymbolRelatedToPreviousError (implementing);
1951
 
                                                container.Compiler.Report.Warning (473, 2, method.Location,
1952
 
                                                        "Explicit interface implementation `{0}' matches more than one interface member. Consider using a non-explicit implementation instead",
1953
 
                                                        method.GetSignatureForError ());
1954
 
                                        }
1955
 
                                } else {
1956
 
                                        //
1957
 
                                        // Setting implementin to null inside this block will trigger a more
1958
 
                                        // verbose error reporting for missing interface implementations
1959
 
                                        //
1960
 
                                        if (implementing.DeclaringType.IsInterface) {
1961
 
                                                //
1962
 
                                                // If this is an interface method implementation,
1963
 
                                                // check for public accessibility
1964
 
                                                //
1965
 
                                                if ((flags & MethodAttributes.MemberAccessMask) != MethodAttributes.Public) {
1966
 
                                                        implementing = null;
1967
 
                                                } else if (optional && (container.Interfaces == null || Array.IndexOf (container.Interfaces, implementing.DeclaringType) < 0)) {
1968
 
                                                        //
1969
 
                                                        // We are not implementing interface when base class already implemented it
1970
 
                                                        //
1971
 
                                                        implementing = null;
1972
 
                                                }
1973
 
                                        } else if ((flags & MethodAttributes.MemberAccessMask) == MethodAttributes.Private) {
1974
 
                                                // We may never be private.
1975
 
                                                implementing = null;
1976
 
 
1977
 
                                        } else if ((modifiers & Modifiers.OVERRIDE) == 0) {
1978
 
                                                //
1979
 
                                                // We may be protected if we're overriding something.
1980
 
                                                //
1981
 
                                                implementing = null;
1982
 
                                        }
1983
 
                                }
1984
 
                                        
1985
 
                                //
1986
 
                                // Static is not allowed
1987
 
                                //
1988
 
                                if ((modifiers & Modifiers.STATIC) != 0){
1989
 
                                        implementing = null;
1990
 
                                }
1991
 
                        }
1992
 
                        
1993
 
                        //
1994
 
                        // If implementing is still valid, set flags
1995
 
                        //
1996
 
                        if (implementing != null){
1997
 
                                //
1998
 
                                // When implementing interface methods, set NewSlot
1999
 
                                // unless, we are overwriting a method.
2000
 
                                //
2001
 
                                if ((modifiers & Modifiers.OVERRIDE) == 0 && implementing.DeclaringType.IsInterface) {
2002
 
                                        flags |= MethodAttributes.NewSlot;
2003
 
                                }
2004
 
 
2005
 
                                flags |= MethodAttributes.Virtual | MethodAttributes.HideBySig;
2006
 
 
2007
 
                                // Set Final unless we're virtual, abstract or already overriding a method.
2008
 
                                if ((modifiers & (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE)) == 0)
2009
 
                                        flags |= MethodAttributes.Final;
2010
 
 
2011
 
                                //
2012
 
                                // clear the pending implementation flag (requires explicit methods to be defined first)
2013
 
                                //
2014
 
                                pending.ImplementMethod (method.MethodName,
2015
 
                                        member.InterfaceType, this, member.IsExplicitImpl, out ambig_iface_method, ref optional);
2016
 
 
2017
 
                                //
2018
 
                                // Update indexer accessor name to match implementing abstract accessor
2019
 
                                //
2020
 
                                if (!implementing.DeclaringType.IsInterface && !member.IsExplicitImpl && implementing.IsAccessor)
2021
 
                                        method_full_name = implementing.MemberDefinition.Name;
2022
 
                        }
2023
 
 
2024
 
                        DefineMethodBuilder (container, method_full_name, method.ParameterInfo);
2025
 
 
2026
 
                        if (builder == null)
2027
 
                                return false;
2028
 
 
2029
 
//                      if (container.CurrentType != null)
2030
 
//                              declaring_type = container.CurrentType;
2031
 
//                      else
2032
 
                                declaring_type = container.Definition;
2033
 
 
2034
 
                        if (implementing != null && member.IsExplicitImpl) {
2035
 
                                container.TypeBuilder.DefineMethodOverride (builder, (MethodInfo) implementing.GetMetaInfo ());
2036
 
                        }
2037
 
 
2038
 
                        return true;
2039
 
                }
2040
 
 
2041
 
 
2042
 
                /// <summary>
2043
 
                /// Create the MethodBuilder for the method 
2044
 
                /// </summary>
2045
 
                void DefineMethodBuilder (TypeDefinition container, string method_name, ParametersCompiled param)
2046
 
                {
2047
 
                        var return_type = method.ReturnType.GetMetaInfo ();
2048
 
                        var p_types = param.GetMetaInfo ();
2049
 
 
2050
 
                        if (builder == null) {
2051
 
                                builder = container.TypeBuilder.DefineMethod (
2052
 
                                        method_name, flags, method.CallingConventions,
2053
 
                                        return_type, p_types);
2054
 
                                return;
2055
 
                        }
2056
 
 
2057
 
                        //
2058
 
                        // Generic method has been already defined to resolve method parameters
2059
 
                        // correctly when they use type parameters
2060
 
                        //
2061
 
                        builder.SetParameters (p_types);
2062
 
                        builder.SetReturnType (return_type);
2063
 
                        if (builder.Attributes != flags) {
2064
 
#if STATIC
2065
 
                                builder.__SetAttributes (flags);
2066
 
#else
2067
 
                                try {
2068
 
                                        if (methodbuilder_attrs_field == null)
2069
 
                                                methodbuilder_attrs_field = typeof (MethodBuilder).GetField ("attrs", BindingFlags.NonPublic | BindingFlags.Instance);
2070
 
                                        methodbuilder_attrs_field.SetValue (builder, flags);
2071
 
                                } catch {
2072
 
                                        container.Compiler.Report.RuntimeMissingSupport (method.Location, "Generic method MethodAttributes");
2073
 
                                }
2074
 
#endif
2075
 
                        }
2076
 
                }
2077
 
 
2078
 
                //
2079
 
                // Emits the code
2080
 
                // 
2081
 
                public void Emit (TypeDefinition parent)
2082
 
                {
2083
 
                        var mc = (IMemberContext) method;
2084
 
 
2085
 
                        method.ParameterInfo.ApplyAttributes (mc, MethodBuilder);
2086
 
 
2087
 
                        ToplevelBlock block = method.Block;
2088
 
                        if (block != null) {
2089
 
                                BlockContext bc = new BlockContext (mc, block, method.ReturnType);
2090
 
                                if (block.Resolve (null, bc, method)) {
2091
 
                                        debug_builder = member.Parent.CreateMethodSymbolEntry ();
2092
 
                                        EmitContext ec = method.CreateEmitContext (MethodBuilder.GetILGenerator (), debug_builder);
2093
 
 
2094
 
                                        block.Emit (ec);
2095
 
                                }
2096
 
                        }
2097
 
                }
2098
 
 
2099
 
                public void WriteDebugSymbol (MonoSymbolFile file)
2100
 
                {
2101
 
                        if (debug_builder == null)
2102
 
                                return;
2103
 
 
2104
 
                        var token = builder.GetToken ();
2105
 
                        int t = token.Token;
2106
 
#if STATIC
2107
 
                        if (token.IsPseudoToken)
2108
 
                                t = member.Module.Builder.ResolvePseudoToken (t);
2109
 
#endif
2110
 
 
2111
 
                        debug_builder.DefineMethod (file, t);
2112
 
                }
2113
 
        }
2114
 
 
2115
 
        public class Destructor : MethodOrOperator
2116
 
        {
2117
 
                const Modifiers AllowedModifiers =
2118
 
                        Modifiers.UNSAFE |
2119
 
                        Modifiers.EXTERN;
2120
 
 
2121
 
                static readonly string[] attribute_targets = new string [] { "method" };
2122
 
 
2123
 
                public static readonly string MetadataName = "Finalize";
2124
 
 
2125
 
                public string Identifier {
2126
 
                        get;
2127
 
                        set;
2128
 
                }
2129
 
                
2130
 
                public Destructor (TypeDefinition parent, Modifiers mod, ParametersCompiled parameters, Attributes attrs, Location l)
2131
 
                        : base (parent, null, mod, AllowedModifiers, new MemberName (MetadataName, l), attrs, parameters)
2132
 
                {
2133
 
                        ModFlags &= ~Modifiers.PRIVATE;
2134
 
                        ModFlags |= Modifiers.PROTECTED | Modifiers.OVERRIDE;
2135
 
                }
2136
 
 
2137
 
                public override void Accept (StructuralVisitor visitor)
2138
 
                {
2139
 
                        visitor.Visit (this);
2140
 
                }
2141
 
 
2142
 
                public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
2143
 
                {
2144
 
                        if (a.Type == pa.Conditional) {
2145
 
                                Error_ConditionalAttributeIsNotValid ();
2146
 
                                return;
2147
 
                        }
2148
 
 
2149
 
                        base.ApplyAttributeBuilder (a, ctor, cdata, pa);
2150
 
                }
2151
 
                
2152
 
                protected override bool CheckBase ()
2153
 
                {
2154
 
                        // Don't check base, destructors have special syntax
2155
 
                        return true;
2156
 
                }
2157
 
 
2158
 
                public override void Emit()
2159
 
                {
2160
 
                        var base_type = Parent.PartialContainer.BaseType;
2161
 
                        if (base_type != null && Block != null) {
2162
 
                                var base_dtor = MemberCache.FindMember (base_type,
2163
 
                                        new MemberFilter (MetadataName, 0, MemberKind.Destructor, null, null), BindingRestriction.InstanceOnly) as MethodSpec;
2164
 
 
2165
 
                                if (base_dtor == null)
2166
 
                                        throw new NotImplementedException ();
2167
 
 
2168
 
                                MethodGroupExpr method_expr = MethodGroupExpr.CreatePredefined (base_dtor, base_type, Location);
2169
 
                                method_expr.InstanceExpression = new BaseThis (base_type, Location);
2170
 
 
2171
 
                                var try_block = new ExplicitBlock (block, block.StartLocation, block.EndLocation) {
2172
 
                                        IsCompilerGenerated = true
2173
 
                                };
2174
 
                                var finaly_block = new ExplicitBlock (block, Location, Location) {
2175
 
                                        IsCompilerGenerated = true
2176
 
                                };
2177
 
 
2178
 
                                //
2179
 
                                // 0-size arguments to avoid CS0250 error
2180
 
                                // TODO: Should use AddScopeStatement or something else which emits correct
2181
 
                                // debugger scope
2182
 
                                //
2183
 
                                finaly_block.AddStatement (new StatementExpression (new Invocation (method_expr, new Arguments (0)), Location.Null));
2184
 
 
2185
 
                                var tf = new TryFinally (try_block, finaly_block, Location);
2186
 
                                block.WrapIntoDestructor (tf, try_block);
2187
 
                        }
2188
 
 
2189
 
                        base.Emit ();
2190
 
                }
2191
 
 
2192
 
                public override string GetSignatureForError ()
2193
 
                {
2194
 
                        return Parent.GetSignatureForError () + ".~" + Parent.MemberName.Name + "()";
2195
 
                }
2196
 
 
2197
 
                protected override bool ResolveMemberType ()
2198
 
                {
2199
 
                        member_type = Compiler.BuiltinTypes.Void;
2200
 
                        return true;
2201
 
                }
2202
 
 
2203
 
                public override string[] ValidAttributeTargets {
2204
 
                        get {
2205
 
                                return attribute_targets;
2206
 
                        }
2207
 
                }
2208
 
        }
2209
 
 
2210
 
        // Ooouh Martin, templates are missing here.
2211
 
        // When it will be possible move here a lot of child code and template method type.
2212
 
        public abstract class AbstractPropertyEventMethod : MemberCore, IMethodData {
2213
 
                protected MethodData method_data;
2214
 
                protected ToplevelBlock block;
2215
 
                protected SecurityType declarative_security;
2216
 
 
2217
 
                protected readonly string prefix;
2218
 
 
2219
 
                ReturnParameter return_attributes;
2220
 
 
2221
 
                public AbstractPropertyEventMethod (InterfaceMemberBase member, string prefix, Attributes attrs, Location loc)
2222
 
                        : base (member.Parent, SetupName (prefix, member, loc), attrs)
2223
 
                {
2224
 
                        this.prefix = prefix;
2225
 
                }
2226
 
 
2227
 
                static MemberName SetupName (string prefix, InterfaceMemberBase member, Location loc)
2228
 
                {
2229
 
                        return new MemberName (member.MemberName.Left, prefix + member.ShortName, member.MemberName.ExplicitInterface, loc);
2230
 
                }
2231
 
 
2232
 
                public void UpdateName (InterfaceMemberBase member)
2233
 
                {
2234
 
                        SetMemberName (SetupName (prefix, member, Location));
2235
 
                }
2236
 
 
2237
 
                #region IMethodData Members
2238
 
 
2239
 
                public ToplevelBlock Block {
2240
 
                        get {
2241
 
                                return block;
2242
 
                        }
2243
 
 
2244
 
                        set {
2245
 
                                block = value;
2246
 
                        }
2247
 
                }
2248
 
 
2249
 
                public CallingConventions CallingConventions {
2250
 
                        get {
2251
 
                                return CallingConventions.Standard;
2252
 
                        }
2253
 
                }
2254
 
 
2255
 
                public EmitContext CreateEmitContext (ILGenerator ig, SourceMethodBuilder sourceMethod)
2256
 
                {
2257
 
                        return new EmitContext (this, ig, ReturnType, sourceMethod);
2258
 
                }
2259
 
 
2260
 
                public bool IsAccessor {
2261
 
                        get {
2262
 
                                return true;
2263
 
                        }
2264
 
                }
2265
 
 
2266
 
                public MemberName MethodName {
2267
 
                        get {
2268
 
                                return MemberName;
2269
 
                        }
2270
 
                }
2271
 
 
2272
 
                public TypeSpec[] ParameterTypes { 
2273
 
                        get {
2274
 
                                return ParameterInfo.Types;
2275
 
                        }
2276
 
                }
2277
 
 
2278
 
                public abstract ParametersCompiled ParameterInfo { get ; }
2279
 
                public abstract TypeSpec ReturnType { get; }
2280
 
 
2281
 
                #endregion
2282
 
 
2283
 
                public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
2284
 
                {
2285
 
                        if (a.Type == pa.CLSCompliant || a.Type == pa.Obsolete || a.Type == pa.Conditional) {
2286
 
                                Report.Error (1667, a.Location,
2287
 
                                        "Attribute `{0}' is not valid on property or event accessors. It is valid on `{1}' declarations only",
2288
 
                                        TypeManager.CSharpName (a.Type), a.GetValidTargets ());
2289
 
                                return;
2290
 
                        }
2291
 
 
2292
 
                        if (a.IsValidSecurityAttribute ()) {
2293
 
                                a.ExtractSecurityPermissionSet (ctor, ref declarative_security);
2294
 
                                return;
2295
 
                        }
2296
 
 
2297
 
                        if (a.Target == AttributeTargets.Method) {
2298
 
                                method_data.MethodBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
2299
 
                                return;
2300
 
                        }
2301
 
 
2302
 
                        if (a.Target == AttributeTargets.ReturnValue) {
2303
 
                                if (return_attributes == null)
2304
 
                                        return_attributes = new ReturnParameter (this, method_data.MethodBuilder, Location);
2305
 
 
2306
 
                                return_attributes.ApplyAttributeBuilder (a, ctor, cdata, pa);
2307
 
                                return;
2308
 
                        }
2309
 
 
2310
 
                        ApplyToExtraTarget (a, ctor, cdata, pa);
2311
 
                }
2312
 
 
2313
 
                protected virtual void ApplyToExtraTarget (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
2314
 
                {
2315
 
                        throw new NotSupportedException ("You forgot to define special attribute target handling");
2316
 
                }
2317
 
 
2318
 
                // It is not supported for the accessors
2319
 
                public sealed override bool Define()
2320
 
                {
2321
 
                        throw new NotSupportedException ();
2322
 
                }
2323
 
 
2324
 
                public virtual void Emit (TypeDefinition parent)
2325
 
                {
2326
 
                        method_data.Emit (parent);
2327
 
 
2328
 
                        if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0 && !Parent.IsCompilerGenerated)
2329
 
                                Module.PredefinedAttributes.CompilerGenerated.EmitAttribute (method_data.MethodBuilder);
2330
 
                        if (((ModFlags & Modifiers.DEBUGGER_HIDDEN) != 0))
2331
 
                                Module.PredefinedAttributes.DebuggerHidden.EmitAttribute (method_data.MethodBuilder);
2332
 
 
2333
 
                        if (ReturnType.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
2334
 
                                return_attributes = new ReturnParameter (this, method_data.MethodBuilder, Location);
2335
 
                                Module.PredefinedAttributes.Dynamic.EmitAttribute (return_attributes.Builder);
2336
 
                        } else if (ReturnType.HasDynamicElement) {
2337
 
                                return_attributes = new ReturnParameter (this, method_data.MethodBuilder, Location);
2338
 
                                Module.PredefinedAttributes.Dynamic.EmitAttribute (return_attributes.Builder, ReturnType, Location);
2339
 
                        }
2340
 
 
2341
 
                        if (OptAttributes != null)
2342
 
                                OptAttributes.Emit ();
2343
 
 
2344
 
                        if (declarative_security != null) {
2345
 
                                foreach (var de in declarative_security) {
2346
 
#if STATIC
2347
 
                                        method_data.MethodBuilder.__AddDeclarativeSecurity (de);
2348
 
#else
2349
 
                                        method_data.MethodBuilder.AddDeclarativeSecurity (de.Key, de.Value);
2350
 
#endif
2351
 
                                }
2352
 
                        }
2353
 
 
2354
 
                        block = null;
2355
 
                }
2356
 
 
2357
 
                public override bool EnableOverloadChecks (MemberCore overload)
2358
 
                {
2359
 
                        if (overload is MethodCore) {
2360
 
                                caching_flags |= Flags.MethodOverloadsExist;
2361
 
                                return true;
2362
 
                        }
2363
 
 
2364
 
                        // This can only happen with indexers and it will
2365
 
                        // be catched as indexer difference
2366
 
                        if (overload is AbstractPropertyEventMethod)
2367
 
                                return true;
2368
 
 
2369
 
                        return false;
2370
 
                }
2371
 
 
2372
 
                public override string GetCallerMemberName ()
2373
 
                {
2374
 
                        return base.GetCallerMemberName ().Substring (prefix.Length);
2375
 
                }
2376
 
 
2377
 
                public override string GetSignatureForDocumentation ()
2378
 
                {
2379
 
                        // should not be called
2380
 
                        throw new NotSupportedException ();
2381
 
                }
2382
 
 
2383
 
                public override bool IsClsComplianceRequired()
2384
 
                {
2385
 
                        return false;
2386
 
                }
2387
 
 
2388
 
                public override void WriteDebugSymbol (MonoSymbolFile file)
2389
 
                {
2390
 
                        if (method_data != null)
2391
 
                                method_data.WriteDebugSymbol (file);
2392
 
                }
2393
 
 
2394
 
                public MethodSpec Spec { get; protected set; }
2395
 
 
2396
 
                //
2397
 
                //   Represents header string for documentation comment.
2398
 
                //
2399
 
                public override string DocCommentHeader {
2400
 
                        get { throw new InvalidOperationException ("Unexpected attempt to get doc comment from " + this.GetType () + "."); }
2401
 
                }
2402
 
        }
2403
 
 
2404
 
        public class Operator : MethodOrOperator {
2405
 
 
2406
 
                const Modifiers AllowedModifiers =
2407
 
                        Modifiers.PUBLIC |
2408
 
                        Modifiers.UNSAFE |
2409
 
                        Modifiers.EXTERN |
2410
 
                        Modifiers.STATIC;
2411
 
 
2412
 
                public enum OpType : byte {
2413
 
 
2414
 
                        // Unary operators
2415
 
                        LogicalNot,
2416
 
                        OnesComplement,
2417
 
                        Increment,
2418
 
                        Decrement,
2419
 
                        True,
2420
 
                        False,
2421
 
 
2422
 
                        // Unary and Binary operators
2423
 
                        Addition,
2424
 
                        Subtraction,
2425
 
 
2426
 
                        UnaryPlus,
2427
 
                        UnaryNegation,
2428
 
                        
2429
 
                        // Binary operators
2430
 
                        Multiply,
2431
 
                        Division,
2432
 
                        Modulus,
2433
 
                        BitwiseAnd,
2434
 
                        BitwiseOr,
2435
 
                        ExclusiveOr,
2436
 
                        LeftShift,
2437
 
                        RightShift,
2438
 
                        Equality,
2439
 
                        Inequality,
2440
 
                        GreaterThan,
2441
 
                        LessThan,
2442
 
                        GreaterThanOrEqual,
2443
 
                        LessThanOrEqual,
2444
 
 
2445
 
                        // Implicit and Explicit
2446
 
                        Implicit,
2447
 
                        Explicit,
2448
 
 
2449
 
                        // Just because of enum
2450
 
                        TOP
2451
 
                };
2452
 
 
2453
 
                public readonly OpType OperatorType;
2454
 
 
2455
 
                static readonly string [] [] names;
2456
 
 
2457
 
                static Operator ()
2458
 
                {
2459
 
                        names = new string[(int)OpType.TOP][];
2460
 
                        names [(int) OpType.LogicalNot] = new string [] { "!", "op_LogicalNot" };
2461
 
                        names [(int) OpType.OnesComplement] = new string [] { "~", "op_OnesComplement" };
2462
 
                        names [(int) OpType.Increment] = new string [] { "++", "op_Increment" };
2463
 
                        names [(int) OpType.Decrement] = new string [] { "--", "op_Decrement" };
2464
 
                        names [(int) OpType.True] = new string [] { "true", "op_True" };
2465
 
                        names [(int) OpType.False] = new string [] { "false", "op_False" };
2466
 
                        names [(int) OpType.Addition] = new string [] { "+", "op_Addition" };
2467
 
                        names [(int) OpType.Subtraction] = new string [] { "-", "op_Subtraction" };
2468
 
                        names [(int) OpType.UnaryPlus] = new string [] { "+", "op_UnaryPlus" };
2469
 
                        names [(int) OpType.UnaryNegation] = new string [] { "-", "op_UnaryNegation" };
2470
 
                        names [(int) OpType.Multiply] = new string [] { "*", "op_Multiply" };
2471
 
                        names [(int) OpType.Division] = new string [] { "/", "op_Division" };
2472
 
                        names [(int) OpType.Modulus] = new string [] { "%", "op_Modulus" };
2473
 
                        names [(int) OpType.BitwiseAnd] = new string [] { "&", "op_BitwiseAnd" };
2474
 
                        names [(int) OpType.BitwiseOr] = new string [] { "|", "op_BitwiseOr" };
2475
 
                        names [(int) OpType.ExclusiveOr] = new string [] { "^", "op_ExclusiveOr" };
2476
 
                        names [(int) OpType.LeftShift] = new string [] { "<<", "op_LeftShift" };
2477
 
                        names [(int) OpType.RightShift] = new string [] { ">>", "op_RightShift" };
2478
 
                        names [(int) OpType.Equality] = new string [] { "==", "op_Equality" };
2479
 
                        names [(int) OpType.Inequality] = new string [] { "!=", "op_Inequality" };
2480
 
                        names [(int) OpType.GreaterThan] = new string [] { ">", "op_GreaterThan" };
2481
 
                        names [(int) OpType.LessThan] = new string [] { "<", "op_LessThan" };
2482
 
                        names [(int) OpType.GreaterThanOrEqual] = new string [] { ">=", "op_GreaterThanOrEqual" };
2483
 
                        names [(int) OpType.LessThanOrEqual] = new string [] { "<=", "op_LessThanOrEqual" };
2484
 
                        names [(int) OpType.Implicit] = new string [] { "implicit", "op_Implicit" };
2485
 
                        names [(int) OpType.Explicit] = new string [] { "explicit", "op_Explicit" };
2486
 
                }
2487
 
 
2488
 
                public Operator (TypeDefinition parent, OpType type, FullNamedExpression ret_type, Modifiers mod_flags, ParametersCompiled parameters,
2489
 
                                 ToplevelBlock block, Attributes attrs, Location loc)
2490
 
                        : base (parent, ret_type, mod_flags, AllowedModifiers, new MemberName (GetMetadataName (type), loc), attrs, parameters)
2491
 
                {
2492
 
                        OperatorType = type;
2493
 
                        Block = block;
2494
 
                }
2495
 
 
2496
 
                public override void Accept (StructuralVisitor visitor)
2497
 
                {
2498
 
                        visitor.Visit (this);
2499
 
                }
2500
 
 
2501
 
                public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
2502
 
                {
2503
 
                        if (a.Type == pa.Conditional) {
2504
 
                                Error_ConditionalAttributeIsNotValid ();
2505
 
                                return;
2506
 
                        }
2507
 
 
2508
 
                        base.ApplyAttributeBuilder (a, ctor, cdata, pa);
2509
 
                }
2510
 
                
2511
 
                public override bool Define ()
2512
 
                {
2513
 
                        const Modifiers RequiredModifiers = Modifiers.PUBLIC | Modifiers.STATIC;
2514
 
                        if ((ModFlags & RequiredModifiers) != RequiredModifiers){
2515
 
                                Report.Error (558, Location, "User-defined operator `{0}' must be declared static and public", GetSignatureForError ());
2516
 
                        }
2517
 
 
2518
 
                        if (!base.Define ())
2519
 
                                return false;
2520
 
 
2521
 
                        if (block != null && block.IsIterator) {
2522
 
                                //
2523
 
                                // Current method is turned into automatically generated
2524
 
                                // wrapper which creates an instance of iterator
2525
 
                                //
2526
 
                                Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags);
2527
 
                                ModFlags |= Modifiers.DEBUGGER_HIDDEN;
2528
 
                        }
2529
 
 
2530
 
                        // imlicit and explicit operator of same types are not allowed
2531
 
                        if (OperatorType == OpType.Explicit)
2532
 
                                Parent.MemberCache.CheckExistingMembersOverloads (this, GetMetadataName (OpType.Implicit), parameters);
2533
 
                        else if (OperatorType == OpType.Implicit)
2534
 
                                Parent.MemberCache.CheckExistingMembersOverloads (this, GetMetadataName (OpType.Explicit), parameters);
2535
 
 
2536
 
                        TypeSpec declaring_type = Parent.CurrentType;
2537
 
                        TypeSpec return_type = MemberType;
2538
 
                        TypeSpec first_arg_type = ParameterTypes [0];
2539
 
                        
2540
 
                        TypeSpec first_arg_type_unwrap = first_arg_type;
2541
 
                        if (first_arg_type.IsNullableType)
2542
 
                                first_arg_type_unwrap = Nullable.NullableInfo.GetUnderlyingType (first_arg_type);
2543
 
                        
2544
 
                        TypeSpec return_type_unwrap = return_type;
2545
 
                        if (return_type.IsNullableType)
2546
 
                                return_type_unwrap = Nullable.NullableInfo.GetUnderlyingType (return_type);
2547
 
 
2548
 
                        //
2549
 
                        // Rules for conversion operators
2550
 
                        //
2551
 
                        if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
2552
 
                                if (first_arg_type_unwrap == return_type_unwrap && first_arg_type_unwrap == declaring_type) {
2553
 
                                        Report.Error (555, Location,
2554
 
                                                "User-defined operator cannot take an object of the enclosing type and convert to an object of the enclosing type");
2555
 
                                        return false;
2556
 
                                }
2557
 
 
2558
 
                                TypeSpec conv_type;
2559
 
                                if (declaring_type == return_type || declaring_type == return_type_unwrap) {
2560
 
                                        conv_type = first_arg_type;
2561
 
                                } else if (declaring_type == first_arg_type || declaring_type == first_arg_type_unwrap) {
2562
 
                                        conv_type = return_type;
2563
 
                                } else {
2564
 
                                        Report.Error (556, Location,
2565
 
                                                "User-defined conversion must convert to or from the enclosing type");
2566
 
                                        return false;
2567
 
                                }
2568
 
 
2569
 
                                if (conv_type.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
2570
 
                                        Report.Error (1964, Location,
2571
 
                                                "User-defined conversion `{0}' cannot convert to or from the dynamic type",
2572
 
                                                GetSignatureForError ());
2573
 
 
2574
 
                                        return false;
2575
 
                                }
2576
 
 
2577
 
                                if (conv_type.IsInterface) {
2578
 
                                        Report.Error (552, Location, "User-defined conversion `{0}' cannot convert to or from an interface type",
2579
 
                                                GetSignatureForError ());
2580
 
                                        return false;
2581
 
                                }
2582
 
 
2583
 
                                if (conv_type.IsClass) {
2584
 
                                        if (TypeSpec.IsBaseClass (declaring_type, conv_type, true)) {
2585
 
                                                Report.Error (553, Location, "User-defined conversion `{0}' cannot convert to or from a base class",
2586
 
                                                        GetSignatureForError ());
2587
 
                                                return false;
2588
 
                                        }
2589
 
 
2590
 
                                        if (TypeSpec.IsBaseClass (conv_type, declaring_type, false)) {
2591
 
                                                Report.Error (554, Location, "User-defined conversion `{0}' cannot convert to or from a derived class",
2592
 
                                                        GetSignatureForError ());
2593
 
                                                return false;
2594
 
                                        }
2595
 
                                }
2596
 
                        } else if (OperatorType == OpType.LeftShift || OperatorType == OpType.RightShift) {
2597
 
                                if (first_arg_type != declaring_type || parameters.Types[1].BuiltinType != BuiltinTypeSpec.Type.Int) {
2598
 
                                        Report.Error (564, Location, "Overloaded shift operator must have the type of the first operand be the containing type, and the type of the second operand must be int");
2599
 
                                        return false;
2600
 
                                }
2601
 
                        } else if (parameters.Count == 1) {
2602
 
                                // Checks for Unary operators
2603
 
 
2604
 
                                if (OperatorType == OpType.Increment || OperatorType == OpType.Decrement) {
2605
 
                                        if (return_type != declaring_type && !TypeSpec.IsBaseClass (return_type, declaring_type, false)) {
2606
 
                                                Report.Error (448, Location,
2607
 
                                                        "The return type for ++ or -- operator must be the containing type or derived from the containing type");
2608
 
                                                return false;
2609
 
                                        }
2610
 
                                        if (first_arg_type != declaring_type) {
2611
 
                                                Report.Error (
2612
 
                                                        559, Location, "The parameter type for ++ or -- operator must be the containing type");
2613
 
                                                return false;
2614
 
                                        }
2615
 
                                }
2616
 
 
2617
 
                                if (first_arg_type_unwrap != declaring_type) {
2618
 
                                        Report.Error (562, Location,
2619
 
                                                "The parameter type of a unary operator must be the containing type");
2620
 
                                        return false;
2621
 
                                }
2622
 
 
2623
 
                                if (OperatorType == OpType.True || OperatorType == OpType.False) {
2624
 
                                        if (return_type.BuiltinType != BuiltinTypeSpec.Type.Bool) {
2625
 
                                                Report.Error (
2626
 
                                                        215, Location,
2627
 
                                                        "The return type of operator True or False " +
2628
 
                                                        "must be bool");
2629
 
                                                return false;
2630
 
                                        }
2631
 
                                }
2632
 
 
2633
 
                        } else if (first_arg_type_unwrap != declaring_type) {
2634
 
                                // Checks for Binary operators
2635
 
 
2636
 
                                var second_arg_type = ParameterTypes[1];
2637
 
                                if (second_arg_type.IsNullableType)
2638
 
                                        second_arg_type = Nullable.NullableInfo.GetUnderlyingType (second_arg_type);
2639
 
 
2640
 
                                if (second_arg_type != declaring_type) {
2641
 
                                        Report.Error (563, Location,
2642
 
                                                "One of the parameters of a binary operator must be the containing type");
2643
 
                                        return false;
2644
 
                                }
2645
 
                        }
2646
 
 
2647
 
                        return true;
2648
 
                }
2649
 
 
2650
 
                protected override bool ResolveMemberType ()
2651
 
                {
2652
 
                        if (!base.ResolveMemberType ())
2653
 
                                return false;
2654
 
 
2655
 
                        flags |= MethodAttributes.SpecialName | MethodAttributes.HideBySig;
2656
 
                        return true;
2657
 
                }
2658
 
 
2659
 
                protected override MemberSpec FindBaseMember (out MemberSpec bestCandidate, ref bool overrides)
2660
 
                {
2661
 
                        // Operator cannot be override
2662
 
                        bestCandidate = null;
2663
 
                        return null;
2664
 
                }
2665
 
 
2666
 
                public static string GetName (OpType ot)
2667
 
                {
2668
 
                        return names [(int) ot] [0];
2669
 
                }
2670
 
 
2671
 
                public static string GetName (string metadata_name)
2672
 
                {
2673
 
                        for (int i = 0; i < names.Length; ++i) {
2674
 
                                if (names [i] [1] == metadata_name)
2675
 
                                        return names [i] [0];
2676
 
                        }
2677
 
                        return null;
2678
 
                }
2679
 
 
2680
 
                public static string GetMetadataName (OpType ot)
2681
 
                {
2682
 
                        return names [(int) ot] [1];
2683
 
                }
2684
 
 
2685
 
                public static string GetMetadataName (string name)
2686
 
                {
2687
 
                        for (int i = 0; i < names.Length; ++i) {
2688
 
                                if (names [i] [0] == name)
2689
 
                                        return names [i] [1];
2690
 
                        }
2691
 
                        return null;
2692
 
                }
2693
 
 
2694
 
                public static OpType? GetType (string metadata_name)
2695
 
                {
2696
 
                        for (int i = 0; i < names.Length; ++i) {
2697
 
                                if (names[i][1] == metadata_name)
2698
 
                                        return (OpType) i;
2699
 
                        }
2700
 
 
2701
 
                        return null;
2702
 
                }
2703
 
 
2704
 
                public OpType GetMatchingOperator ()
2705
 
                {
2706
 
                        switch (OperatorType) {
2707
 
                        case OpType.Equality:
2708
 
                                return OpType.Inequality;
2709
 
                        case OpType.Inequality:
2710
 
                                return OpType.Equality;
2711
 
                        case OpType.True:
2712
 
                                return OpType.False;
2713
 
                        case OpType.False:
2714
 
                                return OpType.True;
2715
 
                        case OpType.GreaterThan:
2716
 
                                return OpType.LessThan;
2717
 
                        case OpType.LessThan:
2718
 
                                return OpType.GreaterThan;
2719
 
                        case OpType.GreaterThanOrEqual:
2720
 
                                return OpType.LessThanOrEqual;
2721
 
                        case OpType.LessThanOrEqual:
2722
 
                                return OpType.GreaterThanOrEqual;
2723
 
                        default:
2724
 
                                return OpType.TOP;
2725
 
                        }
2726
 
                }
2727
 
 
2728
 
                public override string GetSignatureForDocumentation ()
2729
 
                {
2730
 
                        string s = base.GetSignatureForDocumentation ();
2731
 
                        if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
2732
 
                                s = s + "~" + ReturnType.GetSignatureForDocumentation ();
2733
 
                        }
2734
 
 
2735
 
                        return s;
2736
 
                }
2737
 
 
2738
 
                public override string GetSignatureForError ()
2739
 
                {
2740
 
                        StringBuilder sb = new StringBuilder ();
2741
 
                        if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
2742
 
                                sb.AppendFormat ("{0}.{1} operator {2}",
2743
 
                                        Parent.GetSignatureForError (), GetName (OperatorType),
2744
 
                                        member_type == null ? type_expr.GetSignatureForError () : member_type.GetSignatureForError ());
2745
 
                        }
2746
 
                        else {
2747
 
                                sb.AppendFormat ("{0}.operator {1}", Parent.GetSignatureForError (), GetName (OperatorType));
2748
 
                        }
2749
 
 
2750
 
                        sb.Append (parameters.GetSignatureForError ());
2751
 
                        return sb.ToString ();
2752
 
                }
2753
 
        }
2754
 
}
2755