Free cookie consent management tool by TermsFeed Policy Generator

source: branches/CodeEditor/HeuristicLab.ExtLibs/HeuristicLab.NRefactory/5.5.0/NRefactory.CSharp-5.5.0/TypeSystem/CSharpAttribute.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.2 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.Collections.ObjectModel;
22using System.Diagnostics;
23using System.Linq;
24using ICSharpCode.NRefactory.CSharp.Resolver;
25using ICSharpCode.NRefactory.Semantics;
26using ICSharpCode.NRefactory.TypeSystem;
27using ICSharpCode.NRefactory.TypeSystem.Implementation;
28using ICSharpCode.NRefactory.Utils;
29
30namespace ICSharpCode.NRefactory.CSharp.TypeSystem
31{
32  [Serializable]
33  public sealed class CSharpAttribute : IUnresolvedAttribute
34  {
35    ITypeReference attributeType;
36    DomRegion region;
37    IList<IConstantValue> positionalArguments;
38    IList<KeyValuePair<string, IConstantValue>> namedCtorArguments;
39    IList<KeyValuePair<string, IConstantValue>> namedArguments;
40   
41    public CSharpAttribute(ITypeReference attributeType, DomRegion region,
42                           IList<IConstantValue> positionalArguments,
43                           IList<KeyValuePair<string, IConstantValue>> namedCtorArguments,
44                           IList<KeyValuePair<string, IConstantValue>> namedArguments)
45    {
46      if (attributeType == null)
47        throw new ArgumentNullException("attributeType");
48      this.attributeType = attributeType;
49      this.region = region;
50      this.positionalArguments = positionalArguments ?? EmptyList<IConstantValue>.Instance;
51      this.namedCtorArguments = namedCtorArguments ?? EmptyList<KeyValuePair<string, IConstantValue>>.Instance;
52      this.namedArguments = namedArguments ?? EmptyList<KeyValuePair<string, IConstantValue>>.Instance;
53    }
54   
55    public DomRegion Region {
56      get { return region; }
57    }
58   
59    public ITypeReference AttributeType {
60      get { return attributeType; }
61    }
62   
63    public IAttribute CreateResolvedAttribute(ITypeResolveContext context)
64    {
65      return new CSharpResolvedAttribute((CSharpTypeResolveContext)context, this);
66    }
67   
68    sealed class CSharpResolvedAttribute : IAttribute
69    {
70      readonly CSharpTypeResolveContext context;
71      readonly CSharpAttribute unresolved;
72      readonly IType attributeType;
73     
74      IList<KeyValuePair<IMember, ResolveResult>> namedArguments;
75     
76      public CSharpResolvedAttribute(CSharpTypeResolveContext context, CSharpAttribute unresolved)
77      {
78        this.context = context;
79        this.unresolved = unresolved;
80        // Pretty much any access to the attribute checks the type first, so
81        // we don't need to use lazy-loading for that.
82        this.attributeType = unresolved.AttributeType.Resolve(context);
83      }
84     
85      DomRegion IAttribute.Region {
86        get { return unresolved.Region; }
87      }
88     
89      IType IAttribute.AttributeType {
90        get { return attributeType; }
91      }
92     
93      ResolveResult ctorInvocation;
94     
95      InvocationResolveResult GetCtorInvocation()
96      {
97        ResolveResult rr = LazyInit.VolatileRead(ref this.ctorInvocation);
98        if (rr != null) {
99          return rr as InvocationResolveResult;
100        } else {
101          CSharpResolver resolver = new CSharpResolver(context);
102          int totalArgumentCount = unresolved.positionalArguments.Count + unresolved.namedCtorArguments.Count;
103          ResolveResult[] arguments = new ResolveResult[totalArgumentCount];
104          string[] argumentNames = new string[totalArgumentCount];
105          int i = 0;
106          while (i < unresolved.positionalArguments.Count) {
107            IConstantValue cv = unresolved.positionalArguments[i];
108            arguments[i] = cv.Resolve(context);
109            i++;
110          }
111          foreach (var pair in unresolved.namedCtorArguments) {
112            argumentNames[i] = pair.Key;
113            arguments[i] = pair.Value.Resolve(context);
114            i++;
115          }
116          rr = resolver.ResolveObjectCreation(attributeType, arguments, argumentNames);
117          return LazyInit.GetOrSet(ref this.ctorInvocation, rr) as InvocationResolveResult;
118        }
119      }
120     
121      IMethod IAttribute.Constructor {
122        get {
123          var invocation = GetCtorInvocation();
124          if (invocation != null)
125            return invocation.Member as IMethod;
126          else
127            return null;
128        }
129      }
130     
131      IList<ResolveResult> positionalArguments;
132     
133      IList<ResolveResult> IAttribute.PositionalArguments {
134        get {
135          var result = LazyInit.VolatileRead(ref this.positionalArguments);
136          if (result != null) {
137            return result;
138          } else {
139            var invocation = GetCtorInvocation();
140            if (invocation != null)
141              result = invocation.GetArgumentsForCall();
142            else
143              result = EmptyList<ResolveResult>.Instance;
144            return LazyInit.GetOrSet(ref this.positionalArguments, result);
145          }
146        }
147      }
148     
149      IList<KeyValuePair<IMember, ResolveResult>> IAttribute.NamedArguments {
150        get {
151          var namedArgs = LazyInit.VolatileRead(ref this.namedArguments);
152          if (namedArgs != null) {
153            return namedArgs;
154          } else {
155            namedArgs = new List<KeyValuePair<IMember, ResolveResult>>();
156            foreach (var pair in unresolved.namedArguments) {
157              IMember member = attributeType.GetMembers(m => (m.SymbolKind == SymbolKind.Field || m.SymbolKind == SymbolKind.Property) && m.Name == pair.Key).FirstOrDefault();
158              if (member != null) {
159                ResolveResult val = pair.Value.Resolve(context);
160                namedArgs.Add(new KeyValuePair<IMember, ResolveResult>(member, val));
161              }
162            }
163            return LazyInit.GetOrSet(ref this.namedArguments, namedArgs);
164          }
165        }
166      }
167    }
168  }
169}
Note: See TracBrowser for help on using the repository browser.