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

« back to all changes in this revision

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

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

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
ļ»æ// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team
 
2
// 
 
3
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
 
4
// software and associated documentation files (the "Software"), to deal in the Software
 
5
// without restriction, including without limitation the rights to use, copy, modify, merge,
 
6
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
 
7
// to whom the Software is furnished to do so, subject to the following conditions:
 
8
// 
 
9
// The above copyright notice and this permission notice shall be included in all copies or
 
10
// substantial portions of the Software.
 
11
// 
 
12
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
 
13
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 
14
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
 
15
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 
16
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 
17
// DEALINGS IN THE SOFTWARE.
 
18
 
 
19
using System;
 
20
using System.Collections.Generic;
 
21
using ICSharpCode.NRefactory.Semantics;
 
22
using ICSharpCode.NRefactory.Utils;
 
23
 
 
24
namespace ICSharpCode.NRefactory.TypeSystem.Implementation
 
25
{
 
26
        /// <summary>
 
27
        /// Default implementation of <see cref="IUnresolvedAttribute"/>.
 
28
        /// </summary>
 
29
        [Serializable]
 
30
        public sealed class DefaultUnresolvedAttribute : AbstractFreezable, IUnresolvedAttribute, IFreezable, ISupportsInterning
 
31
        {
 
32
                ITypeReference attributeType;
 
33
                DomRegion region;
 
34
                IList<ITypeReference> constructorParameterTypes;
 
35
                IList<IConstantValue> positionalArguments;
 
36
                IList<KeyValuePair<IMemberReference, IConstantValue>> namedArguments;
 
37
                
 
38
                public DefaultUnresolvedAttribute(ITypeReference attributeType)
 
39
                {
 
40
                        if (attributeType == null)
 
41
                                throw new ArgumentNullException("attributeType");
 
42
                        this.attributeType = attributeType;
 
43
                }
 
44
                
 
45
                public DefaultUnresolvedAttribute(ITypeReference attributeType, IEnumerable<ITypeReference> constructorParameterTypes)
 
46
                {
 
47
                        if (attributeType == null)
 
48
                                throw new ArgumentNullException("attributeType");
 
49
                        this.attributeType = attributeType;
 
50
                        this.ConstructorParameterTypes.AddRange(constructorParameterTypes);
 
51
                }
 
52
                
 
53
                protected override void FreezeInternal()
 
54
                {
 
55
                        base.FreezeInternal();
 
56
                        constructorParameterTypes = FreezableHelper.FreezeList(constructorParameterTypes);
 
57
                        positionalArguments = FreezableHelper.FreezeListAndElements(positionalArguments);
 
58
                        namedArguments = FreezableHelper.FreezeList(namedArguments);
 
59
                        foreach (var pair in namedArguments) {
 
60
                                FreezableHelper.Freeze(pair.Key);
 
61
                                FreezableHelper.Freeze(pair.Value);
 
62
                        }
 
63
                }
 
64
                
 
65
                public ITypeReference AttributeType {
 
66
                        get { return attributeType; }
 
67
                }
 
68
                
 
69
                public DomRegion Region {
 
70
                        get { return region; }
 
71
                        set {
 
72
                                FreezableHelper.ThrowIfFrozen(this);
 
73
                                region = value;
 
74
                        }
 
75
                }
 
76
                
 
77
                public IList<ITypeReference> ConstructorParameterTypes {
 
78
                        get {
 
79
                                if (constructorParameterTypes == null)
 
80
                                        constructorParameterTypes = new List<ITypeReference>();
 
81
                                return constructorParameterTypes;
 
82
                        }
 
83
                }
 
84
                
 
85
                public IList<IConstantValue> PositionalArguments {
 
86
                        get {
 
87
                                if (positionalArguments == null)
 
88
                                        positionalArguments = new List<IConstantValue>();
 
89
                                return positionalArguments;
 
90
                        }
 
91
                }
 
92
                
 
93
                public IList<KeyValuePair<IMemberReference, IConstantValue>> NamedArguments {
 
94
                        get {
 
95
                                if (namedArguments == null)
 
96
                                        namedArguments = new List<KeyValuePair<IMemberReference, IConstantValue>>();
 
97
                                return namedArguments;
 
98
                        }
 
99
                }
 
100
                
 
101
                public void AddNamedFieldArgument(string fieldName, IConstantValue value)
 
102
                {
 
103
                        this.NamedArguments.Add(new KeyValuePair<IMemberReference, IConstantValue>(
 
104
                                new DefaultMemberReference(EntityType.Field, attributeType, fieldName),
 
105
                                value
 
106
                        ));
 
107
                }
 
108
                
 
109
                public void AddNamedPropertyArgument(string propertyName, IConstantValue value)
 
110
                {
 
111
                        this.NamedArguments.Add(new KeyValuePair<IMemberReference, IConstantValue>(
 
112
                                new DefaultMemberReference(EntityType.Property, attributeType, propertyName),
 
113
                                value
 
114
                        ));
 
115
                }
 
116
                
 
117
                public IAttribute CreateResolvedAttribute(ITypeResolveContext context)
 
118
                {
 
119
                        return new DefaultResolvedAttribute(this, context);
 
120
                }
 
121
                
 
122
                int ISupportsInterning.GetHashCodeForInterning()
 
123
                {
 
124
                        int hash = attributeType.GetHashCode() ^ constructorParameterTypes.GetHashCode();
 
125
                        unchecked {
 
126
                                if (constructorParameterTypes != null) {
 
127
                                        foreach (var type in constructorParameterTypes) {
 
128
                                                hash *= 27;
 
129
                                                hash += type.GetHashCode();
 
130
                                        }
 
131
                                }
 
132
                                if (positionalArguments != null) {
 
133
                                        foreach (var arg in positionalArguments) {
 
134
                                                hash *= 31;
 
135
                                                hash += arg.GetHashCode();
 
136
                                        }
 
137
                                }
 
138
                                if (namedArguments != null) {
 
139
                                        foreach (var pair in namedArguments) {
 
140
                                                hash *= 71;
 
141
                                                hash += pair.Key.GetHashCode() + pair.Value.GetHashCode() * 73;
 
142
                                        }
 
143
                                }
 
144
                        }
 
145
                        return hash;
 
146
                }
 
147
                
 
148
                bool ISupportsInterning.EqualsForInterning(ISupportsInterning other)
 
149
                {
 
150
                        DefaultUnresolvedAttribute o = other as DefaultUnresolvedAttribute;
 
151
                        return o != null && attributeType == o.attributeType
 
152
                                && ListEquals(constructorParameterTypes, o.constructorParameterTypes)
 
153
                                && ListEquals(positionalArguments, o.positionalArguments)
 
154
                                && ListEquals(namedArguments ?? EmptyList<KeyValuePair<IMemberReference, IConstantValue>>.Instance,
 
155
                                              o.namedArguments ?? EmptyList<KeyValuePair<IMemberReference, IConstantValue>>.Instance);
 
156
                }
 
157
                
 
158
                static bool ListEquals<T>(IList<T> list1, IList<T> list2) where T : class
 
159
                {
 
160
                        if (list1 == null)
 
161
                                list1 = EmptyList<T>.Instance;
 
162
                        if (list2 == null)
 
163
                                list2 = EmptyList<T>.Instance;
 
164
                        if (list1 == list2)
 
165
                                return true;
 
166
                        if (list1.Count != list2.Count)
 
167
                                return false;
 
168
                        for (int i = 0; i < list1.Count; i++) {
 
169
                                if (list1[i] != list2[i])
 
170
                                        return false;
 
171
                        }
 
172
                        return true;
 
173
                }
 
174
                
 
175
                static bool ListEquals(IList<KeyValuePair<IMemberReference, IConstantValue>> list1, IList<KeyValuePair<IMemberReference, IConstantValue>> list2)
 
176
                {
 
177
                        if (list1 == list2)
 
178
                                return true;
 
179
                        if (list1.Count != list2.Count)
 
180
                                return false;
 
181
                        for (int i = 0; i < list1.Count; i++) {
 
182
                                var a = list1[i];
 
183
                                var b = list2[i];
 
184
                                if (!(a.Key == b.Key && a.Value == b.Value))
 
185
                                        return false;
 
186
                        }
 
187
                        return true;
 
188
                }
 
189
                
 
190
                sealed class DefaultResolvedAttribute : IAttribute, ICompilationProvider
 
191
                {
 
192
                        readonly DefaultUnresolvedAttribute unresolved;
 
193
                        readonly ITypeResolveContext context;
 
194
                        readonly IType attributeType;
 
195
                        readonly IList<ResolveResult> positionalArguments;
 
196
                        
 
197
                        // cannot use ProjectedList because KeyValuePair is value type
 
198
                        IList<KeyValuePair<IMember, ResolveResult>> namedArguments;
 
199
                        
 
200
                        IMethod constructor;
 
201
                        volatile bool constructorResolved;
 
202
                        
 
203
                        public DefaultResolvedAttribute(DefaultUnresolvedAttribute unresolved, ITypeResolveContext context)
 
204
                        {
 
205
                                this.unresolved = unresolved;
 
206
                                this.context = context;
 
207
                                
 
208
                                this.attributeType = unresolved.AttributeType.Resolve(context);
 
209
                                this.positionalArguments = unresolved.PositionalArguments.Resolve(context);
 
210
                        }
 
211
                        
 
212
                        public IType AttributeType {
 
213
                                get { return attributeType; }
 
214
                        }
 
215
                        
 
216
                        public DomRegion Region {
 
217
                                get { return unresolved.Region; }
 
218
                        }
 
219
                        
 
220
                        public IMethod Constructor {
 
221
                                get {
 
222
                                        if (!constructorResolved) {
 
223
                                                constructor = ResolveConstructor();
 
224
                                                constructorResolved = true;
 
225
                                        }
 
226
                                        return constructor;
 
227
                                }
 
228
                        }
 
229
                        
 
230
                        IMethod ResolveConstructor()
 
231
                        {
 
232
                                var parameterTypes = unresolved.ConstructorParameterTypes.Resolve(context);
 
233
                                foreach (var ctor in attributeType.GetConstructors(m => m.Parameters.Count == parameterTypes.Count)) {
 
234
                                        bool ok = true;
 
235
                                        for (int i = 0; i < parameterTypes.Count; i++) {
 
236
                                                if (!ctor.Parameters[i].Type.Equals(parameterTypes[i])) {
 
237
                                                        ok = false;
 
238
                                                        break;
 
239
                                                }
 
240
                                        }
 
241
                                        if (ok)
 
242
                                                return ctor;
 
243
                                }
 
244
                                return null;
 
245
                        }
 
246
                        
 
247
                        public IList<ResolveResult> PositionalArguments {
 
248
                                get { return positionalArguments; }
 
249
                        }
 
250
                        
 
251
                        public IList<KeyValuePair<IMember, ResolveResult>> NamedArguments {
 
252
                                get {
 
253
                                        var namedArgs = LazyInit.VolatileRead(ref this.namedArguments);
 
254
                                        if (namedArgs != null) {
 
255
                                                return namedArgs;
 
256
                                        } else {
 
257
                                                namedArgs = new List<KeyValuePair<IMember, ResolveResult>>();
 
258
                                                foreach (var pair in unresolved.NamedArguments) {
 
259
                                                        IMember member = pair.Key.Resolve(context);
 
260
                                                        if (member != null) {
 
261
                                                                ResolveResult val = pair.Value.Resolve(context);
 
262
                                                                namedArgs.Add(new KeyValuePair<IMember, ResolveResult>(member, val));
 
263
                                                        }
 
264
                                                }
 
265
                                                return LazyInit.GetOrSet(ref this.namedArguments, namedArgs);
 
266
                                        }
 
267
                                }
 
268
                        }
 
269
                        
 
270
                        public ICompilation Compilation {
 
271
                                get { return context.Compilation; }
 
272
                        }
 
273
                        
 
274
                        public override string ToString()
 
275
                        {
 
276
                                if (positionalArguments.Count == 0)
 
277
                                        return "[" + attributeType.ToString() + "]";
 
278
                                else
 
279
                                        return "[" + attributeType.ToString() + "(...)]";
 
280
                        }
 
281
                }
 
282
        }
 
283
}