5 // Alexander Chebaturkin (chebaturkin@gmail.com)
7 // Copyright (C) 2011 Alexander Chebaturkin
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 using System.Collections.Generic;
34 using Mono.Collections.Generic;
36 namespace Mono.CodeContracts.Static.AST {
37 class Method : Member, IEquatable<Method> {
39 public delegate void MethodContractProvider (Method method);
42 private readonly MethodDefinition definition;
44 private MethodContract contract;
45 private MethodContractProvider method_contract_provider;
46 private List<Parameter> parameters;
47 private TypeNode returnType;
48 private This thisParameter;
50 public Method (MethodDefinition definition)
51 : base (NodeType.Method)
53 this.definition = definition;
56 private Method (MethodDefinition definition, Block block) : base (NodeType.Method)
58 this.definition = definition;
62 public bool HasGenericParameters
64 get { return this.definition.HasGenericParameters; }
67 public MethodDefinition Definition
69 get { return this.definition; }
72 public override TypeNode DeclaringType
74 get { return TypeNode.Create (this.definition.DeclaringType); }
77 public override Module Module
79 get { return new Module (this.definition.Module); }
82 public Method OverriddenMethod
86 if (!this.definition.HasOverrides)
88 return ParseMethodDefinition (this.definition.Overrides [0].Resolve ());
96 if (this.block == null)
97 this.block = ParseMethodBlock (this.definition);
100 set { this.block = value; }
103 public MethodContract MethodContract
107 if (this.contract == null && ContractProvider != null) {
108 MethodContractProvider provider = ContractProvider;
109 ContractProvider = null;
112 return this.contract;
116 this.contract = value;
118 this.contract.DeclaringMethod = this;
119 ContractProvider = null;
123 public MethodContractProvider ContractProvider
125 get { return this.method_contract_provider; }
129 this.method_contract_provider = null;
133 if (this.method_contract_provider != null)
134 this.method_contract_provider += value;
136 this.method_contract_provider = value;
138 this.contract = null;
145 get { return this.definition.IsFinal; }
150 get { return this.definition.HasBody; }
153 public override bool IsPrivate
155 get { return this.definition.IsPrivate; }
158 public override bool IsAssembly
160 get { return this.definition.IsAssembly; }
163 public override bool IsFamily
165 get { return this.definition.IsFamily; }
168 public override bool IsFamilyOrAssembly
170 get { return this.definition.IsFamilyOrAssembly; }
173 public override bool IsFamilyAndAssembly
175 get { return this.definition.IsFamilyAndAssembly; }
178 public override bool IsPublic
180 get { return this.definition.IsPublic; }
183 public bool IsProtected
185 get { return this.definition.IsFamily; }
188 public bool IsProtectedOrInternal
190 get { return this.definition.IsFamilyOrAssembly; }
193 public bool IsProtectedAndInternal
195 get { return this.definition.IsFamilyAndAssembly; }
200 get { return this.definition.Name; }
203 public string FullName
205 get { return this.definition.FullName; }
208 public bool HasOverrides
210 get { return this.definition.HasOverrides; }
213 public bool IsVirtual
215 get { return this.definition.IsVirtual; }
218 public override bool IsStatic
220 get { return this.definition.IsStatic; }
223 public bool IsNewSlot
225 get { return this.definition.IsNewSlot; }
228 public bool IsAbstract
230 get { return this.definition.IsAbstract; }
233 public bool IsConstructor
235 get { return this.definition.IsConstructor; }
238 public List<Parameter> Parameters
242 if (this.parameters == null)
243 this.parameters = this.definition.Parameters.Select (i => new Parameter (i)).ToList ();
244 return this.parameters;
246 set { this.parameters = value; }
249 public bool HasParameters
251 get { return Parameters != null && Parameters.Count > 0; }
254 public TypeNode ReturnType
258 if (this.returnType == null)
259 this.returnType = TypeNode.Create (this.definition.ReturnType);
260 return this.returnType;
262 set { this.returnType = value; }
267 get { return this.definition.IsSetter; }
272 get { return this.definition.IsGetter; }
275 public This ThisParameter
279 if (this.thisParameter == null && !IsStatic && DeclaringType != null)
280 ThisParameter = !DeclaringType.IsValueType ? new This (DeclaringType.SelfInstantiation ()) : new This (DeclaringType.SelfInstantiation ().GetReferenceType ());
281 return this.thisParameter;
285 this.thisParameter = value;
287 this.thisParameter.DeclaringMethod = this;
291 public Method DeclaringMethod { get; private set; }
293 public List<TypeNode> GenericParameters
297 Collection<GenericParameter> genericParameters = this.definition.GenericParameters;
298 if (genericParameters == null)
300 return genericParameters.Select (it => TypeNode.Create (it)).ToList ();
304 public IList<Local> Locals
308 Collection<VariableDefinition> variables = this.definition.Body.Variables;
309 if (variables == null)
311 return variables.Select (it => new Local (it)).ToList ();
315 public bool IsCompilerGenerated
317 get { return this.definition.IsCompilerControlled; }
320 #region IEquatable<Method> Members
321 public bool Equals (Method other)
323 return this.definition == other.definition;
327 public static Method ParseMethodDefinition (MethodDefinition methodDefinition)
329 Block methodBlock = ParseMethodBlock (methodDefinition);
331 return new Method (methodDefinition, methodBlock);
334 private static Block ParseMethodBlock (MethodDefinition methodDefinition)
336 var bp = new BodyParser (methodDefinition);
337 return new Block (bp.ParseBlocks ());
340 public override string ToString ()
342 return string.Format ("Method(Name: {0})", FullName);