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

« back to all changes in this revision

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