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/ResolvedAttributeBlob.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: 5.4 KB
Line 
1//
2// ResolvedAttributeBlob.cs
3//
4// Author:
5//       Daniel Grunwald <daniel@danielgrunwald.de>
6//
7// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team
8//
9// Permission is hereby granted, free of charge, to any person obtaining a copy
10// of this software and associated documentation files (the "Software"), to deal
11// in the Software without restriction, including without limitation the rights
12// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13// copies of the Software, and to permit persons to whom the Software is
14// furnished to do so, subject to the following conditions:
15//
16// The above copyright notice and this permission notice shall be included in
17// all copies or substantial portions of the Software.
18//
19// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25// THE SOFTWARE.
26
27using System;
28using System.Collections.Generic;
29using System.Diagnostics;
30using System.Threading;
31using ICSharpCode.NRefactory.Semantics;
32using ICSharpCode.NRefactory.Utils;
33
34namespace ICSharpCode.NRefactory.TypeSystem.Implementation
35{
36  sealed class CecilResolvedAttribute : IAttribute
37  {
38    readonly ITypeResolveContext context;
39    readonly byte[] blob;
40    readonly IList<ITypeReference> ctorParameterTypes;
41    readonly IType attributeType;
42   
43    IMethod constructor;
44    volatile bool constructorResolved;
45   
46    IList<ResolveResult> positionalArguments;
47    IList<KeyValuePair<IMember, ResolveResult>> namedArguments;
48   
49    public CecilResolvedAttribute(ITypeResolveContext context, UnresolvedAttributeBlob unresolved)
50    {
51      this.context = context;
52      this.blob = unresolved.blob;
53      this.ctorParameterTypes = unresolved.ctorParameterTypes;
54      this.attributeType = unresolved.attributeType.Resolve(context);
55    }
56   
57    public CecilResolvedAttribute(ITypeResolveContext context, IType attributeType)
58    {
59      this.context = context;
60      this.attributeType = attributeType;
61      this.ctorParameterTypes = EmptyList<ITypeReference>.Instance;
62    }
63   
64    DomRegion IAttribute.Region {
65      get { return DomRegion.Empty; }
66    }
67   
68    public IType AttributeType {
69      get { return attributeType; }
70    }
71   
72    public IMethod Constructor {
73      get {
74        if (!constructorResolved) {
75          constructor = ResolveConstructor();
76          constructorResolved = true;
77        }
78        return constructor;
79      }
80    }
81   
82    IMethod ResolveConstructor()
83    {
84      var parameterTypes = ctorParameterTypes.Resolve(context);
85      foreach (var ctor in attributeType.GetConstructors(m => m.Parameters.Count == parameterTypes.Count)) {
86        bool ok = true;
87        for (int i = 0; i < parameterTypes.Count; i++) {
88          if (!ctor.Parameters[i].Type.Equals(parameterTypes[i])) {
89            ok = false;
90            break;
91          }
92        }
93        if (ok)
94          return ctor;
95      }
96      return null;
97    }
98   
99    public IList<ResolveResult> PositionalArguments {
100      get {
101        var result = LazyInit.VolatileRead(ref this.positionalArguments);
102        if (result != null) {
103          return result;
104        }
105        DecodeBlob();
106        return positionalArguments;
107      }
108    }
109   
110    public IList<KeyValuePair<IMember, ResolveResult>> NamedArguments {
111      get {
112        var result = LazyInit.VolatileRead(ref this.namedArguments);
113        if (result != null) {
114          return result;
115        }
116        DecodeBlob();
117        return namedArguments;
118      }
119    }
120   
121    public override string ToString()
122    {
123      return "[" + attributeType.ToString() + "(...)]";
124    }
125   
126    void DecodeBlob()
127    {
128      var positionalArguments = new List<ResolveResult>();
129      var namedArguments = new List<KeyValuePair<IMember, ResolveResult>>();
130      DecodeBlob(positionalArguments, namedArguments);
131      Interlocked.CompareExchange(ref this.positionalArguments, positionalArguments, null);
132      Interlocked.CompareExchange(ref this.namedArguments, namedArguments, null);
133    }
134   
135    void DecodeBlob(List<ResolveResult> positionalArguments, List<KeyValuePair<IMember, ResolveResult>> namedArguments)
136    {
137      if (blob == null)
138        return;
139      BlobReader reader = new BlobReader(blob, context.CurrentAssembly);
140      if (reader.ReadUInt16() != 0x0001) {
141        Debug.WriteLine("Unknown blob prolog");
142        return;
143      }
144      foreach (var ctorParameter in ctorParameterTypes.Resolve(context)) {
145        ResolveResult arg;
146        bool isError;
147        try {
148          arg = reader.ReadFixedArg (ctorParameter);
149          positionalArguments.Add(arg);
150          isError = arg.IsError;
151        } catch (Exception ex) {
152          Debug.WriteLine("Crash during blob decoding: " + ex);
153          isError = true;
154        }
155        if (isError) {
156          // After a decoding error, we must stop decoding the blob because
157          // we might have read too few bytes due to the error.
158          // Just fill up the remaining arguments with ErrorResolveResult:
159          while (positionalArguments.Count < ctorParameterTypes.Count)
160            positionalArguments.Add(ErrorResolveResult.UnknownError);
161          return;
162        }
163      }
164      try {
165        ushort numNamed = reader.ReadUInt16();
166        for (int i = 0; i < numNamed; i++) {
167          var namedArg = reader.ReadNamedArg(attributeType);
168          if (namedArg.Key != null)
169            namedArguments.Add(namedArg);
170        }
171      } catch (Exception ex) {
172        Debug.WriteLine("Crash during blob decoding: " + ex);
173      }
174    }
175  }
176}
Note: See TracBrowser for help on using the repository browser.