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

« back to all changes in this revision

Viewing changes to contrib/ICSharpCode.NRefactory.CSharp/Parser/mcs/assembly.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
 
// assembly.cs: Assembly declaration and specifications
3
 
//
4
 
// Authors:
5
 
//   Miguel de Icaza (miguel@ximian.com)
6
 
//   Marek Safar (marek.safar@gmail.com)
7
 
//
8
 
// Copyright 2001, 2002, 2003 Ximian, Inc.
9
 
// Copyright 2004-2011 Novell, Inc.
10
 
// Copyright 2011 Xamarin Inc
11
 
//
12
 
 
13
 
 
14
 
using System;
15
 
using System.IO;
16
 
using System.Collections.Generic;
17
 
using System.Globalization;
18
 
using System.Security;
19
 
using System.Security.Cryptography;
20
 
using System.Security.Permissions;
21
 
using Mono.Security.Cryptography;
22
 
using Mono.CompilerServices.SymbolWriter;
23
 
 
24
 
#if STATIC
25
 
using IKVM.Reflection;
26
 
using IKVM.Reflection.Emit;
27
 
using SecurityType = System.Collections.Generic.List<IKVM.Reflection.Emit.CustomAttributeBuilder>;
28
 
#else
29
 
using SecurityType = System.Collections.Generic.Dictionary<System.Security.Permissions.SecurityAction, System.Security.PermissionSet>;
30
 
using System.Reflection;
31
 
using System.Reflection.Emit;
32
 
#endif
33
 
 
34
 
namespace Mono.CSharp
35
 
