Free cookie consent management tool by TermsFeed Policy Generator

source: branches/CodeEditor/HeuristicLab.ExtLibs/HeuristicLab.NRefactory/5.5.0/NRefactory-5.5.0/TypeSystem/Implementation/SpecializedMember.cs @ 11700

Last change on this file since 11700 was 11700, checked in by jkarder, 9 years ago

#2077: created branch and added first version

File size: 11.9 KB
Line 
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
19using System;
20using System.Collections.Generic;
21using System.Diagnostics;
22using System.Linq;
23using System.Text;
24using System.Threading;
25using ICSharpCode.NRefactory.Documentation;
26using ICSharpCode.NRefactory.Utils;
27
28namespace ICSharpCode.NRefactory.TypeSystem.Implementation
29{
30  /// <summary>
31  /// Represents a SpecializedMember (a member on which type substitution has been performed).
32  /// </summary>
33  public abstract class SpecializedMember : IMember
34  {
35    protected readonly IMember baseMember;
36    TypeParameterSubstitution substitution;
37   
38    IType declaringType;
39    IType returnType;
40   
41    protected SpecializedMember(IMember memberDefinition)
42    {
43      if (memberDefinition == null)
44        throw new ArgumentNullException("memberDefinition");
45      if (memberDefinition is SpecializedMember)
46        throw new ArgumentException("Member definition cannot be specialized. Please use IMember.Specialize() instead of directly constructing SpecializedMember instances.");
47     
48      this.baseMember = memberDefinition;
49      this.substitution = TypeParameterSubstitution.Identity;
50    }
51   
52    /// <summary>
53    /// Performs a substitution. This method may only be called by constructors in derived classes.
54    /// </summary>
55    protected void AddSubstitution(TypeParameterSubstitution newSubstitution)
56    {
57      Debug.Assert(declaringType == null);
58      Debug.Assert(returnType == null);
59      this.substitution = TypeParameterSubstitution.Compose(newSubstitution, this.substitution);
60    }
61   
62    [Obsolete("Use IMember.Specialize() instead")]
63    public static IMember Create(IMember memberDefinition, TypeParameterSubstitution substitution)
64    {
65      if (memberDefinition == null) {
66        return null;
67      } else {
68        return memberDefinition.Specialize(substitution);
69      }
70    }
71   
72    public virtual IMemberReference ToMemberReference()
73    {
74      return ToReference();
75    }
76   
77    public virtual IMemberReference ToReference()
78    {
79      return new SpecializingMemberReference(
80        baseMember.ToReference(),
81        ToTypeReference(substitution.ClassTypeArguments),
82        null);
83    }
84   
85    ISymbolReference ISymbol.ToReference()
86    {
87      return ToReference();
88    }
89   
90    internal static IList<ITypeReference> ToTypeReference(IList<IType> typeArguments)
91    {
92      if (typeArguments == null)
93        return null;
94      else
95        return typeArguments.Select(t => t.ToTypeReference()).ToArray();
96    }
97   
98    internal IMethod WrapAccessor(ref IMethod cachingField, IMethod accessorDefinition)
99    {
100      if (accessorDefinition == null)
101        return null;
102      var result = LazyInit.VolatileRead(ref cachingField);
103      if (result != null) {
104        return result;
105      } else {
106        var sm = accessorDefinition.Specialize(substitution);
107        //sm.AccessorOwner = this;
108        return LazyInit.GetOrSet(ref cachingField, sm);
109      }
110    }
111   
112    /// <summary>
113    /// Gets the substitution belonging to this specialized member.
114    /// </summary>
115    public TypeParameterSubstitution Substitution {
116      get { return substitution; }
117    }
118   
119    public IType DeclaringType {
120      get {
121        var result = LazyInit.VolatileRead(ref this.declaringType);
122        if (result != null)
123          return result;
124        IType definitionDeclaringType = baseMember.DeclaringType;
125        ITypeDefinition definitionDeclaringTypeDef = definitionDeclaringType as ITypeDefinition;
126        if (definitionDeclaringTypeDef != null && definitionDeclaringType.TypeParameterCount > 0) {
127          if (substitution.ClassTypeArguments != null && substitution.ClassTypeArguments.Count == definitionDeclaringType.TypeParameterCount) {
128            result = new ParameterizedType(definitionDeclaringTypeDef, substitution.ClassTypeArguments);
129          } else {
130            result = new ParameterizedType(definitionDeclaringTypeDef, definitionDeclaringTypeDef.TypeParameters).AcceptVisitor(substitution);
131          }
132        } else {
133          result = definitionDeclaringType.AcceptVisitor(substitution);
134        }
135        return LazyInit.GetOrSet(ref this.declaringType, result);
136      }
137      internal set {
138        // This setter is used as an optimization when the code constructing
139        // the SpecializedMember already knows the declaring type.
140        Debug.Assert(this.declaringType == null);
141        Debug.Assert(value != null);
142        // As this setter is used only during construction before the member is published
143        // to other threads, we don't need a volatile write.
144        this.declaringType = value;
145      }
146    }
147   
148    public IMember MemberDefinition {
149      get { return baseMember.MemberDefinition; }
150    }
151   
152    public IUnresolvedMember UnresolvedMember {
153      get { return baseMember.UnresolvedMember; }
154    }
155   
156    public IType ReturnType {
157      get {
158        var result = LazyInit.VolatileRead(ref this.returnType);
159        if (result != null)
160          return result;
161        else
162          return LazyInit.GetOrSet(ref this.returnType, baseMember.ReturnType.AcceptVisitor(substitution));
163      }
164      protected set {
165        // This setter is used for LiftedUserDefinedOperator, a special case of specialized member
166        // (not a normal type parameter substitution).
167       
168        // As this setter is used only during construction before the member is published
169        // to other threads, we don't need a volatile write.
170        this.returnType = value;
171      }
172    }
173   
174    public bool IsVirtual {
175      get { return baseMember.IsVirtual; }
176    }
177   
178    public bool IsOverride {
179      get { return baseMember.IsOverride; }
180    }
181   
182    public bool IsOverridable {
183      get { return baseMember.IsOverridable; }
184    }
185   
186    public SymbolKind SymbolKind {
187      get { return baseMember.SymbolKind; }
188    }
189   
190    [Obsolete("Use the SymbolKind property instead.")]
191    public EntityType EntityType {
192      get { return baseMember.EntityType; }
193    }
194   
195    public DomRegion Region {
196      get { return baseMember.Region; }
197    }
198   
199    public DomRegion BodyRegion {
200      get { return baseMember.BodyRegion; }
201    }
202   
203    public ITypeDefinition DeclaringTypeDefinition {
204      get { return baseMember.DeclaringTypeDefinition; }
205    }
206   
207    public IList<IAttribute> Attributes {
208      get { return baseMember.Attributes; }
209    }
210   
211    IList<IMember> implementedInterfaceMembers;
212   
213    public IList<IMember> ImplementedInterfaceMembers {
214      get {
215        return LazyInitializer.EnsureInitialized(ref implementedInterfaceMembers, FindImplementedInterfaceMembers);
216      }
217    }
218   
219    IList<IMember> FindImplementedInterfaceMembers()
220    {
221      var definitionImplementations = baseMember.ImplementedInterfaceMembers;
222      IMember[] result = new IMember[definitionImplementations.Count];
223      for (int i = 0; i < result.Length; i++) {
224        result[i] = definitionImplementations[i].Specialize(substitution);
225      }
226      return result;
227    }
228   
229    public bool IsExplicitInterfaceImplementation {
230      get { return baseMember.IsExplicitInterfaceImplementation; }
231    }
232   
233    public DocumentationComment Documentation {
234      get { return baseMember.Documentation; }
235    }
236   
237    public Accessibility Accessibility {
238      get { return baseMember.Accessibility; }
239    }
240   
241    public bool IsStatic {
242      get { return baseMember.IsStatic; }
243    }
244   
245    public bool IsAbstract {
246      get { return baseMember.IsAbstract; }
247    }
248   
249    public bool IsSealed {
250      get { return baseMember.IsSealed; }
251    }
252   
253    public bool IsShadowing {
254      get { return baseMember.IsShadowing; }
255    }
256   
257    public bool IsSynthetic {
258      get { return baseMember.IsSynthetic; }
259    }
260   
261    public bool IsPrivate {
262      get { return baseMember.IsPrivate; }
263    }
264   
265    public bool IsPublic {
266      get { return baseMember.IsPublic; }
267    }
268   
269    public bool IsProtected {
270      get { return baseMember.IsProtected; }
271    }
272   
273    public bool IsInternal {
274      get { return baseMember.IsInternal; }
275    }
276   
277    public bool IsProtectedOrInternal {
278      get { return baseMember.IsProtectedOrInternal; }
279    }
280   
281    public bool IsProtectedAndInternal {
282      get { return baseMember.IsProtectedAndInternal; }
283    }
284   
285    public string FullName {
286      get { return baseMember.FullName; }
287    }
288   
289    public string Name {
290      get { return baseMember.Name; }
291    }
292   
293    public string Namespace {
294      get { return baseMember.Namespace; }
295    }
296   
297    public string ReflectionName {
298      get { return baseMember.ReflectionName; }
299    }
300   
301    public ICompilation Compilation {
302      get { return baseMember.Compilation; }
303    }
304   
305    public IAssembly ParentAssembly {
306      get { return baseMember.ParentAssembly; }
307    }
308
309    public virtual IMember Specialize(TypeParameterSubstitution newSubstitution)
310    {
311      return baseMember.Specialize(TypeParameterSubstitution.Compose(newSubstitution, this.substitution));
312    }
313
314    public override bool Equals(object obj)
315    {
316      SpecializedMember other = obj as SpecializedMember;
317      if (other == null)
318        return false;
319      return this.baseMember.Equals(other.baseMember) && this.substitution.Equals(other.substitution);
320    }
321   
322    public override int GetHashCode()
323    {
324      unchecked {
325        return 1000000007 * baseMember.GetHashCode() + 1000000009 * substitution.GetHashCode();
326      }
327    }
328   
329    public override string ToString()
330    {
331      StringBuilder b = new StringBuilder("[");
332      b.Append(GetType().Name);
333      b.Append(' ');
334      b.Append(this.DeclaringType.ToString());
335      b.Append('.');
336      b.Append(this.Name);
337      b.Append(':');
338      b.Append(this.ReturnType.ToString());
339      b.Append(']');
340      return b.ToString();
341    }
342  }
343 
344  public abstract class SpecializedParameterizedMember : SpecializedMember, IParameterizedMember
345  {
346    IList<IParameter> parameters;
347   
348    protected SpecializedParameterizedMember(IParameterizedMember memberDefinition)
349      : base(memberDefinition)
350    {
351    }
352   
353    public IList<IParameter> Parameters {
354      get {
355        var result = LazyInit.VolatileRead(ref this.parameters);
356        if (result != null)
357          return result;
358        else
359          return LazyInit.GetOrSet(ref this.parameters, CreateParameters(this.Substitution));
360      }
361      protected set {
362        // This setter is used for LiftedUserDefinedOperator, a special case of specialized member
363        // (not a normal type parameter substitution).
364       
365        // As this setter is used only during construction before the member is published
366        // to other threads, we don't need a volatile write.
367        this.parameters = value;
368      }
369    }
370   
371    protected IList<IParameter> CreateParameters(TypeVisitor substitution)
372    {
373      var paramDefs = ((IParameterizedMember)this.baseMember).Parameters;
374      if (paramDefs.Count == 0) {
375        return EmptyList<IParameter>.Instance;
376      } else {
377        var parameters = new IParameter[paramDefs.Count];
378        for (int i = 0; i < parameters.Length; i++) {
379          var p = paramDefs[i];
380          IType newType = p.Type.AcceptVisitor(substitution);
381          parameters[i] = new DefaultParameter(
382            newType, p.Name, this,
383            p.Region, p.Attributes, p.IsRef, p.IsOut,
384            p.IsParams, p.IsOptional, p.ConstantValue
385          );
386        }
387        return Array.AsReadOnly(parameters);
388      }
389    }
390   
391    public override string ToString()
392    {
393      StringBuilder b = new StringBuilder("[");
394      b.Append(GetType().Name);
395      b.Append(' ');
396      b.Append(this.DeclaringType.ReflectionName);
397      b.Append('.');
398      b.Append(this.Name);
399      b.Append('(');
400      for (int i = 0; i < this.Parameters.Count; i++) {
401        if (i > 0) b.Append(", ");
402        b.Append(this.Parameters[i].ToString());
403      }
404      b.Append("):");
405      b.Append(this.ReturnType.ReflectionName);
406      b.Append(']');
407      return b.ToString();
408    }
409  }
410}
Note: See TracBrowser for help on using the repository browser.