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 namespace Mono.CodeContracts.Static.AST {
35 class TypeNode : Member, IEquatable<TypeNode> {
36 private TypeNode base_type;
37 private List<Method> methods;
38 private List<TypeNode> nestedTypes;
39 private List<Property> properties;
41 protected TypeNode () : base (NodeType.TypeNode)
45 protected TypeNode (NodeType nodeType)
50 protected TypeNode (TypeReference typeReference) : this ()
52 TypeDefinition = typeReference as TypeDefinition ?? typeReference.Resolve ();
55 public TypeDefinition TypeDefinition { get; set; }
57 public IEnumerable<TypeNode> Interfaces
61 if (TypeDefinition == null)
63 return TypeDefinition.Interfaces.Select (i => new TypeNode (i));
67 public TypeNode BaseType
71 if (this.base_type == null && TypeDefinition != null)
72 this.base_type = new TypeNode (TypeDefinition.BaseType);
73 return this.base_type;
75 set { this.base_type = value; }
78 public virtual string FullName
80 get { return TypeDefinition == null ? "<null>" : TypeDefinition.FullName; }
83 public List<Property> Properties
87 if (this.properties == null)
88 this.properties = TypeDefinition.Properties.Select (it => new Property (it)).ToList ();
89 return this.properties;
91 set { this.properties = value; }
94 public List<Method> Methods
98 if (this.methods == null)
99 this.methods = TypeDefinition.Methods.Select (it => new Method (it)).ToList ();
102 set { this.methods = value; }
105 public List<TypeNode> NestedTypes
109 if (this.nestedTypes == null)
110 this.nestedTypes = TypeDefinition.NestedTypes.Select (it => new TypeNode (it)).ToList ();
111 return this.nestedTypes;
113 set { this.nestedTypes = value; }
116 public virtual string Name
118 get { return TypeDefinition.Name; }
121 public static TypeNode Create (TypeReference typeReference)
123 TypeDefinition typeDefinition = typeReference.Resolve ();
124 if (typeDefinition == null)
126 if (typeDefinition.IsClass)
127 return new Class (typeDefinition);
129 return new TypeNode (typeDefinition);
132 public bool IsAssignableTo (TypeNode targetType)
134 if (this == CoreSystemTypes.Instance.TypeVoid)
136 if (targetType == this)
138 if (this == CoreSystemTypes.Instance.TypeObject)
140 if (targetType == CoreSystemTypes.Instance.TypeObject || BaseType.IsAssignableTo (targetType))
142 IEnumerable<TypeNode> interfaces = Interfaces;
143 if (interfaces == null || !interfaces.Any ())
145 foreach (TypeNode iface in interfaces) {
146 if (iface != null && iface.IsAssignableTo (targetType))
152 public TypeNode GetReferenceType ()
154 return new Reference (this);
157 public override string ToString ()
159 return string.Format ("Type({0})", FullName);
162 public TypeNode SelfInstantiation ()
164 //todo: implement this for generic
168 public TypeNode GetArrayType (int rank)
170 return new ArrayTypeNode (this, 0, rank);
173 #region Implementation of IEquatable<TypeNode>
174 public bool Equals (TypeNode other)
176 return TypeDefinition == other.TypeDefinition;
179 public override int GetHashCode ()
181 return TypeDefinition.GetHashCode ();
184 public override bool Equals (object obj)
186 return Equals (obj as TypeNode);
190 #region Overrides of Member
191 private int classSize;
192 private bool classSizeSpecified;
194 public override bool IsStatic
196 get { return false; }
199 public override TypeNode DeclaringType
201 get { return Create (TypeDefinition.DeclaringType); }
204 public override Module Module
208 if (TypeDefinition == null)
210 return new Module (TypeDefinition.Module);
214 public override bool IsPublic
216 get { return TypeDefinition != null && TypeDefinition.IsPublic; }
219 public override bool IsAssembly
221 get { return TypeDefinition != null && TypeDefinition.IsNotPublic; }
224 public override bool IsPrivate
226 get { return false; }
229 public override bool IsFamily
231 get { return false; }
234 public override bool IsFamilyOrAssembly
236 get { return IsFamily || IsAssembly; }
239 public override bool IsFamilyAndAssembly
241 get { return IsFamily && IsAssembly; }
244 public virtual bool IsValueType
246 get { return TypeDefinition != null && TypeDefinition.IsValueType; }
249 public virtual bool IsStruct
251 get { return TypeDefinition != null && TypeDefinition.IsValueType; }
254 public virtual bool IsArray
256 get { return TypeDefinition != null && TypeDefinition.IsArray; }
259 public virtual bool IsInterface
261 get { return TypeDefinition != null && TypeDefinition.IsInterface; }
264 public virtual bool HasGenericParameters
266 get { return TypeDefinition != null && TypeDefinition.HasGenericParameters; }
269 public virtual bool IsNestedFamily
271 get { return TypeDefinition != null && TypeDefinition.IsNestedFamily; }
274 public virtual bool IsNestedPublic
276 get { return TypeDefinition != null && TypeDefinition.IsNestedPublic; }
279 public virtual bool IsNestedInternal
281 get { return TypeDefinition != null && TypeDefinition.IsNestedAssembly; }
284 public virtual bool IsNestedFamilyAndAssembly
286 get { return TypeDefinition != null && TypeDefinition.IsNestedFamilyAndAssembly; }
289 public virtual bool IsNestedAssembly
291 get { return TypeDefinition != null && TypeDefinition.IsNestedAssembly; }
294 public virtual bool IsPrimitive
296 get { return TypeDefinition != null && TypeDefinition.IsPrimitive; }
299 public virtual bool IsEnum
301 get { return TypeDefinition != null && TypeDefinition.IsEnum; }
304 public virtual bool IsClass
306 get { return TypeDefinition != null && TypeDefinition.IsClass; }
309 public virtual IEnumerable<Field> Fields
313 if (TypeDefinition == null)
315 return TypeDefinition.Fields.Select (it => new Field (it));
323 if (!this.classSizeSpecified && TypeDefinition != null)
324 ClassSize = TypeDefinition.ClassSize;
325 return this.classSize;
329 this.classSize = value;
330 this.classSizeSpecified = true;