{
36
 
        public interface IAssemblyDefinition
37
 
        {
38
 
                string FullName { get; }
39
 
                bool HasExtensionMethod { get; }
40
 
                bool IsCLSCompliant { get; }
41
 
                bool IsMissing { get; }
42
 
                string Name { get; }
43
 
 
44
 
                byte[] GetPublicKeyToken ();
45
 
                bool IsFriendAssemblyTo (IAssemblyDefinition assembly);
46
 
        }
47
 
                
48
 
        public abstract class AssemblyDefinition : IAssemblyDefinition
49
 
        {
50
 
                // TODO: make it private and move all builder based methods here
51
 
                public AssemblyBuilder Builder;
52
 
                protected AssemblyBuilderExtension builder_extra;
53
 
                MonoSymbolFile symbol_writer;
54
 
 
55
 
                bool is_cls_compliant;
56
 
                bool wrap_non_exception_throws;
57
 
                bool wrap_non_exception_throws_custom;
58
 
 
59
 
                protected ModuleContainer module;
60
 
                readonly string name;
61
 
                protected readonly string file_name;
62
 
 
63
 
                byte[] public_key, public_key_token;
64
 
                bool delay_sign;
65
 
 
66
 
                // Holds private/public key pair when private key
67
 
                // was available
68
 
                StrongNameKeyPair private_key;  
69
 
 
70
 
                Attribute cls_attribute;
71
 
                Method entry_point;
72
 
 
73
 
                protected List<ImportedModuleDefinition> added_modules;
74
 
                SecurityType declarative_security;
75
 
                Dictionary<ITypeDefinition, Attribute> emitted_forwarders;
76
 
                AssemblyAttributesPlaceholder module_target_attrs;
77
 
 
78
 
                protected AssemblyDefinition (ModuleContainer module, string name)
79
 
                {
80
 
                        this.module = module;
81
 
                        this.name = Path.GetFileNameWithoutExtension (name);
82
 
 
83
 
                        wrap_non_exception_throws = true;
84
 
 
85
 
                        delay_sign = Compiler.Settings.StrongNameDelaySign;
86
 
 
87
 
                        //
88
 
                        // Load strong name key early enough for assembly importer to be able to
89
 
                        // use the keys for InternalsVisibleTo
90
 
                        // This should go somewhere close to ReferencesLoading but don't have the place yet
91
 
                        //
92
 
                        if (Compiler.Settings.HasKeyFileOrContainer) {
93
 
                                LoadPublicKey (Compiler.Settings.StrongNameKeyFile, Compiler.Settings.StrongNameKeyContainer);
94
 
                        }
95
 
                }
96
 
 
97
 
                protected AssemblyDefinition (ModuleContainer module, string name, string fileName)
98
 
                        : this (module, name)
99
 
                {
100
 
                        this.file_name = fileName;
101
 
                }
102
 
 
103
 
                #region Properties
104
 
 
105
 
                public Attribute CLSCompliantAttribute {
106
 
                        get {
107
 
                                return cls_attribute;
108
 
                        }
109
 
                }
110
 
 
111
 
                public CompilerContext Compiler {
112
 
                        get {
113
 
                                return module.Compiler;
114
 
                        }
115
 
                }
116
 
 
117
 
                //
118
 
                // Assembly entry point, aka Main method
119
 
                //
120
 
                public Method EntryPoint {
121
 
                        get {
122
 
                                return entry_point;
123
 
                        }
124
 
                        set {
125
 
                                entry_point = value;
126
 
                        }
127
 
                }
128
 
 
129
 
                public string FullName {
130
 
                        get {
131
 
                                return Builder.FullName;
132
 
                        }
133
 
                }
134
 
 
135
 
                public bool HasExtensionMethod {
136
 
                        get {
137
 
                                return module.HasExtensionMethod;
138
 
                        }
139
 
                }
140
 
 
141
 
                public bool HasCLSCompliantAttribute {
142
 
                        get {
143
 
                                return cls_attribute != null;
144
 
                        }
145
 
                }
146
 
 
147
 
                // TODO: This should not exist here but will require more changes
148
 
                public MetadataImporter Importer {
149
 
                    get; set;
150
 
                }
151
 
 
152
 
                public bool IsCLSCompliant {
153
 
                        get {
154
 
                                return is_cls_compliant;
155
 
                        }
156
 
                }
157
 
 
158
 
                bool IAssemblyDefinition.IsMissing {
159
 
                        get {
160
 
                                return false;
161
 
                        }
162
 
                }
163
 
 
164
 
                public string Name {
165
 
                        get {
166
 
                                return name;
167
 
                        }
168
 
                }
169
 
 
170
 
                public bool WrapNonExceptionThrows {
171
 
                        get {
172
 
                                return wrap_non_exception_throws;
173
 
                        }
174
 
                }
175
 
 
176
 
                protected Report Report {
177
 
                        get {
178
 
                                return Compiler.Report;
179
 
                        }
180
 
                }
181
 
 
182
 
                public MonoSymbolFile SymbolWriter {
183
 
                        get {
184
 
                                return symbol_writer;
185
 
                        }
186
 
                }
187
 
 
188
 
                #endregion
189
 
 
190
 
                public void AddModule (ImportedModuleDefinition module)
191
 
                {
192
 
                        if (added_modules == null) {
193
 
                                added_modules = new List<ImportedModuleDefinition> ();
194
 
                                added_modules.Add (module);
195
 
                        }
196
 
                }
197
 
 
198
 
                public void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
199
 
                {
200
 
                        if (a.IsValidSecurityAttribute ()) {
201
 
                                a.ExtractSecurityPermissionSet (ctor, ref declarative_security);
202
 
                                return;
203
 
                        }
204
 
 
205
 
                        if (a.Type == pa.AssemblyCulture) {
206
 
                                string value = a.GetString ();
207
 
                                if (value == null || value.Length == 0)
208
 
                                        return;
209
 
 
210
 
                                if (Compiler.Settings.Target == Target.Exe) {
211
 
                                        a.Error_AttributeEmitError ("The executables cannot be satelite assemblies, remove the attribute or keep it empty");
212
 
                                        return;
213
 
                                }
214
 
 
215
 
                                if (value == "neutral")
216
 
                                        value = "";
217
 
 
218
 
                                if (Compiler.Settings.Target == Target.Module) {
219
 
                                        SetCustomAttribute (ctor, cdata);
220
 
                                } else {
221
 
                                        builder_extra.SetCulture (value, a.Location);
222
 
                                }
223
 
 
224
 
                                return;
225
 
                        }
226
 
 
227
 
                        if (a.Type == pa.AssemblyVersion) {
228
 
                                string value = a.GetString ();
229
 
                                if (value == null || value.Length == 0)
230
 
                                        return;
231
 
 
232
 
                                var vinfo = IsValidAssemblyVersion (value, true);
233
 
                                if (vinfo == null) {
234
 
                                        a.Error_AttributeEmitError (string.Format ("Specified version `{0}' is not valid", value));
235
 
                                        return;
236
 
                                }
237
 
 
238
 
                                if (Compiler.Settings.Target == Target.Module) {
239
 
                                        SetCustomAttribute (ctor, cdata);
240
 
                                } else {
241
 
                                        builder_extra.SetVersion (vinfo, a.Location);
242
 
                                }
243
 
 
244
 
                                return;
245
 
                        }
246
 
 
247
 
                        if (a.Type == pa.AssemblyAlgorithmId) {
248
 
                                const int pos = 2; // skip CA header
249
 
                                uint alg = (uint) cdata [pos];
250
 
                                alg |= ((uint) cdata [pos + 1]) << 8;
251
 
                                alg |= ((uint) cdata [pos + 2]) << 16;
252
 
                                alg |= ((uint) cdata [pos + 3]) << 24;
253
 
 
254
 
                                if (Compiler.Settings.Target == Target.Module) {
255
 
                                        SetCustomAttribute (ctor, cdata);
256
 
                                } else {
257
 
                                        builder_extra.SetAlgorithmId (alg, a.Location);
258
 
                                }
259
 
 
260
 
                                return;
261
 
                        }
262
 
 
263
 
                        if (a.Type == pa.AssemblyFlags) {
264
 
                                const int pos = 2; // skip CA header
265
 
                                uint flags = (uint) cdata[pos];
266
 
                                flags |= ((uint) cdata [pos + 1]) << 8;
267
 
                                flags |= ((uint) cdata [pos + 2]) << 16;
268
 
                                flags |= ((uint) cdata [pos + 3]) << 24;
269
 
 
270
 
                                // Ignore set PublicKey flag if assembly is not strongnamed
271
 
                                if ((flags & (uint) AssemblyNameFlags.PublicKey) != 0 && public_key == null)
272
 
                                        flags &= ~(uint) AssemblyNameFlags.PublicKey;
273
 
 
274
 
                                if (Compiler.Settings.Target == Target.Module) {
275
 
                                        SetCustomAttribute (ctor, cdata);
276
 
                                } else {
277
 
                                        builder_extra.SetFlags (flags, a.Location);
278
 
                                }
279
 
 
280
 
                                return;
281
 
                        }
282
 
 
283
 
                        if (a.Type == pa.TypeForwarder) {
284
 
                                TypeSpec t = a.GetArgumentType ();
285
 
                                if (t == null || TypeManager.HasElementType (t)) {
286
 
                                        Report.Error (735, a.Location, "Invalid type specified as an argument for TypeForwardedTo attribute");
287
 
                                        return;
288
 
                                }
289
 
 
290
 
                                if (emitted_forwarders == null) {
291
 
                                        emitted_forwarders = new Dictionary<ITypeDefinition, Attribute> ();
292
 
                                } else if (emitted_forwarders.ContainsKey (t.MemberDefinition)) {
293
 
                                        Report.SymbolRelatedToPreviousError (emitted_forwarders[t.MemberDefinition].Location, null);
294
 
                                        Report.Error (739, a.Location, "A duplicate type forward of type `{0}'",
295
 
                                                TypeManager.CSharpName (t));
296
 
                                        return;
297
 
                                }
298
 
 
299
 
                                emitted_forwarders.Add (t.MemberDefinition, a);
300
 
 
301
 
                                if (t.MemberDefinition.DeclaringAssembly == this) {
302
 
                                        Report.SymbolRelatedToPreviousError (t);
303
 
                                        Report.Error (729, a.Location, "Cannot forward type `{0}' because it is defined in this assembly",
304
 
                                                TypeManager.CSharpName (t));
305
 
                                        return;
306
 
                                }
307
 
 
308
 
                                if (t.IsNested) {
309
 
                                        Report.Error (730, a.Location, "Cannot forward type `{0}' because it is a nested type",
310
 
                                                TypeManager.CSharpName (t));
311
 
                                        return;
312
 
                                }
313
 
 
314
 
                                builder_extra.AddTypeForwarder (t.GetDefinition (), a.Location);
315
 
                                return;
316
 
                        }
317
 
 
318
 
                        if (a.Type == pa.Extension) {
319
 
                                a.Error_MisusedExtensionAttribute ();
320
 
                                return;
321
 
                        }
322
 
 
323
 
                        if (a.Type == pa.InternalsVisibleTo) {
324
 
                                string assembly_name = a.GetString ();
325
 
                                if (assembly_name.Length == 0)
326
 
                                        return;
327
 
#if STATIC
328
 
                                ParsedAssemblyName aname;
329
 
                                ParseAssemblyResult r = Fusion.ParseAssemblyName (assembly_name, out aname);
330
 
                                if (r != ParseAssemblyResult.OK) {
331
 
                                        Report.Warning (1700, 3, a.Location, "Assembly reference `{0}' is invalid and cannot be resolved",
332
 
                                                assembly_name);
333
 
                                        return;
334
 
                                }
335
 
 
336
 
                                if (aname.Version != null || aname.Culture != null || aname.ProcessorArchitecture != ProcessorArchitecture.None) {
337
 
                                        Report.Error (1725, a.Location,
338
 
                                                "Friend assembly reference `{0}' is invalid. InternalsVisibleTo declarations cannot have a version, culture or processor architecture specified",
339
 
                                                assembly_name);
340
 
 
341
 
                                        return;
342
 
                                }
343
 
 
344
 
                                if (public_key != null && !aname.HasPublicKey) {
345
 
                                        Report.Error (1726, a.Location,
346
 
                                                "Friend assembly reference `{0}' is invalid. Strong named assemblies must specify a public key in their InternalsVisibleTo declarations",
347
 
                                                assembly_name);
348
 
                                        return;
349
 
                                }
350
 
#endif
351
 
                        } else if (a.Type == pa.RuntimeCompatibility) {
352
 
                                wrap_non_exception_throws_custom = true;
353
 
                        } else if (a.Type == pa.AssemblyFileVersion) {
354
 
                                string value = a.GetString ();
355
 
                                if (string.IsNullOrEmpty (value) || IsValidAssemblyVersion (value, false) == null) {
356
 
                                        Report.Warning (1607, 1, a.Location, "The version number `{0}' specified for `{1}' is invalid",
357
 
                                                value, a.Name);
358
 
                                        return;
359
 
                                }
360
 
                        }
361
 
 
362
 
 
363
 
                        SetCustomAttribute (ctor, cdata);
364
 
                }
365
 
 
366
 
                //
367
 
                // When using assembly public key attributes InternalsVisibleTo key
368
 
                // was not checked, we have to do it later when we actually know what
369
 
                // our public key token is
370
 
                //
371
 
                void CheckReferencesPublicToken ()
372
 
                {
373
 
                        // TODO: It should check only references assemblies but there is
374
 
                        // no working SRE API
375
 
                        foreach (var entry in Importer.Assemblies) {
376
 
                                var a = entry as ImportedAssemblyDefinition;
377
 
                                if (a == null)
378
 
                                        continue;
379
 
 
380
 
                                if (public_key != null && !a.HasStrongName) {
381
 
                                        Report.Error (1577, "Referenced assembly `{0}' does not have a strong name",
382
 
                                                a.FullName);
383
 
                                }
384
 
 
385
 
                                var ci = a.Assembly.GetName ().CultureInfo;
386
 
                                if (!ci.Equals (System.Globalization.CultureInfo.InvariantCulture)) {
387
 
                                        Report.Warning (1607, 1, "Referenced assembly `{0}' has different culture setting of `{1}'",
388
 
                                                a.Name, ci.Name);
389
 
                                }
390
 
 
391
 
                                if (!a.IsFriendAssemblyTo (this))
392
 
                                        continue;
393
 
 
394
 
                                var attr = a.GetAssemblyVisibleToName (this);
395
 
                                var atoken = attr.GetPublicKeyToken ();
396
 
 
397
 
                                if (ArrayComparer.IsEqual (GetPublicKeyToken (), atoken))
398
 
                                        continue;
399
 
 
400
 
                                Report.SymbolRelatedToPreviousError (a.Location);
401
 
                                Report.Error (281,
402
 
                                        "Friend access was granted to `{0}', but the output assembly is named `{1}'. Try adding a reference to `{0}' or change the output assembly name to match it",
403
 
                                        attr.FullName, FullName);
404
 
                        }
405
 
                }
406
 
 
407
 
                protected AssemblyName CreateAssemblyName ()
408
 
                {
409
 
                        var an = new AssemblyName (name);
410
 
 
411
 
                        if (public_key != null && Compiler.Settings.Target != Target.Module) {
412
 
                                if (delay_sign) {
413
 
                                        an.SetPublicKey (public_key);
414
 
                                } else {
415
 
                                        if (public_key.Length == 16) {
416
 
                                                Report.Error (1606, "Could not sign the assembly. ECMA key can only be used to delay-sign assemblies");
417
 
                                        } else if (private_key == null) {
418
 
                                                Error_AssemblySigning ("The specified key file does not have a private key");
419
 
                                        } else {
420
 
                                                an.KeyPair = private_key;
421
 
                                        }
422
 
                                }
423
 
                        }
424
 
 
425
 
                        return an;
426
 
                }
427
 
 
428
 
                public virtual ModuleBuilder CreateModuleBuilder ()
429
 
                {
430
 
                        if (file_name == null)
431
 
                                throw new NotSupportedException ("transient module in static assembly");
432
 
 
433
 
                        var module_name = Path.GetFileName (file_name);
434
 
 
435
 
                        // Always initialize module without symbolInfo. We could be framework dependent
436
 
                        // but returned ISymbolWriter does not have all what we need therefore some
437
 
                        // adaptor will be needed for now we alwayas emit MDB format when generating
438
 
                        // debug info
439
 
                        return Builder.DefineDynamicModule (module_name, module_name, false);
440
 
                }
441
 
 
442
 
                public virtual void Emit ()
443
 
                {
444
 
                        if (Compiler.Settings.Target == Target.Module) {
445
 
                                module_target_attrs = new AssemblyAttributesPlaceholder (module, name);
446
 
                                module_target_attrs.CreateContainer ();
447
 
                                module_target_attrs.DefineContainer ();
448
 
                                module_target_attrs.Define ();
449
 
                                module.AddCompilerGeneratedClass (module_target_attrs);
450
 
                        } else if (added_modules != null) {
451
 
                                ReadModulesAssemblyAttributes ();
452
 
                        }
453
 
 
454
 
                        if (Compiler.Settings.GenerateDebugInfo) {
455
 
                                symbol_writer = new MonoSymbolFile ();
456
 
                        }
457
 
 
458
 
                        module.EmitContainer ();
459
 
 
460
 
                        if (module.HasExtensionMethod) {
461
 
                                var pa = module.PredefinedAttributes.Extension;
462
 
                                if (pa.IsDefined) {
463
 
                                        SetCustomAttribute (pa.Constructor, AttributeEncoder.Empty);
464
 
                                }
465
 
                        }
466
 
 
467
 
                        if (!wrap_non_exception_throws_custom) {
468
 
                                PredefinedAttribute pa = module.PredefinedAttributes.RuntimeCompatibility;
469
 
                                if (pa.IsDefined && pa.ResolveBuilder ()) {
470
 
                                        var prop = module.PredefinedMembers.RuntimeCompatibilityWrapNonExceptionThrows.Get ();
471
 
                                        if (prop != null) {
472
 
                                                AttributeEncoder encoder = new AttributeEncoder ();
473
 
                                                encoder.EncodeNamedPropertyArgument (prop, new BoolLiteral (Compiler.BuiltinTypes, true, Location.Null));
474
 
                                                SetCustomAttribute (pa.Constructor, encoder.ToArray ());
475
 
                                        }
476
 
                                }
477
 
                        }
478
 
 
479
 
                        if (declarative_security != null) {
480
 
#if STATIC
481
 
                                foreach (var entry in declarative_security) {
482
 
                                        Builder.__AddDeclarativeSecurity (entry);
483
 
                                }
484
 
#else
485
 
                                throw new NotSupportedException ("Assembly-level security");
486
 
#endif
487
 
                        }
488
 
 
489
 
                        CheckReferencesPublicToken ();
490
 
 
491
 
                        SetEntryPoint ();
492
 
                }
493
 
 
494
 
                public byte[] GetPublicKeyToken ()
495
 
                {
496
 
                        if (public_key == null || public_key_token != null)
497
 
                                return public_key_token;
498
 
 
499
 
                        HashAlgorithm ha = SHA1.Create ();
500
 
                        byte[] hash = ha.ComputeHash (public_key);
501
 
                        // we need the last 8 bytes in reverse order
502
 
                        public_key_token = new byte[8];
503
 
                        Buffer.BlockCopy (hash, hash.Length - 8, public_key_token, 0, 8);
504
 
                        Array.Reverse (public_key_token, 0, 8);
505
 
                        return public_key_token;
506
 
                }
507
 
 
508
 
                //
509
 
                // Either keyFile or keyContainer has to be non-null
510
 
                //
511
 
                void LoadPublicKey (string keyFile, string keyContainer)
512
 
                {
513
 
                        if (keyContainer != null) {
514
 
                                try {
515
 
                                        private_key = new StrongNameKeyPair (keyContainer);
516
 
                                        public_key = private_key.PublicKey;
517
 
                                } catch {
518
 
                                        Error_AssemblySigning ("The specified key container `" + keyContainer + "' does not exist");
519
 
                                }
520
 
 
521
 
                                return;
522
 
                        }
523
 
 
524
 
                        bool key_file_exists = File.Exists (keyFile);
525
 
 
526
 
                        //
527
 
                        // For attribute based KeyFile do additional lookup
528
 
                        // in output assembly path
529
 
                        //
530
 
                        if (!key_file_exists && Compiler.Settings.StrongNameKeyFile == null) {
531
 
                                //
532
 
                                // The key file can be relative to output assembly
533
 
                                //
534
 
                                string test_path = Path.Combine (Path.GetDirectoryName (file_name), keyFile);
535
 
                                key_file_exists = File.Exists (test_path);
536
 
                                if (key_file_exists)
537
 
                                        keyFile = test_path;
538
 
                        }
539
 
 
540
 
                        if (!key_file_exists) {
541
 
                                Error_AssemblySigning ("The specified key file `" + keyFile + "' does not exist");
542
 
                                return;
543
 
                        }
544
 
 
545
 
                        using (FileStream fs = new FileStream (keyFile, FileMode.Open, FileAccess.Read)) {
546
 
                                byte[] snkeypair = new byte[fs.Length];
547
 
                                fs.Read (snkeypair, 0, snkeypair.Length);
548
 
 
549
 
                                // check for ECMA key
550
 
                                if (snkeypair.Length == 16) {
551
 
                                        public_key = snkeypair;
552
 
                                        return;
553
 
                                }
554
 
 
555
 
                                try {
556
 
                                        // take it, with or without, a private key
557
 
                                        RSA rsa = CryptoConvert.FromCapiKeyBlob (snkeypair);
558
 
                                        // and make sure we only feed the public part to Sys.Ref
559
 
                                        byte[] publickey = CryptoConvert.ToCapiPublicKeyBlob (rsa);
560
 
 
561
 
                                        // AssemblyName.SetPublicKey requires an additional header
562
 
                                        byte[] publicKeyHeader = new byte[8] { 0x00, 0x24, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00 };
563
 
 
564
 
                                        // Encode public key
565
 
                                        public_key = new byte[12 + publickey.Length];
566
 
                                        Buffer.BlockCopy (publicKeyHeader, 0, public_key, 0, publicKeyHeader.Length);
567
 
 
568
 
                                        // Length of Public Key (in bytes)
569
 
                                        int lastPart = public_key.Length - 12;
570
 
                                        public_key[8] = (byte) (lastPart & 0xFF);
571
 
                                        public_key[9] = (byte) ((lastPart >> 8) & 0xFF);
572
 
                                        public_key[10] = (byte) ((lastPart >> 16) & 0xFF);
573
 
                                        public_key[11] = (byte) ((lastPart >> 24) & 0xFF);
574
 
 
575
 
                                        Buffer.BlockCopy (publickey, 0, public_key, 12, publickey.Length);
576
 
                                } catch {
577
 
                                        Error_AssemblySigning ("The specified key file `" + keyFile + "' has incorrect format");
578
 
                                        return;
579
 
                                }
580
 
 
581
 
                                if (delay_sign)
582
 
                                        return;
583
 
 
584
 
                                try {
585
 
                                        // TODO: Is there better way to test for a private key presence ?
586
 
                                        CryptoConvert.FromCapiPrivateKeyBlob (snkeypair);
587
 
                                        private_key = new StrongNameKeyPair (snkeypair);
588
 
                                } catch { }
589
 
                        }
590
 
                }
591
 
 
592
 
                void ReadModulesAssemblyAttributes ()
593
 
                {
594
 
                        foreach (var m in added_modules) {
595
 
                                var cattrs = m.ReadAssemblyAttributes ();
596
 
                                if (cattrs == null)
597
 
                                        continue;
598
 
 
599
 
                                module.OptAttributes.AddAttributes (cattrs);
600
 
                        }
601
 
                }
602
 
 
603
 
                public void Resolve ()
604
 
                {
605
 
                        if (Compiler.Settings.Unsafe && module.PredefinedTypes.SecurityAction.Define ()) {
606
 
                                //
607
 
                                // Emits [assembly: SecurityPermissionAttribute (SecurityAction.RequestMinimum, SkipVerification = true)]
608
 
                                // when -unsafe option was specified
609
 
                                //
610
 
                                Location loc = Location.Null;
611
 
 
612
 
                                MemberAccess system_security_permissions = new MemberAccess (new MemberAccess (
613
 
                                        new QualifiedAliasMember (QualifiedAliasMember.GlobalAlias, "System", loc), "Security", loc), "Permissions", loc);
614
 
 
615
 
                                var req_min = module.PredefinedMembers.SecurityActionRequestMinimum.Resolve (loc);
616
 
 
617
 
                                Arguments pos = new Arguments (1);
618
 
                                pos.Add (new Argument (req_min.GetConstant (null)));
619
 
 
620
 
                                Arguments named = new Arguments (1);
621
 
                                named.Add (new NamedArgument ("SkipVerification", loc, new BoolLiteral (Compiler.BuiltinTypes, true, loc)));
622
 
 
623
 
                                Attribute g = new Attribute ("assembly",
624
 
                                        new MemberAccess (system_security_permissions, "SecurityPermissionAttribute"),
625
 
                                        new Arguments[] { pos, named }, loc, false);
626
 
                                g.AttachTo (module, module);
627
 
                                var ctor = g.Resolve ();
628
 
                                if (ctor != null) {
629
 
                                        g.ExtractSecurityPermissionSet (ctor, ref declarative_security);
630
 
                                }
631
 
                        }
632
 
 
633
 
                        if (module.OptAttributes == null)
634
 
                                return;
635
 
 
636
 
                        // Ensure that we only have GlobalAttributes, since the Search isn't safe with other types.
637
 
                        if (!module.OptAttributes.CheckTargets())
638
 
                                return;
639
 
 
640
 
                        cls_attribute = module.ResolveAssemblyAttribute (module.PredefinedAttributes.CLSCompliant);
641
 
 
642
 
                        if (cls_attribute != null) {
643
 
                                is_cls_compliant = cls_attribute.GetClsCompliantAttributeValue ();
644
 
                        }
645
 
 
646
 
                        if (added_modules != null && Compiler.Settings.VerifyClsCompliance && is_cls_compliant) {
647
 
                                foreach (var m in added_modules) {
648
 
                                        if (!m.IsCLSCompliant) {
649
 
                                                Report.Error (3013,
650
 
                                                        "Added modules must be marked with the CLSCompliant attribute to match the assembly",
651
 
                                                        m.Name);
652
 
                                        }
653
 
                                }
654
 
                        }
655
 
 
656
 
                        Attribute a = module.ResolveAssemblyAttribute (module.PredefinedAttributes.RuntimeCompatibility);
657
 
                        if (a != null) {
658
 
                                var val = a.GetNamedValue ("WrapNonExceptionThrows") as BoolConstant;
659
 
                                if (val != null)
660
 
                                        wrap_non_exception_throws = val.Value;
661
 
                        }
662
 
                }
663
 
 
664
 
                protected void ResolveAssemblySecurityAttributes ()
665
 
                {
666
 
                        string key_file = null;
667
 
                        string key_container = null;
668
 
 
669
 
                        if (module.OptAttributes != null) {
670
 
                                foreach (Attribute a in module.OptAttributes.Attrs) {
671
 
                                        // cannot rely on any resolve-based members before you call Resolve
672
 
                                        if (a.ExplicitTarget != "assembly")
673
 
                                                continue;
674
 
 
675
 
                                        // TODO: This code is buggy: comparing Attribute name without resolving is wrong.
676
 
                                        //       However, this is invoked by CodeGen.Init, when none of the namespaces
677
 
                                        //       are loaded yet.
678
 
                                        // TODO: Does not handle quoted attributes properly
679
 
                                        switch (a.Name) {
680
 
                                        case "AssemblyKeyFile":
681
 
                                        case "AssemblyKeyFileAttribute":
682
 
                                        case "System.Reflection.AssemblyKeyFileAttribute":
683
 
                                                if (Compiler.Settings.StrongNameKeyFile != null) {
684
 
                                                        Report.SymbolRelatedToPreviousError (a.Location, a.GetSignatureForError ());
685
 
                                                        Report.Warning (1616, 1, "Option `{0}' overrides attribute `{1}' given in a source file or added module",
686
 
                                                                        "keyfile", "System.Reflection.AssemblyKeyFileAttribute");
687
 
                                                } else {
688
 
                                                        string value = a.GetString ();
689
 
                                                        if (!string.IsNullOrEmpty (value)) {
690
 
                                                                Error_ObsoleteSecurityAttribute (a, "keyfile");
691
 
                                                                key_file = value;
692
 
                                                        }
693
 
                                                }
694
 
                                                break;
695
 
                                        case "AssemblyKeyName":
696
 
                                        case "AssemblyKeyNameAttribute":
697
 
                                        case "System.Reflection.AssemblyKeyNameAttribute":
698
 
                                                if (Compiler.Settings.StrongNameKeyContainer != null) {
699
 
                                                        Report.SymbolRelatedToPreviousError (a.Location, a.GetSignatureForError ());
700
 
                                                        Report.Warning (1616, 1, "Option `{0}' overrides attribute `{1}' given in a source file or added module",
701
 
                                                                        "keycontainer", "System.Reflection.AssemblyKeyNameAttribute");
702
 
                                                } else {
703
 
                                                        string value = a.GetString ();
704
 
                                                        if (!string.IsNullOrEmpty (value)) {
705
 
                                                                Error_ObsoleteSecurityAttribute (a, "keycontainer");
706
 
                                                                key_container = value;
707
 
                                                        }
708
 
                                                }
709
 
                                                break;
710
 
                                        case "AssemblyDelaySign":
711
 
                                        case "AssemblyDelaySignAttribute":
712
 
                                        case "System.Reflection.AssemblyDelaySignAttribute":
713
 
                                                bool b = a.GetBoolean ();
714
 
                                                if (b) {
715
 
                                                        Error_ObsoleteSecurityAttribute (a, "delaysign");
716
 
                                                }
717
 
 
718
 
                                                delay_sign = b;
719
 
                                                break;
720
 
                                        }
721
 
                                }
722
 
                        }
723
 
 
724
 
                        // We came here only to report assembly attributes warnings
725
 
                        if (public_key != null)
726
 
                                return;
727
 
 
728
 
                        //
729
 
                        // Load the strong key file found in attributes when no
730
 
                        // command line key was given
731
 
                        //
732
 
                        if (key_file != null || key_container != null) {
733
 
                                LoadPublicKey (key_file, key_container);
734
 
                        } else if (delay_sign) {
735
 
                                Report.Warning (1607, 1, "Delay signing was requested but no key file was given");
736
 
                        }
737
 
                }
738
 
 
739
 
                public void EmbedResources ()
740
 
                {
741
 
                        //
742
 
                        // Add Win32 resources
743
 
                        //
744
 
                        if (Compiler.Settings.Win32ResourceFile != null) {
745
 
                                Builder.DefineUnmanagedResource (Compiler.Settings.Win32ResourceFile);
746
 
                        } else {
747
 
                                Builder.DefineVersionInfoResource ();
748
 
                        }
749
 
 
750
 
                        if (Compiler.Settings.Win32IconFile != null) {
751
 
                                builder_extra.DefineWin32IconResource (Compiler.Settings.Win32IconFile);
752
 
                        }
753
 
 
754
 
                        if (Compiler.Settings.Resources != null) {
755
 
                                if (Compiler.Settings.Target == Target.Module) {
756
 
                                        Report.Error (1507, "Cannot link resource file when building a module");
757
 
                                } else {
758
 
                                        int counter = 0;
759
 
                                        foreach (var res in Compiler.Settings.Resources) {
760
 
                                                if (!File.Exists (res.FileName)) {
761
 
                                                        Report.Error (1566, "Error reading resource file `{0}'", res.FileName);
762
 
                                                        continue;
763
 
                                                }
764
 
 
765
 
                                                if (res.IsEmbeded) {
766
 
                                                        Stream stream;
767
 
                                                        if (counter++ < 10) {
768
 
                                                                stream = File.OpenRead (res.FileName);
769
 
                                                        } else {
770
 
                                                                // TODO: SRE API requires resource stream to be available during AssemblyBuilder::Save
771
 
                                                                // we workaround it by reading everything into memory to compile projects with
772
 
                                                                // many embedded resource (over 3500) references
773
 
                                                                stream = new MemoryStream (File.ReadAllBytes (res.FileName));
774
 
                                                        }
775
 
 
776
 
                                                        module.Builder.DefineManifestResource (res.Name, stream, res.Attributes);
777
 
                                                } else {
778
 
                                                        Builder.AddResourceFile (res.Name, Path.GetFileName (res.FileName), res.Attributes);
779
 
                                                }
780
 
                                        }
781
 
                                }
782
 
                        }
783
 
                }
784
 
 
785
 
                public void Save ()
786
 
                {
787
 
                        PortableExecutableKinds pekind = PortableExecutableKinds.ILOnly;
788
 
                        ImageFileMachine machine;
789
 
 
790
 
                        switch (Compiler.Settings.Platform) {
791
 
                        case Platform.X86:
792
 
                                pekind |= PortableExecutableKinds.Required32Bit;
793
 
                                machine = ImageFileMachine.I386;
794
 
                                break;
795
 
                        case Platform.X64:
796
 
                                pekind |= PortableExecutableKinds.PE32Plus;
797
 
                                machine = ImageFileMachine.AMD64;
798
 
                                break;
799
 
                        case Platform.IA64:
800
 
                                machine = ImageFileMachine.IA64;
801
 
                                break;
802
 
                        case Platform.AnyCPU32Preferred:
803
 
#if STATIC
804
 
                                pekind |= PortableExecutableKinds.Preferred32Bit;
805
 
                                machine = ImageFileMachine.I386;
806
 
                                break;
807
 
#else
808
 
                                throw new NotSupportedException ();
809
 
#endif
810
 
                        case Platform.Arm:
811
 
#if STATIC
812
 
                                machine = ImageFileMachine.ARM;
813
 
                                break;
814
 
#else
815
 
                                throw new NotSupportedException ();
816
 
#endif
817
 
                        case Platform.AnyCPU:
818
 
                        default:
819
 
                                machine = ImageFileMachine.I386;
820
 
                                break;
821
 
                        }
822
 
 
823
 
                        Compiler.TimeReporter.Start (TimeReporter.TimerType.OutputSave);
824
 
                        try {
825
 
                                if (Compiler.Settings.Target == Target.Module) {
826
 
                                        SaveModule (pekind, machine);
827
 
                                } else {
828
 
                                        Builder.Save (module.Builder.ScopeName, pekind, machine);
829
 
                                }
830
 
                        } catch (Exception e) {
831
 
                                Report.Error (16, "Could not write to file `" + name + "', cause: " + e.Message);
832
 
                        }
833
 
                        Compiler.TimeReporter.Stop (TimeReporter.TimerType.OutputSave);
834
 
 
835
 
                        // Save debug symbols file
836
 
                        if (symbol_writer != null && Compiler.Report.Errors == 0) {
837
 
                                // TODO: it should run in parallel
838
 
                                Compiler.TimeReporter.Start (TimeReporter.TimerType.DebugSave);
839
 
 
840
 
                                var filename = file_name + ".mdb";
841
 
                                try {
842
 
                                        // We mmap the file, so unlink the previous version since it may be in use
843
 
                                        File.Delete (filename);
844
 
                                } catch {
845
 
                                        // We can safely ignore
846
 
                                }
847
 
 
848
 
                                module.WriteDebugSymbol (symbol_writer);
849
 
 
850
 
                                using (FileStream fs = new FileStream (filename, FileMode.Create, FileAccess.Write)) {
851
 
                                        symbol_writer.CreateSymbolFile (module.Builder.ModuleVersionId, fs);
852
 
                                }
853
 
 
854
 
                                Compiler.TimeReporter.Stop (TimeReporter.TimerType.DebugSave);
855
 
                        }
856
 
                }
857
 
 
858
 
                protected virtual void SaveModule (PortableExecutableKinds pekind, ImageFileMachine machine)
859
 
                {
860
 
                        Report.RuntimeMissingSupport (Location.Null, "-target:module");
861
 
                }
862
 
 
863
 
                void SetCustomAttribute (MethodSpec ctor, byte[] data)
864
 
                {
865
 
                        if (module_target_attrs != null)
866
 
                                module_target_attrs.AddAssemblyAttribute (ctor, data);
867
 
                        else
868
 
                                Builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), data);
869
 
                }
