~ubuntu-branches/ubuntu/wily/monodevelop/wily

« back to all changes in this revision

Viewing changes to contrib/ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2012-05-27 18:08:20 UTC
  • mfrom: (19.1.8 experimental)
  • Revision ID: package-import@ubuntu.com-20120527180820-fydl21qnbnfr8w2t
Tags: 3.0.2+dfsg-3
* [fcecfe7] Fix monodevelop-core-addins.pc.in to point to actual 
  installed location of assemblies.
* [26e1a07] DebSrc 3.0 does not support Quilt's -p parameter, so 
  manually adjust the path in the patch file.

Show diffs side-by-side

added added

removed removed

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