668 lines
25 KiB
C#
668 lines
25 KiB
C#
|
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Globalization;
|
|||
|
using System.Linq;
|
|||
|
using System.Text;
|
|||
|
|
|||
|
using Mono.Cecil;
|
|||
|
|
|||
|
using Mono.Documentation.Util;
|
|||
|
|
|||
|
namespace Mono.Documentation.Updater
|
|||
|
{
|
|||
|
public class CSharpFullMemberFormatter : MemberFormatter
|
|||
|
{
|
|||
|
|
|||
|
public override string Language
|
|||
|
{
|
|||
|
get { return "C#"; }
|
|||
|
}
|
|||
|
|
|||
|
protected override StringBuilder AppendNamespace (StringBuilder buf, TypeReference type)
|
|||
|
{
|
|||
|
|
|||
|
string ns = DocUtils.GetNamespace (type);
|
|||
|
if (GetCSharpType (type.FullName) == null && ns != null && ns.Length > 0 && ns != "System")
|
|||
|
buf.Append (ns).Append ('.');
|
|||
|
return buf;
|
|||
|
}
|
|||
|
|
|||
|
protected virtual string GetCSharpType (string t)
|
|||
|
{
|
|||
|
// make sure there are no modifiers in the type string (add them back before returning)
|
|||
|
string typeToCompare = t;
|
|||
|
string[] splitType = null;
|
|||
|
if (t.Contains (' '))
|
|||
|
{
|
|||
|
splitType = t.Split (' ');
|
|||
|
typeToCompare = splitType[0];
|
|||
|
}
|
|||
|
|
|||
|
switch (typeToCompare)
|
|||
|
{
|
|||
|
case "System.Byte": typeToCompare = "byte"; break;
|
|||
|
case "System.SByte": typeToCompare = "sbyte"; break;
|
|||
|
case "System.Int16": typeToCompare = "short"; break;
|
|||
|
case "System.Int32": typeToCompare = "int"; break;
|
|||
|
case "System.Int64": typeToCompare = "long"; break;
|
|||
|
|
|||
|
case "System.UInt16": typeToCompare = "ushort"; break;
|
|||
|
case "System.UInt32": typeToCompare = "uint"; break;
|
|||
|
case "System.UInt64": typeToCompare = "ulong"; break;
|
|||
|
|
|||
|
case "System.Single": typeToCompare = "float"; break;
|
|||
|
case "System.Double": typeToCompare = "double"; break;
|
|||
|
case "System.Decimal": typeToCompare = "decimal"; break;
|
|||
|
case "System.Boolean": typeToCompare = "bool"; break;
|
|||
|
case "System.Char": typeToCompare = "char"; break;
|
|||
|
case "System.Void": typeToCompare = "void"; break;
|
|||
|
case "System.String": typeToCompare = "string"; break;
|
|||
|
case "System.Object": typeToCompare = "object"; break;
|
|||
|
}
|
|||
|
|
|||
|
if (splitType != null)
|
|||
|
{
|
|||
|
// re-add modreq/modopt if it was there
|
|||
|
splitType[0] = typeToCompare;
|
|||
|
typeToCompare = string.Join (" ", splitType);
|
|||
|
}
|
|||
|
return typeToCompare == t ? null : typeToCompare;
|
|||
|
}
|
|||
|
|
|||
|
protected override StringBuilder AppendTypeName (StringBuilder buf, TypeReference type, DynamicParserContext context)
|
|||
|
{
|
|||
|
if (context != null && context.TransformFlags != null &&
|
|||
|
(context.TransformFlags.Count == 0 || context.TransformFlags[context.TransformIndex]))
|
|||
|
{
|
|||
|
context.TransformIndex++;
|
|||
|
return buf.Append ("dynamic");
|
|||
|
}
|
|||
|
|
|||
|
if (type is GenericParameter)
|
|||
|
return AppendGenericParameterConstraints (buf, (GenericParameter)type, context).Append (type.Name);
|
|||
|
string t = type.FullName;
|
|||
|
if (!t.StartsWith ("System."))
|
|||
|
{
|
|||
|
return base.AppendTypeName (buf, type, context);
|
|||
|
}
|
|||
|
|
|||
|
string s = GetCSharpType (t);
|
|||
|
if (s != null)
|
|||
|
{
|
|||
|
if (context != null)
|
|||
|
context.TransformIndex++;
|
|||
|
return buf.Append (s);
|
|||
|
}
|
|||
|
|
|||
|
return base.AppendTypeName (buf, type, context);
|
|||
|
}
|
|||
|
|
|||
|
private StringBuilder AppendGenericParameterConstraints (StringBuilder buf, GenericParameter type, DynamicParserContext context)
|
|||
|
{
|
|||
|
if (MemberFormatterState != MemberFormatterState.WithinGenericTypeParameters)
|
|||
|
return buf;
|
|||
|
GenericParameterAttributes attrs = type.Attributes;
|
|||
|
bool isout = (attrs & GenericParameterAttributes.Covariant) != 0;
|
|||
|
bool isin = (attrs & GenericParameterAttributes.Contravariant) != 0;
|
|||
|
if (isin)
|
|||
|
buf.Append ("in ");
|
|||
|
else if (isout)
|
|||
|
buf.Append ("out ");
|
|||
|
return buf;
|
|||
|
}
|
|||
|
|
|||
|
protected override string GetTypeDeclaration (TypeDefinition type)
|
|||
|
{
|
|||
|
string visibility = GetTypeVisibility (type.Attributes);
|
|||
|
if (visibility == null)
|
|||
|
return null;
|
|||
|
|
|||
|
StringBuilder buf = new StringBuilder ();
|
|||
|
|
|||
|
buf.Append (visibility);
|
|||
|
buf.Append (" ");
|
|||
|
|
|||
|
MemberFormatter full = new CSharpFullMemberFormatter ();
|
|||
|
|
|||
|
if (DocUtils.IsDelegate (type))
|
|||
|
{
|
|||
|
buf.Append ("delegate ");
|
|||
|
MethodDefinition invoke = type.GetMethod ("Invoke");
|
|||
|
buf.Append (full.GetName (invoke.ReturnType, new DynamicParserContext (invoke.MethodReturnType))).Append (" ");
|
|||
|
buf.Append (GetName (type));
|
|||
|
AppendParameters (buf, invoke, invoke.Parameters);
|
|||
|
AppendGenericTypeConstraints (buf, type);
|
|||
|
buf.Append (";");
|
|||
|
|
|||
|
return buf.ToString ();
|
|||
|
}
|
|||
|
|
|||
|
if (type.IsAbstract && !type.IsInterface)
|
|||
|
buf.Append ("abstract ");
|
|||
|
if (type.IsSealed && !DocUtils.IsDelegate (type) && !type.IsValueType)
|
|||
|
buf.Append ("sealed ");
|
|||
|
buf.Replace ("abstract sealed", "static");
|
|||
|
|
|||
|
buf.Append (GetTypeKind (type));
|
|||
|
buf.Append (" ");
|
|||
|
buf.Append (GetCSharpType (type.FullName) == null
|
|||
|
? GetName (type)
|
|||
|
: type.Name);
|
|||
|
|
|||
|
if (!type.IsEnum)
|
|||
|
{
|
|||
|
TypeReference basetype = type.BaseType;
|
|||
|
if (basetype != null && basetype.FullName == "System.Object" || type.IsValueType) // FIXME
|
|||
|
basetype = null;
|
|||
|
|
|||
|
List<string> interface_names = DocUtils.GetUserImplementedInterfaces (type)
|
|||
|
.Select (iface => full.GetName (iface))
|
|||
|
.OrderBy (s => s)
|
|||
|
.ToList ();
|
|||
|
|
|||
|
if (basetype != null || interface_names.Count > 0)
|
|||
|
buf.Append (" : ");
|
|||
|
|
|||
|
if (basetype != null)
|
|||
|
{
|
|||
|
buf.Append (full.GetName (basetype));
|
|||
|
if (interface_names.Count > 0)
|
|||
|
buf.Append (", ");
|
|||
|
}
|
|||
|
|
|||
|
for (int i = 0; i < interface_names.Count; i++)
|
|||
|
{
|
|||
|
if (i != 0)
|
|||
|
buf.Append (", ");
|
|||
|
buf.Append (interface_names[i]);
|
|||
|
}
|
|||
|
AppendGenericTypeConstraints (buf, type);
|
|||
|
}
|
|||
|
|
|||
|
return buf.ToString ();
|
|||
|
}
|
|||
|
|
|||
|
static string GetTypeKind (TypeDefinition t)
|
|||
|
{
|
|||
|
if (t.IsEnum)
|
|||
|
return "enum";
|
|||
|
if (t.IsValueType)
|
|||
|
return "struct";
|
|||
|
if (t.IsClass || t.FullName == "System.Enum")
|
|||
|
return "class";
|
|||
|
if (t.IsInterface)
|
|||
|
return "interface";
|
|||
|
throw new ArgumentException (t.FullName);
|
|||
|
}
|
|||
|
|
|||
|
static string GetTypeVisibility (TypeAttributes ta)
|
|||
|
{
|
|||
|
switch (ta & TypeAttributes.VisibilityMask)
|
|||
|
{
|
|||
|
case TypeAttributes.Public:
|
|||
|
case TypeAttributes.NestedPublic:
|
|||
|
return "public";
|
|||
|
|
|||
|
case TypeAttributes.NestedFamily:
|
|||
|
return "protected";
|
|||
|
|
|||
|
case TypeAttributes.NestedFamORAssem:
|
|||
|
return "protected internal";
|
|||
|
|
|||
|
default:
|
|||
|
return null;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
protected override StringBuilder AppendGenericTypeConstraints (StringBuilder buf, TypeReference type)
|
|||
|
{
|
|||
|
if (type.GenericParameters.Count == 0)
|
|||
|
return buf;
|
|||
|
return AppendConstraints (buf, type.GenericParameters);
|
|||
|
}
|
|||
|
|
|||
|
private StringBuilder AppendConstraints (StringBuilder buf, IList<GenericParameter> genArgs)
|
|||
|
{
|
|||
|
foreach (GenericParameter genArg in genArgs)
|
|||
|
{
|
|||
|
GenericParameterAttributes attrs = genArg.Attributes;
|
|||
|
#if NEW_CECIL
|
|||
|
Mono.Collections.Generic.Collection<GenericParameterConstraint> constraints = genArg.Constraints;
|
|||
|
#else
|
|||
|
IList<TypeReference> constraints = genArg.Constraints;
|
|||
|
#endif
|
|||
|
if (attrs == GenericParameterAttributes.NonVariant && constraints.Count == 0)
|
|||
|
continue;
|
|||
|
|
|||
|
bool isref = (attrs & GenericParameterAttributes.ReferenceTypeConstraint) != 0;
|
|||
|
bool isvt = (attrs & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0;
|
|||
|
bool isnew = (attrs & GenericParameterAttributes.DefaultConstructorConstraint) != 0;
|
|||
|
bool comma = false;
|
|||
|
|
|||
|
if (!isref && !isvt && !isnew && constraints.Count == 0)
|
|||
|
continue;
|
|||
|
buf.Append (" where ").Append (genArg.Name).Append (" : ");
|
|||
|
if (isref)
|
|||
|
{
|
|||
|
buf.Append ("class");
|
|||
|
comma = true;
|
|||
|
}
|
|||
|
else if (isvt)
|
|||
|
{
|
|||
|
buf.Append ("struct");
|
|||
|
comma = true;
|
|||
|
}
|
|||
|
if (constraints.Count > 0 && !isvt)
|
|||
|
{
|
|||
|
if (comma)
|
|||
|
buf.Append (", ");
|
|||
|
#if NEW_CECIL
|
|||
|
buf.Append (GetTypeName (constraints[0].ConstraintType));
|
|||
|
for (int i = 1; i < constraints.Count; ++i)
|
|||
|
buf.Append (", ").Append (GetTypeName (constraints[i].ConstraintType));
|
|||
|
#else
|
|||
|
buf.Append (GetTypeName (constraints[0]));
|
|||
|
for (int i = 1; i < constraints.Count; ++i)
|
|||
|
buf.Append (", ").Append (GetTypeName (constraints[i]));
|
|||
|
#endif
|
|||
|
}
|
|||
|
if (isnew && !isvt)
|
|||
|
{
|
|||
|
if (comma)
|
|||
|
buf.Append (", ");
|
|||
|
buf.Append ("new()");
|
|||
|
}
|
|||
|
}
|
|||
|
return buf;
|
|||
|
}
|
|||
|
|
|||
|
protected override string GetConstructorDeclaration (MethodDefinition constructor)
|
|||
|
{
|
|||
|
StringBuilder buf = new StringBuilder ();
|
|||
|
AppendVisibility (buf, constructor);
|
|||
|
if (buf.Length == 0)
|
|||
|
return null;
|
|||
|
|
|||
|
buf.Append (' ');
|
|||
|
base.AppendTypeName (buf, constructor.DeclaringType.Name).Append (' ');
|
|||
|
AppendParameters (buf, constructor, constructor.Parameters);
|
|||
|
buf.Append (';');
|
|||
|
|
|||
|
return buf.ToString ();
|
|||
|
}
|
|||
|
|
|||
|
protected override string GetMethodDeclaration (MethodDefinition method)
|
|||
|
{
|
|||
|
string decl = base.GetMethodDeclaration (method);
|
|||
|
if (decl != null)
|
|||
|
return decl + ";";
|
|||
|
return null;
|
|||
|
}
|
|||
|
|
|||
|
protected override StringBuilder AppendMethodName (StringBuilder buf, MethodDefinition method)
|
|||
|
{
|
|||
|
if (DocUtils.IsExplicitlyImplemented (method))
|
|||
|
{
|
|||
|
TypeReference iface;
|
|||
|
MethodReference ifaceMethod;
|
|||
|
DocUtils.GetInfoForExplicitlyImplementedMethod (method, out iface, out ifaceMethod);
|
|||
|
return buf.Append (new CSharpMemberFormatter ().GetName (iface))
|
|||
|
.Append ('.')
|
|||
|
.Append (ifaceMethod.Name);
|
|||
|
}
|
|||
|
|
|||
|
if (method.Name.StartsWith ("op_", StringComparison.Ordinal))
|
|||
|
{
|
|||
|
// this is an operator
|
|||
|
switch (method.Name)
|
|||
|
{
|
|||
|
case "op_Implicit":
|
|||
|
case "op_Explicit":
|
|||
|
buf.Length--; // remove the last space, which assumes a member name is coming
|
|||
|
return buf;
|
|||
|
case "op_Addition":
|
|||
|
case "op_UnaryPlus":
|
|||
|
return buf.Append ("operator +");
|
|||
|
case "op_Subtraction":
|
|||
|
case "op_UnaryNegation":
|
|||
|
return buf.Append ("operator -");
|
|||
|
case "op_Division":
|
|||
|
return buf.Append ("operator /");
|
|||
|
case "op_Multiply":
|
|||
|
return buf.Append ("operator *");
|
|||
|
case "op_Modulus":
|
|||
|
return buf.Append ("operator %");
|
|||
|
case "op_BitwiseAnd":
|
|||
|
return buf.Append ("operator &");
|
|||
|
case "op_BitwiseOr":
|
|||
|
return buf.Append ("operator |");
|
|||
|
case "op_ExclusiveOr":
|
|||
|
return buf.Append ("operator ^");
|
|||
|
case "op_LeftShift":
|
|||
|
return buf.Append ("operator <<");
|
|||
|
case "op_RightShift":
|
|||
|
return buf.Append ("operator >>");
|
|||
|
case "op_LogicalNot":
|
|||
|
return buf.Append ("operator !");
|
|||
|
case "op_OnesComplement":
|
|||
|
return buf.Append ("operator ~");
|
|||
|
case "op_Decrement":
|
|||
|
return buf.Append ("operator --");
|
|||
|
case "op_Increment":
|
|||
|
return buf.Append ("operator ++");
|
|||
|
case "op_True":
|
|||
|
return buf.Append ("operator true");
|
|||
|
case "op_False":
|
|||
|
return buf.Append ("operator false");
|
|||
|
case "op_Equality":
|
|||
|
return buf.Append ("operator ==");
|
|||
|
case "op_Inequality":
|
|||
|
return buf.Append ("operator !=");
|
|||
|
case "op_LessThan":
|
|||
|
return buf.Append ("operator <");
|
|||
|
case "op_LessThanOrEqual":
|
|||
|
return buf.Append ("operator <=");
|
|||
|
case "op_GreaterThan":
|
|||
|
return buf.Append ("operator >");
|
|||
|
case "op_GreaterThanOrEqual":
|
|||
|
return buf.Append ("operator >=");
|
|||
|
default:
|
|||
|
return base.AppendMethodName (buf, method);
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
return base.AppendMethodName (buf, method);
|
|||
|
}
|
|||
|
|
|||
|
protected override StringBuilder AppendGenericMethodConstraints (StringBuilder buf, MethodDefinition method)
|
|||
|
{
|
|||
|
if (method.GenericParameters.Count == 0)
|
|||
|
return buf;
|
|||
|
return AppendConstraints (buf, method.GenericParameters);
|
|||
|
}
|
|||
|
|
|||
|
protected override string RefTypeModifier
|
|||
|
{
|
|||
|
get { return ""; }
|
|||
|
}
|
|||
|
|
|||
|
protected override string GetFinalizerName (MethodDefinition method)
|
|||
|
{
|
|||
|
StringBuilder buf = new StringBuilder();
|
|||
|
base.AppendTypeName(buf, method.DeclaringType.Name);
|
|||
|
|
|||
|
return $"~{buf} ()";
|
|||
|
}
|
|||
|
|
|||
|
protected override StringBuilder AppendVisibility (StringBuilder buf, MethodDefinition method)
|
|||
|
{
|
|||
|
if (method == null)
|
|||
|
return buf;
|
|||
|
if (method.IsPublic)
|
|||
|
return buf.Append ("public");
|
|||
|
if (method.IsFamily)
|
|||
|
return buf.Append ("protected");
|
|||
|
if (method.IsFamilyOrAssembly)
|
|||
|
return buf.Append("protected internal");
|
|||
|
return buf;
|
|||
|
}
|
|||
|
|
|||
|
protected override StringBuilder AppendModifiers (StringBuilder buf, MethodDefinition method)
|
|||
|
{
|
|||
|
string modifiers = String.Empty;
|
|||
|
if (method.IsStatic) modifiers += " static";
|
|||
|
if (method.IsVirtual && !method.IsAbstract)
|
|||
|
{
|
|||
|
if ((method.Attributes & MethodAttributes.NewSlot) != 0) modifiers += " virtual";
|
|||
|
else modifiers += " override";
|
|||
|
}
|
|||
|
TypeDefinition declType = (TypeDefinition)method.DeclaringType;
|
|||
|
if (method.IsAbstract && !declType.IsInterface) modifiers += " abstract";
|
|||
|
if (method.IsFinal) modifiers += " sealed";
|
|||
|
if (modifiers == " virtual sealed") modifiers = "";
|
|||
|
|
|||
|
if ((method.ReturnType.IsRequiredModifier
|
|||
|
&& ((RequiredModifierType)method.ReturnType).ElementType.IsByReference)
|
|||
|
|| method.ReturnType.IsByReference)
|
|||
|
{
|
|||
|
modifiers += " ref";
|
|||
|
}
|
|||
|
|
|||
|
if (method.ReturnType.IsRequiredModifier
|
|||
|
&& method.MethodReturnType.CustomAttributes.Any(attr => attr.AttributeType.FullName == "System.Runtime.CompilerServices.IsReadOnlyAttribute"))
|
|||
|
{
|
|||
|
modifiers += " readonly";
|
|||
|
}
|
|||
|
|
|||
|
switch (method.Name)
|
|||
|
{
|
|||
|
case "op_Implicit":
|
|||
|
modifiers += " implicit operator";
|
|||
|
break;
|
|||
|
case "op_Explicit":
|
|||
|
modifiers += " explicit operator";
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
return buf.Append (modifiers);
|
|||
|
}
|
|||
|
|
|||
|
protected override StringBuilder AppendGenericMethod (StringBuilder buf, MethodDefinition method)
|
|||
|
{
|
|||
|
if (method.IsGenericMethod ())
|
|||
|
{
|
|||
|
IList<GenericParameter> args = method.GenericParameters;
|
|||
|
if (args.Count > 0)
|
|||
|
{
|
|||
|
buf.Append ("<");
|
|||
|
buf.Append (args[0].Name);
|
|||
|
for (int i = 1; i < args.Count; ++i)
|
|||
|
buf.Append (",").Append (args[i].Name);
|
|||
|
buf.Append (">");
|
|||
|
}
|
|||
|
}
|
|||
|
return buf;
|
|||
|
}
|
|||
|
|
|||
|
protected override StringBuilder AppendParameters (StringBuilder buf, MethodDefinition method, IList<ParameterDefinition> parameters)
|
|||
|
{
|
|||
|
return AppendParameters (buf, method, parameters, '(', ')');
|
|||
|
}
|
|||
|
|
|||
|
private StringBuilder AppendParameters (StringBuilder buf, MethodDefinition method, IList<ParameterDefinition> parameters, char begin, char end)
|
|||
|
{
|
|||
|
buf.Append (begin);
|
|||
|
|
|||
|
if (parameters.Count > 0)
|
|||
|
{
|
|||
|
if (DocUtils.IsExtensionMethod (method))
|
|||
|
buf.Append ("this ");
|
|||
|
AppendParameter (buf, parameters[0]);
|
|||
|
for (int i = 1; i < parameters.Count; ++i)
|
|||
|
{
|
|||
|
buf.Append (", ");
|
|||
|
AppendParameter (buf, parameters[i]);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return buf.Append (end);
|
|||
|
}
|
|||
|
|
|||
|
private StringBuilder AppendParameter (StringBuilder buf, ParameterDefinition parameter)
|
|||
|
{
|
|||
|
if (parameter.ParameterType is ByReferenceType)
|
|||
|
{
|
|||
|
if (parameter.IsOut)
|
|||
|
buf.Append ("out ");
|
|||
|
else
|
|||
|
buf.Append ("ref ");
|
|||
|
}
|
|||
|
if (parameter.HasCustomAttributes)
|
|||
|
{
|
|||
|
var isParams = parameter.CustomAttributes.Any (ca => ca.AttributeType.Name == "ParamArrayAttribute");
|
|||
|
if (isParams)
|
|||
|
buf.AppendFormat ("params ");
|
|||
|
}
|
|||
|
buf.Append (GetTypeName (parameter.ParameterType, new DynamicParserContext (parameter))).Append (" ");
|
|||
|
buf.Append (parameter.Name);
|
|||
|
if (parameter.HasDefault && parameter.IsOptional && parameter.HasConstant)
|
|||
|
{
|
|||
|
buf.AppendFormat (" = {0}", MDocUpdater.MakeAttributesValueString (parameter.Constant, parameter.ParameterType));
|
|||
|
}
|
|||
|
return buf;
|
|||
|
}
|
|||
|
|
|||
|
protected override string GetPropertyDeclaration (PropertyDefinition property)
|
|||
|
{
|
|||
|
MethodDefinition method;
|
|||
|
|
|||
|
string get_visible = null;
|
|||
|
if ((method = property.GetMethod) != null &&
|
|||
|
(DocUtils.IsExplicitlyImplemented (method) ||
|
|||
|
(!method.IsPrivate && !method.IsAssembly && !method.IsFamilyAndAssembly)))
|
|||
|
get_visible = AppendVisibility (new StringBuilder (), method).ToString ();
|
|||
|
string set_visible = null;
|
|||
|
if ((method = property.SetMethod) != null &&
|
|||
|
(DocUtils.IsExplicitlyImplemented (method) ||
|
|||
|
(!method.IsPrivate && !method.IsAssembly && !method.IsFamilyAndAssembly)))
|
|||
|
set_visible = AppendVisibility (new StringBuilder (), method).ToString ();
|
|||
|
|
|||
|
if ((set_visible == null) && (get_visible == null))
|
|||
|
return null;
|
|||
|
|
|||
|
string visibility;
|
|||
|
StringBuilder buf = new StringBuilder ();
|
|||
|
if (get_visible != null && (set_visible == null || (set_visible != null && get_visible == set_visible)))
|
|||
|
buf.Append (visibility = get_visible);
|
|||
|
else if (set_visible != null && get_visible == null)
|
|||
|
buf.Append (visibility = set_visible);
|
|||
|
else
|
|||
|
buf.Append (visibility = "public");
|
|||
|
|
|||
|
// Pick an accessor to use for static/virtual/override/etc. checks.
|
|||
|
method = property.SetMethod;
|
|||
|
if (method == null)
|
|||
|
method = property.GetMethod;
|
|||
|
|
|||
|
string modifiers = String.Empty;
|
|||
|
if (method.IsStatic) modifiers += " static";
|
|||
|
if (method.IsVirtual && !method.IsAbstract)
|
|||
|
{
|
|||
|
if ((method.Attributes & MethodAttributes.NewSlot) != 0)
|
|||
|
modifiers += " virtual";
|
|||
|
else
|
|||
|
modifiers += " override";
|
|||
|
}
|
|||
|
TypeDefinition declDef = (TypeDefinition)method.DeclaringType;
|
|||
|
if (method.IsAbstract && !declDef.IsInterface)
|
|||
|
modifiers += " abstract";
|
|||
|
if (method.IsFinal)
|
|||
|
modifiers += " sealed";
|
|||
|
if (modifiers == " virtual sealed")
|
|||
|
modifiers = "";
|
|||
|
buf.Append (modifiers).Append (' ');
|
|||
|
|
|||
|
buf.Append (GetTypeName (property.PropertyType, new DynamicParserContext (property))).Append (' ');
|
|||
|
|
|||
|
IEnumerable<MemberReference> defs = property.DeclaringType.GetDefaultMembers ();
|
|||
|
string name = property.Name;
|
|||
|
foreach (MemberReference mi in defs)
|
|||
|
{
|
|||
|
if (mi == property)
|
|||
|
{
|
|||
|
name = "this";
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
buf.Append (name == "this" ? name : DocUtils.GetPropertyName (property, NestedTypeSeparator));
|
|||
|
|
|||
|
if (property.Parameters.Count != 0)
|
|||
|
{
|
|||
|
AppendParameters (buf, method, property.Parameters, '[', ']');
|
|||
|
}
|
|||
|
|
|||
|
buf.Append (" {");
|
|||
|
if (get_visible != null)
|
|||
|
{
|
|||
|
if (get_visible != visibility)
|
|||
|
buf.Append (' ').Append (get_visible);
|
|||
|
buf.Append (" get;");
|
|||
|
}
|
|||
|
if (set_visible != null)
|
|||
|
{
|
|||
|
if (set_visible != visibility)
|
|||
|
buf.Append (' ').Append (set_visible);
|
|||
|
buf.Append (" set;");
|
|||
|
}
|
|||
|
buf.Append (" }");
|
|||
|
|
|||
|
return buf[0] != ' ' ? buf.ToString () : buf.ToString (1, buf.Length - 1);
|
|||
|
}
|
|||
|
|
|||
|
protected override string GetFieldDeclaration (FieldDefinition field)
|
|||
|
{
|
|||
|
TypeDefinition declType = (TypeDefinition)field.DeclaringType;
|
|||
|
if (declType.IsEnum && field.Name == "value__")
|
|||
|
return null; // This member of enums aren't documented.
|
|||
|
|
|||
|
StringBuilder buf = new StringBuilder ();
|
|||
|
AppendFieldVisibility (buf, field);
|
|||
|
if (buf.Length == 0)
|
|||
|
return null;
|
|||
|
|
|||
|
if (declType.IsEnum)
|
|||
|
return field.Name;
|
|||
|
|
|||
|
if (field.IsStatic && !field.IsLiteral)
|
|||
|
buf.Append (" static");
|
|||
|
if (field.IsInitOnly)
|
|||
|
buf.Append (" readonly");
|
|||
|
if (field.IsLiteral)
|
|||
|
buf.Append (" const");
|
|||
|
|
|||
|
buf.Append (' ').Append (GetTypeName (field.FieldType, new DynamicParserContext (field))).Append (' ');
|
|||
|
buf.Append (field.Name);
|
|||
|
DocUtils.AppendFieldValue (buf, field);
|
|||
|
buf.Append (';');
|
|||
|
|
|||
|
return buf.ToString ();
|
|||
|
}
|
|||
|
|
|||
|
static void AppendFieldVisibility (StringBuilder buf, FieldDefinition field)
|
|||
|
{
|
|||
|
if (field.IsPublic)
|
|||
|
{
|
|||
|
buf.Append("public");
|
|||
|
return;
|
|||
|
}
|
|||
|
if (field.IsFamily)
|
|||
|
{
|
|||
|
buf.Append("protected");
|
|||
|
}
|
|||
|
if ( field.IsFamilyOrAssembly)
|
|||
|
{
|
|||
|
buf.Append("protected internal");
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
protected override string GetEventDeclaration (EventDefinition e)
|
|||
|
{
|
|||
|
StringBuilder buf = new StringBuilder ();
|
|||
|
|
|||
|
if (AppendVisibility (buf, e.AddMethod).Length == 0 && !IsPublicEII (e))
|
|||
|
{
|
|||
|
return null;
|
|||
|
}
|
|||
|
if (e.DeclaringType.IsInterface)
|
|||
|
buf.Clear ();
|
|||
|
|
|||
|
AppendModifiers (buf, e.AddMethod);
|
|||
|
|
|||
|
buf.Append (buf.Length == 0 ? "event " : " event ");
|
|||
|
buf.Append (GetTypeName (e.EventType, new DynamicParserContext (e.AddMethod.Parameters[0]))).Append (' ');
|
|||
|
buf.Append (e.Name).Append (';');
|
|||
|
|
|||
|
return buf.ToString ();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|