870
 
 
871
 
                void SetEntryPoint ()
872
 
                {
873
 
                        if (!Compiler.Settings.NeedsEntryPoint) {
874
 
                                if (Compiler.Settings.MainClass != null)
875
 
                                        Report.Error (2017, "Cannot specify -main if building a module or library");
876
 
 
877
 
                                return;
878
 
                        }
879
 
 
880
 
                        PEFileKinds file_kind;
881
 
 
882
 
                        switch (Compiler.Settings.Target) {
883
 
                        case Target.Library:
884
 
                        case Target.Module:
885
 
                                file_kind = PEFileKinds.Dll;
886
 
                                break;
887
 
                        case Target.WinExe:
888
 
                                file_kind = PEFileKinds.WindowApplication;
889
 
                                break;
890
 
                        default:
891
 
                                file_kind = PEFileKinds.ConsoleApplication;
892
 
                                break;
893
 
                        }
894
 
 
895
 
                        if (entry_point == null) {
896
 
                                string main_class = Compiler.Settings.MainClass;
897
 
                                if (main_class != null) {
898
 
                                        // TODO: Handle dotted names
899
 
                                        var texpr = module.GlobalRootNamespace.LookupType (module, main_class, 0, LookupMode.Probing, Location.Null);
900
 
                                        if (texpr == null) {
901
 
                                                Report.Error (1555, "Could not find `{0}' specified for Main method", main_class);
902
 
                                                return;
903
 
                                        }
904
 
 
905
 
                                        var mtype = texpr.Type.MemberDefinition as ClassOrStruct;
906
 
                                        if (mtype == null) {
907
 
                                                Report.Error (1556, "`{0}' specified for Main method must be a valid class or struct", main_class);
908
 
                                                return;
909
 
                                        }
910
 
 
911
 
                                        Report.Error (1558, mtype.Location, "`{0}' does not have a suitable static Main method", mtype.GetSignatureForError ());
912
 
                                } else {
913
 
                                        string pname = file_name == null ? name : Path.GetFileName (file_name);
914
 
                                        Report.Error (5001, "Program `{0}' does not contain a static `Main' method suitable for an entry point",
915
 
                                                pname);
916
 
                                }
917
 
 
918
 
                                return;
919
 
                        }
920
 
 
921
 
                        Builder.SetEntryPoint (entry_point.MethodBuilder, file_kind);
922
 
                }
