1
ļ»æ// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team
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:
9
// The above copyright notice and this permission notice shall be included in all copies or
10
// substantial portions of the Software.
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.
20
using System.Collections.Generic;
21
using System.Threading;
23
namespace ICSharpCode.NRefactory.TypeSystem.Implementation
25
public sealed class DummyTypeParameter : AbstractType, ITypeParameter
27
static ITypeParameter[] methodTypeParameters = { new DummyTypeParameter(EntityType.Method, 0) };
28
static ITypeParameter[] classTypeParameters = { new DummyTypeParameter(EntityType.TypeDefinition, 0) };
30
public static ITypeParameter GetMethodTypeParameter(int index)
32
return GetTypeParameter(ref methodTypeParameters, EntityType.Method, index);
35
public static ITypeParameter GetClassTypeParameter(int index)
37
return GetTypeParameter(ref classTypeParameters, EntityType.TypeDefinition, index);
40
static ITypeParameter GetTypeParameter(ref ITypeParameter[] typeParameters, EntityType entityType, int index)
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(entityType, i);
52
ITypeParameter[] oldTps = Interlocked.CompareExchange(ref typeParameters, newTps, tps);
54
// exchange successful
57
// exchange not successful
64
sealed class NormalizeMethodTypeParametersVisitor : TypeVisitor
66
public override IType VisitTypeParameter(ITypeParameter type)
68
if (type.OwnerType == EntityType.Method) {
69
return DummyTypeParameter.GetMethodTypeParameter(type.Index);
71
return base.VisitTypeParameter(type);
75
sealed class NormalizeClassTypeParametersVisitor : TypeVisitor
77
public override IType VisitTypeParameter(ITypeParameter type)
79
if (type.OwnerType == EntityType.TypeDefinition) {
80
return DummyTypeParameter.GetClassTypeParameter(type.Index);
82
return base.VisitTypeParameter(type);
87
static readonly NormalizeMethodTypeParametersVisitor normalizeMethodTypeParameters = new NormalizeMethodTypeParametersVisitor();
88
static readonly NormalizeClassTypeParametersVisitor normalizeClassTypeParameters = new NormalizeClassTypeParametersVisitor();
91
/// Replaces all occurrences of method type parameters in the given type
92
/// by normalized type parameters. This allows comparing parameter types from different
95
public static IType NormalizeMethodTypeParameters(IType type)
97
return type.AcceptVisitor(normalizeMethodTypeParameters);
101
/// Replaces all occurrences of class type parameters in the given type
102
/// by normalized type parameters. This allows comparing parameter types from different
105
public static IType NormalizeClassTypeParameters(IType type)
107
return type.AcceptVisitor(normalizeClassTypeParameters);
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
115
public static IType NormalizeAllTypeParameters(IType type)
117
return type.AcceptVisitor(normalizeClassTypeParameters).AcceptVisitor(normalizeMethodTypeParameters);
120
readonly EntityType ownerType;
123
private DummyTypeParameter(EntityType ownerType, int index)
125
this.ownerType = ownerType;
129
public override string Name {
131
return (ownerType == EntityType.Method ? "!!" : "!") + index;
135
public override string ReflectionName {
137
return (ownerType == EntityType.Method ? "``" : "`") + index;
141
public override string ToString()
143
return ReflectionName + " (dummy)";
146
public override bool? IsReferenceType {
150
public override TypeKind Kind {
151
get { return TypeKind.TypeParameter; }
154
public override ITypeReference ToTypeReference()
156
return TypeParameterReference.Create(ownerType, index);
159
public override IType AcceptVisitor(TypeVisitor visitor)
161
return visitor.VisitTypeParameter(this);
165
get { return index; }
168
IList<IAttribute> ITypeParameter.Attributes {
169
get { return EmptyList<IAttribute>.Instance; }
172
EntityType ITypeParameter.OwnerType {
173
get { return ownerType; }
176
VarianceModifier ITypeParameter.Variance {
177
get { return VarianceModifier.Invariant; }
180
DomRegion ITypeParameter.Region {
181
get { return DomRegion.Empty; }
184
IEntity ITypeParameter.Owner {
188
IType ITypeParameter.EffectiveBaseClass {
189
get { return SpecialType.UnknownType; }
192
ICollection<IType> ITypeParameter.EffectiveInterfaceSet {
193
get { return EmptyList<IType>.Instance; }
196
bool ITypeParameter.HasDefaultConstructorConstraint {
197
get { return false; }
200
bool ITypeParameter.HasReferenceTypeConstraint {
201
get { return false; }
204
bool ITypeParameter.HasValueTypeConstraint {
205
get { return false; }