|
using System;
using System.Text;
using System.Reflection;
namespace TenTec.Utils
{
internal class XmlHelpNameManager
{
#region Consts
private const string cTypePrefix = "T:";
private const string cFieldPrefix = "F:";
private const string cMethodPrefix = "M:";
private const string cEventPrefix = "E:";
private const string cPropertyPrefix = "P:";
private const string cNamespacePrefix = "N:";
private const char cDelimiter = '.';
private const char cNestedDelimiter = '+';
private const char cPeriodSubstitute = '#';
#endregion
#region Methods
public static string Get(string @namespace)
{
return cNamespacePrefix + @namespace;
}
public static string Get(MemberInfo member)
{
StringBuilder myResult = new StringBuilder();
switch (member.MemberType)
{
case System.Reflection.MemberTypes.TypeInfo:
myResult.Append(cTypePrefix);
break;
case System.Reflection.MemberTypes.NestedType:
myResult.Append(cTypePrefix);
break;
case System.Reflection.MemberTypes.Event:
myResult.Append(cEventPrefix);
break;
case System.Reflection.MemberTypes.Field:
myResult.Append(cFieldPrefix);
break;
case System.Reflection.MemberTypes.Constructor:
case System.Reflection.MemberTypes.Method:
myResult.Append(cMethodPrefix);
break;
case System.Reflection.MemberTypes.Property:
myResult.Append(cPropertyPrefix);
break;
}
if(member.DeclaringType != null)
{
myResult.Append(member.DeclaringType.FullName);
myResult.Append(cDelimiter);
}
else
{
Type myType = member as Type;
if(myType != null && myType.Namespace != null)
{
myResult.Append(myType.Namespace);
myResult.Append(cDelimiter);
}
}
myResult.Append(member.Name.Replace(cDelimiter, cPeriodSubstitute));
myResult.Replace(cNestedDelimiter, cDelimiter);
if (
member.MemberType == System.Reflection.MemberTypes.Method ||
member.MemberType == System.Reflection.MemberTypes.Constructor)
{
MethodBase lvMethodBase = (member as MethodBase);
if (lvMethodBase.IsGenericMethod)
myResult.Append(GetMethodGenericParamsDefinition(lvMethodBase));
myResult.Append(GetMethodParametersString(lvMethodBase.GetParameters()));
}
else if (member.MemberType == System.Reflection.MemberTypes.Property)
{
myResult.Append(GetMethodParametersString(ReflectionManager.GetParameters(member as PropertyInfo)));
}
return myResult.ToString();
}
private static string GetMethodGenericParamsDefinition(MethodBase method)
{
if (method == null)
throw new ArgumentNullException("XmlHelpNameManager.GetMethodGenericParamsDefinition(method)");
if (!method.ContainsGenericParameters)
return string.Empty;
int myGenericParamsCount = method.GetGenericArguments().Length;
return ConstsXmlHelp.cGenericMethodParameterPrefix + myGenericParamsCount.ToString();
}
public static string GetTypeName(string fullName)
{
if(fullName == null)
throw new ArgumentNullException("XmlHelpNameManager.GetTypeName(fullName)");
if(fullName.Length == 0)
throw new ArgumentNullException("XmlHelpNameManager.GetTypeName(fullName)");
fullName = fullName.Replace(cNestedDelimiter, cDelimiter);
return cTypePrefix + fullName;
}
private static string GetMethodParametersString(ParameterInfo[] parameters)
{
StringBuilder myString;
if(parameters.Length > 0)
{
myString = new StringBuilder(ConstsXmlHelp.cOpenBracket);
for(int i = 0; i < parameters.Length; i++)
{
ParameterInfo myInfo = parameters[i];
myString.Append(GetFullName(myInfo.ParameterType));
if(i+1 < parameters.Length)
myString.Append(ConstsXmlHelp.cParameterDelimeter);
}
myString.Append(ConstsXmlHelp.cCloseBracket);
return myString.ToString();
}
return String.Empty;
}
private static string GetFullName(Type type)
{
#region Check whether the type an element type
if (type.HasElementType)
{
string lvElementTypeName = GetFullName(type.GetElementType());
if (type.IsByRef) // Check whether it is a by-reference type (ref or out parameter)
return lvElementTypeName + ConstsXmlHelp.cPointerSuffix;
if (type.IsArray)
return lvElementTypeName + GetArrayTypeSuffix(type);
}
#endregion
#region Check whether it is a generic parameter. If so, return its name
if (type.IsGenericParameter)
{
if (type.DeclaringMethod == null)
return ConstsXmlHelp.cGenericTypeParameterPrexif + type.GenericParameterPosition.ToString();
else
return ConstsXmlHelp.cGenericMethodParameterPrefix + type.GenericParameterPosition.ToString();
}
#endregion
#region Get the name prefix (namespace or nested type full name)
string myPrefix;
if (type.IsNested)
myPrefix = GetFullName(type.DeclaringType);
else
myPrefix = type.Namespace;
#endregion
#region Change the generic closed constructed type declaration (replace '`' with {...}) and return it
if (type.IsGenericType)
{
int lvIndexOfTypeGenericParameterPrefix = type.Name.LastIndexOf(ConstsXmlHelp.cGenericTypeParameterPrexif);
return
myPrefix + ConstsXmlHelp.cDelimiter +
type.Name.Substring(0, lvIndexOfTypeGenericParameterPrefix) +
GetGenericClosedConstructedTypeArgumentsString(type);
}
#endregion
return myPrefix + ConstsXmlHelp.cDelimiter + type.Name;
}
/// <summary>
/// Returns the suffix which should be added to the element type name
/// of the specified array ([0:,0:,...]).
/// </summary>
private static string GetArrayTypeSuffix(Type type)
{
if (type == null)
throw new ArgumentNullException("XmlHelpNameManager.GetArrayTypeSuffix(type)");
if (!type.IsArray)
throw new ArgumentException("XmlHelpNameManager.GetArrayTypeSuffix(type)");
StringBuilder myResult = new StringBuilder();
myResult.Append(ConstsXmlHelp.cOpenSquareBrackets);
int lvArrayRank = type.GetArrayRank();
if (lvArrayRank > 1)
{
myResult.Append(ConstsXmlHelp.cArrayLowerBoundAndSize);
for (int myArrayDimension = 1; myArrayDimension < lvArrayRank; myArrayDimension++)
{
myResult.Append(ConstsXmlHelp.cArrayDimensionDelimeter);
myResult.Append(ConstsXmlHelp.cArrayLowerBoundAndSize);
}
}
myResult.Append(ConstsXmlHelp.cCloseSquareBrackets);
return myResult.ToString();
}
private static string GetGenericClosedConstructedTypeArgumentsString(Type type)
{
if (type == null)
throw new ArgumentNullException("XmlHelpNameManager.GetGenericClosedConstructedTypeArgumentsString(type)");
Type[] myArgumentTypes = type.GetGenericArguments();
StringBuilder lvResult = new StringBuilder();
lvResult.Append(ConstsXmlHelp.cGenericMethodParameterArgumentListStart);
foreach (Type myArgumentType in myArgumentTypes)
{
if (myArgumentType.IsGenericParameter)
{
if (myArgumentType.DeclaringType != null && myArgumentType.DeclaringType != type)
{
#region Check whether the current argument type is declared in a nesting type
bool lvIsArgumentTypeDeclaredInNestingType = false;
Type lvNestingType = type.DeclaringType;
while (lvNestingType != null)
{
if (lvNestingType == myArgumentType.DeclaringType)
{
lvIsArgumentTypeDeclaredInNestingType = true;
break;
}
lvNestingType = lvNestingType.DeclaringType;
}
#endregion
if (lvIsArgumentTypeDeclaredInNestingType)
continue;
}
}
if (lvResult.Length > ConstsXmlHelp.cGenericMethodParameterArgumentListStart.Length)
lvResult.Append(ConstsXmlHelp.cParameterDelimeter);
lvResult.Append(GetFullName(myArgumentType));
}
lvResult.Append(ConstsXmlHelp.cGenericMethodParameterArgumentListEnd);
return lvResult.ToString();
}
#endregion
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.