923
 
 
924
 
                void Error_ObsoleteSecurityAttribute (Attribute a, string option)
925
 
                {
926
 
                        Report.Warning (1699, 1, a.Location,
927
 
                                "Use compiler option `{0}' or appropriate project settings instead of `{1}' attribute",
928
 
                                option, a.Name);
929
 
                }
930
 
 
931
 
                void Error_AssemblySigning (string text)
932
 
                {
933
 
                        Report.Error (1548, "Error during assembly signing. " + text);
934
 
                }
935
 
 
936
 
                public bool IsFriendAssemblyTo (IAssemblyDefinition assembly)
937
 
                {
938
 
                        return false;
939
 
                }
940
 
 
941
 
                static Version IsValidAssemblyVersion (string version, bool allowGenerated)
942
 
                {
943
 
                        string[] parts = version.Split ('.');
944
 
                        if (parts.Length < 1 || parts.Length > 4)
945
 
                                return null;
946
 
 
947
 
                        var values = new int[4];
948
 
                        for (int i = 0; i < parts.Length; ++i) {
949
 
                                if (!int.TryParse (parts[i], out values[i])) {
950
 
                                        if (parts[i].Length == 1 && parts[i][0] == '*' && allowGenerated) {
951
 
                                                if (i == 2) {
952
 
                                                        // Nothing can follow *
953
 
                                                        if (parts.Length > 3)
954
 
                                                                return null;
955
 
 
956
 
                                                        // Generate Build value based on days since 1/1/2000
957
 
                                                        TimeSpan days = DateTime.Today - new DateTime (2000, 1, 1);
958
 
                                                        values[i] = System.Math.Max (days.Days, 0);
959
 
                                                        i = 3;
960
 
                                                }
961
 
 
962
 
                                                if (i == 3) {
963
 
                                                        // Generate Revision value based on every other second today
964
 
                                                        var seconds = DateTime.Now - DateTime.Today;
965
 
                                                        values[i] = (int) seconds.TotalSeconds / 2;
966
 
                                                        continue;
967
 
                                                }
968
 
                                        }
969
 
 
970
 
                                        return null;
971
 
                                }
972
 
 
973
 
                                if (values[i] > ushort.MaxValue)
974
 
                                        return null;
975
 
                        }
976
 
 
977
 
                        return new Version (values[0], values[1], values[2], values[3]);
978
 
                }
