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

« back to all changes in this revision

Viewing changes to contrib/ICSharpCode.NRefactory/TypeSystem/CecilLoader.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
 
ļ»æ// Copyright (c) AlphaSierraPapa for the SharpDevelop Team
2
 
// 
3
 
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
4
 
// software and associated documentation files (the "Software"), to deal in the Software
5
 
// without restriction, including without limitation the rights to use, copy, modify, merge,
6
 
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
7
 
// to whom the Software is furnished to do so, subject to the following conditions:
8
 
// 
9
 
// The above copyright notice and this permission notice shall be included in all copies or
10
 
// substantial portions of the Software.
11
 
// 
12
 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
13
 
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14
 
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
15
 
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
16
 
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
17
 
// DEALINGS IN THE SOFTWARE.
18
 
 
19
 
using System;
20
 
using System.Collections.Generic;
21
 
using System.Collections.ObjectModel;
22
 
using System.Diagnostics;
23
 
using System.IO;
24
 
using System.Linq;
25
 
using System.Runtime.CompilerServices;
26
 
using System.Runtime.InteropServices;
27
 
using System.Runtime.Serialization;
28
 
using System.Threading;
29
 
using ICSharpCode.NRefactory.Documentation;
30
 
using ICSharpCode.NRefactory.Semantics;
31
 
using ICSharpCode.NRefactory.TypeSystem.Implementation;
32
 
using ICSharpCode.NRefactory.Utils;
33
 
using Mono.Cecil;
34
 
 
35
 
namespace ICSharpCode.NRefactory.TypeSystem
36
 
