The StaDyn Programming Language
Source code documentation of StaDyn, a hybrid static and dynamic typing language.
Instrospection.cs
Go to the documentation of this file.
1 // -------------------------------------------------------------------------- //
3 // Project rROTOR //
4 // -------------------------------------------------------------------------- //
5 // File: Instrospection.cs //
6 // Authors: Cristina Gonzalez Muņoz - cristi.gm@gmail.com //
7 // Francisco Ortin - francisco.ortin@gmail.com //
8 // Description: //
9 // Represents a type obtained using introspection. //
10 // Implements Composite pattern [Composite]. //
11 // Implements Adapter pattern [Adaptee].
12 // -------------------------------------------------------------------------- //
13 // Create date: 31-01-2007 //
14 // Modification date: 06-04-2007 //
16 
17 using System;
18 using System.Collections.Generic;
19 using System.Reflection;
20 using System.Text;
21 
22 using AST;
23 using ErrorManagement;
24 
25 namespace TypeSystem {
33  class Introspection {
34  #region Fields
35 
39  private Type reflectionType;
40 
44  private IBCLUserType userType;
45 
46  #endregion
47 
48  #region Properties
49 
53  public Type TypeInfo {
54  get { return this.reflectionType; }
55  }
56 
57  #endregion
58 
59  #region Constructor
60 
66  public Introspection(IBCLUserType userType, Type type) {
67  this.reflectionType = type;
68  this.userType = userType;
69  }
70 
71  #endregion
72 
79  #region createBCLUserType()
80  public static TypeExpression createBCLUserType(string name, System.Type type, Location location) {
81  if ((type.IsClass) || (type.IsValueType))
82  return new BCLClassType(name, type);
83  if (type.IsInterface)
84  return new BCLInterfaceType(name, type);
85  throw new ArgumentException(String.Format("The type '{0}' is not a class, nor an interface.", type));
86  }
87  #endregion
88 
89  #region createMethod
90  private void createMethods(MethodInfo[] methods, Location location) {
98  AccessModifier accessModifierInfo;
99  MethodType mt;
100  foreach (MethodInfo method in methods) {
101  mt = new MethodType(TypeTable.Instance.GetType(method.ReturnType.FullName, location));
102  ParameterInfo[] parameters = method.GetParameters();
103  for (int j = 0; j < parameters.GetLength(0); j++)
104  if (parameters[j].ParameterType.FullName!=null)
105  mt.AddParameter(TypeTable.Instance.GetType(parameters[j].ParameterType.FullName, location));
106 
107  List<Modifier> mods = getMethodModifierList(method);
108 
109  accessModifierInfo = new AccessModifier(mods, method.Name, mt, false);
110  mt.MemberInfo = accessModifierInfo;
111  accessModifierInfo.Class = (UserType)userType;
112 
113  if (userType.Members.ContainsKey(method.Name)) {
114  if (!(userType.Members[method.Name].Type is IntersectionType)) // * It is not an intersection
115  // * An intersection type must be created
116  userType.Members[method.Name].Type = new IntersectionMemberType(userType.Members[method.Name].Type);
117  // * The type is added
118  ((IntersectionType)userType.Members[method.Name].Type).AddType(mt);
119  }
120  else
121  userType.AddMember(method.Name, accessModifierInfo);
122  accessModifierInfo.Type.BuildTypeExpressionString(TypeExpression.MAX_DEPTH_LEVEL_TYPE_EXPRESSION);
123  }
124  }
125 
126  #endregion
127 
128  #region createField()
129 
138  private FieldType createField(FieldInfo field, Location location) {
139  AccessModifier accessModifierInfo;
140  FieldType ft = new FieldType(TypeTable.Instance.GetType(field.FieldType.FullName, location));
141 
142  List<Modifier> mods = getFieldModifierList(field);
143 
144  accessModifierInfo = new AccessModifier(mods, field.Name, ft, false);
145  ft.MemberInfo = accessModifierInfo;
146  accessModifierInfo.Class = (UserType)userType;
147 
148  userType.AddMember(field.Name, accessModifierInfo);
149 
150  accessModifierInfo.Type.BuildTypeExpressionString(TypeExpression.MAX_DEPTH_LEVEL_TYPE_EXPRESSION);
151 
152  return ft;
153  }
154 
155  #endregion
156 
157  #region createProperty()
158 
168  private PropertyType createProperty(PropertyInfo prop, Location location) {
169  AccessModifier accessModifierInfo;
170  PropertyType pt = new PropertyType(TypeTable.Instance.GetType(prop.PropertyType.FullName, location), prop.CanRead, prop.CanWrite);
171 
172  // * The modifiers of a X property are the ones of the get_X method
173  MethodInfo methodInfo;
174  if (prop.CanRead)
175  methodInfo = userType.TypeInfo.GetMethod("get_" + prop.Name);
176  else
177  methodInfo = userType.TypeInfo.GetMethod("set_" + prop.Name);
178  List<Modifier> mods = getMethodModifierList(methodInfo);
179  mods = getPropertyModifierList(prop, mods);
180 
181  accessModifierInfo = new AccessModifier(mods, prop.Name, pt, false);
182  pt.MemberInfo = accessModifierInfo;
183  accessModifierInfo.Class = (UserType)userType;
184 
185  userType.Members[prop.Name] = accessModifierInfo;
186  accessModifierInfo.Type.BuildTypeExpressionString(TypeExpression.MAX_DEPTH_LEVEL_TYPE_EXPRESSION);
187 
188  return pt;
189  }
190 
191  #endregion
192 
193  // WriteType inference
194 
195  #region FindMember()
196  public TypeExpression FindMember(string memberName, Location location) {
207  TypeExpression member = this.FindMember(memberName);
208  if (member == null)
209  ErrorManager.Instance.NotifyError(new UnknownMemberError(memberName, location));
210  return member;
211  }
219  public TypeExpression FindMember(string memberName) {
220  FieldInfo fieldInfo;
221  MethodInfo[] methodsInfo;
222  PropertyInfo propertyInfo;
223  BindingFlags flags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly;
224 
225  // * Has been previously found?
226  if (userType.Members.ContainsKey(memberName))
227  return userType.Members[memberName].Type;
228 
229  // * Retrieve from the BCL by means of introspection
230  if ((fieldInfo = reflectionType.GetField(memberName, flags)) != null)
231  return createField(fieldInfo, new Location());
232 
233  if ((propertyInfo = reflectionType.GetProperty(memberName, flags)) != null)
234  return createProperty(propertyInfo, new Location());
235 
236  if ((methodsInfo = reflectionType.GetMethods(flags)) != null) {
237  createMethods(methodsInfo, new Location());
238  if (!userType.Members.ContainsKey(memberName))
239  // * Not found
240  return null;
241  return userType.Members[memberName].Type;
242  }
243 
244  return null;
245  }
246  #endregion
247 
248  #region Parenthesis()anulada
249 
250 
251  #endregion
252  #region FindConstructor
253  public TypeExpression FindConstructor(Location location) {
261  ConstructorInfo[] constructors = userType.TypeInfo.GetConstructors();
262  AccessModifier accessModifierInfo;
263  MethodType mt;
264  foreach (ConstructorInfo constructor in constructors) {
265  mt = new MethodType((UserType)userType); // The constructor returns its own class
266  ParameterInfo[] parameters = constructor.GetParameters();
267  for (int j = 0; j < parameters.GetLength(0); j++)
268  mt.AddParameter(TypeTable.Instance.GetType(parameters[j].ParameterType.FullName, location));
269 
270  List<Modifier> mods = getMethodModifierList(constructor);
271 
272  accessModifierInfo = new AccessModifier(mods, constructor.Name, mt, false);
273  mt.MemberInfo = accessModifierInfo;
274  accessModifierInfo.Class = (UserType)userType;
275 
276  if (userType.Constructors != null) {
277  if (!(userType.Constructors.Type is IntersectionType)) // * It is not an intersection
278  // * An intersection type must be created
279  userType.Members[userType.Name].Type = new IntersectionMemberType(userType.Members[userType.Name].Type);
280  // * The type is added
281  ((IntersectionType)userType.Members[userType.Name].Type).AddType(mt);
282  }
283  else
284  userType.AddMember(userType.Name, accessModifierInfo);
285  accessModifierInfo.Type.BuildTypeExpressionString(TypeExpression.MAX_DEPTH_LEVEL_TYPE_EXPRESSION);
286  }
287  if (userType.Members.ContainsKey(userType.Name))
288  return userType.Members[userType.Name].Type;
289  return null;
290  }
291 
292  #endregion
293 
294 
295  // Helper Methods
296 
297  #region GetMethodModifierList()
298  public static List<Modifier> getMethodModifierList(MethodBase method) {
304  List<Modifier> mods = new List<Modifier>();
305  if (method.IsAbstract)
306  mods.Add(Modifier.Abstract);
307  if (method.IsPrivate)
308  mods.Add(Modifier.Private);
309  if (method.IsPublic)
310  mods.Add(Modifier.Public);
311  if (method.IsFamily)
312  mods.Add(Modifier.Protected);
313  if (method.IsStatic)
314  mods.Add(Modifier.Static);
315  if (method.IsVirtual)
316  mods.Add(Modifier.Virtual);
317  return mods;
318  }
319  public static List<Modifier> getMethodModifierList(MemberInfo member) {
320  List<Modifier> mods = new List<Modifier>();
321  if (member.DeclaringType.IsAbstract)
322  mods.Add(Modifier.Abstract);
323  if (member.DeclaringType.IsNotPublic)
324  mods.Add(Modifier.Private);
325  if (member.DeclaringType.IsPublic)
326  mods.Add(Modifier.Public);
327  return mods;
328  }
329  #endregion
330 
331  #region GetFieldModifierList()
332  private static List<Modifier> getFieldModifierList(FieldInfo field) {
338  List<Modifier> mods = new List<Modifier>();
339  if (field.IsPrivate)
340  mods.Add(Modifier.Private);
341  if (field.IsPublic)
342  mods.Add(Modifier.Public);
343  if (field.IsFamily)
344  mods.Add(Modifier.Protected);
345  if (field.IsStatic)
346  mods.Add(Modifier.Static);
347  return mods;
348  }
349  #endregion
350 
351  #region GetPropertyModifierList()
352  private static List<Modifier> getPropertyModifierList(PropertyInfo property, List<Modifier> mods) {
358  if (property.CanRead)
359  mods.Add(Modifier.CanRead);
360  if (property.CanWrite)
361  mods.Add(Modifier.CanWrite);
362  return mods;
363  }
364 
365  #endregion
366 
367 
368  #region createBaseClassAndInterfacesTree()
369  public void createBaseClassAndInterfacesTree() {
374  // * Creates the base class tree
375  System.Type baseClass = this.reflectionType.BaseType;
376  if (baseClass != null) {
377  BCLClassType BCLBaseClass = new BCLClassType(baseClass.FullName, baseClass);
378  userType.AddBaseClass(BCLBaseClass, new Location(null, 0, 0));
379  }
380  // * Creates the intefaces tree
381  Type[] interfaces = this.reflectionType.GetInterfaces();
382  foreach (Type interfaze in interfaces) {
383  BCLInterfaceType baseInterface = new BCLInterfaceType(interfaze.FullName, interfaze);
384  userType.AddBaseInterface(baseInterface, new Location(null, 0, 0));
385  }
386  }
387 
388  #endregion
389  }
390 }
Represents a type obtained using introspection.
void createBaseClassAndInterfacesTree()
Creates, based on introspection, the base class of the user type and the list of interfaces implement...
static TypeTable Instance
Gets the unique instance of TypeTable
Definition: TypeTable.cs:57
This class encapsulates a location in a specific file. Implements an Inmutable pattern. So it can be used in any context, that is his internal fields never change.
Definition: Location.cs:24
static List< Modifier > getMethodModifierList(MemberInfo member)
TypeExpression FindMember(string memberName, Location location)
Finds a attribute of a BCL user type, using introspection. Inheritance is not taken into account...
static List< Modifier > getMethodModifierList(MethodBase method)
Gets the modifier list from a method info
Abstract class that represents all different types.
TypeExpression GetType(string name, Location location)
Gets the type associated to the name specified in the argument.
Definition: TypeTable.cs:117
TypeExpression FindMember(string memberName)
Finds a attribute of a BCL user type, using introspection. Inheritance is not taken into account...
AccessModifier Constructors
Gets the constructor list
Definition: IBCLUserType.cs:37
Implementation of a table of types.
Definition: TypeTable.cs:30
Introspection(IBCLUserType userType, Type type)
Constructor of Introspection.
Dictionary< string, AccessModifier > Members
Gets and sets the attribute list
Definition: IBCLUserType.cs:32
Type TypeInfo
Gets the type
Representa a method type.
Definition: MethodType.cs:37
static TypeExpression createBCLUserType(string name, System.Type type, Location location)
Method that encapsulates the creation of a BCL class or interface
const int MAX_DEPTH_LEVEL_TYPE_EXPRESSION
In order to avoid stack overflow in the construction of typeexpression string (ToString), we set a maximum level of depth
Association Class between ClassType and MethodType (or Fields). Represents the access modifier inform...
A class that makes possible to have intersection types as class members (overload) ...
TypeExpression Type
Gets or sets the attribute type expression
Representa an intersection type.
TypeExpression FindConstructor(Location location)
Finds and adds the list of constructor to a BCL type
Represents a error produced when the attribute identifier is not defined.
string Name
Class identifier;
Definition: IBCLUserType.cs:42
Represents a class or interface type.
Definition: UserType.cs:31
void AddParameter(TypeExpression paramType)
Adds a new parameter type.
Definition: MethodType.cs:190