979
 
        }
980
 
 
981
 
        public class AssemblyResource : IEquatable<AssemblyResource>
982
 
        {
983
 
                public AssemblyResource (string fileName, string name)
984
 
                        : this (fileName, name, false)
985
 
                {
986
 
                }
987
 
 
988
 
                public AssemblyResource (string fileName, string name, bool isPrivate)
989
 
                {
990
 
                        FileName = fileName;
991
 
                        Name = name;
992
 
                        Attributes = isPrivate ? ResourceAttributes.Private : ResourceAttributes.Public;
993
 
                }
994
 
 
995
 
                public ResourceAttributes Attributes { get; private set; }
996
 
                public string Name { get; private set; }
997
 
                public string FileName { get; private set; }
998
 
                public bool IsEmbeded { get; set; }
999
 
 
1000
 
                #region IEquatable<AssemblyResource> Members
1001
 
 
1002
 
                public bool Equals (AssemblyResource other)
1003
 
                {
1004
 
                        return Name == other.Name;
1005
 
                }
1006
 
 
1007
 
                #endregion
1008
 
        }
1009
 
 
1010
 
        //
1011
 
        // A placeholder class for assembly attributes when emitting module
1012
 
        //
1013
 
        class AssemblyAttributesPlaceholder : CompilerGeneratedContainer