{
37
 
        /// <summary>
38
 
        /// Allows loading an IProjectContent from an already compiled assembly.
39
 
        /// </summary>
40
 
        /// <remarks>Instance methods are not thread-safe; you need to create multiple instances of CecilLoader
41
 
        /// if you want to load multiple project contents in parallel.</remarks>
42
 
        public class CecilLoader
43
 
        {
44
 
                #region Options
45
 
                /// <summary>
46
 
                /// Specifies whether to include internal members. The default is false.
47
 
                /// </summary>
48
 
                public bool IncludeInternalMembers { get; set; }
49
 
                
50
 
                /// <summary>
51
 
                /// Gets/Sets the documentation provider that is used to retrieve the XML documentation for all members.
52
 
                /// </summary>
53
 
                public IDocumentationProvider DocumentationProvider { get; set; }
54
 
                
55
 
                /// <summary>
56
 
                /// Gets/Sets the interning provider.
57
 
                /// </summary>
58
 
                public IInterningProvider InterningProvider { get; set; }
59
 
                
60
 
                /// <summary>
61
 
                /// Gets/Sets the cancellation token used by the cecil loader.
62
 
                /// </summary>
63
 
                public CancellationToken CancellationToken { get; set; }
64
 
                
65
 
                /// <summary>
66
 
                /// Gets a value indicating whether this instance stores references to the cecil objects.
67
 
                /// </summary>
68
 
                /// <value>
69
 
                /// <c>true</c> if this instance has references to the cecil objects; otherwise, <c>false</c>.
70
 
                /// </value>
71
 
                public bool HasCecilReferences { get { return typeSystemTranslationTable != null; } }
72
 
                #endregion
73
 
                
74
 
                ModuleDefinition currentModule;
75
 
                CecilUnresolvedAssembly currentAssembly;
76
 
                
77
 
                /// <summary>
78
 
                /// Initializes a new instance of the <see cref="ICSharpCode.NRefactory.TypeSystem.CecilLoader"/> class.
79
 
                /// </summary>
80
 
                /// <param name='createCecilReferences'>
81
 
                /// If true references to the cecil objects are hold. In this case the cecil loader can do a type system -> cecil mapping.
82
 
                /// </param>
83
 
                public CecilLoader (bool createCecilReferences = false)
84
 
                {
85
 
                        if (createCecilReferences)
86
 
                                typeSystemTranslationTable = new Dictionary<object, object> ();
87
 
                        
88
 
                        // Enable interning by default.
89
 
                        this.InterningProvider = new SimpleInterningProvider();
90
 
                }
91
 
                
92
 
                #region Load From AssemblyDefinition
93
 
                /// <summary>
94
 
                /// Loads the assembly definition into a project content.
95
 
                /// </summary>
96
 
                /// <returns>IProjectContent that represents the assembly</returns>
97
 
                [CLSCompliant(false)]
98
 
                public IUnresolvedAssembly LoadAssembly(AssemblyDefinition assemblyDefinition)
99
 
                {
100
 
                        if (assemblyDefinition == null)
101
 
                                throw new ArgumentNullException("assemblyDefinition");
102
 
                        
103
 
                        this.currentModule = assemblyDefinition.MainModule;
104
 
                        
105
 
                        // Read assembly and module attributes
106
 
                        IList<IUnresolvedAttribute> assemblyAttributes = new List<IUnresolvedAttribute>();
107
 
                        IList<IUnresolvedAttribute> moduleAttributes = new List<IUnresolvedAttribute>();
108
 
                        AddAttributes(assemblyDefinition, assemblyAttributes);
109
 
                        AddAttributes(assemblyDefinition.MainModule, moduleAttributes);
110
 
                        
111
 
                        if (this.InterningProvider != null) {
112
 
                                assemblyAttributes = this.InterningProvider.InternList(assemblyAttributes);
113
 
                                moduleAttributes = this.InterningProvider.InternList(moduleAttributes);
114
 
                        }
115
 
                        
116
 
                        this.currentAssembly = new CecilUnresolvedAssembly(assemblyDefinition.Name.Name, this.DocumentationProvider);
117
 
                        currentAssembly.AssemblyAttributes.AddRange(assemblyAttributes);
118
 
                        currentAssembly.ModuleAttributes.AddRange(assemblyAttributes);
119
 
                        
120
 
                        // Register type forwarders:
121
 
                        foreach (ExportedType type in assemblyDefinition.MainModule.ExportedTypes) {
122
 
                                if (type.IsForwarder) {
123
 
                                        int typeParameterCount;
124
 
                                        string name = ReflectionHelper.SplitTypeParameterCountFromReflectionName(type.Name, out typeParameterCount);
125
 
                                        var typeRef = new GetClassTypeReference(GetAssemblyReference(type.Scope), type.Namespace, name, typeParameterCount);
126
 
                                        typeRef = this.InterningProvider.Intern(typeRef);
127
 
                                        var key = new FullNameAndTypeParameterCount(type.Namespace, name, typeParameterCount);
128
 
                                        currentAssembly.AddTypeForwarder(key, typeRef);
129
 
                                }
130
 
                        }
131
 
                        
132
 
                        // Create and register all types:
133
 
                        List<TypeDefinition> cecilTypeDefs = new List<TypeDefinition>();
134
 
                        List<DefaultUnresolvedTypeDefinition> typeDefs = new List<DefaultUnresolvedTypeDefinition>();
135
 
                        foreach (ModuleDefinition module in assemblyDefinition.Modules) {
136
 
                                foreach (TypeDefinition td in module.Types) {
137
 
                                        this.CancellationToken.ThrowIfCancellationRequested();
138
 
                                        if (this.IncludeInternalMembers || (td.Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.Public) {
139
 
                                                string name = td.Name;
140
 
                                                if (name.Length == 0 || name[0] == '<')
141
 
                                                        continue;
142
 
                                                
143
 
                                                var t = CreateTopLevelTypeDefinition(td);
144
 
                                                cecilTypeDefs.Add(td);
145
 
                                                typeDefs.Add(t);
146
 
                                                currentAssembly.AddTypeDefinition(t);
147
 
                                        }
148
 
                                }
149
 
                        }
150
 
                        // Initialize the type's members:
151
 
                        for (int i = 0; i < typeDefs.Count; i++) {
152
 
                                InitTypeDefinition(cecilTypeDefs[i], typeDefs[i]);
153
 
                        }
154
 
                        
155
 
                        if (HasCecilReferences)
156
 
                                typeSystemTranslationTable[this.currentAssembly] = assemblyDefinition;
157
 
                        
158
 
                        var result = this.currentAssembly;
159
 
                        this.currentAssembly = null;
160
 
                        this.currentModule = null;
161
 
                        return result;
162
 
                }
163
 
                
164
 
                /// <summary>
165
 
                /// Loads a type from Cecil.
166
 
                /// </summary>
167
 
                /// <param name="typeDefinition">The Cecil TypeDefinition.</param>
168
 
                /// <returns>ITypeDefinition representing the Cecil type.</returns>
169
 
                [CLSCompliant(false)]
170
 
                public IUnresolvedTypeDefinition LoadType(TypeDefinition typeDefinition)
171
 
                {
172
 
                        if (typeDefinition == null)
173
 
                                throw new ArgumentNullException("typeDefinition");
174
 
                        var td = CreateTopLevelTypeDefinition(typeDefinition);
175
 
                        InitTypeDefinition(typeDefinition, td);
176
 
                        return td;
177
 
                }
178
 
                #endregion
179
 
                
180
 
                #region IUnresolvedAssembly implementation
181
 
                [Serializable]
182
 
                sealed class CecilUnresolvedAssembly : DefaultUnresolvedAssembly, IDocumentationProvider, IDocumentationProviderContainer
183
 
                {
184
 
                        [NonSerialized]
185
 
                        IDocumentationProvider documentationProvider;
186
 
 
187
 
                        public IDocumentationProvider DocumentationProvider {
188
 
                                get {
189
 
                                        return documentationProvider;
190
 
                                }
191
 
                                set {
192
 
                                        documentationProvider = value;
193
 
                                }
194
 
                        }
195
 
 
196
 
                        public CecilUnresolvedAssembly(string assemblyName, IDocumentationProvider documentationProvider)
197
 
                                : base(assemblyName)
198
 
                        {
199
 
                                Debug.Assert(assemblyName != null);
200
 
                                this.documentationProvider = documentationProvider;
201
 
                        }
202
 
                        
203
 
                        DocumentationComment IDocumentationProvider.GetDocumentation(IEntity entity)
204
 
                        {
205
 
                                if (documentationProvider != null)
206
 
                                        return documentationProvider.GetDocumentation(entity);
207
 
                                else
208
 
                                        return null;
209
 
                        }
210
 
                }
211
 
                #endregion
212
 
                
213
 
                #region Load Assembly From Disk
214
 
                public IUnresolvedAssembly LoadAssemblyFile(string fileName)
215
 
                {
216
 
                        if (fileName == null)
217
 
                                throw new ArgumentNullException("fileName");
218
 
                        var param = new ReaderParameters { AssemblyResolver = new DummyAssemblyResolver() };
219
 
                        AssemblyDefinition asm = AssemblyDefinition.ReadAssembly(fileName, param);
220
 
                        var result = LoadAssembly(asm);
221
 
                        if (HasCecilReferences)
222
 
                                typeSystemTranslationTable[result] = asm;
223
 
                        return result;
224
 
                }
225
 
                
226
 
                // used to prevent Cecil from loading referenced assemblies
227
 
                sealed class DummyAssemblyResolver : IAssemblyResolver
228
 
                {
229
 
                        public AssemblyDefinition Resolve(AssemblyNameReference name)
230
 
                        {
231
 
                                return null;
232
 
                        }
233
 
                        
234
 
                        public AssemblyDefinition Resolve(string fullName)
235
 
                        {
236
 
                                return null;
237
 
                        }
238
 
                        
239
 
                        public AssemblyDefinition Resolve(AssemblyNameReference name, ReaderParameters parameters)
240
 
                        {
241
 
                                return null;
242
 
                        }
243
 
                        
244
 
                        public AssemblyDefinition Resolve(string fullName, ReaderParameters parameters)
245
 
                        {
246
 
                                return null;
247
 
                        }
248
 
                }
249
 
                #endregion
250
 
                
251
 
                #region Read Type Reference
252
 
                /// <summary>
253
 
                /// Reads a type reference.
254
 
                /// </summary>
255
 
                /// <param name="type">The Cecil type reference that should be converted into
256
 
                /// a type system type reference.</param>
257
 
                /// <param name="typeAttributes">Attributes associated with the Cecil type reference.
258
 
                /// This is used to support the 'dynamic' type.</param>
259
 
                [CLSCompliant(false)]
260
 
                public ITypeReference ReadTypeReference(TypeReference type, ICustomAttributeProvider typeAttributes = null)
261
 
                {
262
 
                        int typeIndex = 0;
263
 
                        return CreateType(type, typeAttributes, ref typeIndex);
264
 
                }
265
 
                
266
 
                ITypeReference CreateType(TypeReference type, ICustomAttributeProvider typeAttributes, ref int typeIndex)
267
 
                {
268
 
                        while (type is OptionalModifierType || type is RequiredModifierType) {
269
 
                                type = ((TypeSpecification)type).ElementType;
270
 
                        }
271
 
                        if (type == null) {
272
 
                                return SpecialType.UnknownType;
273
 
                        }
274
 
                        
275
 
                        if (type is Mono.Cecil.ByReferenceType) {
276
 
                                typeIndex++;
277
 
                                return new ByReferenceTypeReference(
278
 
                                        CreateType(
279
 
                                                (type as Mono.Cecil.ByReferenceType).ElementType,
280
 
                                                typeAttributes, ref typeIndex));
281
 
                        } else if (type is Mono.Cecil.PointerType) {
282
 
                                typeIndex++;
283
 
                                return new PointerTypeReference(
284
 
                                        CreateType(
285
 
                                                (type as Mono.Cecil.PointerType).ElementType,
286
 
                                                typeAttributes, ref typeIndex));
287
 
                        } else if (type is Mono.Cecil.ArrayType) {
288
 
                                typeIndex++;
289
 
                                return new ArrayTypeReference(
290
 
                                        CreateType(
291
 
                                                (type as Mono.Cecil.ArrayType).ElementType,
292
 
                                                typeAttributes, ref typeIndex),
293
 
                                        (type as Mono.Cecil.ArrayType).Rank);
294
 
                        } else if (type is GenericInstanceType) {
295
 
                                GenericInstanceType gType = (GenericInstanceType)type;
296
 
                                ITypeReference baseType = CreateType(gType.ElementType, typeAttributes, ref typeIndex);
297
 
                                ITypeReference[] para = new ITypeReference[gType.GenericArguments.Count];
298
 
                                for (int i = 0; i < para.Length; ++i) {
299
 
                                        typeIndex++;
300
 
                                        para[i] = CreateType(gType.GenericArguments[i], typeAttributes, ref typeIndex);
301
 
                                }
302
 
                                return new ParameterizedTypeReference(baseType, para);
303
 
                        } else if (type is GenericParameter) {
304
 
                                GenericParameter typeGP = (GenericParameter)type;
305
 
                                return new TypeParameterReference(typeGP.Owner is MethodDefinition ? EntityType.Method : EntityType.TypeDefinition, typeGP.Position);
306
 
                        } else if (type.IsNested) {
307
 
                                ITypeReference typeRef = CreateType(type.DeclaringType, typeAttributes, ref typeIndex);
308
 
                                int partTypeParameterCount;
309
 
                                string namepart = ReflectionHelper.SplitTypeParameterCountFromReflectionName(type.Name, out partTypeParameterCount);
310
 
                                return new NestedTypeReference(typeRef, namepart, partTypeParameterCount);
311
 
                        } else {
312
 
                                string ns = type.Namespace ?? string.Empty;
313
 
                                string name = type.Name;
314
 
                                if (name == null)
315
 
                                        throw new InvalidOperationException("type.Name returned null. Type: " + type.ToString());
316
 
                                
317
 
                                if (name == "Object" && ns == "System" && HasDynamicAttribute(typeAttributes, typeIndex)) {
318
 
                                        return SpecialType.Dynamic;
319
 
                                } else {
320
 
                                        int typeParameterCount;
321
 
                                        name = ReflectionHelper.SplitTypeParameterCountFromReflectionName(name, out typeParameterCount);
322
 
                                        if (currentAssembly != null) {
323
 
                                                IUnresolvedTypeDefinition c = currentAssembly.GetTypeDefinition(ns, name, typeParameterCount);
324
 
                                                if (c != null)
325
 
                                                        return c;
326
 
                                        }
327
 
                                        return new GetClassTypeReference(GetAssemblyReference(type.Scope), ns, name, typeParameterCount);
328
 
                                }
329
 
                        }
330
 
                }
331
 
                
332
 
                IAssemblyReference GetAssemblyReference(IMetadataScope scope)
333
 
                {
334
 
                        if (scope == null || scope == currentModule)
335
 
                                return DefaultAssemblyReference.CurrentAssembly;
336
 
                        else
337
 
                                return new DefaultAssemblyReference(scope.Name);
338
 
                }
339
 
                
340
 
                static bool HasDynamicAttribute(ICustomAttributeProvider attributeProvider, int typeIndex)
341
 
                {
342
 
                        if (attributeProvider == null || !attributeProvider.HasCustomAttributes)
343
 
                                return false;
344
 
                        foreach (CustomAttribute a in attributeProvider.CustomAttributes) {
345
 
                                TypeReference type = a.AttributeType;
346
 
                                if (type.Name == "DynamicAttribute" && type.Namespace == "System.Runtime.CompilerServices") {
347
 
                                        if (a.ConstructorArguments.Count == 1) {
348
 
                                                CustomAttributeArgument[] values = a.ConstructorArguments[0].Value as CustomAttributeArgument[];
349
 
                                                if (values != null && typeIndex < values.Length && values[typeIndex].Value is bool)
350
 
                                                        return (bool)values[typeIndex].Value;
351
 
                                        }
352
 
                                        return true;
353
 
                                }
354
 
                        }
355
 
                        return false;
356
 
                }
357
 
                #endregion
358
 
                
359
 
                #region Read Attributes
360
 
                #region Assembly Attributes
361
 
                static readonly ITypeReference assemblyVersionAttributeTypeRef = typeof(System.Reflection.AssemblyVersionAttribute).ToTypeReference();
362
 
                
363
 
                void AddAttributes(AssemblyDefinition assembly, IList<IUnresolvedAttribute> outputList)
364
 
                {
365
 
                        if (assembly.HasCustomAttributes) {
366
 
                                AddCustomAttributes(assembly.CustomAttributes, outputList);
367
 
                        }
368
 
                        if (assembly.HasSecurityDeclarations) {
369
 
                                AddSecurityAttributes(assembly.SecurityDeclarations, outputList);
370
 
                        }
371
 
                        
372
 
                        // AssemblyVersionAttribute
373
 
                        if (assembly.Name.Version != null) {
374
 
                                var assemblyVersion = new DefaultUnresolvedAttribute(assemblyVersionAttributeTypeRef, new[] { KnownTypeReference.String });
375
 
                                assemblyVersion.PositionalArguments.Add(new SimpleConstantValue(KnownTypeReference.String, assembly.Name.Version.ToString()));
376
 
                                outputList.Add(assemblyVersion);
377
 
                        }
378
 
                }
379
 
                #endregion
380
 
                
381
 
                #region Module Attributes
382
 
                void AddAttributes(ModuleDefinition module, IList<IUnresolvedAttribute> outputList)
383
 
                {
384
 
                        if (module.HasCustomAttributes) {
385
 
                                AddCustomAttributes(module.CustomAttributes, outputList);
386
 
                        }
387
 
                }
388
 
                #endregion
389
 
                
390
 
                #region Parameter Attributes
391
 
                static readonly IUnresolvedAttribute inAttribute = new DefaultUnresolvedAttribute(typeof(InAttribute).ToTypeReference());
392
 
                static readonly IUnresolvedAttribute outAttribute = new DefaultUnresolvedAttribute(typeof(OutAttribute).ToTypeReference());
393
 
                
394
 
                void AddAttributes(ParameterDefinition parameter, DefaultUnresolvedParameter targetParameter)
395
 
                {
396
 
                        if (!targetParameter.IsOut) {
397
 
                                if (parameter.IsIn)
398
 
                                        targetParameter.Attributes.Add(inAttribute);
399
 
                                if (parameter.IsOut)
400
 
                                        targetParameter.Attributes.Add(outAttribute);
401
 
                        }
402
 
                        if (parameter.HasCustomAttributes) {
403
 
                                AddCustomAttributes(parameter.CustomAttributes, targetParameter.Attributes);
404
 
                        }
405
 
                        if (parameter.HasMarshalInfo) {
406
 
                                targetParameter.Attributes.Add(ConvertMarshalInfo(parameter.MarshalInfo));
407
 
                        }
408
 
                }
409
 
                #endregion
410
 
                
411
 
                #region Method Attributes
412
 
                static readonly ITypeReference dllImportAttributeTypeRef = typeof(DllImportAttribute).ToTypeReference();
413
 
                static readonly SimpleConstantValue trueValue = new SimpleConstantValue(KnownTypeReference.Boolean, true);
414
 
                static readonly SimpleConstantValue falseValue = new SimpleConstantValue(KnownTypeReference.Boolean, false);
415
 
                static readonly ITypeReference callingConventionTypeRef = typeof(CallingConvention).ToTypeReference();
416
 
                static readonly IUnresolvedAttribute preserveSigAttribute = new DefaultUnresolvedAttribute(typeof(PreserveSigAttribute).ToTypeReference());
417
 
                static readonly ITypeReference methodImplAttributeTypeRef = typeof(MethodImplAttribute).ToTypeReference();
418
 
                static readonly ITypeReference methodImplOptionsTypeRef = typeof(MethodImplOptions).ToTypeReference();
419
 
                
420
 
                static bool HasAnyAttributes(MethodDefinition methodDefinition)
421
 
                {
422
 
                        if (methodDefinition.HasPInvokeInfo)
423
 
                                return true;
424
 
                        if ((methodDefinition.ImplAttributes & ~MethodImplAttributes.CodeTypeMask) != 0)
425
 
                                return true;
426
 
                        if (methodDefinition.MethodReturnType.HasFieldMarshal)
427
 
                                return true;
428
 
                        return methodDefinition.HasCustomAttributes || methodDefinition.MethodReturnType.HasCustomAttributes;
429
 
                }
430
 
                
431
 
                void AddAttributes(MethodDefinition methodDefinition, IList<IUnresolvedAttribute> attributes, IList<IUnresolvedAttribute> returnTypeAttributes)
432
 
                {
433
 
                        MethodImplAttributes implAttributes = methodDefinition.ImplAttributes & ~MethodImplAttributes.CodeTypeMask;
434
 
                        
435
 
                        #region DllImportAttribute
436
 
                        if (methodDefinition.HasPInvokeInfo) {
437
 
                                PInvokeInfo info = methodDefinition.PInvokeInfo;
438
 
                                var dllImport = new DefaultUnresolvedAttribute(dllImportAttributeTypeRef, new[] { KnownTypeReference.String });
439
 
                                dllImport.PositionalArguments.Add(new SimpleConstantValue(KnownTypeReference.String, info.Module.Name));
440
 
                                
441
 
                                if (info.IsBestFitDisabled)
442
 
                                        dllImport.AddNamedFieldArgument("BestFitMapping", falseValue);
443
 
                                if (info.IsBestFitEnabled)
444
 
                                        dllImport.AddNamedFieldArgument("BestFitMapping", trueValue);
445
 
                                
446
 
                                CallingConvention callingConvention;
447
 
                                switch (info.Attributes & PInvokeAttributes.CallConvMask) {
448
 
                                        case (PInvokeAttributes)0:
449
 
                                                Debug.WriteLine ("P/Invoke calling convention not set on:" + methodDefinition.FullName);
450
 
                                                callingConvention = CallingConvention.StdCall;
451
 
                                                break;
452
 
                                        case PInvokeAttributes.CallConvCdecl:
453
 
                                                callingConvention = CallingConvention.Cdecl;
454
 
                                                break;
455
 
                                        case PInvokeAttributes.CallConvFastcall:
456
 
                                                callingConvention = CallingConvention.FastCall;
457
 
                                                break;
458
 
                                        case PInvokeAttributes.CallConvStdCall:
459
 
                                                callingConvention = CallingConvention.StdCall;
460
 
                                                break;
461
 
                                        case PInvokeAttributes.CallConvThiscall:
462
 
                                                callingConvention = CallingConvention.ThisCall;
463
 
                                                break;
464
 
                                        case PInvokeAttributes.CallConvWinapi:
465
 
                                                callingConvention = CallingConvention.Winapi;
466
 
                                                break;
467
 
                                        default:
468
 
                                                throw new NotSupportedException("unknown calling convention");
469
 
                                }
470
 
                                if (callingConvention != CallingConvention.Winapi)
471
 
                                        dllImport.AddNamedFieldArgument("CallingConvention", callingConventionTypeRef, (int)callingConvention);
472
 
                                
473
 
                                CharSet charSet = CharSet.None;
474
 
                                switch (info.Attributes & PInvokeAttributes.CharSetMask) {
475
 
                                        case PInvokeAttributes.CharSetAnsi:
476
 
                                                charSet = CharSet.Ansi;
477
 
                                                break;
478
 
                                        case PInvokeAttributes.CharSetAuto:
479
 
                                                charSet = CharSet.Auto;
480
 
                                                break;
481
 
                                        case PInvokeAttributes.CharSetUnicode:
482
 
                                                charSet = CharSet.Unicode;
483
 
                                                break;
484
 
                                }
485
 
                                if (charSet != CharSet.None)
486
 
                                        dllImport.AddNamedFieldArgument("CharSet", charSetTypeRef, (int)charSet);
487
 
                                
488
 
                                if (!string.IsNullOrEmpty(info.EntryPoint) && info.EntryPoint != methodDefinition.Name)
489
 
                                        dllImport.AddNamedFieldArgument("EntryPoint", KnownTypeReference.String, info.EntryPoint);
490
 
                                
491
 
                                if (info.IsNoMangle)
492
 
                                        dllImport.AddNamedFieldArgument("ExactSpelling", trueValue);
493
 
                                
494
 
                                if ((implAttributes & MethodImplAttributes.PreserveSig) == MethodImplAttributes.PreserveSig)
495
 
                                        implAttributes &= ~MethodImplAttributes.PreserveSig;
496
 
                                else
497
 
                                        dllImport.AddNamedFieldArgument("PreserveSig", falseValue);
498
 
                                
499
 
                                if (info.SupportsLastError)
500
 
                                        dllImport.AddNamedFieldArgument("SetLastError", trueValue);
501
 
                                
502
 
                                if (info.IsThrowOnUnmappableCharDisabled)
503
 
                                        dllImport.AddNamedFieldArgument("ThrowOnUnmappableChar", falseValue);
504
 
                                if (info.IsThrowOnUnmappableCharEnabled)
505
 
                                        dllImport.AddNamedFieldArgument("ThrowOnUnmappableChar", trueValue);
506
 
                                
507
 
                                attributes.Add(dllImport);
508
 
                        }
509
 
                        #endregion
510
 
                        
511
 
                        #region PreserveSigAttribute
512
 
                        if (implAttributes == MethodImplAttributes.PreserveSig) {
513
 
                                attributes.Add(preserveSigAttribute);
514
 
                                implAttributes = 0;
515
 
                        }
516
 
                        #endregion
517
 
                        
518
 
                        #region MethodImplAttribute
519
 
                        if (implAttributes != 0) {
520
 
                                var methodImpl = new DefaultUnresolvedAttribute(methodImplAttributeTypeRef, new[] { methodImplOptionsTypeRef });
521
 
                                methodImpl.PositionalArguments.Add(new SimpleConstantValue(methodImplOptionsTypeRef, (int)implAttributes));
522
 
                                attributes.Add(methodImpl);
523
 
                        }
524
 
                        #endregion
525
 
                        
526
 
                        if (methodDefinition.HasCustomAttributes) {
527
 
                                AddCustomAttributes(methodDefinition.CustomAttributes, attributes);
528
 
                        }
529
 
                        if (methodDefinition.HasSecurityDeclarations) {
530
 
                                AddSecurityAttributes(methodDefinition.SecurityDeclarations, attributes);
531
 
                        }
532
 
                        if (methodDefinition.MethodReturnType.HasMarshalInfo) {
533
 
                                returnTypeAttributes.Add(ConvertMarshalInfo(methodDefinition.MethodReturnType.MarshalInfo));
534
 
                        }
535
 
                        if (methodDefinition.MethodReturnType.HasCustomAttributes) {
536
 
                                AddCustomAttributes(methodDefinition.MethodReturnType.CustomAttributes, returnTypeAttributes);
537
 
                        }
538
 
                }
539
 
                #endregion
540
 
                
541
 
                #region Type Attributes
542
 
                static readonly DefaultUnresolvedAttribute serializableAttribute = new DefaultUnresolvedAttribute(typeof(SerializableAttribute).ToTypeReference());
543
 
                static readonly DefaultUnresolvedAttribute comImportAttribute = new DefaultUnresolvedAttribute(typeof(ComImportAttribute).ToTypeReference());
544
 
                static readonly ITypeReference structLayoutAttributeTypeRef = typeof(StructLayoutAttribute).ToTypeReference();
545
 
                static readonly ITypeReference layoutKindTypeRef = typeof(LayoutKind).ToTypeReference();
546
 
                static readonly ITypeReference charSetTypeRef = typeof(CharSet).ToTypeReference();
547
 
                
548
 
                void AddAttributes(TypeDefinition typeDefinition, IUnresolvedTypeDefinition targetEntity)
549
 
                {
550
 
                        // SerializableAttribute
551
 
                        if (typeDefinition.IsSerializable)
552
 
                                targetEntity.Attributes.Add(serializableAttribute);
553
 
                        
554
 
                        // ComImportAttribute
555
 
                        if (typeDefinition.IsImport)
556
 
                                targetEntity.Attributes.Add(comImportAttribute);
557
 
                        
558
 
                        #region StructLayoutAttribute
559
 
                        LayoutKind layoutKind = LayoutKind.Auto;
560
 
                        switch (typeDefinition.Attributes & TypeAttributes.LayoutMask) {
561
 
                                case TypeAttributes.SequentialLayout:
562
 
                                        layoutKind = LayoutKind.Sequential;
563
 
                                        break;
564
 
                                case TypeAttributes.ExplicitLayout:
565
 
                                        layoutKind = LayoutKind.Explicit;
566
 
                                        break;
567
 
                        }
568
 
                        CharSet charSet = CharSet.None;
569
 
                        switch (typeDefinition.Attributes & TypeAttributes.StringFormatMask) {
570
 
                                case TypeAttributes.AnsiClass:
571
 
                                        charSet = CharSet.Ansi;
572
 
                                        break;
573
 
                                case TypeAttributes.AutoClass:
574
 
                                        charSet = CharSet.Auto;
575
 
                                        break;
576
 
                                case TypeAttributes.UnicodeClass:
577
 
                                        charSet = CharSet.Unicode;
578
 
                                        break;
579
 
                        }
580
 
                        LayoutKind defaultLayoutKind = (typeDefinition.IsValueType && !typeDefinition.IsEnum) ? LayoutKind.Sequential: LayoutKind.Auto;
581
 
                        if (layoutKind != defaultLayoutKind || charSet != CharSet.Ansi || typeDefinition.PackingSize > 0 || typeDefinition.ClassSize > 0) {
582
 
                                DefaultUnresolvedAttribute structLayout = new DefaultUnresolvedAttribute(structLayoutAttributeTypeRef, new[] { layoutKindTypeRef });
583
 
                                structLayout.PositionalArguments.Add(new SimpleConstantValue(layoutKindTypeRef, (int)layoutKind));
584
 
                                if (charSet != CharSet.Ansi) {
585
 
                                        structLayout.AddNamedFieldArgument("CharSet", charSetTypeRef, (int)charSet);
586
 
                                }
587
 
                                if (typeDefinition.PackingSize > 0) {
588
 
                                        structLayout.AddNamedFieldArgument("Pack", KnownTypeReference.Int32, (int)typeDefinition.PackingSize);
589
 
                                }
590
 
                                if (typeDefinition.ClassSize > 0) {
591
 
                                        structLayout.AddNamedFieldArgument("Size", KnownTypeReference.Int32, (int)typeDefinition.ClassSize);
592
 
                                }
593
 
                                targetEntity.Attributes.Add(structLayout);
594
 
                        }
595
 
                        #endregion
596
 
                        
597
 
                        if (typeDefinition.HasCustomAttributes) {
598
 
                                AddCustomAttributes(typeDefinition.CustomAttributes, targetEntity.Attributes);
599
 
                        }
600
 
                        if (typeDefinition.HasSecurityDeclarations) {
601
 
                                AddSecurityAttributes(typeDefinition.SecurityDeclarations, targetEntity.Attributes);
602
 
                        }
603
 
                }
604
 
                #endregion
605
 
                
606
 
                #region Field Attributes
607
 
                static readonly ITypeReference fieldOffsetAttributeTypeRef = typeof(FieldOffsetAttribute).ToTypeReference();
608
 
                static readonly IUnresolvedAttribute nonSerializedAttribute = new DefaultUnresolvedAttribute(typeof(NonSerializedAttribute).ToTypeReference());
609
 
                
610
 
                void AddAttributes(FieldDefinition fieldDefinition, IUnresolvedEntity targetEntity)
611
 
                {
612
 
                        // FieldOffsetAttribute
613
 
                        if (fieldDefinition.HasLayoutInfo) {
614
 
                                DefaultUnresolvedAttribute fieldOffset = new DefaultUnresolvedAttribute(fieldOffsetAttributeTypeRef, new[] { KnownTypeReference.Int32 });
615
 
                                fieldOffset.PositionalArguments.Add(new SimpleConstantValue(KnownTypeReference.Int32, fieldDefinition.Offset));
616
 
                                targetEntity.Attributes.Add(fieldOffset);
617
 
                        }
618
 
                        
619
 
                        // NonSerializedAttribute
620
 
                        if (fieldDefinition.IsNotSerialized) {
621
 
                                targetEntity.Attributes.Add(nonSerializedAttribute);
622
 
                        }
623
 
                        
624
 
                        if (fieldDefinition.HasMarshalInfo) {
625
 
                                targetEntity.Attributes.Add(ConvertMarshalInfo(fieldDefinition.MarshalInfo));
626
 
                        }
627
 
                        
628
 
                        if (fieldDefinition.HasCustomAttributes) {
629
 
                                AddCustomAttributes(fieldDefinition.CustomAttributes, targetEntity.Attributes);
630
 
                        }
631
 
                }
632
 
                #endregion
633
 
                
634
 
                #region Event Attributes
635
 
                void AddAttributes(EventDefinition eventDefinition, IUnresolvedEntity targetEntity)
636
 
                {
637
 
                        if (eventDefinition.HasCustomAttributes) {
638
 
                                AddCustomAttributes(eventDefinition.CustomAttributes, targetEntity.Attributes);
639
 
                        }
640
 
                }
641
 
                #endregion
642
 
                
643
 
                #region Property Attributes
644
 
                void AddAttributes(PropertyDefinition propertyDefinition, IUnresolvedEntity targetEntity)
645
 
                {
646
 
                        if (propertyDefinition.HasCustomAttributes) {
647
 
                                AddCustomAttributes(propertyDefinition.CustomAttributes, targetEntity.Attributes);
648
 
                        }
649
 
                }
650
 
                #endregion
651
 
                
652
 
                #region MarshalAsAttribute (ConvertMarshalInfo)
653
 
                static readonly ITypeReference marshalAsAttributeTypeRef = typeof(MarshalAsAttribute).ToTypeReference();
654
 
                static readonly ITypeReference unmanagedTypeTypeRef = typeof(UnmanagedType).ToTypeReference();
655
 
                
656
 
                static IUnresolvedAttribute ConvertMarshalInfo(MarshalInfo marshalInfo)
657
 
                {
658
 
                        DefaultUnresolvedAttribute attr = new DefaultUnresolvedAttribute(marshalAsAttributeTypeRef, new[] { unmanagedTypeTypeRef });
659
 
                        attr.PositionalArguments.Add(new SimpleConstantValue(unmanagedTypeTypeRef, (int)marshalInfo.NativeType));
660
 
                        
661
 
                        FixedArrayMarshalInfo fami = marshalInfo as FixedArrayMarshalInfo;
662
 
                        if (fami != null) {
663
 
                                attr.AddNamedFieldArgument("SizeConst", KnownTypeReference.Int32, (int)fami.Size);
664
 
                                if (fami.ElementType != NativeType.None)
665
 
                                        attr.AddNamedFieldArgument("ArraySubType", unmanagedTypeTypeRef, (int)fami.ElementType);
666
 
                        }
667
 
                        SafeArrayMarshalInfo sami = marshalInfo as SafeArrayMarshalInfo;
668
 
                        if (sami != null && sami.ElementType != VariantType.None) {
669
 
                                attr.AddNamedFieldArgument("SafeArraySubType", typeof(VarEnum).ToTypeReference(), (int)sami.ElementType);
670
 
                        }
671
 
                        ArrayMarshalInfo ami = marshalInfo as ArrayMarshalInfo;
672
 
                        if (ami != null) {
673
 
                                if (ami.ElementType != NativeType.Max)
674
 
                                        attr.AddNamedFieldArgument("ArraySubType", unmanagedTypeTypeRef, (int)ami.ElementType);
675
 
                                if (ami.Size >= 0)
676
 
                                        attr.AddNamedFieldArgument("SizeConst", KnownTypeReference.Int32, (int)ami.Size);
677
 
                                if (ami.SizeParameterMultiplier != 0 && ami.SizeParameterIndex >= 0)
678
 
                                        attr.AddNamedFieldArgument("SizeParamIndex", KnownTypeReference.Int16, (short)ami.SizeParameterIndex);
679
 
                        }
680
 
                        CustomMarshalInfo cmi = marshalInfo as CustomMarshalInfo;
681
 
                        if (cmi != null) {
682
 
                                attr.AddNamedFieldArgument("MarshalType", KnownTypeReference.String, cmi.ManagedType.FullName);
683
 
                                if (!string.IsNullOrEmpty(cmi.Cookie))
684
 
                                        attr.AddNamedFieldArgument("MarshalCookie", KnownTypeReference.String, cmi.Cookie);
685
 
                        }
686
 
                        FixedSysStringMarshalInfo fssmi = marshalInfo as FixedSysStringMarshalInfo;
687
 
                        if (fssmi != null) {
688
 
                                attr.AddNamedFieldArgument("SizeConst", KnownTypeReference.Int32, (int)fssmi.Size);
689
 
                        }
690
 
                        
691
 
                        return attr;
692
 
                }
693
 
                #endregion
694
 
                
695
 
                #region Custom Attributes (ReadAttribute)
696
 
                void AddCustomAttributes(Mono.Collections.Generic.Collection<CustomAttribute> attributes, IList<IUnresolvedAttribute> targetCollection)
697
 
                {
698
 
                        foreach (var cecilAttribute in attributes) {
699
 
                                TypeReference type = cecilAttribute.AttributeType;
700
 
                                if (type.Namespace == "System.Runtime.CompilerServices") {
701
 
                                        if (type.Name == "DynamicAttribute" || type.Name == "ExtensionAttribute")
702
 
                                                continue;
703
 
                                } else if (type.Name == "ParamArrayAttribute" && type.Namespace == "System") {
704
 
                                        continue;
705
 
                                }
706
 
                                targetCollection.Add(ReadAttribute(cecilAttribute));
707
 
                        }
708
 
                }
709
 
                
710
 
                [CLSCompliant(false)]
711
 
                public IUnresolvedAttribute ReadAttribute(CustomAttribute attribute)
712
 
                {
713
 
                        if (attribute == null)
714
 
                                throw new ArgumentNullException("attribute");
715
 
                        MethodReference ctor = attribute.Constructor;
716
 
                        ITypeReference attributeType = ReadTypeReference(attribute.AttributeType);
717
 
                        IList<ITypeReference> ctorParameterTypes = null;
718
 
                        if (ctor.HasParameters) {
719
 
                                ctorParameterTypes = new ITypeReference[ctor.Parameters.Count];
720
 
                                for (int i = 0; i < ctorParameterTypes.Count; i++) {
721
 
                                        ctorParameterTypes[i] = ReadTypeReference(ctor.Parameters[i].ParameterType);
722
 
                                }
723
 
                        }
724
 
                        if (this.InterningProvider != null) {
725
 
                                attributeType = this.InterningProvider.Intern(attributeType);
726
 
                                ctorParameterTypes = this.InterningProvider.InternList(ctorParameterTypes);
727
 
                        }
728
 
                        return new CecilUnresolvedAttribute(attributeType, ctorParameterTypes ?? EmptyList<ITypeReference>.Instance, attribute.GetBlob());
729
 
                }
730
 
                #endregion
731
 
                
732
 
                #region CecilUnresolvedAttribute
733
 
                static int GetBlobHashCode(byte[] blob)
734
 
                {
735
 
                        unchecked {
736
 
                                int hash = 0;
737
 
                                foreach (byte b in blob) {
738
 
                                        hash *= 257;
739
 
                                        hash += b;
740
 
                                }
741
 
                                return hash;
742
 
                        }
743
 
                }
744
 
                
745
 
                static bool BlobEquals(byte[] a, byte[] b)
746
 
                {
747
 
                        if (a.Length != b.Length)
748
 
                                return false;
749
 
                        for (int i = 0; i < a.Length; i++) {
750
 
                                if (a[i] != b[i])
751
 
                                        return false;
752
 
                        }
753
 
                        return true;
754
 
                }
755
 
                
756
 
                [Serializable]
757
 
                sealed class CecilUnresolvedAttribute : IUnresolvedAttribute, ISupportsInterning
758
 
                {
759
 
                        internal readonly ITypeReference attributeType;
760
 
                        internal readonly IList<ITypeReference> ctorParameterTypes;
761
 
                        internal readonly byte[] blob;
762
 
                        
763
 
                        public CecilUnresolvedAttribute(ITypeReference attributeType, IList<ITypeReference> ctorParameterTypes, byte[] blob)
764
 
                        {
765
 
                                Debug.Assert(attributeType != null);
766
 
                                Debug.Assert(ctorParameterTypes != null);
767
 
                                Debug.Assert(blob != null);
768
 
                                this.attributeType = attributeType;
769
 
                                this.ctorParameterTypes = ctorParameterTypes;
770
 
                                this.blob = blob;
771
 
                        }
772
 
                        
773
 
                        DomRegion IUnresolvedAttribute.Region {
774
 
                                get { return DomRegion.Empty; }
775
 
                        }
776
 
                        
777
 
                        IAttribute IUnresolvedAttribute.CreateResolvedAttribute(ITypeResolveContext context)
778
 
                        {
779
 
                                if (context.CurrentAssembly == null)
780
 
                                        throw new InvalidOperationException("Cannot resolve CecilUnresolvedAttribute without a parent assembly");
781
 
                                return new CecilResolvedAttribute(context, this);
782
 
                        }
783
 
                        
784
 
                        void ISupportsInterning.PrepareForInterning(IInterningProvider provider)
785
 
                        {
786
 
                                // We already interned our child elements in ReadAttribute().
787
 
                        }
788
 
                        
789
 
                        int ISupportsInterning.GetHashCodeForInterning()
790
 
                        {
791
 
                                return attributeType.GetHashCode() ^ ctorParameterTypes.GetHashCode() ^ GetBlobHashCode(blob);
792
 
                        }
793
 
                        
794
 
                        bool ISupportsInterning.EqualsForInterning(ISupportsInterning other)
795
 
                        {
796
 
                                CecilUnresolvedAttribute o = other as CecilUnresolvedAttribute;
797
 
                                return o != null && attributeType == o.attributeType && ctorParameterTypes == o.ctorParameterTypes
798
 
                                        && BlobEquals(blob, o.blob);
799
 
                        }
800
 
                }
801
 
                #endregion
802
 
                
803
 
                #region CecilResolvedAttribute
804
 
                sealed class CecilResolvedAttribute : IAttribute
805
 
                {
806
 
                        readonly ITypeResolveContext context;
807
 
                        readonly byte[] blob;
808
 
                        readonly IList<ITypeReference> ctorParameterTypes;
809
 
                        readonly IType attributeType;
810
 
                        
811
 
                        IMethod constructor;
812
 
                        volatile bool constructorResolved;
813
 
                        
814
 
                        IList<ResolveResult> positionalArguments;
815
 
                        IList<KeyValuePair<IMember, ResolveResult>> namedArguments;
816
 
                        
817
 
                        public CecilResolvedAttribute(ITypeResolveContext context, CecilUnresolvedAttribute unresolved)
818
 
                        {
819
 
                                this.context = context;
820
 
                                this.blob = unresolved.blob;
821
 
                                this.ctorParameterTypes = unresolved.ctorParameterTypes;
822
 
                                this.attributeType = unresolved.attributeType.Resolve(context);
823
 
                        }
824
 
                        
825
 
                        public CecilResolvedAttribute(ITypeResolveContext context, IType attributeType)
826
 
                        {
827
 
                                this.context = context;
828
 
                                this.attributeType = attributeType;
829
 
                                this.ctorParameterTypes = EmptyList<ITypeReference>.Instance;
830
 
                        }
831
 
                        
832
 
                        public DomRegion Region {
833
 
                                get { return DomRegion.Empty; }
834
 
                        }
835
 
                        
836
 
                        public IType AttributeType {
837
 
                                get { return attributeType; }
838
 
                        }
839
 
                        
840
 
                        public IMethod Constructor {
841
 
                                get {
842
 
                                        if (!constructorResolved) {
843
 
                                                constructor = ResolveConstructor();
844
 
                                                constructorResolved = true;
845
 
                                        }
846
 
                                        return constructor;
847
 
                                }
848
 
                        }
849
 
                        
850
 
                        IMethod ResolveConstructor()
851
 
                        {
852
 
                                var parameterTypes = ctorParameterTypes.Resolve(context);
853
 
                                foreach (var ctor in attributeType.GetConstructors(m => m.Parameters.Count == parameterTypes.Count)) {
854
 
                                        bool ok = true;
855
 
                                        for (int i = 0; i < parameterTypes.Count; i++) {
856
 
                                                if (!ctor.Parameters[i].Type.Equals(parameterTypes[i])) {
857
 
                                                        ok = false;
858
 
                                                        break;
859
 
                                                }
860
 
                                        }
861
 
                                        if (ok)
862
 
                                                return ctor;
863
 
                                }
864
 
                                return null;
865
 
                        }
866
 
                        
867
 
                        public IList<ResolveResult> PositionalArguments {
868
 
                                get {
869
 
                                        var result = LazyInit.VolatileRead(ref this.positionalArguments);
870
 
                                        if (result != null) {
871
 
                                                return result;
872
 
                                        }
873
 
                                        DecodeBlob();
874
 
                                        return positionalArguments;
875
 
                                }
876
 
                        }
877
 
                        
878
 
                        public IList<KeyValuePair<IMember, ResolveResult>> NamedArguments {
879
 
                                get {
880
 
                                        var result = LazyInit.VolatileRead(ref this.namedArguments);
881
 
                                        if (result != null) {
882
 
                                                return result;
883
 
                                        }
884
 
                                        DecodeBlob();
885
 
                                        return namedArguments;
886
 
                                }
887
 
                        }
888
 
                        
889
 
                        public override string ToString()
890
 
                        {
891
 
                                return "[" + attributeType.ToString() + "(...)]";
892
 
                        }
893
 
                        
894
 
                        void DecodeBlob()
895
 
                        {
896
 
                                var positionalArguments = new List<ResolveResult>();
897
 
                                var namedArguments = new List<KeyValuePair<IMember, ResolveResult>>();
898
 
                                DecodeBlob(positionalArguments, namedArguments);
899
 
                                Interlocked.CompareExchange(ref this.positionalArguments, positionalArguments, null);
900
 
                                Interlocked.CompareExchange(ref this.namedArguments, namedArguments, null);
901
 
                        }
902
 
                        
903
 
                        void DecodeBlob(List<ResolveResult> positionalArguments, List<KeyValuePair<IMember, ResolveResult>> namedArguments)
904
 
                        {
905
 
                                if (blob == null)
906
 
                                        return;
907
 
                                BlobReader reader = new BlobReader(blob, context.CurrentAssembly);
908
 
                                if (reader.ReadUInt16() != 0x0001) {
909
 
                                        Debug.WriteLine("Unknown blob prolog");
910
 
                                        return;
911
 
                                }
912
 
                                foreach (var ctorParameter in ctorParameterTypes.Resolve(context)) {
913
 
                                        positionalArguments.Add(reader.ReadFixedArg(ctorParameter));
914
 
                                }
915
 
                                ushort numNamed = reader.ReadUInt16();
916
 
                                for (int i = 0; i < numNamed; i++) {
917
 
                                        var namedArg = reader.ReadNamedArg(attributeType);
918
 
                                        if (namedArg.Key != null)
919
 
                                                namedArguments.Add(namedArg);
920
 
                                }
921
 
                        }
922
 
                }
923
 
                #endregion
924
 
                
925
 
                #region class BlobReader
926
 
                class BlobReader
927
 
                {
928
 
                        byte[] buffer;
929
 
                        int position;
930
 
                        readonly IAssembly currentResolvedAssembly;
931
 
 
932
 
                        public BlobReader(byte[] buffer, IAssembly currentResolvedAssembly)
933
 
                        {
934
 
                                if (buffer == null)
935
 
                                        throw new ArgumentNullException("buffer");
936
 
                                this.buffer = buffer;
937
 
                                this.currentResolvedAssembly = currentResolvedAssembly;
938
 
                        }
939
 
                        
940
 
                        public byte ReadByte()
941
 
                        {
942
 
                                return buffer[position++];
943
 
                        }
944
 
 
945
 
                        public sbyte ReadSByte()
946
 
                        {
947
 
                                unchecked {
948
 
                                        return(sbyte) ReadByte();
949
 
                                }
950
 
                        }
951
 
                        
952
 
                        public byte[] ReadBytes(int length)
953
 
                        {
954
 
                                var bytes = new byte[length];
955
 
                                Buffer.BlockCopy(buffer, position, bytes, 0, length);
956
 
                                position += length;
957
 
                                return bytes;
958
 
                        }
959
 
 
960
 
                        public ushort ReadUInt16()
961
 
                        {
962
 
                                unchecked {
963
 
                                        ushort value =(ushort)(buffer[position]
964
 
                                                               |(buffer[position + 1] << 8));
965
 
                                        position += 2;
966
 
                                        return value;
967
 
                                }
968
 
                        }
969
 
 
970
 
                        public short ReadInt16()
971
 
                        {
972
 
                                unchecked {
973
 
                                        return(short) ReadUInt16();
974
 
                                }
975
 
                        }
976
 
 
977
 
                        public uint ReadUInt32()
978
 
                        {
979
 
                                unchecked {
980
 
                                        uint value =(uint)(buffer[position]
981
 
                                                           |(buffer[position + 1] << 8)
982
 
                                                           |(buffer[position + 2] << 16)
983
 
                                                           |(buffer[position + 3] << 24));
984
 
                                        position += 4;
985
 
                                        return value;
986
 
                                }
987
 
                        }
988
 
 
989
 
                        public int ReadInt32()
990
 
                        {
991
 
                                unchecked {
992
 
                                        return(int) ReadUInt32();
993
 
                                }
994
 
                        }
995
 
 
996
 
                        public ulong ReadUInt64()
997
 
                        {
998
 
                                unchecked {
999
 
                                        uint low = ReadUInt32();
1000
 
                                        uint high = ReadUInt32();
1001
 
 
1002
 
                                        return(((ulong) high) << 32) | low;
1003
 
                                }
1004
 
                        }
1005
 
 
1006
 
                        public long ReadInt64()
1007
 
                        {
1008
 
                                unchecked {
1009
 
                                        return(long) ReadUInt64();
1010
 
                                }
1011
 
                        }
1012
 
 
1013
 
                        public uint ReadCompressedUInt32()
1014
 
                        {
1015
 
                                unchecked {
1016
 
                                        byte first = ReadByte();
1017
 
                                        if((first & 0x80) == 0)
1018
 
                                                return first;
1019
 
 
1020
 
                                        if((first & 0x40) == 0)
1021
 
                                                return((uint)(first & ~0x80) << 8)
1022
 
                                                        | ReadByte();
1023
 
 
1024
 
                                        return((uint)(first & ~0xc0) << 24)
1025
 
                                                |(uint) ReadByte() << 16
1026
 
                                                |(uint) ReadByte() << 8
1027
 
                                                | ReadByte();
1028
 
                                }
1029
 
                        }
1030
 
 
1031
 
                        public float ReadSingle()
1032
 
                        {
1033
 
                                unchecked {
1034
 
                                        if(!BitConverter.IsLittleEndian) {
1035
 
                                                var bytes = ReadBytes(4);
1036
 
                                                Array.Reverse(bytes);
1037
 
                                                return BitConverter.ToSingle(bytes, 0);
1038
 
                                        }
1039
 
 
1040
 
                                        float value = BitConverter.ToSingle(buffer, position);
1041
 
                                        position += 4;
1042
 
                                        return value;
1043
 
                                }
1044
 
                        }
1045
 
 
1046
 
                        public double ReadDouble()
1047
 
                        {
1048
 
                                unchecked {
1049
 
                                        if(!BitConverter.IsLittleEndian) {
1050
 
                                                var bytes = ReadBytes(8);
1051
 
                                                Array.Reverse(bytes);
1052
 
                                                return BitConverter.ToDouble(bytes, 0);
1053
 
                                        }
1054
 
 
1055
 
                                        double value = BitConverter.ToDouble(buffer, position);
1056
 
                                        position += 8;
1057
 
                                        return value;
1058
 
                                }
1059
 
                        }
1060
 
                        
1061
 
                        public ResolveResult ReadFixedArg(IType argType)
1062
 
                        {
1063
 
                                if (argType.Kind == TypeKind.Array) {
1064
 
                                        if (((ArrayType)argType).Dimensions != 1) {
1065
 
                                                // Only single-dimensional arrays are supported
1066
 
                                                return ErrorResolveResult.UnknownError;
1067
 
                                        }
1068
 
                                        IType elementType = ((ArrayType)argType).ElementType;
1069
 
                                        uint numElem = ReadUInt32();
1070
 
                                        if (numElem == 0xffffffff) {
1071
 
                                                // null reference
1072
 
                                                return new ConstantResolveResult(argType, null);
1073
 
                                        } else {
1074
 
                                                ResolveResult[] elements = new ResolveResult[numElem];
1075
 
                                                for (int i = 0; i < elements.Length; i++) {
1076
 
                                                        elements[i] = ReadElem(elementType);
1077
 
                                                }
1078
 
                                                return new ArrayCreateResolveResult(argType, null, elements);
1079
 
                                        }
1080
 
                                } else {
1081
 
                                        return ReadElem(argType);
1082
 
                                }
1083
 
                        }
1084
 
                        
1085
 
                        public ResolveResult ReadElem(IType elementType)
1086
 
                        {
1087
 
                                ITypeDefinition underlyingType;
1088
 
                                if (elementType.Kind == TypeKind.Enum) {
1089
 
                                        underlyingType = elementType.GetDefinition().EnumUnderlyingType.GetDefinition();
1090
 
                                } else {
1091
 
                                        underlyingType = elementType.GetDefinition();
1092
 
                                }
1093
 
                                if (underlyingType == null)
1094
 
                                        return ErrorResolveResult.UnknownError;
1095
 
                                KnownTypeCode typeCode = underlyingType.KnownTypeCode;
1096
 
                                if (typeCode == KnownTypeCode.Object) {
1097
 
                                        // boxed value type
1098
 
                                        IType boxedTyped = ReadCustomAttributeFieldOrPropType();
1099
 
                                        ResolveResult elem = ReadElem(boxedTyped);
1100
 
                                        if (elem.IsCompileTimeConstant && elem.ConstantValue == null)
1101
 
                                                return new ConstantResolveResult(elementType, null);
1102
 
                                        else
1103
 
                                                return new ConversionResolveResult(elementType, elem, Conversion.BoxingConversion);
1104
 
                                } else if (typeCode == KnownTypeCode.Type) {
1105
 
                                        return new TypeOfResolveResult(underlyingType, ReadType());
1106
 
                                } else {
1107
 
                                        return new ConstantResolveResult(elementType, ReadElemValue(typeCode));
1108
 
                                }
1109
 
                        }
1110
 
                        
1111
 
                        object ReadElemValue(KnownTypeCode typeCode)
1112
 
                        {
1113
 
                                switch (typeCode) {
1114
 
                                        case KnownTypeCode.Boolean:
1115
 
                                                return ReadByte() != 0;
1116
 
                                        case KnownTypeCode.Char:
1117
 
                                                return (char)ReadUInt16();
1118
 
                                        case KnownTypeCode.SByte:
1119
 
                                                return ReadSByte();
1120
 
                                        case KnownTypeCode.Byte:
1121
 
                                                return ReadByte();
1122
 
                                        case KnownTypeCode.Int16:
1123
 
                                                return ReadInt16();
1124
 
                                        case KnownTypeCode.UInt16:
1125
 
                                                return ReadUInt16();
1126
 
                                        case KnownTypeCode.Int32:
1127
 
                                                return ReadInt32();
1128
 
                                        case KnownTypeCode.UInt32:
1129
 
                                                return ReadUInt32();
1130
 
                                        case KnownTypeCode.Int64:
1131
 
                                                return ReadInt64();
1132
 
                                        case KnownTypeCode.UInt64:
1133
 
                                                return ReadUInt64();
1134
 
                                        case KnownTypeCode.Single:
1135
 
                                                return ReadSingle();
1136
 
                                        case KnownTypeCode.Double:
1137
 
                                                return ReadDouble();
1138
 
                                        case KnownTypeCode.String:
1139
 
                                                return ReadSerString();
1140
 
                                        default:
1141
 
                                                throw new NotSupportedException();
1142
 
                                }
1143
 
                        }
1144
 
                        
1145
 
                        public string ReadSerString ()
1146
 
                        {
1147
 
                                if (buffer [position] == 0xff) {
1148
 
                                        position++;
1149
 
                                        return null;
1150
 
                                }
1151
 
 
1152
 
                                int length = (int) ReadCompressedUInt32();
1153
 
                                if (length == 0)
1154
 
                                        return string.Empty;
1155
 
 
1156
 
                                string @string = System.Text.Encoding.UTF8.GetString(
1157
 
                                        buffer, position,
1158
 
                                        buffer [position + length - 1] == 0 ? length - 1 : length);
1159
 
 
1160
 
                                position += length;
1161
 
                                return @string;
1162
 
                        }
1163
 
                        
1164
 
                        public KeyValuePair<IMember, ResolveResult> ReadNamedArg(IType attributeType)
1165
 
                        {
1166
 
                                EntityType memberType;
1167
 
                                switch (ReadByte()) {
1168
 
                                        case 0x53:
1169
 
                                                memberType = EntityType.Field;
1170
 
                                                break;
1171
 
                                        case 0x54:
1172
 
                                                memberType = EntityType.Property;
1173
 
                                                break;
1174
 
                                        default:
1175
 
                                                throw new NotSupportedException();
1176
 
                                }
1177
 
                                IType type = ReadCustomAttributeFieldOrPropType();
1178
 
                                string name = ReadSerString();
1179
 
                                ResolveResult val = ReadFixedArg(type);
1180
 
                                IMember member = null;
1181
 
                                // Use last matching member, as GetMembers() returns members from base types first.
1182
 
                                foreach (IMember m in attributeType.GetMembers(m => m.EntityType == memberType && m.Name == name)) {
1183
 
                                        if (m.ReturnType.Equals(type))
1184
 
                                                member = m;
1185
 
                                }
1186
 
                                return new KeyValuePair<IMember, ResolveResult>(member, val);
1187
 
                        }
1188
 
                        
1189
 
                        IType ReadCustomAttributeFieldOrPropType()
1190
 
                        {
1191
 
                                ICompilation compilation = currentResolvedAssembly.Compilation;
1192
 
                                var b = ReadByte();
1193
 
                                switch (b) {
1194
 
                                        case 0x02:
1195
 
                                                return compilation.FindType(KnownTypeCode.Boolean);
1196
 
                                        case 0x03:
1197
 
                                                return compilation.FindType(KnownTypeCode.Char);
1198
 
                                        case 0x04:
1199
 
                                                return compilation.FindType(KnownTypeCode.SByte);
1200
 
                                        case 0x05:
1201
 
                                                return compilation.FindType(KnownTypeCode.Byte);
1202
 
                                        case 0x06:
1203
 
                                                return compilation.FindType(KnownTypeCode.Int16);
1204
 
                                        case 0x07:
1205
 
                                                return compilation.FindType(KnownTypeCode.UInt16);
1206
 
                                        case 0x08:
1207
 
                                                return compilation.FindType(KnownTypeCode.Int32);
1208
 
                                        case 0x09:
1209
 
                                                return compilation.FindType(KnownTypeCode.UInt32);
1210
 
                                        case 0x0a:
1211
 
                                                return compilation.FindType(KnownTypeCode.Int64);
1212
 
                                        case 0x0b:
1213
 
                                                return compilation.FindType(KnownTypeCode.UInt64);
1214
 
                                        case 0x0c:
1215
 
                                                return compilation.FindType(KnownTypeCode.Single);
1216
 
                                        case 0x0d:
1217
 
                                                return compilation.FindType(KnownTypeCode.Double);
1218
 
                                        case 0x0e:
1219
 
                                                return compilation.FindType(KnownTypeCode.String);
1220
 
                                        case 0x1d:
1221
 
                                                return new ArrayType(compilation, ReadCustomAttributeFieldOrPropType());
1222
 
                                        case 0x50:
1223
 
                                                return compilation.FindType(KnownTypeCode.Type);
1224
 
                                        case 0x51: // boxed value type
1225
 
                                                return compilation.FindType(KnownTypeCode.Object);
1226
 
                                        case 0x55: // enum
1227
 
                                                return ReadType();
1228
 
                                        default:
1229
 
                                                throw new NotSupportedException(string.Format("Custom attribute type 0x{0:x} is not supported.", b));
1230
 
                                }
1231
 
                        }
1232
 
                        
1233
 
                        IType ReadType()
1234
 
                        {
1235
 
                                string typeName = ReadSerString();
1236
 
                                ITypeReference typeReference = ReflectionHelper.ParseReflectionName(typeName);
1237
 
                                IType typeInCurrentAssembly = typeReference.Resolve(new SimpleTypeResolveContext(currentResolvedAssembly));
1238
 
                                if (typeInCurrentAssembly.Kind != TypeKind.Unknown)
1239
 
                                        return typeInCurrentAssembly;
1240
 
                                
1241
 
                                // look for the type in mscorlib
1242
 
                                ITypeDefinition systemObject = currentResolvedAssembly.Compilation.FindType(KnownTypeCode.Object).GetDefinition();
1243
 
                                if (systemObject != null) {
1244
 
                                        return typeReference.Resolve(new SimpleTypeResolveContext(systemObject.ParentAssembly));
1245
 
                                } else {
1246
 
                                        // couldn't find corlib - return the unknown IType for the current assembly
1247
 
                                        return typeInCurrentAssembly;
1248
 
                                }
1249
 
                        }
1250
 
                }
1251
 
                #endregion
1252
 
                
1253
 
                #region Security Attributes
1254
 
                static readonly ITypeReference securityActionTypeReference = typeof(System.Security.Permissions.SecurityAction).ToTypeReference();
1255
 
                static readonly ITypeReference permissionSetAttributeTypeReference = typeof(System.Security.Permissions.PermissionSetAttribute).ToTypeReference();
1256
 
                
1257
 
                /// <summary>
1258
 
                /// Reads a security declaration.
1259
 
                /// </summary>
1260
 
                [CLSCompliant(false)]
1261
 
                public IList<IUnresolvedAttribute> ReadSecurityDeclaration(SecurityDeclaration secDecl)
1262
 
                {
1263
 
                        if (secDecl == null)
1264
 
                                throw new ArgumentNullException("secDecl");
1265
 
                        var result = new List<IUnresolvedAttribute>();
1266
 
                        AddSecurityAttributes(secDecl, result);
1267
 
                        return result;
1268
 
                }
1269
 
                
1270
 
                void AddSecurityAttributes(Mono.Collections.Generic.Collection<SecurityDeclaration> securityDeclarations, IList<IUnresolvedAttribute> targetCollection)
1271
 
                {
1272
 
                        foreach (var secDecl in securityDeclarations) {
1273
 
                                AddSecurityAttributes(secDecl, targetCollection);
1274
 
                        }
1275
 
                }
1276
 
                
1277
 
                void AddSecurityAttributes(SecurityDeclaration secDecl, IList<IUnresolvedAttribute> targetCollection)
1278
 
                {
1279
 
                        byte[] blob = secDecl.GetBlob();
1280
 
                        BlobReader reader = new BlobReader(blob, null);
1281
 
                        var securityAction = new SimpleConstantValue(securityActionTypeReference, (int)secDecl.Action);
1282
 
                        if (reader.ReadByte() == '.') {
1283
 
                                // binary attribute
1284
 
                                uint attributeCount = reader.ReadCompressedUInt32();
1285
 
                                UnresolvedSecurityDeclaration unresolvedSecDecl = new UnresolvedSecurityDeclaration(securityAction, blob);
1286
 
                                if (this.InterningProvider != null) {
1287
 
                                        unresolvedSecDecl = this.InterningProvider.Intern(unresolvedSecDecl);
1288
 
                                }
1289
 
                                for (uint i = 0; i < attributeCount; i++) {
1290
 
                                        targetCollection.Add(new UnresolvedSecurityAttribute(unresolvedSecDecl, (int)i));
1291
 
                                }
1292
 
                        } else {
1293
 
                                // for backward compatibility with .NET 1.0: XML-encoded attribute
1294
 
                                var attr = new DefaultUnresolvedAttribute(permissionSetAttributeTypeReference);
1295
 
                                attr.ConstructorParameterTypes.Add(securityActionTypeReference);
1296
 
                                attr.PositionalArguments.Add(securityAction);
1297
 
                                string xml = System.Text.Encoding.Unicode.GetString(blob);
1298
 
                                attr.AddNamedPropertyArgument("XML", KnownTypeReference.String, xml);
1299
 
                                targetCollection.Add(attr);
1300
 
                        }
1301
 
                }
1302
 
                
1303
 
                [Serializable]
1304
 
                sealed class UnresolvedSecurityDeclaration : ISupportsInterning
1305
 
                {
1306
 
                        IConstantValue securityAction;
1307
 
                        byte[] blob;
1308
 
                        
1309
 
                        public UnresolvedSecurityDeclaration(IConstantValue securityAction, byte[] blob)
1310
 
                        {
1311
 
                                Debug.Assert(securityAction != null);
1312
 
                                Debug.Assert(blob != null);
1313
 
                                this.securityAction = securityAction;
1314
 
                                this.blob = blob;
1315
 
                        }
1316
 
                        
1317
 
                        public IList<IAttribute> Resolve(IAssembly currentAssembly)
1318
 
                        {
1319
 
                                // TODO: make this a per-assembly cache
1320
 
//                              CacheManager cache = currentAssembly.Compilation.CacheManager;
1321
 
//                              IList<IAttribute> result = (IList<IAttribute>)cache.GetShared(this);
1322
 
//                              if (result != null)
1323
 
//                                      return result;
1324
 
                                
1325
 
                                ITypeResolveContext context = new SimpleTypeResolveContext(currentAssembly);
1326
 
                                BlobReader reader = new BlobReader(blob, currentAssembly);
1327
 
                                if (reader.ReadByte() != '.') {
1328
 
                                        // should not use UnresolvedSecurityDeclaration for XML secdecls
1329
 
                                        throw new InvalidOperationException();
1330
 
                                }
1331
 
                                ResolveResult securityActionRR = securityAction.Resolve(context);
1332
 
                                uint attributeCount = reader.ReadCompressedUInt32();
1333
 
                                IAttribute[] attributes = new IAttribute[attributeCount];
1334
 
                                try {
1335
 
                                        ReadSecurityBlob(reader, attributes, context, securityActionRR);
1336
 
                                } catch (NotSupportedException ex) {
1337
 
                                        // ignore invalid blobs
1338
 
                                        Debug.WriteLine(ex.ToString());
1339
 
                                }
1340
 
                                for (int i = 0; i < attributes.Length; i++) {
1341
 
                                        if (attributes[i] == null)
1342
 
                                                attributes[i] = new CecilResolvedAttribute(context, SpecialType.UnknownType);
1343
 
                                }
1344
 
                                return attributes;
1345
 
//                              return (IList<IAttribute>)cache.GetOrAddShared(this, attributes);
1346
 
                        }
1347
 
                        
1348
 
                        void ReadSecurityBlob(BlobReader reader, IAttribute[] attributes, ITypeResolveContext context, ResolveResult securityActionRR)
1349
 
                        {
1350
 
                                for (int i = 0; i < attributes.Length; i++) {
1351
 
                                        string attributeTypeName = reader.ReadSerString();
1352
 
                                        ITypeReference attributeTypeRef = ReflectionHelper.ParseReflectionName(attributeTypeName);
1353
 
                                        IType attributeType = attributeTypeRef.Resolve(context);
1354
 
                                        
1355
 
                                        reader.ReadCompressedUInt32(); // ??
1356
 
                                        // The specification seems to be incorrect here, so I'm using the logic from Cecil instead.
1357
 
                                        uint numNamed = reader.ReadCompressedUInt32();
1358
 
                                        
1359
 
                                        var namedArgs = new List<KeyValuePair<IMember, ResolveResult>>((int)numNamed);
1360
 
                                        for (uint j = 0; j < numNamed; j++) {
1361
 
                                                var namedArg = reader.ReadNamedArg(attributeType);
1362
 
                                                if (namedArg.Key != null)
1363
 
                                                        namedArgs.Add(namedArg);
1364
 
                                                
1365
 
                                        }
1366
 
                                        attributes[i] = new ResolvedSecurityAttribute {
1367
 
                                                AttributeType = attributeType,
1368
 
                                                NamedArguments = namedArgs,
1369
 
                                                PositionalArguments = new ResolveResult[] { securityActionRR }
1370
 
                                        };
1371
 
                                }
1372
 
                        }
1373
 
                        
1374
 
                        void ISupportsInterning.PrepareForInterning(IInterningProvider provider)
1375
 
                        {
1376
 
                                securityAction = provider.Intern(securityAction);
1377
 
                        }
1378
 
                        
1379
 
                        int ISupportsInterning.GetHashCodeForInterning()
1380
 
                        {
1381
 
                                return securityAction.GetHashCode() ^ GetBlobHashCode(blob);
1382
 
                        }
1383
 
                        
1384
 
                        bool ISupportsInterning.EqualsForInterning(ISupportsInterning other)
1385
 
                        {
1386
 
                                UnresolvedSecurityDeclaration o = other as UnresolvedSecurityDeclaration;
1387
 
                                return o != null && securityAction == o.securityAction && BlobEquals(blob, o.blob);
1388
 
                        }
1389
 
                }
1390
 
                
1391
 
                [Serializable]
1392
 
                sealed class UnresolvedSecurityAttribute : IUnresolvedAttribute
1393
 
                {
1394
 
                        readonly UnresolvedSecurityDeclaration secDecl;
1395
 
                        readonly int index;
1396
 
                        
1397
 
                        public UnresolvedSecurityAttribute(UnresolvedSecurityDeclaration secDecl, int index)
1398
 
                        {
1399
 
                                Debug.Assert(secDecl != null);
1400
 
                                this.secDecl = secDecl;
1401
 
                                this.index = index;
1402
 
                        }
1403
 
                        
1404
 
                        DomRegion IUnresolvedAttribute.Region {
1405
 
                                get { return DomRegion.Empty; }
1406
 
                        }
1407
 
                        
1408
 
                        IAttribute IUnresolvedAttribute.CreateResolvedAttribute(ITypeResolveContext context)
1409
 
                        {
1410
 
                                return secDecl.Resolve(context.CurrentAssembly)[index];
1411
 
                        }
1412
 
                }
1413
 
                
1414
 
                sealed class ResolvedSecurityAttribute : IAttribute
1415
 
                {
1416
 
                        public IType AttributeType { get; internal set; }
1417
 
                        
1418
 
                        DomRegion IAttribute.Region {
1419
 
                                get { return DomRegion.Empty; }
1420
 
                        }
1421
 
                        
1422
 
                        volatile IMethod constructor;
1423
 
                        
1424
 
                        public IMethod Constructor {
1425
 
                                get {
1426
 
                                        IMethod ctor = this.constructor;
1427
 
                                        if (ctor == null) {
1428
 
                                                foreach (IMethod candidate in this.AttributeType.GetConstructors(m => m.Parameters.Count == 1)) {
1429
 
                                                        if (candidate.Parameters[0].Type.Equals(this.PositionalArguments[0].Type)) {
1430
 
                                                                ctor = candidate;
1431
 
                                                                break;
1432
 
                                                        }
1433
 
                                                }
1434
 
                                                this.constructor = ctor;
1435
 
                                        }
1436
 
                                        return ctor;
1437
 
                                }
1438
 
                        }
1439
 
                        
1440
 
                        public IList<ResolveResult> PositionalArguments { get; internal set; }
1441
 
                        
1442
 
                        public IList<KeyValuePair<IMember, ResolveResult>> NamedArguments { get; internal set; }
1443
 
                }
1444
 
                #endregion
1445
 
                #endregion
1446
 
                
1447
 
                #region Read Type Definition
1448
 
                DefaultUnresolvedTypeDefinition CreateTopLevelTypeDefinition(TypeDefinition typeDefinition)
1449
 
                {
1450
 
                        string name = ReflectionHelper.SplitTypeParameterCountFromReflectionName(typeDefinition.Name);
1451
 
                        var td = new DefaultUnresolvedTypeDefinition(typeDefinition.Namespace, name);
1452
 
                        InitTypeParameters(typeDefinition, td);
1453
 
                        return td;
1454
 
                }
1455
 
                
1456
 
                static void InitTypeParameters(TypeDefinition typeDefinition, DefaultUnresolvedTypeDefinition td)
1457
 
                {
1458
 
                        // Type parameters are initialized within the constructor so that the class can be put into the type storage
1459
 
                        // before the rest of the initialization runs - this allows it to be available for early binding as soon as possible.
1460
 
                        for (int i = 0; i < typeDefinition.GenericParameters.Count; i++) {
1461
 
                                if (typeDefinition.GenericParameters[i].Position != i)
1462
 
                                        throw new InvalidOperationException("g.Position != i");
1463
 
                                td.TypeParameters.Add(new DefaultUnresolvedTypeParameter(
1464
 
                                        EntityType.TypeDefinition, i, typeDefinition.GenericParameters[i].Name));
1465
 
                        }
1466
 
                }
1467
 
                
1468
 
                void InitTypeDefinition(TypeDefinition typeDefinition, DefaultUnresolvedTypeDefinition td)
1469
 
                {
1470
 
                        InitTypeModifiers(typeDefinition, td);
1471
 
                        
1472
 
                        if (typeDefinition.HasGenericParameters) {
1473
 
                                for (int i = 0; i < typeDefinition.GenericParameters.Count; i++) {
1474
 
                                        AddConstraints((DefaultUnresolvedTypeParameter)td.TypeParameters[i], typeDefinition.GenericParameters[i]);
1475
 
                                }
1476
 
                        }
1477
 
                        
1478
 
                        InitNestedTypes(typeDefinition, td); // nested types can be initialized only after generic parameters were created
1479
 
                        AddAttributes(typeDefinition, td);
1480
 
                        td.HasExtensionMethods = HasExtensionAttribute(typeDefinition);
1481
 
                        
1482
 
                        // set base classes
1483
 
                        if (typeDefinition.IsEnum) {
1484
 
                                foreach (FieldDefinition enumField in typeDefinition.Fields) {
1485
 
                                        if (!enumField.IsStatic) {
1486
 
                                                td.BaseTypes.Add(ReadTypeReference(enumField.FieldType));
1487
 
                                                break;
1488
 
                                        }
1489
 
                                }
1490
 
                        } else {
1491
 
                                if (typeDefinition.BaseType != null) {
1492
 
                                        td.BaseTypes.Add(ReadTypeReference(typeDefinition.BaseType));
1493
 
                                }
1494
 
                                if (typeDefinition.HasInterfaces) {
1495
 
                                        foreach (TypeReference iface in typeDefinition.Interfaces) {
1496
 
                                                td.BaseTypes.Add(ReadTypeReference(iface));
1497
 
                                        }
1498
 
                                }
1499
 
                        }
1500
 
                        
1501
 
                        InitMembers(typeDefinition, td);
1502
 
                        if (HasCecilReferences)
1503
 
                                typeSystemTranslationTable[td] = typeDefinition;
1504
 
                        if (this.InterningProvider != null) {
1505
 
                                td.ApplyInterningProvider(this.InterningProvider);
1506
 
                        }
1507
 
                        td.Freeze();
1508
 
                }
1509
 
                
1510
 
                void InitNestedTypes(TypeDefinition typeDefinition, DefaultUnresolvedTypeDefinition td)
1511
 
                {
1512
 
                        if (!typeDefinition.HasNestedTypes)
1513
 
                                return;
1514
 
                        foreach (TypeDefinition nestedTypeDef in typeDefinition.NestedTypes) {
1515
 
                                TypeAttributes visibility = nestedTypeDef.Attributes & TypeAttributes.VisibilityMask;
1516
 
                                if (this.IncludeInternalMembers
1517
 
                                    || visibility == TypeAttributes.NestedPublic
1518
 
                                    || visibility == TypeAttributes.NestedFamily
1519
 
                                    || visibility == TypeAttributes.NestedFamORAssem)
1520
 
                                {
1521
 
                                        string name = nestedTypeDef.Name;
1522
 
                                        int pos = name.LastIndexOf('/');
1523
 
                                        if (pos > 0)
1524
 
                                                name = name.Substring(pos + 1);
1525
 
                                        if (name.Length == 0 || name[0] == '<')
1526
 
                                                continue;
1527
 
                                        name = ReflectionHelper.SplitTypeParameterCountFromReflectionName(name);
1528
 
                                        var nestedType = new DefaultUnresolvedTypeDefinition(td, name);
1529
 
                                        InitTypeParameters(nestedTypeDef, nestedType);
1530
 
                                        td.NestedTypes.Add(nestedType);
1531
 
                                        InitTypeDefinition(nestedTypeDef, nestedType);
1532
 
                                }
1533
 
                        }
1534
 
                }
1535
 
                
1536
 
                static void InitTypeModifiers(TypeDefinition typeDefinition, DefaultUnresolvedTypeDefinition td)
1537
 
                {
1538
 
                        // set classtype
1539
 
                        if (typeDefinition.IsInterface) {
1540
 
                                td.Kind = TypeKind.Interface;
1541
 
                        } else if (typeDefinition.IsEnum) {
1542
 
                                td.Kind = TypeKind.Enum;
1543
 
                        } else if (typeDefinition.IsValueType) {
1544
 
                                td.Kind = TypeKind.Struct;
1545
 
                        } else if (IsDelegate(typeDefinition)) {
1546
 
                                td.Kind = TypeKind.Delegate;
1547
 
                        } else if (IsModule(typeDefinition)) {
1548
 
                                td.Kind = TypeKind.Module;
1549
 
                        } else {
1550
 
                                td.Kind = TypeKind.Class;
1551
 
                        }
1552
 
                        td.IsSealed = typeDefinition.IsSealed;
1553
 
                        td.IsAbstract = typeDefinition.IsAbstract;
1554
 
                        switch (typeDefinition.Attributes & TypeAttributes.VisibilityMask) {
1555
 
                                case TypeAttributes.NotPublic:
1556
 
                                case TypeAttributes.NestedAssembly:
1557
 
                                        td.Accessibility = Accessibility.Internal;
1558
 
                                        break;
1559
 
                                case TypeAttributes.Public:
1560
 
                                case TypeAttributes.NestedPublic:
1561
 
                                        td.Accessibility = Accessibility.Public;
1562
 
                                        break;
1563
 
                                case TypeAttributes.NestedPrivate:
1564
 
                                        td.Accessibility = Accessibility.Private;
1565
 
                                        break;
1566
 
                                case TypeAttributes.NestedFamily:
1567
 
                                        td.Accessibility = Accessibility.Protected;
1568
 
                                        break;
1569
 
                                case TypeAttributes.NestedFamANDAssem:
1570
 
                                        td.Accessibility = Accessibility.ProtectedAndInternal;
1571
 
                                        break;
1572
 
                                case TypeAttributes.NestedFamORAssem:
1573
 
                                        td.Accessibility = Accessibility.ProtectedOrInternal;
1574
 
                                        break;
1575
 
                        }
1576
 
                }
1577
 
                
1578
 
                static bool IsDelegate(TypeDefinition type)
1579
 
                {
1580
 
                        if (type.BaseType == null)
1581
 
                                return false;
1582
 
                        else
1583
 
                                return type.BaseType.FullName == "System.Delegate"
1584
 
                                        || type.BaseType.FullName == "System.MulticastDelegate";
1585
 
                }
1586
 
                
1587
 
                static bool IsModule(TypeDefinition type)
1588
 
                {
1589
 
                        if (!type.HasCustomAttributes)
1590
 
                                return false;
1591
 
                        foreach (var att in type.CustomAttributes) {
1592
 
                                if (att.AttributeType.FullName == "Microsoft.VisualBasic.CompilerServices.StandardModuleAttribute"
1593
 
                                    || att.AttributeType.FullName == "System.Runtime.CompilerServices.CompilerGlobalScopeAttribute")
1594
 
                                {
1595
 
                                        return true;
1596
 
                                }
1597
 
                        }
1598
 
                        return false;
1599
 
                }
1600
 
                
1601
 
                void InitMembers(TypeDefinition typeDefinition, DefaultUnresolvedTypeDefinition td)
1602
 
                {
1603
 
                        td.AddDefaultConstructorIfRequired = (td.Kind == TypeKind.Struct || td.Kind == TypeKind.Enum);
1604
 
                        if (typeDefinition.HasMethods) {
1605
 
                                foreach (MethodDefinition method in typeDefinition.Methods) {
1606
 
                                        if (IsVisible(method.Attributes) && !IsAccessor(method.SemanticsAttributes)) {
1607
 
                                                EntityType type = EntityType.Method;
1608
 
                                                if (method.IsSpecialName) {
1609
 
                                                        if (method.IsConstructor)
1610
 
                                                                type = EntityType.Constructor;
1611
 
                                                        else if (method.Name.StartsWith("op_", StringComparison.Ordinal))
1612
 
                                                                type = EntityType.Operator;
1613
 
                                                }
1614
 
                                                td.Members.Add(ReadMethod(method, td, type));
1615
 
                                        }
1616
 
                                }
1617
 
                        }
1618
 
                        if (typeDefinition.HasFields) {
1619
 
                                foreach (FieldDefinition field in typeDefinition.Fields) {
1620
 
                                        if (IsVisible(field.Attributes) && !field.IsSpecialName) {
1621
 
                                                td.Members.Add(ReadField(field, td));
1622
 
                                        }
1623
 
                                }
1624
 
                        }
1625
 
                        if (typeDefinition.HasProperties) {
1626
 
                                string defaultMemberName = null;
1627
 
                                var defaultMemberAttribute = typeDefinition.CustomAttributes.FirstOrDefault(
1628
 
                                        a => a.AttributeType.FullName == typeof(System.Reflection.DefaultMemberAttribute).FullName);
1629
 
                                if (defaultMemberAttribute != null && defaultMemberAttribute.ConstructorArguments.Count == 1) {
1630
 
                                        defaultMemberName = defaultMemberAttribute.ConstructorArguments[0].Value as string;
1631
 
                                }
1632
 
                                foreach (PropertyDefinition property in typeDefinition.Properties) {
1633
 
                                        bool getterVisible = property.GetMethod != null && IsVisible(property.GetMethod.Attributes);
1634
 
                                        bool setterVisible = property.SetMethod != null && IsVisible(property.SetMethod.Attributes);
1635
 
                                        if (getterVisible || setterVisible) {
1636
 
                                                EntityType type = property.Name == defaultMemberName ? EntityType.Indexer : EntityType.Property;
1637
 
                                                td.Members.Add(ReadProperty(property, td, type));
1638
 
                                        }
1639
 
                                }
1640
 
                        }
1641
 
                        if (typeDefinition.HasEvents) {
1642
 
                                foreach (EventDefinition ev in typeDefinition.Events) {
1643
 
                                        if (ev.AddMethod != null && IsVisible(ev.AddMethod.Attributes)) {
1644
 
                                                td.Members.Add(ReadEvent(ev, td));
1645
 
                                        }
1646
 
                                }
1647
 
                        }
1648
 
                }
1649
 
                
1650
 
                static bool IsAccessor(MethodSemanticsAttributes semantics)
1651
 
                {
1652
 
                        return !(semantics == MethodSemanticsAttributes.None || semantics == MethodSemanticsAttributes.Other);
1653
 
                }
1654
 
                #endregion
1655
 
                
1656
 
                #region Read Method
1657
 
                [CLSCompliant(false)]
1658
 
                public IUnresolvedMethod ReadMethod(MethodDefinition method, IUnresolvedTypeDefinition parentType, EntityType methodType = EntityType.Method)
1659
 
                {
1660
 
                        if (method == null)
1661
 
                                return null;
1662
 
                        DefaultUnresolvedMethod m = new DefaultUnresolvedMethod(parentType, method.Name);
1663
 
                        m.EntityType = methodType;
1664
 
                        if (method.HasGenericParameters) {
1665
 
                                for (int i = 0; i < method.GenericParameters.Count; i++) {
1666
 
                                        if (method.GenericParameters[i].Position != i)
1667
 
                                                throw new InvalidOperationException("g.Position != i");
1668
 
                                        m.TypeParameters.Add(new DefaultUnresolvedTypeParameter(
1669
 
                                                EntityType.Method, i, method.GenericParameters[i].Name));
1670
 
                                }
1671
 
                                for (int i = 0; i < method.GenericParameters.Count; i++) {
1672
 
                                        AddConstraints((DefaultUnresolvedTypeParameter)m.TypeParameters[i], method.GenericParameters[i]);
1673
 
                                }
1674
 
                        }
1675
 
                        
1676
 
                        m.ReturnType = ReadTypeReference(method.ReturnType, typeAttributes: method.MethodReturnType);
1677
 
                        
1678
 
                        if (HasAnyAttributes(method))
1679
 
                                AddAttributes(method, m.Attributes, m.ReturnTypeAttributes);
1680
 
                        TranslateModifiers(method, m);
1681
 
                        
1682
 
                        if (method.HasParameters) {
1683
 
                                foreach (ParameterDefinition p in method.Parameters) {
1684
 
                                        m.Parameters.Add(ReadParameter(p));
1685
 
                                }
1686
 
                        }
1687
 
                        
1688
 
                        // mark as extension method if the attribute is set
1689
 
                        if (method.IsStatic && HasExtensionAttribute(method)) {
1690
 
                                m.IsExtensionMethod = true;
1691
 
                        }
1692
 
                        
1693
 
                        FinishReadMember(m, method);
1694
 
                        return m;
1695
 
                }
1696
 
                
1697
 
                static bool HasExtensionAttribute(ICustomAttributeProvider provider)
1698
 
                {
1699
 
                        if (provider.HasCustomAttributes) {
1700
 
                                foreach (var attr in provider.CustomAttributes) {
1701
 
                                        if (attr.AttributeType.Name == "ExtensionAttribute" && attr.AttributeType.Namespace == "System.Runtime.CompilerServices")
1702
 
                                                return true;
1703
 
                                }
1704
 
                        }
1705
 
                        return false;
1706
 
                }
1707
 
                
1708
 
                bool IsVisible(MethodAttributes att)
1709
 
                {
1710
 
                        att &= MethodAttributes.MemberAccessMask;
1711
 
                        return IncludeInternalMembers
1712
 
                                || att == MethodAttributes.Public
1713
 
                                || att == MethodAttributes.Family
1714
 
                                || att == MethodAttributes.FamORAssem;
1715
 
                }
1716
 
                
1717
 
                static Accessibility GetAccessibility(MethodAttributes attr)
1718
 
                {
1719
 
                        switch (attr & MethodAttributes.MemberAccessMask) {
1720
 
                                case MethodAttributes.Public:
1721
 
                                        return Accessibility.Public;
1722
 
                                case MethodAttributes.FamANDAssem:
1723
 
                                        return Accessibility.ProtectedAndInternal;
1724
 
                                case MethodAttributes.Assembly:
1725
 
                                        return Accessibility.Internal;
1726
 
                                case MethodAttributes.Family:
1727
 
                                        return Accessibility.Protected;
1728
 
                                case MethodAttributes.FamORAssem:
1729
 
                                        return Accessibility.ProtectedOrInternal;
1730
 
                                default:
1731
 
                                        return Accessibility.Private;
1732
 
                        }
1733
 
                }
1734
 
                
1735
 
                void TranslateModifiers(MethodDefinition method, AbstractUnresolvedMember m)
1736
 
                {
1737
 
                        if (m.DeclaringTypeDefinition.Kind == TypeKind.Interface) {
1738
 
                                // interface members don't have modifiers, but we want to handle them as "public abstract"
1739
 
                                m.Accessibility = Accessibility.Public;
1740
 
                                m.IsAbstract = true;
1741
 
                        } else {
1742
 
                                m.Accessibility = GetAccessibility(method.Attributes);
1743
 
                                if (method.IsAbstract) {
1744
 
                                        m.IsAbstract = true;
1745
 
                                        m.IsOverride = !method.IsNewSlot;
1746
 
                                } else if (method.IsFinal) {
1747
 
                                        if (!method.IsNewSlot) {
1748
 
                                                m.IsSealed = true;
1749
 
                                                m.IsOverride = true;
1750
 
                                        }
1751
 
                                } else if (method.IsVirtual) {
1752
 
                                        if (method.IsNewSlot)
1753
 
                                                m.IsVirtual = true;
1754
 
                                        else
1755
 
                                                m.IsOverride = true;
1756
 
                                }
1757
 
                                m.IsStatic = method.IsStatic;
1758
 
                        }
1759
 
                }
1760
 
                #endregion
1761
 
                
1762
 
                #region Read Parameter
1763
 
                [CLSCompliant(false)]
1764
 
                public IUnresolvedParameter ReadParameter(ParameterDefinition parameter)
1765
 
                {
1766
 
                        if (parameter == null)
1767
 
                                throw new ArgumentNullException("parameter");
1768
 
                        var type = ReadTypeReference(parameter.ParameterType, typeAttributes: parameter);
1769
 
                        var p = new DefaultUnresolvedParameter(type, parameter.Name);
1770
 
                        
1771
 
                        if (parameter.ParameterType is Mono.Cecil.ByReferenceType) {
1772
 
                                if (!parameter.IsIn && parameter.IsOut)
1773
 
                                        p.IsOut = true;
1774
 
                                else
1775
 
                                        p.IsRef = true;
1776
 
                        }
1777
 
                        AddAttributes(parameter, p);
1778
 
                        
1779
 
                        if (parameter.IsOptional) {
1780
 
                                p.DefaultValue = new SimpleConstantValue(type, parameter.Constant);
1781
 
                        }
1782
 
                        
1783
 
                        if (parameter.ParameterType is Mono.Cecil.ArrayType) {
1784
 
                                foreach (CustomAttribute att in parameter.CustomAttributes) {
1785
 
                                        if (att.AttributeType.FullName == typeof(ParamArrayAttribute).FullName) {
1786
 
                                                p.IsParams = true;
1787
 
                                                break;
1788
 
                                        }
1789
 
                                }
1790
 
                        }
1791
 
                        
1792
 
                        return p;
1793
 
                }
1794
 
                #endregion
1795
 
                
1796
 
                #region Read Field
1797
 
                bool IsVisible(FieldAttributes att)
1798
 
                {
1799
 
                        att &= FieldAttributes.FieldAccessMask;
1800
 
                        return IncludeInternalMembers
1801
 
                                || att == FieldAttributes.Public
1802
 
                                || att == FieldAttributes.Family
1803
 
                                || att == FieldAttributes.FamORAssem;
1804
 
                }
1805
 
                
1806
 
                [CLSCompliant(false)]
1807
 
                public IUnresolvedField ReadField(FieldDefinition field, IUnresolvedTypeDefinition parentType)
1808
 
                {
1809
 
                        if (field == null)
1810
 
                                throw new ArgumentNullException("field");
1811
 
                        if (parentType == null)
1812
 
                                throw new ArgumentNullException("parentType");
1813
 
                        
1814
 
                        DefaultUnresolvedField f = new DefaultUnresolvedField(parentType, field.Name);
1815
 
                        f.Accessibility = GetAccessibility(field.Attributes);
1816
 
                        f.IsReadOnly = field.IsInitOnly;
1817
 
                        f.IsStatic = field.IsStatic;
1818
 
                        f.ReturnType = ReadTypeReference(field.FieldType, typeAttributes: field);
1819
 
                        if (field.HasConstant) {
1820
 
                                f.ConstantValue = new SimpleConstantValue(f.ReturnType, field.Constant);
1821
 
                        }
1822
 
                        AddAttributes(field, f);
1823
 
                        
1824
 
                        RequiredModifierType modreq = field.FieldType as RequiredModifierType;
1825
 
                        if (modreq != null && modreq.ModifierType.FullName == typeof(IsVolatile).FullName) {
1826
 
                                f.IsVolatile = true;
1827
 
                        }
1828
 
                        
1829
 
                        FinishReadMember(f, field);
1830
 
                        return f;
1831
 
                }
1832
 
                
1833
 
                static Accessibility GetAccessibility(FieldAttributes attr)
1834
 
                {
1835
 
                        switch (attr & FieldAttributes.FieldAccessMask) {
1836
 
                                case FieldAttributes.Public:
1837
 
                                        return Accessibility.Public;
1838
 
                                case FieldAttributes.FamANDAssem:
1839
 
                                        return Accessibility.ProtectedAndInternal;
1840
 
                                case FieldAttributes.Assembly:
1841
 
                                        return Accessibility.Internal;
1842
 
                                case FieldAttributes.Family:
1843
 
                                        return Accessibility.Protected;
1844
 
                                case FieldAttributes.FamORAssem:
1845
 
                                        return Accessibility.ProtectedOrInternal;
1846
 
                                default:
1847
 
                                        return Accessibility.Private;
1848
 
                        }
1849
 
                }
1850
 
                #endregion
1851
 
                
1852
 
                #region Type Parameter Constraints
1853
 
                void AddConstraints(DefaultUnresolvedTypeParameter tp, GenericParameter g)
1854
 
                {
1855
 
                        switch (g.Attributes & GenericParameterAttributes.VarianceMask) {
1856
 
                                case GenericParameterAttributes.Contravariant:
1857
 
                                        tp.Variance = VarianceModifier.Contravariant;
1858
 
                                        break;
1859
 
                                case GenericParameterAttributes.Covariant:
1860
 
                                        tp.Variance = VarianceModifier.Covariant;
1861
 
                                        break;
1862
 
                        }
1863
 
                        
1864
 
                        tp.HasReferenceTypeConstraint = g.HasReferenceTypeConstraint;
1865
 
                        tp.HasValueTypeConstraint = g.HasNotNullableValueTypeConstraint;
1866
 
                        tp.HasDefaultConstructorConstraint = g.HasDefaultConstructorConstraint;
1867
 
                        
1868
 
                        if (g.HasConstraints) {
1869
 
                                foreach (TypeReference constraint in g.Constraints) {
1870
 
                                        tp.Constraints.Add(ReadTypeReference(constraint));
1871
 
                                }
1872
 
                        }
1873
 
                }
1874
 
                #endregion
1875
 
                
1876
 
                #region Read Property
1877
 
                [CLSCompliant(false)]
1878
 
                public IUnresolvedProperty ReadProperty(PropertyDefinition property, IUnresolvedTypeDefinition parentType, EntityType propertyType = EntityType.Property)
1879
 
                {
1880
 
                        if (property == null)
1881
 
                                throw new ArgumentNullException("property");
1882
 
                        if (parentType == null)
1883
 
                                throw new ArgumentNullException("parentType");
1884
 
                        DefaultUnresolvedProperty p = new DefaultUnresolvedProperty(parentType, property.Name);
1885
 
                        p.EntityType = propertyType;
1886
 
                        TranslateModifiers(property.GetMethod ?? property.SetMethod, p);
1887
 
                        p.ReturnType = ReadTypeReference(property.PropertyType, typeAttributes: property);
1888
 
                        
1889
 
                        p.Getter = ReadMethod(property.GetMethod, parentType);
1890
 
                        p.Setter = ReadMethod(property.SetMethod, parentType);
1891
 
                        
1892
 
                        if (property.HasParameters) {
1893
 
                                foreach (ParameterDefinition par in property.Parameters) {
1894
 
                                        p.Parameters.Add(ReadParameter(par));
1895
 
                                }
1896
 
                        }
1897
 
                        AddAttributes(property, p);
1898
 
                        
1899
 
                        FinishReadMember(p, property);
1900
 
                        return p;
1901
 
                }
1902
 
                #endregion
1903
 
                
1904
 
                #region Read Event
1905
 
                [CLSCompliant(false)]
1906
 
                public IUnresolvedEvent ReadEvent(EventDefinition ev, IUnresolvedTypeDefinition parentType)
1907
 
                {
1908
 
                        if (ev == null)
1909
 
                                throw new ArgumentNullException("ev");
1910
 
                        if (parentType == null)
1911
 
                                throw new ArgumentNullException("parentType");
1912
 
                        
1913
 
                        DefaultUnresolvedEvent e = new DefaultUnresolvedEvent(parentType, ev.Name);
1914
 
                        TranslateModifiers(ev.AddMethod, e);
1915
 
                        e.ReturnType = ReadTypeReference(ev.EventType, typeAttributes: ev);
1916
 
                        
1917
 
                        e.AddAccessor = ReadMethod(ev.AddMethod, parentType);
1918
 
                        e.RemoveAccessor = ReadMethod(ev.RemoveMethod, parentType);
1919
 
                        e.InvokeAccessor = ReadMethod(ev.InvokeMethod, parentType);
1920
 
                        
1921
 
                        AddAttributes(ev, e);
1922
 
                        
1923
 
                        FinishReadMember(e, ev);
1924
 
                        
1925
 
                        return e;
1926
 
                }
1927
 
                #endregion
1928
 
                
1929
 
                void FinishReadMember(AbstractUnresolvedMember member, object cecilDefinition)
1930
 
                {
1931
 
                        member.ApplyInterningProvider(this.InterningProvider);
1932
 
                        member.Freeze();
1933
 
                        if (HasCecilReferences)
1934
 
                                typeSystemTranslationTable[member] = cecilDefinition;
1935
 
                }
1936
 
                
1937
 
                #region Type system translation table
1938
 
                Dictionary<object, object> typeSystemTranslationTable;
1939
 
                
1940
 
                T InternalGetCecilObject<T> (object typeSystemObject) where T : class
1941
 
                {
1942
 
                        if (typeSystemObject == null)
1943
 
                                throw new ArgumentNullException ("typeSystemObject");
1944
 
                        if (!HasCecilReferences)
1945
 
                                throw new NotSupportedException ("This instance contains no cecil references.");
1946
 
                        object result;
1947
 
                        if (!typeSystemTranslationTable.TryGetValue (typeSystemObject, out result))
1948
 
                                return null;
1949
 
                        return result as T;
1950
 
                }
1951
 
                
1952
 
                [CLSCompliant(false)]
1953
 
                public AssemblyDefinition GetCecilObject (IUnresolvedAssembly content)
1954
 
                {
1955
 
                        return InternalGetCecilObject<AssemblyDefinition> (content);
1956
 
                }
1957
 
                
1958
 
                [CLSCompliant(false)]
1959
 
                public TypeDefinition GetCecilObject (IUnresolvedTypeDefinition type)
1960
 
                {
1961
 
                        if (type == null)
1962
 
                                throw new ArgumentNullException ("type");
1963
 
                        return InternalGetCecilObject<TypeDefinition> (type);
1964
 
                }
1965
 
                
1966
 
                [CLSCompliant(false)]
1967
 
                public MethodDefinition GetCecilObject (IUnresolvedMethod method)
1968
 
                {
1969
 
                        return InternalGetCecilObject<MethodDefinition> (method);
1970
 
                }
1971
 
                
1972
 
                [CLSCompliant(false)]
1973
 
                public FieldDefinition GetCecilObject (IUnresolvedField field)
1974
 
                {
1975
 
                        return InternalGetCecilObject<FieldDefinition> (field);
1976
 
                }
1977
 
                
1978
 
                [CLSCompliant(false)]
1979
 
                public EventDefinition GetCecilObject (IUnresolvedEvent evt)
1980
 
                {
1981
 
                        return InternalGetCecilObject<EventDefinition> (evt);
1982
 
                }
1983
 
                
1984
 
                [CLSCompliant(false)]
1985
 
                public PropertyDefinition GetCecilObject (IUnresolvedProperty property)
1986
 
                {
1987
 
                        return InternalGetCecilObject<PropertyDefinition> (property);
1988
 
                }
1989
 
                #endregion
1990
 
        }
1991
 
}