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/DummyTypeParameter.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: 6.7 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.Threading;
22
23namespace ICSharpCode.NRefactory.TypeSystem.Implementation
24{
25  public sealed class DummyTypeParameter : AbstractType, ITypeParameter
26  {
27    static ITypeParameter[] methodTypeParameters = { new DummyTypeParameter(SymbolKind.Method, 0) };
28    static ITypeParameter[] classTypeParameters = { new DummyTypeParameter(SymbolKind.TypeDefinition, 0) };
29   
30    public static ITypeParameter GetMethodTypeParameter(int index)
31    {
32      return GetTypeParameter(ref methodTypeParameters, SymbolKind.Method, index);
33    }
34   
35    public static ITypeParameter GetClassTypeParameter(int index)
36    {
37      return GetTypeParameter(ref classTypeParameters, SymbolKind.TypeDefinition, index);
38    }
39   
40    static ITypeParameter GetTypeParameter(ref ITypeParameter[] typeParameters, SymbolKind symbolKind, int index)
41    {
42      ITypeParameter[] tps = typeParameters;
43      while (index >= tps.Length) {
44        // We don't have a normal type parameter for this index, so we need to extend our array.
45        // Because the array can be used concurrently from multiple threads, we have to use
46        // Interlocked.CompareExchange.
47        ITypeParameter[] newTps = new ITypeParameter[index + 1];
48        tps.CopyTo(newTps, 0);
49        for (int i = tps.Length; i < newTps.Length; i++) {
50          newTps[i] = new DummyTypeParameter(symbolKind, i);
51        }
52        ITypeParameter[] oldTps = Interlocked.CompareExchange(ref typeParameters, newTps, tps);
53        if (oldTps == tps) {
54          // exchange successful
55          tps = newTps;
56        } else {
57          // exchange not successful
58          tps = oldTps;
59        }
60      }
61      return tps[index];
62    }
63   
64    sealed class NormalizeMethodTypeParametersVisitor : TypeVisitor
65    {
66      public override IType VisitTypeParameter(ITypeParameter type)
67      {
68        if (type.OwnerType == SymbolKind.Method) {
69          return DummyTypeParameter.GetMethodTypeParameter(type.Index);
70        } else {
71          return base.VisitTypeParameter(type);
72        }
73      }
74    }
75    sealed class NormalizeClassTypeParametersVisitor : TypeVisitor
76    {
77      public override IType VisitTypeParameter(ITypeParameter type)
78      {
79        if (type.OwnerType == SymbolKind.TypeDefinition) {
80          return DummyTypeParameter.GetClassTypeParameter(type.Index);
81        } else {
82          return base.VisitTypeParameter(type);
83        }
84      }
85    }
86   
87    static readonly NormalizeMethodTypeParametersVisitor normalizeMethodTypeParameters = new NormalizeMethodTypeParametersVisitor();
88    static readonly NormalizeClassTypeParametersVisitor normalizeClassTypeParameters = new NormalizeClassTypeParametersVisitor();
89   
90    /// <summary>
91    /// Replaces all occurrences of method type parameters in the given type
92    /// by normalized type parameters. This allows comparing parameter types from different
93    /// generic methods.
94    /// </summary>
95    public static IType NormalizeMethodTypeParameters(IType type)
96    {
97      return type.AcceptVisitor(normalizeMethodTypeParameters);
98    }
99   
100    /// <summary>
101    /// Replaces all occurrences of class type parameters in the given type
102    /// by normalized type parameters. This allows comparing parameter types from different
103    /// generic methods.
104    /// </summary>
105    public static IType NormalizeClassTypeParameters(IType type)
106    {
107      return type.AcceptVisitor(normalizeClassTypeParameters);
108    }
109   
110    /// <summary>
111    /// Replaces all occurrences of class and method type parameters in the given type
112    /// by normalized type parameters. This allows comparing parameter types from different
113    /// generic methods.
114    /// </summary>
115    public static IType NormalizeAllTypeParameters(IType type)
116    {
117      return type.AcceptVisitor(normalizeClassTypeParameters).AcceptVisitor(normalizeMethodTypeParameters);
118    }
119   
120    readonly SymbolKind ownerType;
121    readonly int index;
122   
123    private DummyTypeParameter(SymbolKind ownerType, int index)
124    {
125      this.ownerType = ownerType;
126      this.index = index;
127    }
128   
129    SymbolKind ISymbol.SymbolKind {
130      get { return SymbolKind.TypeParameter; }
131    }
132   
133    public override string Name {
134      get {
135        return (ownerType == SymbolKind.Method ? "!!" : "!") + index;
136      }
137    }
138   
139    public override string ReflectionName {
140      get {
141        return (ownerType == SymbolKind.Method ? "``" : "`") + index;
142      }
143    }
144   
145    public override string ToString()
146    {
147      return ReflectionName + " (dummy)";
148    }
149   
150    public override bool? IsReferenceType {
151      get { return null; }
152    }
153   
154    public override TypeKind Kind {
155      get { return TypeKind.TypeParameter; }
156    }
157   
158    public override ITypeReference ToTypeReference()
159    {
160      return TypeParameterReference.Create(ownerType, index);
161    }
162   
163    public override IType AcceptVisitor(TypeVisitor visitor)
164    {
165      return visitor.VisitTypeParameter(this);
166    }
167   
168    public int Index {
169      get { return index; }
170    }
171   
172    IList<IAttribute> ITypeParameter.Attributes {
173      get { return EmptyList<IAttribute>.Instance; }
174    }
175   
176    SymbolKind ITypeParameter.OwnerType {
177      get { return ownerType; }
178    }
179   
180    VarianceModifier ITypeParameter.Variance {
181      get { return VarianceModifier.Invariant; }
182    }
183   
184    DomRegion ITypeParameter.Region {
185      get { return DomRegion.Empty; }
186    }
187   
188    IEntity ITypeParameter.Owner {
189      get { return null; }
190    }
191   
192    IType ITypeParameter.EffectiveBaseClass {
193      get { return SpecialType.UnknownType; }
194    }
195   
196    ICollection<IType> ITypeParameter.EffectiveInterfaceSet {
197      get { return EmptyList<IType>.Instance; }
198    }
199   
200    bool ITypeParameter.HasDefaultConstructorConstraint {
201      get { return false; }
202    }
203   
204    bool ITypeParameter.HasReferenceTypeConstraint {
205      get { return false; }
206    }
207   
208    bool ITypeParameter.HasValueTypeConstraint {
209      get { return false; }
210    }
211
212    public ISymbolReference ToReference()
213    {
214      return new TypeParameterReference(ownerType, index);
215    }
216  }
217}
Note: See TracBrowser for help on using the repository browser.