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

« back to all changes in this revision

Viewing changes to external/nrefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/module.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
// module.cs: keeps a tree representation of the generated code
 
3
//
 
4
// Authors: Miguel de Icaza (miguel@gnu.org)
 
5
//          Marek Safar  (marek.safar@gmail.com)
 
6
//
 
7
// Dual licensed under the terms of the MIT X11 or GNU GPL
 
8
//
 
9
// Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
 
10
// Copyright 2003-2008 Novell, Inc.
 
11
// Copyright 2011 Xamarin Inc
 
12
//
 
13
 
 
14
using System;
 
15
using System.Collections.Generic;
 
16
using System.Runtime.InteropServices;
 
17
using Mono.CompilerServices.SymbolWriter;
 
18
using System.Linq;
 
19
 
 
20
#if STATIC
 
21
using IKVM.Reflection;
 
22
using IKVM.Reflection.Emit;
 
23
#else
 
24
using System.Reflection;
 
25
using System.Reflection.Emit;
 
26
#endif
 
27
 
 
28
namespace Mono.CSharp
 
29
{
 
30
        //
 
31
        // Module (top-level type) container
 
32
        //
 
33
        public sealed class ModuleContainer : TypeContainer
 
34
        {
 
35
#if STATIC
 
36
                //
 
37
                // Compiler generated container for static data
 
38
                //
 
39
                sealed class StaticDataContainer : CompilerGeneratedContainer
 
40
                {
 
41
                        readonly Dictionary<int, Struct> size_types;
 
42
                        int fields;
 
43
 
 
44
                        public StaticDataContainer (ModuleContainer module)
 
45
                                : base (module, new MemberName ("<PrivateImplementationDetails>" + module.builder.ModuleVersionId.ToString ("B"), Location.Null),
 
46
                                        Modifiers.STATIC | Modifiers.INTERNAL)
 
47
                        {
 
48
                                size_types = new Dictionary<int, Struct> ();
 
49
                        }
 
50
 
 
51
                        public override void CloseContainer ()
 
52
                        {
 
53
                                base.CloseContainer ();
 
54
 
 
55
                                foreach (var entry in size_types) {
 
56
                                        entry.Value.CloseContainer ();
 
57
                                }
 
58
                        }
 
59
 
 
60
                        public FieldSpec DefineInitializedData (byte[] data, Location loc)
 
61
                        {
 
62
                                Struct size_type;
 
63
                                if (!size_types.TryGetValue (data.Length, out size_type)) {
 
64
                                        //
 
65
                                        // Build common type for this data length. We cannot use
 
66
                                        // DefineInitializedData because it creates public type,
 
67
                                        // and its name is not unique among modules
 
68
                                        //
 
69
                                        size_type = new Struct (this, new MemberName ("$ArrayType=" + data.Length, loc), Modifiers.PRIVATE | Modifiers.COMPILER_GENERATED, null);
 
70
                                        size_type.CreateContainer ();
 
71
                                        size_type.DefineContainer ();
 
72
 
 
73
                                        size_types.Add (data.Length, size_type);
 
74
 
 
75
                                        // It has to work even if StructLayoutAttribute does not exist
 
76
                                        size_type.TypeBuilder.__SetLayout (1, data.Length);
 
77
                                }
 
78
 
 
79
                                var name = "$field-" + fields.ToString ("X");
 
80
                                ++fields;
 
81
                                const Modifiers fmod = Modifiers.STATIC | Modifiers.INTERNAL;
 
82
                                var fbuilder = TypeBuilder.DefineField (name, size_type.CurrentType.GetMetaInfo (), ModifiersExtensions.FieldAttr (fmod) | FieldAttributes.HasFieldRVA);
 
83
                                fbuilder.__SetDataAndRVA (data);
 
84
 
 
85
                                return new FieldSpec (CurrentType, null, size_type.CurrentType, fbuilder, fmod);
 
86
                        }
 
87
                }
 
88
 
 
89
                StaticDataContainer static_data;
 
90
 
 
91
                //
 
92
                // Makes const data field inside internal type container
 
93
                //
 
94
                public FieldSpec MakeStaticData (byte[] data, Location loc)
 
95
                {
 
96
                        if (static_data == null) {
 
97
                                static_data = new StaticDataContainer (this);
 
98
                                static_data.CreateContainer ();
 
99
                                static_data.DefineContainer ();
 
100
 
 
101
                                AddCompilerGeneratedClass (static_data);
 
102
                        }
 
103
 
 
104
                        return static_data.DefineInitializedData (data, loc);
 
105
                }
 
106
#endif
 
107
 
 
108
                public CharSet? DefaultCharSet;
 
109
                public TypeAttributes DefaultCharSetType = TypeAttributes.AnsiClass;
 
110
 
 
111
                readonly Dictionary<int, List<AnonymousTypeClass>> anonymous_types;
 
112
                readonly Dictionary<ArrayContainer.TypeRankPair, ArrayContainer> array_types;
 
113
                readonly Dictionary<TypeSpec, PointerContainer> pointer_types;
 
114
                readonly Dictionary<TypeSpec, ReferenceContainer> reference_types;
 
115
                readonly Dictionary<TypeSpec, MethodSpec> attrs_cache;
 
116
                readonly Dictionary<TypeSpec, AwaiterDefinition> awaiters;
 
117
 
 
118
                AssemblyDefinition assembly;
 
119
                readonly CompilerContext context;
 
120
                readonly RootNamespace global_ns;
 
121
                readonly Dictionary<string, RootNamespace> alias_ns;
 
122
 
 
123
                ModuleBuilder builder;
 
124
 
 
125
                bool has_extenstion_method;
 
126
 
 
127
                PredefinedAttributes predefined_attributes;
 
128
                PredefinedTypes predefined_types;
 
129
                PredefinedMembers predefined_members;
 
130
 
 
131
                static readonly string[] attribute_targets = new string[] { "assembly", "module" };
 
132
 
 
133
                public ModuleContainer (CompilerContext context)
 
134
                        : base (null, MemberName.Null, null, 0)
 
135
                {
 
136
                        this.context = context;
 
137
 
 
138
                        caching_flags &= ~(Flags.Obsolete_Undetected | Flags.Excluded_Undetected);
 
139
 
 
140
                        containers = new List<TypeContainer> ();
 
141
                        anonymous_types = new Dictionary<int, List<AnonymousTypeClass>> ();
 
142
                        global_ns = new GlobalRootNamespace ();
 
143
                        alias_ns = new Dictionary<string, RootNamespace> ();
 
144
                        array_types = new Dictionary<ArrayContainer.TypeRankPair, ArrayContainer> ();
 
145
                        pointer_types = new Dictionary<TypeSpec, PointerContainer> ();
 
146
                        reference_types = new Dictionary<TypeSpec, ReferenceContainer> ();
 
147
                        attrs_cache = new Dictionary<TypeSpec, MethodSpec> ();
 
148
                        awaiters = new Dictionary<TypeSpec, AwaiterDefinition> ();
 
149
                }
 
150
 
 
151
                #region Properties
 
152
 
 
153
                internal Dictionary<ArrayContainer.TypeRankPair, ArrayContainer> ArrayTypesCache {
 
154
                        get {
 
155
                                return array_types;
 
156
                        }
 
157
                }
 
158
 
 
159
                //
 
160
                // Cache for parameter-less attributes
 
161
                //
 
162
                internal Dictionary<TypeSpec, MethodSpec> AttributeConstructorCache {
 
163
                        get {
 
164
                                return attrs_cache;
 
165
                        }
 
166
                }
 
167
 
 
168
                public override AttributeTargets AttributeTargets {
 
169
                        get {
 
170
                                return AttributeTargets.Assembly;
 
171
                        }
 
172
                }
 
173
 
 
174
                public ModuleBuilder Builder {
 
175
                        get {
 
176
                                return builder;
 
177
                        }
 
178
                }
 
179
 
 
180
                public override CompilerContext Compiler {
 
181
                        get {
 
182
                                return context;
 
183
                        }
 
184
                }
 
185
 
 
186
                public int CounterAnonymousTypes { get; set; }
 
187
                public int CounterAnonymousMethods { get; set; }
 
188
                public int CounterAnonymousContainers { get; set; }
 
189
                public int CounterSwitchTypes { get; set; }
 
190
 
 
191
                public AssemblyDefinition DeclaringAssembly {
 
192
                        get {
 
193
                                return assembly;
 
194
                        }
 
195
                }
 
196
 
 
197
                internal DocumentationBuilder DocumentationBuilder {
 
198
                        get; set;
 
199
                }
 
200
 
 
201
                public override string DocCommentHeader {
 
202
                        get {
 
203
                                throw new NotSupportedException ();
 
204
                        }
 
205
                }
 
206
 
 
207
                public Evaluator Evaluator {
 
208
                        get; set;
 
209
                }
 
210
 
 
211
                public bool HasDefaultCharSet {
 
212
                        get {
 
213
                                return DefaultCharSet.HasValue;
 
214
                        }
 
215
                }
 
216
 
 
217
                public bool HasExtensionMethod {
 
218
                        get {
 
219
                                return has_extenstion_method;
 
220
                        }
 
221
                        set {
 
222
                                has_extenstion_method = value;
 
223
                        }
 
224
                }
 
225
 
 
226
                public bool HasTypesFullyDefined {
 
227
                        get; set;
 
228
                }
 
229
 
 
230
                //
 
231
                // Returns module global:: namespace
 
232
                //
 
233
                public RootNamespace GlobalRootNamespace {
 
234
                    get {
 
235
                        return global_ns;
 
236
                    }
 
237
                }
 
238
 
 
239
                public override ModuleContainer Module {
 
240
                        get {
 
241
                                return this;
 
242
                        }
 
243
                }
 
244
 
 
245
                internal Dictionary<TypeSpec, PointerContainer> PointerTypesCache {
 
246
                        get {
 
247
                                return pointer_types;
 
248
                        }
 
249
                }
 
250
 
 
251
                internal PredefinedAttributes PredefinedAttributes {
 
252
                        get {
 
253
                                return predefined_attributes;
 
254
                        }
 
255
                }
 
256
 
 
257
                internal PredefinedMembers PredefinedMembers {
 
258
                        get {
 
259
                                return predefined_members;
 
260
                        }
 
261
                }
 
262
 
 
263
                internal PredefinedTypes PredefinedTypes {
 
264
                        get {
 
265
                                return predefined_types;
 
266
                        }
 
267
                }
 
268
 
 
269
                internal Dictionary<TypeSpec, ReferenceContainer> ReferenceTypesCache {
 
270
                        get {
 
271
                                return reference_types;
 
272
                        }
 
273
                }
 
274
 
 
275
                public override string[] ValidAttributeTargets {
 
276
                        get {
 
277
                                return attribute_targets;
 
278
                        }
 
279
                }
 
280
 
 
281
                #endregion
 
282
 
 
283
                public override void Accept (StructuralVisitor visitor)
 
284
                {
 
285
                        visitor.Visit (this);
 
286
                }
 
287
 
 
288
                public void AddAnonymousType (AnonymousTypeClass type)
 
289
                {
 
290
                        List<AnonymousTypeClass> existing;
 
291
                        if (!anonymous_types.TryGetValue (type.Parameters.Count, out existing))
 
292
                        if (existing == null) {
 
293
                                existing = new List<AnonymousTypeClass> ();
 
294
                                anonymous_types.Add (type.Parameters.Count, existing);
 
295
                        }
 
296
 
 
297
                        existing.Add (type);
 
298
                }
 
299
 
 
300
                public void AddAttribute (Attribute attr, IMemberContext context)
 
301
                {
 
302
                        attr.AttachTo (this, context);
 
303
 
 
304
                        if (attributes == null) {
 
305
                                attributes = new Attributes (attr);
 
306
                                return;
 
307
                        }
 
308
 
 
309
                        attributes.AddAttribute (attr);
 
310
                }
 
311
 
 
312
                public override void AddTypeContainer (TypeContainer tc)
 
313
                {
 
314
                        containers.Add (tc);
 
315
                }
 
316
 
 
317
                public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
 
318
                {
 
319
                        if (a.Target == AttributeTargets.Assembly) {
 
320
                                assembly.ApplyAttributeBuilder (a, ctor, cdata, pa);
 
321
                                return;
 
322
                        }
 
323
 
 
324
                        if (a.Type == pa.DefaultCharset) {
 
325
                                switch (a.GetCharSetValue ()) {
 
326
                                case CharSet.Ansi:
 
327
                                case CharSet.None:
 
328
                                        break;
 
329
                                case CharSet.Auto:
 
330
                                        DefaultCharSet = CharSet.Auto;
 
331
                                        DefaultCharSetType = TypeAttributes.AutoClass;
 
332
                                        break;
 
333
                                case CharSet.Unicode:
 
334
                                        DefaultCharSet = CharSet.Unicode;
 
335
                                        DefaultCharSetType = TypeAttributes.UnicodeClass;
 
336
                                        break;
 
337
                                default:
 
338
                                        Report.Error (1724, a.Location, "Value specified for the argument to `{0}' is not valid",
 
339
                                                a.GetSignatureForError ());
 
340
                                        break;
 
341
                                }
 
342
                        } else if (a.Type == pa.CLSCompliant) {
 
343
                                Attribute cls = DeclaringAssembly.CLSCompliantAttribute;
 
344
                                if (cls == null) {
 
345
                                        Report.Warning (3012, 1, a.Location,
 
346
                                                "You must specify the CLSCompliant attribute on the assembly, not the module, to enable CLS compliance checking");
 
347
                                } else if (DeclaringAssembly.IsCLSCompliant != a.GetBoolean ()) {
 
348
                                        Report.SymbolRelatedToPreviousError (cls.Location, cls.GetSignatureForError ());
 
349
                                        Report.Warning (3017, 1, a.Location,
 
350
                                                "You cannot specify the CLSCompliant attribute on a module that differs from the CLSCompliant attribute on the assembly");
 
351
                                        return;
 
352
                                }
 
353
                        }
 
354
 
 
355
                        builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
 
356
                }
 
357
 
 
358
                public override void CloseContainer ()
 
359
                {
 
360
                        if (anonymous_types != null) {
 
361
                                foreach (var atypes in anonymous_types)
 
362
                                        foreach (var at in atypes.Value)
 
363
                                                at.CloseContainer ();
 
364
                        }
 
365
 
 
366
                        base.CloseContainer ();
 
367
                }
 
368
 
 
369
                public TypeBuilder CreateBuilder (string name, TypeAttributes attr, int typeSize)
 
370
                {
 
371
                        return builder.DefineType (name, attr, null, typeSize);
 
372
                }
 
373
 
 
374
                //
 
375
                // Creates alias global namespace
 
376
                //
 
377
                public RootNamespace CreateRootNamespace (string alias)
 
378
                {
 
379
                        if (alias == global_ns.Alias) {
 
380
                                RootNamespace.Error_GlobalNamespaceRedefined (Report, Location.Null);
 
381
                                return global_ns;
 
382
                        }
 
383
 
 
384
                        RootNamespace rn;
 
385
                        if (!alias_ns.TryGetValue (alias, out rn)) {
 
386
                                rn = new RootNamespace (alias);
 
387
                                alias_ns.Add (alias, rn);
 
388
                        }
 
389
 
 
390
                        return rn;
 
391
                }
 
392
 
 
393
                public void Create (AssemblyDefinition assembly, ModuleBuilder moduleBuilder)
 
394
                {
 
395
                        this.assembly = assembly;
 
396
                        builder = moduleBuilder;
 
397
                }
 
398
 
 
399
                public override bool Define ()
 
400
                {
 
401
                        DefineContainer ();
 
402
 
 
403
                        ExpandBaseInterfaces ();
 
404
 
 
405
                        base.Define ();
 
406
 
 
407
                        HasTypesFullyDefined = true;
 
408
 
 
409
                        return true;
 
410
                }
 
411
 
 
412
                public override bool DefineContainer ()
 
413
                {
 
414
                        DefineNamespace ();
 
415
 
 
416
                        return base.DefineContainer ();
 
417
                }
 
418
 
 
419
                public void EnableRedefinition ()
 
420
                {
 
421
                        is_defined = false;
 
422
                }
 
423
 
 
424
                public override void EmitContainer ()
 
425
                {
 
426
                        if (OptAttributes != null)
 
427
                                OptAttributes.Emit ();
 
428
 
 
429
                        if (Compiler.Settings.Unsafe && !assembly.IsSatelliteAssembly) {
 
430
                                var pa = PredefinedAttributes.UnverifiableCode;
 
431
                                if (pa.IsDefined)
 
432
                                        pa.EmitAttribute (builder);
 
433
                        }
 
434
 
 
435
                        foreach (var tc in containers) {
 
436
                                tc.PrepareEmit ();
 
437
                        }
 
438
 
 
439
                        base.EmitContainer ();
 
440
 
 
441
                        if (Compiler.Report.Errors == 0 && !Compiler.Settings.WriteMetadataOnly)
 
442
                                VerifyMembers ();
 
443
 
 
444
                        if (anonymous_types != null) {
 
445
                                foreach (var atypes in anonymous_types)
 
446
                                        foreach (var at in atypes.Value)
 
447
                                                at.EmitContainer ();
 
448
                        }
 
449
                }
 
450
 
 
451
                internal override void GenerateDocComment (DocumentationBuilder builder)
 
452
                {
 
453
                        foreach (var tc in containers)
 
454
                                tc.GenerateDocComment (builder);
 
455
                }
 
456
 
 
457
                public AnonymousTypeClass GetAnonymousType (IList<AnonymousTypeParameter> parameters)
 
458
                {
 
459
                        List<AnonymousTypeClass> candidates;
 
460
                        if (!anonymous_types.TryGetValue (parameters.Count, out candidates))
 
461
                                return null;
 
462
 
 
463
                        int i;
 
464
                        foreach (AnonymousTypeClass at in candidates) {
 
465
                                for (i = 0; i < parameters.Count; ++i) {
 
466
                                        if (!parameters [i].Equals (at.Parameters [i]))
 
467
                                                break;
 
468
                                }
 
469
 
 
470
                                if (i == parameters.Count)
 
471
                                        return at;
 
472
                        }
 
473
 
 
474
                        return null;
 
475
                }
 
476
 
 
477
                //
 
478
                // Return container with awaiter definition. It never returns null
 
479
                // but all container member can be null for easier error reporting
 
480
                //
 
481
                public AwaiterDefinition GetAwaiter (TypeSpec type)
 
482
                {
 
483
                        AwaiterDefinition awaiter;
 
484
                        if (awaiters.TryGetValue (type, out awaiter))
 
485
                                return awaiter;
 
486
 
 
487
                        awaiter = new AwaiterDefinition ();
 
488
 
 
489
                        //
 
490
                        // Predefined: bool IsCompleted { get; } 
 
491
                        //
 
492
                        awaiter.IsCompleted = MemberCache.FindMember (type, MemberFilter.Property ("IsCompleted", Compiler.BuiltinTypes.Bool),
 
493
                                BindingRestriction.InstanceOnly) as PropertySpec;
 
494
 
 
495
                        //
 
496
                        // Predefined: GetResult ()
 
497
                        //
 
498
                        // The method return type is also result type of await expression
 
499
                        //
 
500
                        awaiter.GetResult = MemberCache.FindMember (type, MemberFilter.Method ("GetResult", 0,
 
501
                                ParametersCompiled.EmptyReadOnlyParameters, null),
 
502
                                BindingRestriction.InstanceOnly) as MethodSpec;
 
503
 
 
504
                        //
 
505
                        // Predefined: INotifyCompletion.OnCompleted (System.Action)
 
506
                        //
 
507
                        var nc = PredefinedTypes.INotifyCompletion;
 
508
                        awaiter.INotifyCompletion = !nc.Define () || type.ImplementsInterface (nc.TypeSpec, false);
 
509
 
 
510
                        awaiters.Add (type, awaiter);
 
511
                        return awaiter;
 
512
                }
 
513
 
 
514
                public override void GetCompletionStartingWith (string prefix, List<string> results)
 
515
                {
 
516
                        var names = Evaluator.GetVarNames ();
 
517
                        results.AddRange (names.Where (l => l.StartsWith (prefix)));
 
518
                }
 
519
 
 
520
                public RootNamespace GetRootNamespace (string name)
 
521
                {
 
522
                        RootNamespace rn;
 
523
                        alias_ns.TryGetValue (name, out rn);
 
524
                        return rn;
 
525
                }
 
526
 
 
527
                public override string GetSignatureForError ()
 
528
                {
 
529
                        return "<module>";
 
530
                }
 
531
 
 
532
                public void InitializePredefinedTypes ()
 
533
                {
 
534
                        predefined_attributes = new PredefinedAttributes (this);
 
535
                        predefined_types = new PredefinedTypes (this);
 
536
                        predefined_members = new PredefinedMembers (this);
 
537
                }
 
538
 
 
539
                public override bool IsClsComplianceRequired ()
 
540
                {
 
541
                        return DeclaringAssembly.IsCLSCompliant;
 
542
                }
 
543
 
 
544
                public Attribute ResolveAssemblyAttribute (PredefinedAttribute a_type)
 
545
                {
 
546
                        Attribute a = OptAttributes.Search ("assembly", a_type);
 
547
                        if (a != null) {
 
548
                                a.Resolve ();
 
549
                        }
 
550
                        return a;
 
551
                }
 
552
 
 
553
                public void SetDeclaringAssembly (AssemblyDefinition assembly)
 
554
                {
 
555
                        // TODO: This setter is quite ugly but I have not found a way around it yet
 
556
                        this.assembly = assembly;
 
557
                }
 
558
        }
 
559
}