1014
 
        {
1015
 
                static readonly string TypeNamePrefix = "<$AssemblyAttributes${0}>";
1016
 
                public static readonly string AssemblyFieldName = "attributes";
1017
 
 
1018
 
                Field assembly;
1019
 
 
1020
 
                public AssemblyAttributesPlaceholder (ModuleContainer parent, string outputName)
1021
 
                        : base (parent, new MemberName (GetGeneratedName (outputName)), Modifiers.STATIC | Modifiers.INTERNAL)
1022
 
                {
1023
 
                        assembly = new Field (this, new TypeExpression (parent.Compiler.BuiltinTypes.Object, Location), Modifiers.PUBLIC | Modifiers.STATIC,
1024
 
                                new MemberName (AssemblyFieldName), null);
1025
 
 
1026
 
                        AddField (assembly);
1027
 
                }
1028
 
 
1029
 
                public void AddAssemblyAttribute (MethodSpec ctor, byte[] data)
1030
 
                {
1031
 
                        assembly.SetCustomAttribute (ctor, data);
1032
 
                }
1033
 
 
1034
 
                public static string GetGeneratedName (string outputName)
1035
 
                {
1036
 
                        return string.Format (TypeNamePrefix, outputName);
1037
 
                }
1038
 
        }
1039
 
 
1040
 
        //
