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

« back to all changes in this revision

Viewing changes to external/nrefactory/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedAssembly.cs

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2013-05-12 09:46:03 UTC
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130512094603-mad323bzcxvmcam0
Tags: upstream-4.0.5+dfsg
ImportĀ upstreamĀ versionĀ 4.0.5+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
ļ»æ// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team
 
2
// 
 
3
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
 
4
// software and associated documentation files (the "Software"), to deal in the Software
 
5
// without restriction, including without limitation the rights to use, copy, modify, merge,
 
6
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
 
7
// to whom the Software is furnished to do so, subject to the following conditions:
 
8
// 
 
9
// The above copyright notice and this permission notice shall be included in all copies or
 
10
// substantial portions of the Software.
 
11
// 
 
12
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
 
13
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 
14
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
 
15
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 
16
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 
17
// DEALINGS IN THE SOFTWARE.
 
18
 
 
19
using System;
 
20
using System.Collections.Concurrent;
 
21
using System.Collections.Generic;
 
22
using System.Diagnostics;
 
23
using System.Linq;
 
24
using System.Runtime.Serialization;
 
25
using System.Threading;
 
26
 
 
27
using ICSharpCode.NRefactory.Semantics;
 
28
using ICSharpCode.NRefactory.Utils;
 
29
 
 
30
namespace ICSharpCode.NRefactory.TypeSystem.Implementation
 
