using System;
using System.Collections;
using System.Collections.Specialized;
using System.Reflection;
using URAnticipatingMinds.PlatformServices.UnmanagedReflection;
namespace AnticipatingMinds.Genesis.CodeDOM{
/// <summary>
/// Represents information about declared or imported type.
/// </summary>
[Serializable]
public abstract class CodeTypeInfo
{
/// <summary>
/// Gets type full name.
/// </summary>
public abstract string FullName
{
get;
}
/// <summary>
/// Gets if type is an interface.
/// </summary>
public abstract bool IsInterface
{
get;
}
/// <summary>
/// Gets a value indicating if the type is an array.
/// </summary>
/// <value>True if the type is an array. False otherwise.</value>
public abstract bool IsArray
{
get;
}
/// <summary>
/// Gets a value indicating if the type is a pointer.
/// </summary>
/// <value>True if the type is a pointer. False otherwise.</value>
public abstract bool IsPointer
{
get;
}
/// <summary>
/// Gets a value indicating if the type is a delegate.
/// </summary>
/// <value>True if the type is a delegate. False otherwise.</value>
public abstract bool IsDelegate
{
get;
}
/// <summary>
/// Gets a type info for an array element if type is an array.
/// </summary>
/// <value>Returns type info for an array element is type is an array. Otherwise returns null.</value>
public abstract CodeTypeInfo ElementType
{
get;
}
/// <summary>
/// Gets delegate return typename if type is a delegate.
/// </summary>
public abstract string GetDelegateReturnType();
/// <summary>
/// Gets delegate parameters if type is a delegate.
/// </summary>
public abstract CodeParameterInfo[] GetDelegateParameters();
/// <summary>
/// Gets name of the base type.
/// </summary>
/// <returns>Gets name of the base type. Returns null for System.Object</returns>
public abstract string GetBaseType();
/// <summary>
/// Get names of the implemented interfaces.
/// </summary>
/// <returns>An array of typenames of implemented interfaces.</returns>
public abstract string[] GetInterfaces();
/// <summary>
/// Gets an array type of the current type.
/// </summary>
/// <returns>Returns an array type of the current type. If the current type is string this function will return type info for string[].</returns>
public CodeTypeInfo GetArrayType()
{
if(arrayTypeInfo == null)
arrayTypeInfo = new CodeEncompassTypeInfo(this,true,false);
return arrayTypeInfo;
}
/// <summary>
/// Gets a pointer type of the current type.
/// </summary>
/// <returns>Returns a pointer type of the current type. If the current type is string this function will return type info for string*.</returns>
public CodeTypeInfo GetPointerType()
{
if(pointerTypeInfo == null)
pointerTypeInfo = new CodeEncompassTypeInfo(this,false,true);
return pointerTypeInfo;
}
public static CodeTypeInfo GetNullTypeInfo()
{
return nullTypeInfo;
}
/// <summary>
/// THis function is intended for internal use only.
/// </summary>
/// <param name="memberInfo"></param>
protected void AddMember(params CodeTypeMemberInfo[] memberInfo)
{
lock(this)
{
fields = null;
methods = null;
properties = null;
events = null;
members.AddRange(memberInfo);
}
}
/// <summary>
/// Gets an array of type members.
/// </summary>
/// <returns>An array of type memebers.</returns>
public CodeMethodInfo[] GetMethods()
{
lock(this)
{
if(methods == null)
{
ArrayList tempArray = new ArrayList();
foreach(CodeTypeMemberInfo member in members)
if(member is CodeMethodInfo)
tempArray.Add(member);
methods = new CodeMethodInfo[tempArray.Count];
tempArray.CopyTo(methods);
}
return methods;
}
}
/// <summary>
/// Finds a member property specified by propertyName.
/// </summary>
/// <param name="propertyName">Name of the property to find</param>
/// <param name="isCaseSensitive">Is name case sensitive.</param>
/// <returns>Returns property information if found - null otherwise.</returns>
public CodePropertyInfo FindProperty(string propertyName,bool isCaseSensitive)
{
foreach(CodePropertyInfo propertyInfo in GetProperties())
if(string.Compare(propertyInfo.Name,propertyName,!isCaseSensitive) == 0)
return propertyInfo;
return null;
}
/// <summary>
/// Gets an array of all declared proeprties.
/// </summary>
/// <returns>An array of declared properties.</returns>
public CodePropertyInfo[] GetProperties()
{
lock(this)
{
if(properties == null)
{
ArrayList tempArray = new ArrayList();
foreach(CodeTypeMemberInfo member in members)
if(member is CodePropertyInfo)
tempArray.Add(member);
properties = new CodePropertyInfo[tempArray.Count];
tempArray.CopyTo(properties);
}
return properties;
}
}
/// <summary>
/// Finds a member field specified by fieldName.
/// </summary>
/// <param name="fieldName">Name of the field to find</param>
/// <param name="isCaseSensitive">Is name case sensitive.</param>
/// <returns>Returns field information if found - null otherwise.</returns>
public CodeFieldInfo FindField(string fieldName, bool isCaseSensitive)
{
foreach(CodeFieldInfo fieldInfo in GetFields())
if(string.Compare(fieldInfo.Name,fieldName,!isCaseSensitive) == 0)
return fieldInfo;
return null;
}
/// <summary>
/// Gets an array of all declared fields.
/// </summary>
/// <returns>An array of declared fields.</returns>
public CodeFieldInfo[] GetFields()
{
lock(this)
{
if(fields == null)
{
ArrayList tempArray = new ArrayList();
foreach(CodeTypeMemberInfo member in members)
if(member is CodeFieldInfo)
tempArray.Add(member);
fields = new CodeFieldInfo[tempArray.Count];
tempArray.CopyTo(fields);
}
return fields;
}
}
/// <summary>
/// Finds a member event specified by eventName.
/// </summary>
/// <param name="eventName">Name of the event to find</param>
/// <param name="isCaseSensitive">Is name case sensitive.</param>
/// <returns>Returns event information if found - null otherwise.</returns>
public CodeEventInfo FindEvent(string eventName, bool isCaseSensitive)
{
foreach(CodeEventInfo eventInfo in GetEvents())
if(string.Compare(eventInfo.Name,eventName,!isCaseSensitive) == 0)
return eventInfo;
return null;
}
/// <summary>
/// Gets an array of all declared events.
/// </summary>
/// <returns>An array of declared events.</returns>
public CodeEventInfo[] GetEvents()
{
lock(this)
{
if(events == null)
{
ArrayList tempArray = new ArrayList();
foreach(CodeTypeMemberInfo member in members)
if(member is CodeEventInfo)
tempArray.Add(member);
events = new CodeEventInfo[tempArray.Count];
tempArray.CopyTo(events);
}
return events;
}
}
private CodeTypeInfo arrayTypeInfo = null;
private CodeTypeInfo pointerTypeInfo = null;
private CodeMethodInfo[] methods = null;
private CodePropertyInfo[] properties = null;
private CodeFieldInfo[] fields = null;
private CodeEventInfo[] events = null;
private CodeTypeMemberInfoCollection members = new CodeTypeMemberInfoCollection();
private static CodeTypeInfo nullTypeInfo = new CodeNullTypeInfo();
}
[Serializable]
internal class CodeMetadataTypeInfo : CodeTypeInfo
{
private bool IsMethodVisible(UR.MethodInfo methodInfo)
{
if(methodInfo == null)
return false;
MethodAttributes methodVisibility = (MethodAttributes) ((int) methodInfo.CorAttributes & (int) MethodAttributes.MemberAccessMask);
if(methodVisibility != MethodAttributes.Public &&
methodVisibility != MethodAttributes.FamANDAssem &&
methodVisibility != MethodAttributes.Family)
{
return false;
}
return true;
}
internal CodeMetadataTypeInfo(UR.TypeInfo typeInfo)
{
fullName= typeInfo.FullName;
isInterface = ((typeInfo.CorAttributes & TypeAttributes.Interface) != 0);
if(typeInfo.BaseType != null)
baseType = typeInfo.BaseType.FullName;
else
baseType = "System.Object";
StringCollection interfaces = new StringCollection();
foreach(UR.TypeInfo interfaceType in typeInfo.ImplementedInterfaces)
interfaces.Add(interfaceType.FullName);
inheritedInterfaces = new string[interfaces.Count];
interfaces.CopyTo(inheritedInterfaces,0);
UR.FieldInfo[] fields = typeInfo.GetDefinedFields();
UR.EventInfo[] events = typeInfo.GetDefinedEvents();
UR.PropertyInfo[] properties = typeInfo.GetDefinedProperties();
UR.MethodInfo[] methods= typeInfo.GetDefinedMethods();
for(int i = 0; i < fields.Length; i++)
{
FieldAttributes fieldVisibility = (FieldAttributes) ((int) fields[i].CorAttributes & (int) FieldAttributes.FieldAccessMask);
if(fieldVisibility != FieldAttributes.Public &&
fieldVisibility != FieldAttributes.FamANDAssem &&
fieldVisibility != FieldAttributes.Family)
{
continue;
}
AddMember(new CodeMetadataFieldInfo(fields[i],this));
}
for(int i = 0; i < methods.Length; i++)
{
if(!IsMethodVisible(methods[i]))
{
continue;
}
AddMember(new CodeMetadataMethodInfo(methods[i],this));
}
for(int i = 0; i < properties.Length; i++)
{
if(!IsMethodVisible(properties[i].GetterMethodInfo) && !IsMethodVisible(properties[i].SetterMethodInfo))
{
continue;
}
AddMember(new CodeMetadataPropertyInfo(properties[i],this));
}
for(int i = 0; i < events.Length; i++)
{
if(!IsMethodVisible(events[i].AddMethodInfo))
{
continue;
}
AddMember(new CodeMetadataEventInfo(events[i],this));
}
}
public override string FullName
{
get { return fullName; }
}
public override bool IsInterface
{
get { return isInterface; }
}
public override string GetBaseType()
{
return baseType;
}
public override string[] GetInterfaces()
{
return inheritedInterfaces;
}
public override bool IsArray
{
get
{
return false;
}
}
public override bool IsPointer
{
get
{
return false;
}
}
public override CodeTypeInfo ElementType
{
get
{
return null;
}
}
public override string GetDelegateReturnType()
{
return null;
}
public override CodeParameterInfo[] GetDelegateParameters()
{
return null;
}
public override bool IsDelegate
{
get
{
return false;
}
}
private string baseType;
private string[] inheritedInterfaces;
private string fullName;
private bool isInterface;
}
/// <summary>
/// This internal class implements CodeTypeInfo interface
/// </summary>
[Serializable]
internal class CodeModelTypeInfo : CodeTypeInfo
{
internal CodeModelTypeInfo(CodeTypeDeclaration typeDeclaration)
{
this.typeDeclaration = typeDeclaration;
CodeTypeMemberDeclarationCollection declaredMembers = null;
if(typeDeclaration is CodeClassDeclaration)
declaredMembers = (typeDeclaration as CodeClassDeclaration).Members;
if(typeDeclaration is CodeInterfaceDeclaration)
declaredMembers = (typeDeclaration as CodeInterfaceDeclaration).Members;
if(typeDeclaration is CodeStructDeclaration)
declaredMembers = (typeDeclaration as CodeStructDeclaration).Members;
if(declaredMembers != null)
{
foreach(CodeTypeMemberDeclaration typeMember in declaredMembers)
{
if(typeMember is CodeTypeMethodDeclaration)
{
AddMember(new CodeModelMethodInfo(typeMember as CodeTypeMethodDeclaration,this));
continue;
}
if(typeMember is CodeTypePropertyDeclaration)
{
AddMember(new CodeModelPropertyInfo(typeMember as CodeTypePropertyDeclaration,this));
continue;
}
if(typeMember is CodeTypeFieldDeclaration)
{
foreach(CodeVariableDeclarationMember filedDeclaration in (typeMember as CodeTypeFieldDeclaration).DeclaredFields)
{
AddMember(new CodeModelFieldInfo(typeMember as CodeTypeFieldDeclaration,filedDeclaration.Name,this));
}
continue;
}
if(typeMember is CodeTypeEventDeclaration)
{
AddMember(new CodeModelEventInfo(typeMember as CodeTypeEventDeclaration,this));
continue;
}
if(typeMember is CodeTypeEventListDeclaration)
{
foreach(CodeVariableDeclarationMember eventDeclaration in (typeMember as CodeTypeEventListDeclaration).DeclaredEvents)
{
AddMember(new CodeModelEventInfo(typeMember as CodeTypeEventListDeclaration,eventDeclaration.Name,this));
}
continue;
}
System.Diagnostics.Debug.Assert(false,"What kind of other member exists?");
}
}
if(typeDeclaration is CodeTypeDelegateDeclaration)
{
CodeTypeDelegateDeclaration delegateDeclaration = typeDeclaration as CodeTypeDelegateDeclaration;
delegateParameters = new CodeParameterInfo[delegateDeclaration.Parameters.Count];
for(int parameterIndex = 0; parameterIndex < delegateDeclaration.Parameters.Count;parameterIndex++)
{
delegateParameters[parameterIndex] = new CodeModelParameterInfo(delegateDeclaration.Parameters[parameterIndex]);
}
}
}
public override string FullName
{
get { return typeDeclaration.FullName; }
}
public override bool IsInterface
{
get { return typeDeclaration is CodeInterfaceDeclaration; }
}
public override string GetBaseType()
{
//Get it dynamicly
if(typeDeclaration is CodeClassDeclaration)
if((typeDeclaration as CodeClassDeclaration).BaseTypes.Count != 0)
if((typeDeclaration as CodeClassDeclaration).BaseTypes[0].TypeInfo != null)
if(!(typeDeclaration as CodeClassDeclaration).BaseTypes[0].TypeInfo.IsInterface)
return (typeDeclaration as CodeClassDeclaration).BaseTypes[0].TypeInfo.FullName;
if(typeDeclaration is CodeEnumDeclaration)
if((typeDeclaration as CodeEnumDeclaration).EnumBase != null && (typeDeclaration as CodeEnumDeclaration).EnumBase.TypeInfo != null)
return (typeDeclaration as CodeEnumDeclaration).EnumBase.TypeInfo.FullName;
if(typeDeclaration is CodeStructDeclaration)
return typeof(ValueType).FullName;
if(typeDeclaration is CodeTypeDelegateDeclaration)
return typeof(System.Delegate).FullName;
return typeof(object).FullName;
}
public override string[] GetInterfaces()
{
CodeTypeReferenceCollection baseTypes = null;
if(typeDeclaration is CodeClassDeclaration)
baseTypes = (typeDeclaration as CodeClassDeclaration).BaseTypes;
if(typeDeclaration is CodeInterfaceDeclaration)
baseTypes = (typeDeclaration as CodeInterfaceDeclaration).Interfaces;
if(typeDeclaration is CodeStructDeclaration)
baseTypes = (typeDeclaration as CodeStructDeclaration).Interfaces;
StringCollection interfaces = new StringCollection();
if(baseTypes != null && baseTypes.Count != 0)
foreach(CodeTypeReference baseTypeReference in baseTypes)
{
if(baseTypeReference.TypeInfo != null && baseTypeReference.TypeInfo.IsInterface)
interfaces.Add(baseTypeReference.TypeInfo.FullName);
}
if(interfaces.Count == 0)
return emptyStringArray;
string[] inheritedInterfaces = new string[interfaces.Count];
interfaces.CopyTo(inheritedInterfaces,0);
return inheritedInterfaces;
}
public override bool IsArray
{
get
{
return false;
}
}
public override bool IsPointer
{
get
{
return false;
}
}
public override CodeTypeInfo ElementType
{
get
{
return null;
}
}
public override bool IsDelegate
{
get
{
return typeDeclaration is CodeTypeDelegateDeclaration;
}
}
public override string GetDelegateReturnType()
{
if(typeDeclaration is CodeTypeDelegateDeclaration)
{
if((typeDeclaration as CodeTypeDelegateDeclaration).ReturnType != null)
{
if((typeDeclaration as CodeTypeDelegateDeclaration).ReturnType.TypeInfo != null)
{
return (typeDeclaration as CodeTypeDelegateDeclaration).ReturnType.TypeInfo.FullName;
}
else
{
return (typeDeclaration as CodeTypeDelegateDeclaration).ReturnType.TypeName;
}
}
}
return null;
}
public override CodeParameterInfo[] GetDelegateParameters()
{
return delegateParameters;
}
private CodeTypeDeclaration typeDeclaration;
private static string[] emptyStringArray = new string[0];
private CodeParameterInfo[] delegateParameters = null;
}
[Serializable]
internal class CodeEncompassTypeInfo : CodeTypeInfo
{
internal CodeEncompassTypeInfo(CodeTypeInfo elementType,bool isArray, bool isPointer)
{
this.isPointer = isPointer;
this.isArray = isArray;
this.elementType = elementType;
}
public override bool IsArray
{
get
{
return isArray;
}
}
public override bool IsPointer
{
get
{
return isPointer;
}
}
public override CodeTypeInfo ElementType
{
get
{
return elementType;
}
}
public override string FullName
{
get
{
if(isArray)
return ElementType.FullName + "[]";
if(isPointer)
return ElementType.FullName + "*";
throw new InvalidOperationException("Encompass Type must be a pointer or an array");
}
}
public override bool IsInterface
{
get { return false; }
}
public override string GetBaseType()
{
if(isArray)
return typeof(System.Array).FullName;
else
return null;
}
public override string[] GetInterfaces()
{
return emptyStringArray;
}
public override CodeParameterInfo[] GetDelegateParameters()
{
return null;
}
public override string GetDelegateReturnType()
{
return null;
}
public override bool IsDelegate
{
get
{
return false;
}
}
private bool isArray;
private bool isPointer;
private CodeTypeInfo elementType;
private static string[] emptyStringArray = new string[0];
}
[Serializable]
internal class CodeNullTypeInfo : CodeTypeInfo
{
internal CodeNullTypeInfo()
{
}
public override bool IsArray
{
get
{
return false;
}
}
public override bool IsPointer
{
get
{
return false;
}
}
public override CodeTypeInfo ElementType
{
get
{
return null;
}
}
public override string FullName
{
get
{
return "null";
}
}
public override bool IsInterface
{
get { return false; }
}
public override string GetBaseType()
{
return null;
}
public override string[] GetInterfaces()
{
return emptyStringArray;
}
public override CodeParameterInfo[] GetDelegateParameters()
{
return null;
}
public override string GetDelegateReturnType()
{
return null;
}
public override bool IsDelegate
{
get
{
return false;
}
}
private static string[] emptyStringArray = new string[0];
}
}
|