Free cookie consent management tool by TermsFeed Policy Generator

source: tags/3.3.13/HeuristicLab.ExtLibs/HeuristicLab.NRefactory/5.5.0/NRefactory-5.5.0/TypeSystem/Implementation/DefaultResolvedTypeParameter.cs @ 18242

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

#2077: created branch and added first version

File size: 8.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.Linq;
22using System.Threading;
23using ICSharpCode.NRefactory.Utils;
24
25namespace ICSharpCode.NRefactory.TypeSystem.Implementation
26{
27  public class DefaultTypeParameter : AbstractTypeParameter
28  {
29    readonly bool hasValueTypeConstraint;
30    readonly bool hasReferenceTypeConstraint;
31    readonly bool hasDefaultConstructorConstraint;
32    readonly IList<IType> constraints;
33   
34    public DefaultTypeParameter(
35      IEntity owner,
36      int index, string name = null,
37      VarianceModifier variance = VarianceModifier.Invariant,
38      IList<IAttribute> attributes = null,
39      DomRegion region = default(DomRegion),
40      bool hasValueTypeConstraint = false, bool hasReferenceTypeConstraint = false, bool hasDefaultConstructorConstraint = false,
41      IList<IType> constraints = null)
42      : base(owner, index, name, variance, attributes, region)
43    {
44      this.hasValueTypeConstraint = hasValueTypeConstraint;
45      this.hasReferenceTypeConstraint = hasReferenceTypeConstraint;
46      this.hasDefaultConstructorConstraint = hasDefaultConstructorConstraint;
47      this.constraints = constraints ?? EmptyList<IType>.Instance;
48    }
49   
50    public DefaultTypeParameter(
51      ICompilation compilation, SymbolKind ownerType,
52      int index, string name = null,
53      VarianceModifier variance = VarianceModifier.Invariant,
54      IList<IAttribute> attributes = null,
55      DomRegion region = default(DomRegion),
56      bool hasValueTypeConstraint = false, bool hasReferenceTypeConstraint = false, bool hasDefaultConstructorConstraint = false,
57      IList<IType> constraints = null)
58      : base(compilation, ownerType, index, name, variance, attributes, region)
59    {
60      this.hasValueTypeConstraint = hasValueTypeConstraint;
61      this.hasReferenceTypeConstraint = hasReferenceTypeConstraint;
62      this.hasDefaultConstructorConstraint = hasDefaultConstructorConstraint;
63      this.constraints = constraints ?? EmptyList<IType>.Instance;
64    }
65   
66    public override bool HasValueTypeConstraint {
67      get { return hasValueTypeConstraint; }
68    }
69   
70    public override bool HasReferenceTypeConstraint {
71      get { return hasReferenceTypeConstraint; }
72    }
73   
74    public override bool HasDefaultConstructorConstraint {
75      get { return hasDefaultConstructorConstraint; }
76    }
77   
78    public override IEnumerable<IType> DirectBaseTypes {
79      get {
80        bool hasNonInterfaceConstraint = false;
81        foreach (IType c in constraints) {
82          yield return c;
83          if (c.Kind != TypeKind.Interface)
84            hasNonInterfaceConstraint = true;
85        }
86        // Do not add the 'System.Object' constraint if there is another constraint with a base class.
87        if (this.HasValueTypeConstraint || !hasNonInterfaceConstraint) {
88          yield return this.Compilation.FindType(this.HasValueTypeConstraint ? KnownTypeCode.ValueType : KnownTypeCode.Object);
89        }
90      }
91    }
92  }
93 
94  /*
95  /// <summary>
96  /// Default implementation of <see cref="ITypeParameter"/>.
97  /// </summary>
98  [Serializable]
99  public sealed class DefaultTypeParameter : AbstractTypeParameter
100  {
101    IList<ITypeReference> constraints;
102   
103    BitVector16 flags;
104   
105    const ushort FlagReferenceTypeConstraint      = 0x0001;
106    const ushort FlagValueTypeConstraint          = 0x0002;
107    const ushort FlagDefaultConstructorConstraint = 0x0004;
108   
109    protected override void FreezeInternal()
110    {
111      constraints = FreezeList(constraints);
112      base.FreezeInternal();
113    }
114   
115    public DefaultTypeParameter(SymbolKind ownerType, int index, string name)
116      : base(ownerType, index, name)
117    {
118    }
119   
120    public IList<ITypeReference> Constraints {
121      get {
122        if (constraints == null)
123          constraints = new List<ITypeReference>();
124        return constraints;
125      }
126    }
127   
128    public bool HasDefaultConstructorConstraint {
129      get { return flags[FlagDefaultConstructorConstraint]; }
130      set {
131        CheckBeforeMutation();
132        flags[FlagDefaultConstructorConstraint] = value;
133      }
134    }
135   
136    public bool HasReferenceTypeConstraint {
137      get { return flags[FlagReferenceTypeConstraint]; }
138      set {
139        CheckBeforeMutation();
140        flags[FlagReferenceTypeConstraint] = value;
141      }
142    }
143   
144    public bool HasValueTypeConstraint {
145      get { return flags[FlagValueTypeConstraint]; }
146      set {
147        CheckBeforeMutation();
148        flags[FlagValueTypeConstraint] = value;
149      }
150    }
151   
152    public override bool? IsReferenceType(ITypeResolveContext context)
153    {
154      switch (flags.Data & (FlagReferenceTypeConstraint | FlagValueTypeConstraint)) {
155        case FlagReferenceTypeConstraint:
156          return true;
157        case FlagValueTypeConstraint:
158          return false;
159      }
160     
161      return base.IsReferenceTypeHelper(GetEffectiveBaseClass(context));
162    }
163   
164    public override IType GetEffectiveBaseClass(ITypeResolveContext context)
165    {
166      // protect against cyclic type parameters
167      using (var busyLock = BusyManager.Enter(this)) {
168        if (!busyLock.Success)
169          return SpecialTypes.UnknownType;
170       
171        if (HasValueTypeConstraint)
172          return context.GetTypeDefinition("System", "ValueType", 0, StringComparer.Ordinal) ?? SpecialTypes.UnknownType;
173       
174        List<IType> classTypeConstraints = new List<IType>();
175        foreach (ITypeReference constraintRef in this.Constraints) {
176          IType constraint = constraintRef.Resolve(context);
177          if (constraint.Kind == TypeKind.Class) {
178            classTypeConstraints.Add(constraint);
179          } else if (constraint.Kind == TypeKind.TypeParameter) {
180            IType baseClass = ((ITypeParameter)constraint).GetEffectiveBaseClass(context);
181            if (baseClass.Kind == TypeKind.Class)
182              classTypeConstraints.Add(baseClass);
183          }
184        }
185        if (classTypeConstraints.Count == 0)
186          return KnownTypeReference.Object.Resolve(context);
187        // Find the derived-most type in the resulting set:
188        IType result = classTypeConstraints[0];
189        for (int i = 1; i < classTypeConstraints.Count; i++) {
190          if (classTypeConstraints[i].GetDefinition().IsDerivedFrom(result.GetDefinition(), context))
191            result = classTypeConstraints[i];
192        }
193        return result;
194      }
195    }
196   
197    public override IEnumerable<IType> GetEffectiveInterfaceSet(ITypeResolveContext context)
198    {
199      List<IType> result = new List<IType>();
200      // protect against cyclic type parameters
201      using (var busyLock = BusyManager.Enter(this)) {
202        if (busyLock.Success) {
203          foreach (ITypeReference constraintRef in this.Constraints) {
204            IType constraint = constraintRef.Resolve(context);
205            if (constraint.Kind == TypeKind.Interface) {
206              result.Add(constraint);
207            } else if (constraint.Kind == TypeKind.TypeParameter) {
208              result.AddRange(((ITypeParameter)constraint).GetEffectiveInterfaceSet(context));
209            }
210          }
211        }
212      }
213      return result.Distinct();
214    }
215   
216    public override ITypeParameterConstraints GetConstraints(ITypeResolveContext context)
217    {
218      return new DefaultTypeParameterConstraints(
219        this.Constraints.Select(c => c.Resolve(context)),
220        this.HasDefaultConstructorConstraint, this.HasReferenceTypeConstraint, this.HasValueTypeConstraint);
221    }
222   
223    /*
224   * Interning for type parameters is disabled; we can't intern cyclic structures as might
225   * occur in the constraints, and incomplete interning is dangerous for type parameters
226   * as we use reference equality.
227    void ISupportsInterning.PrepareForInterning(IInterningProvider provider)
228    {
229      // protect against cyclic constraints
230      using (var busyLock = BusyManager.Enter(this)) {
231        if (busyLock.Success) {
232          constraints = provider.InternList(constraints);
233          base.PrepareForInterning(provider);
234        }
235      }
236    }
237   
238    int ISupportsInterning.GetHashCodeForInterning()
239    {
240      unchecked {
241        int hashCode = base.GetHashCodeForInterning();
242        if (constraints != null)
243          hashCode += constraints.GetHashCode();
244        hashCode += 771 * flags.Data;
245        return hashCode;
246      }
247    }
248   
249    bool ISupportsInterning.EqualsForInterning(ISupportsInterning other)
250    {
251      DefaultTypeParameter o = other as DefaultTypeParameter;
252      return base.EqualsForInterning(o)
253        && this.constraints == o.constraints
254        && this.flags == o.flags;
255    }
256  }*/
257}
Note: See TracBrowser for help on using the repository browser.