31
{
 
32
        /// <summary>
 
33
        /// Default implementation for <see cref="IUnresolvedAssembly"/>.
 
34
        /// </summary>
 
35
        [Serializable]
 
36
        public class DefaultUnresolvedAssembly : AbstractFreezable, IUnresolvedAssembly
 
37
        {
 
38
                string assemblyName;
 
39
                string fullAssemblyName;
 
40
                IList<IUnresolvedAttribute> assemblyAttributes;
 
41
                IList<IUnresolvedAttribute> moduleAttributes;
 
42
                Dictionary<TopLevelTypeName, IUnresolvedTypeDefinition> typeDefinitions = new Dictionary<TopLevelTypeName, IUnresolvedTypeDefinition>(TopLevelTypeNameComparer.Ordinal);
 
43
                Dictionary<TopLevelTypeName, ITypeReference> typeForwarders = new Dictionary<TopLevelTypeName, ITypeReference>(TopLevelTypeNameComparer.Ordinal);
 
44
                
 
45
                protected override void FreezeInternal()
 
46
                {
 
47
                        base.FreezeInternal();
 
48
                        assemblyAttributes = FreezableHelper.FreezeListAndElements(assemblyAttributes);
 
49
                        moduleAttributes = FreezableHelper.FreezeListAndElements(moduleAttributes);
 
50
                        foreach (var type in typeDefinitions.Values) {
 
51
                                FreezableHelper.Freeze(type);
 
52
                        }
 
53
                }
 
54
                
 
55
                /// <summary>
 
56
                /// Creates a new unresolved assembly.
 
57
                /// </summary>
 
58
                /// <param name="assemblyName">Full assembly name</param>
 
59
                public DefaultUnresolvedAssembly(string assemblyName)
 
60
                {
 
61
                        if (assemblyName == null)
 
62
                                throw new ArgumentNullException("assemblyName");
 
63
                        this.fullAssemblyName = assemblyName;
 
64
                        int pos = assemblyName != null ? assemblyName.IndexOf(',') : -1;
 
65
                        this.assemblyName = pos < 0 ? assemblyName : assemblyName.Substring(0, pos);
 
66
                        this.assemblyAttributes = new List<IUnresolvedAttribute>();
 
67
                        this.moduleAttributes = new List<IUnresolvedAttribute>();
 
68
                }
 
69
                
 
70
                /// <summary>
 
71
                /// Gets/Sets the short assembly name.
 
72
                /// </summary>
 
73
                /// <remarks>
 
74
                /// This class handles the short and the full name independently;
 
75
                /// if you change the short name, you should also change the full name.
 
76
                /// </remarks>
 
77
                public string AssemblyName {
 
78
                        get { return assemblyName; }
 
79
                        set {
 
80
                                if (value == null)
 
81
                                        throw new ArgumentNullException("value");
 
82
                                FreezableHelper.ThrowIfFrozen(this);
 
83
                                assemblyName = value;
 
84
                        }
 
85
                }
 
86
                
 
87
                /// <summary>
 
88
                /// Gets/Sets the full assembly name.
 
89
                /// </summary>
 
90
                /// <remarks>
 
91
                /// This class handles the short and the full name independently;
 
92
                /// if you change the full name, you should also change the short name.
 
93
                /// </remarks>
 
94
                public string FullAssemblyName {
 
95
                        get { return fullAssemblyName; }
 
96
                        set {
 
97
                                if (value == null)
 
98
                                        throw new ArgumentNullException("value");
 
99
                                FreezableHelper.ThrowIfFrozen(this);
 
100
                                fullAssemblyName = value;
 
101
                        }
 
102
                }
 
103
                
 
104
                string location;
 
105
                public string Location {
 
106
                        get {
 
107
                                return location;
 
108
                        }
 
109
                        set {
 
110
                                FreezableHelper.ThrowIfFrozen(this);
 
111
                                location = value;
 
112
                        }
 
113
                }
 
114
 
 
115
                public IList<IUnresolvedAttribute> AssemblyAttributes {
 
116
                        get { return assemblyAttributes; }
 
117
                }
 
118
                
 
119
                IEnumerable<IUnresolvedAttribute> IUnresolvedAssembly.AssemblyAttributes {
 
120
                        get { return assemblyAttributes; }
 
121
                }
 
122
                
 
123
                public IList<IUnresolvedAttribute> ModuleAttributes {
 
124
                        get { return moduleAttributes; }
 
125
                }
 
126
                
 
127
                IEnumerable<IUnresolvedAttribute> IUnresolvedAssembly.ModuleAttributes {
 
128
                        get { return moduleAttributes; }
 
129
                }
 
130
                
 
131
                public IEnumerable<IUnresolvedTypeDefinition> TopLevelTypeDefinitions {
 
132
                        get { return typeDefinitions.Values; }
 
133
                }
 
134
                
 
135
                /// <summary>
 
136
                /// Adds a new top-level type definition to this assembly.
 
137
                /// </summary>
 
138
                /// <remarks>DefaultUnresolvedAssembly does not support partial classes.
 
139
                /// Adding more than one part of a type will cause an ArgumentException.</remarks>
 
140
                public void AddTypeDefinition(IUnresolvedTypeDefinition typeDefinition)
 
141
                {
 
142
                        if (typeDefinition == null)
 
143
                                throw new ArgumentNullException("typeDefinition");
 
144
                        if (typeDefinition.DeclaringTypeDefinition != null)
 
145
                                throw new ArgumentException("Cannot add nested types.");
 
146
                        FreezableHelper.ThrowIfFrozen(this);
 
147
                        var key = new TopLevelTypeName(typeDefinition.Namespace, typeDefinition.Name, typeDefinition.TypeParameters.Count);
 
148
                        typeDefinitions.Add(key, typeDefinition);
 
149
                }
 
150
                
 
151
                static readonly ITypeReference typeForwardedToAttributeTypeRef = typeof(System.Runtime.CompilerServices.TypeForwardedToAttribute).ToTypeReference();
 
152
                
 
153
                /// <summary>
 
154
                /// Adds a type forwarder.
 
155
                /// This adds both an assembly attribute and an internal forwarder entry, which will be used
 
156
                /// by the resolved assembly to provide the forwarded types.
 
157
                /// </summary>
 
158
                /// <param name="typeName">The name of the type.</param>
 
159
                /// <param name="referencedType">The reference used to look up the type in the target assembly.</param>
 
160
                public void AddTypeForwarder(TopLevelTypeName typeName, ITypeReference referencedType)
 
161
                {
 
162
                        if (referencedType == null)
 
163
                                throw new ArgumentNullException("referencedType");
 
164
                        FreezableHelper.ThrowIfFrozen(this);
 
165
                        var attribute = new DefaultUnresolvedAttribute(typeForwardedToAttributeTypeRef, new[] { KnownTypeReference.Type });
 
166
                        attribute.PositionalArguments.Add(new TypeOfConstantValue(referencedType));
 
167
                        assemblyAttributes.Add(attribute);
 
168
                        
 
169
                        typeForwarders[typeName] = referencedType;
 
170
                }
 
171
                
 
172
                [Serializable]
 
173
                sealed class TypeOfConstantValue : IConstantValue
 
174
                {
 
175
                        readonly ITypeReference typeRef;
 
176
                        
 
177
                        public TypeOfConstantValue(ITypeReference typeRef)
 
178
                        {
 
179
                                this.typeRef = typeRef;
 
180
                        }
 
181
                        
 
182
                        public ResolveResult Resolve(ITypeResolveContext context)
 
183
                        {
 
184
                                return new TypeOfResolveResult(context.Compilation.FindType(KnownTypeCode.Type), typeRef.Resolve(context));
 
185
                        }
 
186
                }
 
187
                
 
188
                public IUnresolvedTypeDefinition GetTypeDefinition(string ns, string name, int typeParameterCount)
 
189
                {
 
190
                        var key = new TopLevelTypeName(ns ?? string.Empty, name, typeParameterCount);
 
191
                        IUnresolvedTypeDefinition td;
 
192
                        if (typeDefinitions.TryGetValue(key, out td))
 
193
                                return td;
 
194
                        else
 
195
                                return null;
 
196
                }
 
197
                
 
198
                public IAssembly Resolve(ITypeResolveContext context)
 
199
                {
 
200
                        if (context == null)
 
201
                                throw new ArgumentNullException("context");
 
202
                        Freeze();
 
203
                        var cache = context.Compilation.CacheManager;
 
204
                        IAssembly asm = (IAssembly)cache.GetShared(this);
 
205
                        if (asm != null) {
 
206
                                return asm;
 
207
                        } else {
 
208
                                asm = new DefaultResolvedAssembly(context.Compilation, this);
 
209
                                return (IAssembly)cache.GetOrAddShared(this, asm);
 
210
                        }
 
211
                }
 
212
                
 
213
                public override string ToString()
 
214
                {
 
215
                        return "[" + GetType().Name + " " + assemblyName + "]";
 
216
                }
 
217
                
 
218
                //[NonSerialized]
 
219
                //List<Dictionary<TopLevelTypeName, IUnresolvedTypeDefinition>> cachedTypeDictionariesPerNameComparer;
 
220
                
 
221
                Dictionary<TopLevelTypeName, IUnresolvedTypeDefinition> GetTypeDictionary(StringComparer nameComparer)
 
222
                {
 
223
                        Debug.Assert(IsFrozen);
 
224
                        if (nameComparer == StringComparer.Ordinal)
 
225
                                return typeDefinitions;
 
226
                        else
 
227
                                throw new NotImplementedException();
 
228
                }
 
229
                
 
230
                #region UnresolvedNamespace
 
231
                sealed class UnresolvedNamespace
 
232
                {
 
233
                        internal readonly string FullName;
 
234
                        internal readonly string Name;
 
235
                        internal readonly List<UnresolvedNamespace> Children = new List<UnresolvedNamespace>();
 
236
                        
 
237
                        public UnresolvedNamespace(string fullName, string name)
 
238
                        {
 
239
                                this.FullName = fullName;
 
240
                                this.Name = name;
 
241
                        }
 
242
                }
 
243
                
 
244
                [NonSerialized]
 
245
                List<KeyValuePair<StringComparer, UnresolvedNamespace>> unresolvedNamespacesPerNameComparer;
 
246
                
 
247
                UnresolvedNamespace GetUnresolvedRootNamespace(StringComparer nameComparer)
 
248
                {
 
249
                        Debug.Assert(IsFrozen);
 
250
                        LazyInitializer.EnsureInitialized(ref unresolvedNamespacesPerNameComparer);
 
251
                        lock (unresolvedNamespacesPerNameComparer) {
 
252
                                foreach (var pair in unresolvedNamespacesPerNameComparer) {
 
253
                                        if (pair.Key == nameComparer)
 
254
                                                return pair.Value;
 
255
                                }
 
256
                                var root = new UnresolvedNamespace(string.Empty, string.Empty);
 
257
                                var dict = new Dictionary<string, UnresolvedNamespace>(nameComparer);
 
258
                                dict.Add(root.FullName, root);
 
259
                                foreach (var typeName in typeDefinitions.Keys) {
 
260
                                        GetOrAddNamespace(dict, typeName.Namespace);
 
261
                                }
 
262
                                unresolvedNamespacesPerNameComparer.Add(new KeyValuePair<StringComparer, UnresolvedNamespace>(nameComparer, root));
 
263
                                return root;
 
264
                        }
 
265
                }
 
266
                
 
267
                static UnresolvedNamespace GetOrAddNamespace(Dictionary<string, UnresolvedNamespace> dict, string fullName)
 
268
                {
 
269
                        UnresolvedNamespace ns;
 
270
                        if (dict.TryGetValue(fullName, out ns))
 
271
                                return ns;
 
272
                        int pos = fullName.LastIndexOf('.');
 
273
                        UnresolvedNamespace parent;
 
274
                        string name;
 
275
                        if (pos < 0) {
 
276
                                parent = dict[string.Empty]; // root
 
277
                                name = fullName;
 
278
                        } else {
 
279
                                parent = GetOrAddNamespace(dict, fullName.Substring(0, pos));
 
280
                                name = fullName.Substring(pos + 1);
 
281
                        }
 
282
                        ns = new UnresolvedNamespace(fullName, name);
 
283
                        parent.Children.Add(ns);
 
284
                        dict.Add(fullName, ns);
 
285
                        return ns;
 
286
                }
 
287
                #endregion
 
288
                
 
289
                sealed class DefaultResolvedAssembly : IAssembly
 
290
                {
 
291
                        readonly DefaultUnresolvedAssembly unresolvedAssembly;
 
292
                        readonly ICompilation compilation;
 
293
                        readonly ITypeResolveContext context;
 
294
                        readonly Dictionary<TopLevelTypeName, IUnresolvedTypeDefinition> unresolvedTypeDict;
 
295
                        readonly ConcurrentDictionary<IUnresolvedTypeDefinition, ITypeDefinition> typeDict = new ConcurrentDictionary<IUnresolvedTypeDefinition, ITypeDefinition>();
 
296
                        readonly INamespace rootNamespace;
 
297
                        
 
298
                        public DefaultResolvedAssembly(ICompilation compilation, DefaultUnresolvedAssembly unresolved)
 
299
                        {
 
300
                                this.compilation = compilation;
 
301
                                this.unresolvedAssembly = unresolved;
 
302
                                this.unresolvedTypeDict = unresolved.GetTypeDictionary(compilation.NameComparer);
 
303
                                this.rootNamespace = new NS(this, unresolved.GetUnresolvedRootNamespace(compilation.NameComparer), null);
 
304
                                this.context = new SimpleTypeResolveContext(this);
 
305
                                this.AssemblyAttributes = unresolved.AssemblyAttributes.CreateResolvedAttributes(context);
 
306
                                this.ModuleAttributes = unresolved.ModuleAttributes.CreateResolvedAttributes(context);
 
307
                        }
 
308
                        
 
309
                        public IUnresolvedAssembly UnresolvedAssembly {
 
310
                                get { return unresolvedAssembly; }
 
311
                        }
 
312
                        
 
313
                        public bool IsMainAssembly {
 
314
                                get { return this.Compilation.MainAssembly == this; }
 
315
                        }
 
316
                        
 
317
                        public string AssemblyName {
 
318
                                get { return unresolvedAssembly.AssemblyName; }
 
319
                        }
 
320
                        
 
321
                        public string FullAssemblyName {
 
322
                                get { return unresolvedAssembly.FullAssemblyName; }
 
323
                        }
 
324
                        
 
325
                        public IList<IAttribute> AssemblyAttributes { get; private set; }
 
326
                        public IList<IAttribute> ModuleAttributes { get; private set; }
 
327
                        
 
328
                        public INamespace RootNamespace {
 
329
                                get { return rootNamespace; }
 
330
                        }
 
331
                        
 
332
                        public ICompilation Compilation {
 
333
                                get { return compilation; }
 
334
                        }
 
335
                        
 
336
                        public bool InternalsVisibleTo(IAssembly assembly)
 
337
                        {
 
338
                                return assembly == this;
 
339
                        }
 
340
                        
 
341
                        public ITypeDefinition GetTypeDefinition(TopLevelTypeName topLevelTypeName)
 
342
                        {
 
343
                                IUnresolvedTypeDefinition td;
 
344
                                ITypeReference typeRef;
 
345
                                if (unresolvedAssembly.typeDefinitions.TryGetValue(topLevelTypeName, out td))
 
346
                                        return GetTypeDefinition(td);
 
347
                                else if (unresolvedAssembly.typeForwarders.TryGetValue(topLevelTypeName, out typeRef))
 
348
                                        return typeRef.Resolve(compilation.TypeResolveContext).GetDefinition();
 
349
                                else
 
350
                                        return null;
 
351
                        }
 
352
                        
 
353
                        ITypeDefinition GetTypeDefinition(IUnresolvedTypeDefinition unresolved)
 
354
                        {
 
355
                                return typeDict.GetOrAdd(unresolved, t => CreateTypeDefinition(t));
 
356
                        }
 
357
                        
 
358
                        ITypeDefinition CreateTypeDefinition(IUnresolvedTypeDefinition unresolved)
 
359
                        {
 
360
                                if (unresolved.DeclaringTypeDefinition != null) {
 
361
                                        ITypeDefinition declaringType = GetTypeDefinition(unresolved.DeclaringTypeDefinition);
 
362
                                        return new DefaultResolvedTypeDefinition(context.WithCurrentTypeDefinition(declaringType), unresolved);
 
363
                                } else if (unresolved.Name == "Void" && unresolved.Namespace == "System" && unresolved.TypeParameters.Count == 0) {
 
364
                                        return new VoidTypeDefinition(context, unresolved);
 
365
                                } else {
 
366
                                        return new DefaultResolvedTypeDefinition(context, unresolved);
 
367
                                }
 
368
                        }
 
369
                        
 
370
                        public IEnumerable<ITypeDefinition> TopLevelTypeDefinitions {
 
371
                                get {
 
372
                                        return unresolvedAssembly.TopLevelTypeDefinitions.Select(t => GetTypeDefinition(t));
 
373
                                }
 
374
                        }
 
375
                        
 
376
                        public override string ToString()
 
377
                        {
 
378
                                return "[DefaultResolvedAssembly " + AssemblyName + "]";
 
379
                        }
 
380
                        
 
381
                        sealed class NS : INamespace
 
382
                        {
 
383
                                readonly DefaultResolvedAssembly assembly;
 
384
                                readonly UnresolvedNamespace ns;
 
385
                                readonly INamespace parentNamespace;
 
386
                                readonly IList<NS> childNamespaces;
 
387
                                IEnumerable<ITypeDefinition> types;
 
388
                                
 
389
                                public NS(DefaultResolvedAssembly assembly, UnresolvedNamespace ns, INamespace parentNamespace)
 
390
                                {
 
391
                                        this.assembly = assembly;
 
392
                                        this.ns = ns;
 
393
                                        this.parentNamespace = parentNamespace;
 
394
                                        this.childNamespaces = new ProjectedList<NS, UnresolvedNamespace, NS>(
 
395
                                                this, ns.Children, (self, c) => new NS(self.assembly, c, self));
 
396
                                }
 
397
                                
 
398
                                string INamespace.ExternAlias {
 
399
                                        get { return null; }
 
400
                                }
 
401
                                
 
402
                                string INamespace.FullName {
 
403
                                        get { return ns.FullName; }
 
404
                                }
 
405
                                
 
406
                                string INamespace.Name {
 
407
                                        get { return ns.Name; }
 
408
                                }
 
409
                                
 
410
                                INamespace INamespace.ParentNamespace {
 
411
                                        get { return parentNamespace; }
 
412
                                }
 
413
                                
 
414
                                IEnumerable<IAssembly> INamespace.ContributingAssemblies {
 
415
                                        get { return new [] { assembly }; }
 
416
                                }
 
417
                                
 
418
                                IEnumerable<INamespace> INamespace.ChildNamespaces {
 
419
                                        get { return childNamespaces; }
 
420
                                }
 
421
                                
 
422
                                INamespace INamespace.GetChildNamespace(string name)
 
423
                                {
 
424
                                        var nameComparer = assembly.compilation.NameComparer;
 
425
                                        for (int i = 0; i < childNamespaces.Count; i++) {
 
426
                                                if (nameComparer.Equals(name, ns.Children[i].Name))
 
427
                                                        return childNamespaces[i];
 
428
                                        }
 
429
                                        return null;
 
430
                                }
 
431
                                
 
432
                                ICompilation ICompilationProvider.Compilation {
 
433
                                        get { return assembly.compilation; }
 
434
                                }
 
435
                                
 
436
                                IEnumerable<ITypeDefinition> INamespace.Types {
 
437
                                        get {
 
438
                                                var result = LazyInit.VolatileRead(ref this.types);
 
439
                                                if (result != null) {
 
440
                                                        return result;
 
441
                                                } else {
 
442
                                                        var hashSet = new HashSet<ITypeDefinition>();
 
443
                                                        foreach (IUnresolvedTypeDefinition typeDef in assembly.UnresolvedAssembly.TopLevelTypeDefinitions) {
 
444
                                                                if (typeDef.Namespace == ns.FullName)
 
445
                                                                        hashSet.Add(assembly.GetTypeDefinition(typeDef));
 
446
                                                        }
 
447
                                                        return LazyInit.GetOrSet(ref this.types, hashSet.ToArray());
 
448
                                                }
 
449
                                        }
 
450
                                }
 
451
                                
 
452
                                ITypeDefinition INamespace.GetTypeDefinition(string name, int typeParameterCount)
 
453
                                {
 
454
                                        var key = new TopLevelTypeName(ns.FullName, name, typeParameterCount);
 
455
                                        IUnresolvedTypeDefinition unresolvedTypeDef;
 
456
                                        if (assembly.unresolvedTypeDict.TryGetValue(key, out unresolvedTypeDef))
 
457
                                                return assembly.GetTypeDefinition(unresolvedTypeDef);
 
458
                                        else
 
459
                                                return null;
 
460
                                }
 
461
                        }
 
462
                }
 
463
        }
 
464
}