1041
 
        // Extension to System.Reflection.Emit.AssemblyBuilder to have fully compatible
1042
 
        // compiler. This is a default implementation for framework System.Reflection.Emit
1043
 
        // which does not implement any of the methods
1044
 
        //
1045
 
        public class AssemblyBuilderExtension
1046
 
        {
1047
 
                readonly CompilerContext ctx;
1048
 
 
1049
 
                public AssemblyBuilderExtension (CompilerContext ctx)
1050
 
                {
1051
 
                        this.ctx = ctx;
1052
 
                }
1053
 
 
1054
 
                public virtual System.Reflection.Module AddModule (string module)
1055
 
                {
1056
 
                        ctx.Report.RuntimeMissingSupport (Location.Null, "-addmodule");
1057
 
                        return null;
1058
 
                }
1059
 
 
1060
 
                public virtual void AddPermissionRequests (PermissionSet[] permissions)
1061
 
                {
1062
 
                        ctx.Report.RuntimeMissingSupport (Location.Null, "assembly declarative security");
1063
 
                }
1064
 
 
1065
 
                public virtual void AddTypeForwarder (TypeSpec type, Location loc)
1066
 
                {
1067
 
                        ctx.Report.RuntimeMissingSupport (loc, "TypeForwardedToAttribute");
1068
 
                }
1069
 
 
1070
 
                public virtual void DefineWin32IconResource (string fileName)
1071
 
                {
1072
 
                        ctx.Report.RuntimeMissingSupport (Location.Null, "-win32icon");
1073
 
                }
1074
 
 
1075
 
                public virtual void SetAlgorithmId (uint value, Location loc)
1076
 
                {
1077
 
                        ctx.Report.RuntimeMissingSupport (loc, "AssemblyAlgorithmIdAttribute");
1078
 
                }
1079
 
 
1080
 
                public virtual void SetCulture (string culture, Location loc)
1081
 
                {
1082
 
                        ctx.Report.RuntimeMissingSupport (loc, "AssemblyCultureAttribute");
1083
 
                }
1084
 
 
1085
 
                public virtual void SetFlags (uint flags, Location loc)
1086
 
                {
1087
 
                        ctx.Report.RuntimeMissingSupport (loc, "AssemblyFlagsAttribute");
1088
 
                }
1089
 
 
1090
 
                public virtual void SetVersion (Version version, Location loc)
1091
 
                {
1092
 
                        ctx.Report.RuntimeMissingSupport (loc, "AssemblyVersionAttribute");
1093
 
                }
1094
 
        }
