diff options
Diffstat (limited to 'tools/Sandcastle/Source/Reflection/WhidbeyNamer.cs')
-rw-r--r-- | tools/Sandcastle/Source/Reflection/WhidbeyNamer.cs | 275 |
1 files changed, 275 insertions, 0 deletions
diff --git a/tools/Sandcastle/Source/Reflection/WhidbeyNamer.cs b/tools/Sandcastle/Source/Reflection/WhidbeyNamer.cs new file mode 100644 index 0000000..f6234a8 --- /dev/null +++ b/tools/Sandcastle/Source/Reflection/WhidbeyNamer.cs @@ -0,0 +1,275 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// + +using System; +using System.Collections.Generic; +using System.IO; + +using System.Compiler; + +namespace Microsoft.Ddue.Tools.Reflection { + + public class WhidbeyNamer : ApiNamer { + + public override string GetMemberName(Member member) { + + using (TextWriter writer = new StringWriter()) { + + switch (member.NodeType) { + case NodeType.Field: + writer.Write("F:"); + WriteField((Field)member, writer); + break; + case NodeType.Property: + writer.Write("P:"); + WriteProperty((Property)member, writer); + break; + case NodeType.Method: + writer.Write("M:"); + WriteMethod((Method)member, writer); + break; + case NodeType.InstanceInitializer: + writer.Write("M:"); + WriteConstructor((InstanceInitializer)member, writer); + break; + case NodeType.StaticInitializer: + writer.Write("M:"); + WriteStaticConstructor((StaticInitializer)member, writer); + break; + case NodeType.Event: + writer.Write("E:"); + WriteEvent((Event)member, writer); + break; + } + + return (writer.ToString()); + + } + + } + + public override string GetNamespaceName(Namespace space) { + using (TextWriter writer = new StringWriter()) { + writer.Write("N:"); + WriteNamespace(space, writer); + return (writer.ToString()); + } + } + + public override string GetTypeName(TypeNode type) { + using (TextWriter writer = new StringWriter()) { + writer.Write("T:"); + WriteType(type, writer); + return (writer.ToString()); + } + } + + + private static string GetName(Member entity) { + + using (TextWriter writer = new StringWriter()) { + + TypeNode type = entity as TypeNode; + if (type != null) { + writer.Write("T:"); + WriteType(type, writer); + return (writer.ToString()); + } + + switch (entity.NodeType) { + case NodeType.Namespace: + writer.Write("N:"); + WriteNamespace(entity as Namespace, writer); + break; + case NodeType.Field: + writer.Write("F:"); + WriteField(entity as Field, writer); + break; + case NodeType.Property: + writer.Write("P:"); + WriteProperty(entity as Property, writer); + break; + case NodeType.Method: + writer.Write("M:"); + WriteMethod(entity as Method, writer); + break; + case NodeType.InstanceInitializer: + writer.Write("M:"); + WriteConstructor(entity as InstanceInitializer, writer); + break; + case NodeType.StaticInitializer: + writer.Write("M:"); + WriteStaticConstructor(entity as StaticInitializer, writer); + break; + case NodeType.Event: + writer.Write("E:"); + WriteEvent(entity as Event, writer); + break; + } + + return (writer.ToString()); + + } + + } + + private static void WriteConstructor(InstanceInitializer constructor, TextWriter writer) { + WriteType(constructor.DeclaringType, writer); + writer.Write(".#ctor"); + WriteParameters(constructor.Parameters, writer); + } + + private static void WriteEvent(Event trigger, TextWriter writer) { + WriteType(trigger.DeclaringType, writer); + writer.Write(".{0}", trigger.Name.Name); + } + + private static void WriteField(Field field, TextWriter writer) { + WriteType(field.DeclaringType, writer); + writer.Write(".{0}", field.Name.Name); + } + + private static void WriteMethod(Method method, TextWriter writer) { + string name = method.Name.Name; + WriteType(method.DeclaringType, writer); + writer.Write(".{0}", name); + if (method.IsGeneric) { + TypeNodeList genericParameters = method.TemplateParameters; + if (genericParameters != null) { + writer.Write("``{0}", genericParameters.Count); + } + } + WriteParameters(method.Parameters, writer); + // add ~ for conversion operators + if ((name == "op_Implicit") || (name == "op_Explicit")) { + writer.Write("~"); + WriteType(method.ReturnType, writer); + } + + } + + // The actual logic to construct names + + private static void WriteNamespace(Namespace space, TextWriter writer) { + writer.Write(space.Name); + } + + private static void WriteParameters(ParameterList parameters, TextWriter writer) { + if ((parameters == null) || (parameters.Count == 0)) return; + writer.Write("("); + for (int i = 0; i < parameters.Count; i++) { + if (i > 0) writer.Write(","); + WriteType(parameters[i].Type, writer); + } + writer.Write(")"); + } + + private static void WriteProperty(Property property, TextWriter writer) { + WriteType(property.DeclaringType, writer); + writer.Write(".{0}", property.Name.Name); + ParameterList parameters = property.Parameters; + WriteParameters(parameters, writer); + } + + private static void WriteStaticConstructor(StaticInitializer constructor, TextWriter writer) { + WriteType(constructor.DeclaringType, writer); + writer.Write(".#cctor"); + WriteParameters(constructor.Parameters, writer); + } + + private static void WriteType(TypeNode type, TextWriter writer) { + switch (type.NodeType) { + case NodeType.ArrayType: + ArrayType array = type as ArrayType; + WriteType(array.ElementType, writer); + writer.Write("["); + for (int i = 1; i < array.Rank; i++) writer.Write(","); + writer.Write("]"); + break; + case NodeType.Reference: + Reference reference = type as Reference; + TypeNode referencedType = reference.ElementType; + WriteType(referencedType, writer); + + // DocStudio fails to add @ to template parameters or arrays of template + // parameters, so we have to mirror this bizarre behavior here + bool writeAt = true; + if (referencedType.IsTemplateParameter) writeAt = false; + if (referencedType.NodeType == NodeType.ArrayType) { + ArrayType referencedArray = referencedType as ArrayType; + if (referencedArray.ElementType.IsTemplateParameter) writeAt = false; + } + if (writeAt) writer.Write("@"); + break; + case NodeType.Pointer: + Pointer pointer = type as Pointer; + WriteType(pointer.ElementType, writer); + writer.Write("*"); + break; + case NodeType.OptionalModifier: + TypeModifier optionalModifierClause = type as TypeModifier; + WriteType(optionalModifierClause.ModifiedType, writer); + writer.Write("!"); + WriteType(optionalModifierClause.Modifier, writer); + break; + case NodeType.RequiredModifier: + TypeModifier requiredModifierClause = type as TypeModifier; + WriteType(requiredModifierClause.ModifiedType, writer); + writer.Write("|"); + WriteType(requiredModifierClause.Modifier, writer); + break; + default: + if (type.IsTemplateParameter) { + ITypeParameter gtp = (ITypeParameter)type; + if (gtp.DeclaringMember is TypeNode) { + writer.Write("`"); + } else if (gtp.DeclaringMember is Method) { + writer.Write("``"); + } else { + throw new InvalidOperationException("Generic parameter not on type or method."); + } + writer.Write(gtp.ParameterListIndex); + } else { + // namespace + TypeNode declaringType = type.DeclaringType; + if (declaringType != null) { + // names of nested types begin with outer type name + WriteType(declaringType, writer); + writer.Write("."); + } else { + // otherwise just prepend the namespace + string space = type.Namespace.Name; + if (space != null && space.Length > 0) { + writer.Write(space); + writer.Write("."); + } + } + // name + writer.Write(type.GetUnmangledNameWithoutTypeParameters()); + // generic parameters + if (type.IsGeneric) { + // number of parameters + TypeNodeList parameters = type.TemplateParameters; + if (parameters != null) { + writer.Write("`{0}", parameters.Count); + } + // arguments + TypeNodeList arguments = type.TemplateArguments; + if ((arguments != null) && (arguments.Count > 0)) { + writer.Write("{"); + for (int i = 0; i < arguments.Count; i++) { + TypeNode argument = arguments[i]; + if (i > 0) writer.Write(","); + WriteType(arguments[i], writer); + } + writer.Write("}"); + } + } + } + break; + } + } + + } + +} |