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/DefaultUnresolvedParameter.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: 7.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.Text;
23using ICSharpCode.NRefactory.Semantics;
24using ICSharpCode.NRefactory.Utils;
25
26namespace ICSharpCode.NRefactory.TypeSystem.Implementation
27{
28  /// <summary>
29  /// Default implementation for IUnresolvedParameter.
30  /// </summary>
31  [Serializable]
32  public sealed class DefaultUnresolvedParameter : IUnresolvedParameter, IFreezable, ISupportsInterning
33  {
34    string name = string.Empty;
35    ITypeReference type = SpecialType.UnknownType;
36    IList<IUnresolvedAttribute> attributes;
37    IConstantValue defaultValue;
38    DomRegion region;
39    byte flags;
40   
41    public DefaultUnresolvedParameter()
42    {
43    }
44   
45    public DefaultUnresolvedParameter(ITypeReference type, string name)
46    {
47      if (type == null)
48        throw new ArgumentNullException("type");
49      if (name == null)
50        throw new ArgumentNullException("name");
51      this.type = type;
52      this.name = name;
53    }
54   
55    void FreezeInternal()
56    {
57      attributes = FreezableHelper.FreezeListAndElements(attributes);
58      FreezableHelper.Freeze(defaultValue);
59    }
60   
61    public string Name {
62      get { return name; }
63      set {
64        if (value == null)
65          throw new ArgumentNullException("value");
66        FreezableHelper.ThrowIfFrozen(this);
67        name = value;
68      }
69    }
70   
71    public ITypeReference Type {
72      get { return type; }
73      set {
74        if (value == null)
75          throw new ArgumentNullException("value");
76        FreezableHelper.ThrowIfFrozen(this);
77        type = value;
78      }
79    }
80   
81    public IList<IUnresolvedAttribute> Attributes {
82      get {
83        if (attributes == null)
84          attributes = new List<IUnresolvedAttribute>();
85        return attributes;
86      }
87    }
88   
89    public IConstantValue DefaultValue {
90      get { return defaultValue; }
91      set {
92        FreezableHelper.ThrowIfFrozen(this);
93        defaultValue = value;
94      }
95    }
96   
97    public DomRegion Region {
98      get { return region; }
99      set {
100        FreezableHelper.ThrowIfFrozen(this);
101        region = value;
102      }
103    }
104   
105    bool HasFlag(byte flag)
106    {
107      return (this.flags & flag) != 0;
108    }
109    void SetFlag(byte flag, bool value)
110    {
111      FreezableHelper.ThrowIfFrozen(this);
112      if (value)
113        this.flags |= flag;
114      else
115        this.flags &= unchecked((byte)~flag);
116    }
117   
118    public bool IsFrozen {
119      get { return HasFlag(1); }
120    }
121   
122    public void Freeze()
123    {
124      if (!this.IsFrozen) {
125        FreezeInternal();
126        this.flags |= 1;
127      }
128    }
129   
130    public bool IsRef {
131      get { return HasFlag(2); }
132      set { SetFlag(2, value); }
133    }
134   
135    public bool IsOut {
136      get { return HasFlag(4); }
137      set { SetFlag(4, value); }
138    }
139   
140    public bool IsParams {
141      get { return HasFlag(8); }
142      set { SetFlag(8, value); }
143    }
144   
145    public bool IsOptional {
146      get { return this.DefaultValue != null; }
147    }
148   
149    int ISupportsInterning.GetHashCodeForInterning()
150    {
151      unchecked {
152        int hashCode = 1919191 ^ (flags & ~1);
153        hashCode *= 31;
154        hashCode += type.GetHashCode();
155        hashCode *= 31;
156        hashCode += name.GetHashCode();
157        if (attributes != null) {
158          foreach (var attr in attributes)
159            hashCode ^= attr.GetHashCode ();
160        }
161        if (defaultValue != null)
162          hashCode ^= defaultValue.GetHashCode ();
163        return hashCode;
164      }
165    }
166   
167    bool ISupportsInterning.EqualsForInterning(ISupportsInterning other)
168    {
169      // compare everything except for the IsFrozen flag
170      DefaultUnresolvedParameter p = other as DefaultUnresolvedParameter;
171      return p != null && type == p.type && name == p.name &&
172        defaultValue == p.defaultValue && region == p.region && (flags & ~1) == (p.flags & ~1) && ListEquals(attributes, p.attributes);
173    }
174   
175    static bool ListEquals(IList<IUnresolvedAttribute> list1, IList<IUnresolvedAttribute> list2)
176    {
177      return (list1 ?? EmptyList<IUnresolvedAttribute>.Instance).SequenceEqual(list2 ?? EmptyList<IUnresolvedAttribute>.Instance);
178    }
179   
180    public override string ToString()
181    {
182      StringBuilder b = new StringBuilder();
183      if (IsRef)
184        b.Append("ref ");
185      if (IsOut)
186        b.Append("out ");
187      if (IsParams)
188        b.Append("params ");
189      b.Append(name);
190      b.Append(':');
191      b.Append(type.ToString());
192      if (defaultValue != null) {
193        b.Append(" = ");
194        b.Append(defaultValue.ToString());
195      }
196      return b.ToString();
197    }
198
199    static bool IsOptionalAttribute (IType attributeType)
200    {
201      return attributeType.Name == "OptionalAttribute" && attributeType.Namespace == "System.Runtime.InteropServices";
202    }
203   
204    public IParameter CreateResolvedParameter(ITypeResolveContext context)
205    {
206      Freeze();
207      if (defaultValue != null) {
208        return new ResolvedParameterWithDefaultValue(defaultValue, context) {
209          Type = type.Resolve(context),
210          Name = name,
211          Region = region,
212          Attributes = attributes.CreateResolvedAttributes(context),
213          IsRef = this.IsRef,
214          IsOut = this.IsOut,
215          IsParams = this.IsParams
216        };
217      } else {
218        var owner = context.CurrentMember as IParameterizedMember;
219        var resolvedAttributes = attributes.CreateResolvedAttributes (context);
220        bool isOptional = resolvedAttributes != null && resolvedAttributes.Any (a => IsOptionalAttribute (a.AttributeType));
221        return new DefaultParameter (type.Resolve (context), name, owner, region,
222                                     resolvedAttributes, IsRef, IsOut, IsParams, isOptional);
223      }
224    }
225   
226    sealed class ResolvedParameterWithDefaultValue : IParameter
227    {
228      readonly IConstantValue defaultValue;
229      readonly ITypeResolveContext context;
230     
231      public ResolvedParameterWithDefaultValue(IConstantValue defaultValue, ITypeResolveContext context)
232      {
233        this.defaultValue = defaultValue;
234        this.context = context;
235      }
236     
237      SymbolKind ISymbol.SymbolKind { get { return SymbolKind.Parameter; } }
238      public IParameterizedMember Owner { get { return context.CurrentMember as IParameterizedMember; } }
239      public IType Type { get; internal set; }
240      public string Name { get; internal set; }
241      public DomRegion Region { get; internal set; }
242      public IList<IAttribute> Attributes { get; internal set; }
243      public bool IsRef { get; internal set; }
244      public bool IsOut { get; internal set; }
245      public bool IsParams { get; internal set; }
246      public bool IsOptional { get { return true; } }
247      bool IVariable.IsConst { get { return false; } }
248     
249      ResolveResult resolvedDefaultValue;
250     
251      public object ConstantValue {
252        get {
253          ResolveResult rr = LazyInit.VolatileRead(ref this.resolvedDefaultValue);
254          if (rr == null) {
255            rr = defaultValue.Resolve(context);
256            LazyInit.GetOrSet(ref this.resolvedDefaultValue, rr);
257          }
258          return rr.ConstantValue;
259        }
260      }
261     
262      public override string ToString()
263      {
264        return DefaultParameter.ToString(this);
265      }
266
267      public ISymbolReference ToReference()
268      {
269        if (Owner == null)
270          return new ParameterReference(Type.ToTypeReference(), Name, Region, IsRef, IsOut, IsParams, true, ConstantValue);
271        return new OwnedParameterReference(Owner.ToReference(), Owner.Parameters.IndexOf(this));
272      }
273    }
274  }
275}
Note: See TracBrowser for help on using the repository browser.