1095
 
 
1096
 
        abstract class AssemblyReferencesLoader<T>
1097
 
        {
1098
 
                protected readonly CompilerContext compiler;
1099
 
 
1100
 
                protected readonly List<string> paths;
1101
 
 
1102
 
                public AssemblyReferencesLoader (CompilerContext compiler)
1103
 
                {
1104
 
                        this.compiler = compiler;
1105
 
 
1106
 
                        paths = new List<string> ();
1107
 
                        paths.AddRange (compiler.Settings.ReferencesLookupPaths);
1108
 
                        paths.Add (Directory.GetCurrentDirectory ());
1109
 
                }
1110
 
 
1111
 
                public abstract bool HasObjectType (T assembly);
1112
 
                protected abstract string[] GetDefaultReferences ();
1113
 
                public abstract T LoadAssemblyFile (string fileName, bool isImplicitReference);
1114
 
                public abstract void LoadReferences (ModuleContainer module);
1115
 
 
1116
 
                protected void Error_FileNotFound (string fileName)
1117
 
                {
1118
 
                        compiler.Report.Error (6, "Metadata file `{0}' could not be found", fileName);
1119
 
                }
1120
 
 
1121
 
                protected void Error_FileCorrupted (string fileName)
1122
 
                {
1123
 
                        compiler.Report.Error (9, "Metadata file `{0}' does not contain valid metadata", fileName);
1124
 
                }
1125
 
 
1126
 
                protected void Error_AssemblyIsModule (string fileName)
1127
 
                {
1128
 
                        compiler.Report.Error (1509,
1129
 
                                "Referenced assembly file `{0}' is a module. Consider using `-addmodule' option to add the module",
1130
 
                                fileName);
1131
 
                }
1132
 
 
1133
 
                protected void Error_ModuleIsAssembly (string fileName)
1134
 
                {
1135
 
                        compiler.Report.Error (1542,
1136
 
                                "Added module file `{0}' is an assembly. Consider using `-r' option to reference the file",
1137
 
                                fileName);
1138
 
                }
1139
 
 
1140
 
                protected void LoadReferencesCore (ModuleContainer module, out T corlib_assembly, out List<Tuple<RootNamespace, T>> loaded)
1141
 
                {
1142
 
                        compiler.TimeReporter.Start (TimeReporter.TimerType.ReferencesLoading);
1143
 
 
1144
 
                        loaded = new List<Tuple<RootNamespace, T>> ();
1145
 
 
1146
 
                        //
1147
 
                        // Load mscorlib.dll as the first
1148
 
                        //
1149
 
                        if (module.Compiler.Settings.StdLib) {
1150
 
                                corlib_assembly = LoadAssemblyFile ("mscorlib.dll", true);
1151
 
                        } else {
1152
 
                                corlib_assembly = default (T);
1153
 
                        }
1154
 
 
1155
 
                        T a;
1156
 
                        foreach (string r in module.Compiler.Settings.AssemblyReferences) {
1157
 
                                a = LoadAssemblyFile (r, false);
1158
 
                                if (a == null || EqualityComparer<T>.Default.Equals (a, corlib_assembly))
1159
 
                                        continue;
1160
 
 
1161
 
                                var key = Tuple.Create (module.GlobalRootNamespace, a);
1162
 
                                if (loaded.Contains (key))
1163
 
                                        continue;
1164
 
 
1165
 
                                // A corlib assembly is the first assembly which contains System.Object
1166
 
                                if (corlib_assembly == null && HasObjectType (a)) {
1167
 
                                        corlib_assembly = a;
1168
 
                                        continue;
1169
 
                                }
1170
 
 
1171
 
                                loaded.Add (key);
1172
 
                        }
1173
 
 
1174
 
                        foreach (var entry in module.Compiler.Settings.AssemblyReferencesAliases) {
1175
 
                                a = LoadAssemblyFile (entry.Item2, false);
1176
 
                                if (a == null)
1177
 
                                        continue;
1178
 
 
1179
 
                                var key = Tuple.Create (module.CreateRootNamespace (entry.Item1), a);
1180
 
                                if (loaded.Contains (key))
1181
 
                                        continue;
1182
 
 
1183
 
                                loaded.Add (key);
1184
 
                        }
1185
 
 
1186
 
                        if (compiler.Settings.LoadDefaultReferences) {
1187
 
                                foreach (string r in GetDefaultReferences ()) {
1188
 
                                        a = LoadAssemblyFile (r, true);
1189
 
                                        if (a == null)
1190
 
                                                continue;
1191
 
 
1192
 
                                        var key = Tuple.Create (module.GlobalRootNamespace, a);
1193
 
                                        if (loaded.Contains (key))
1194
 
                                                continue;
1195
 
 
1196
 
                                        loaded.Add (key);
1197
 
                                }
1198
 
                        }
1199
 
 
1200
 
                        compiler.TimeReporter.Stop (TimeReporter.TimerType.ReferencesLoading);
1201
 
                }
1202
 
        }
1203
 
}