Xamarin Public Jenkins (auto-signing) 95fdb59ea6 Imported Upstream version 6.6.0.89
Former-commit-id: b39a328747c2f3414dc52e009fb6f0aa80ca2492
2019-09-24 08:53:40 +00:00

590 lines
22 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 ILFullMemberFormatter : MemberFormatter
{
public override string Language
{
get { return "ILAsm"; }
}
protected override string NestedTypeSeparator
{
get
{
return "/";
}
}
protected override StringBuilder AppendNamespace (StringBuilder buf, TypeReference type)
{
if (GetBuiltinType (type.FullName) != null)
return buf;
string ns = DocUtils.GetNamespace (type);
if (ns != null && ns.Length > 0)
{
if (type.IsValueType)
buf.Append ("valuetype ");
else
buf.Append ("class ");
buf.Append (ns).Append ('.');
}
return buf;
}
protected static string GetBuiltinType (string t)
{
switch (t)
{
case "System.Byte": return "unsigned int8";
case "System.SByte": return "int8";
case "System.Int16": return "int16";
case "System.Int32": return "int32";
case "System.Int64": return "int64";
case "System.IntPtr": return "native int";
case "System.UInt16": return "unsigned int16";
case "System.UInt32": return "unsigned int32";
case "System.UInt64": return "unsigned int64";
case "System.UIntPtr": return "native unsigned int";
case "System.Single": return "float32";
case "System.Double": return "float64";
case "System.Boolean": return "bool";
case "System.Char": return "char";
case "System.Void": return "void";
case "System.String": return "string";
case "System.Object": return "object";
}
return null;
}
protected override StringBuilder AppendTypeName (StringBuilder buf, string typename)
{
return buf.Append (typename);
}
protected override StringBuilder AppendTypeName (StringBuilder buf, TypeReference type, DynamicParserContext context)
{
if (type is GenericParameter)
{
AppendGenericParameterConstraints (buf, (GenericParameter)type).Append (type.Name);
return buf;
}
string s = GetBuiltinType (type.FullName);
if (s != null)
{
return buf.Append (s);
}
return base.AppendTypeName (buf, type, context);
}
private StringBuilder AppendGenericParameterConstraints (StringBuilder buf, GenericParameter type)
{
if (MemberFormatterState != MemberFormatterState.WithinGenericTypeParameters)
{
return buf.Append (type.Owner is TypeReference ? "!" : "!!");
}
GenericParameterAttributes attrs = type.Attributes;
if ((attrs & GenericParameterAttributes.ReferenceTypeConstraint) != 0)
buf.Append ("class ");
if ((attrs & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0)
buf.Append ("struct ");
if ((attrs & GenericParameterAttributes.DefaultConstructorConstraint) != 0)
buf.Append (".ctor ");
MemberFormatterState = 0;
#if NEW_CECIL
Mono.Collections.Generic.Collection<GenericParameterConstraint> constraints = type.Constraints;
if (constraints.Count > 0)
{
var full = new ILFullMemberFormatter ();
buf.Append ("(").Append (full.GetName (constraints[0].ConstraintType));
for (int i = 1; i < constraints.Count; ++i)
{
buf.Append (", ").Append (full.GetName (constraints[i].ConstraintType));
}
buf.Append (") ");
}
#else
IList<TypeReference> constraints = type.Constraints;
if (constraints.Count > 0)
{
var full = new ILFullMemberFormatter ();
buf.Append ("(").Append (full.GetName (constraints[0]));
for (int i = 1; i < constraints.Count; ++i)
{
buf.Append (", ").Append (full.GetName (constraints[i]));
}
buf.Append (") ");
}
#endif
MemberFormatterState = MemberFormatterState.WithinGenericTypeParameters;
if ((attrs & GenericParameterAttributes.Covariant) != 0)
buf.Append ("+ ");
if ((attrs & GenericParameterAttributes.Contravariant) != 0)
buf.Append ("- ");
return buf;
}
protected override string GetTypeDeclaration (TypeDefinition type)
{
string visibility = GetTypeVisibility (type.Attributes);
if (visibility == null)
return null;
StringBuilder buf = new StringBuilder ();
buf.Append (".class ");
if (type.IsNested)
buf.Append ("nested ");
buf.Append (visibility).Append (" ");
if (type.IsInterface)
buf.Append ("interface ");
if (type.IsSequentialLayout)
buf.Append ("sequential ");
if (type.IsAutoLayout)
buf.Append ("auto ");
if (type.IsAnsiClass)
buf.Append ("ansi ");
if (type.IsAbstract)
buf.Append ("abstract ");
if (type.IsSerializable)
buf.Append ("serializable ");
if (type.IsSealed)
buf.Append ("sealed ");
if (type.IsBeforeFieldInit)
buf.Append ("beforefieldinit ");
var state = MemberFormatterState;
MemberFormatterState = MemberFormatterState.WithinGenericTypeParameters;
buf.Append (GetName (type));
MemberFormatterState = state;
var full = new ILFullMemberFormatter ();
if (type.BaseType != null)
{
buf.Append (" extends ");
if (type.BaseType.FullName == "System.Object")
buf.Append ("System.Object");
else
buf.Append (full.GetName (type.BaseType).Substring ("class ".Length));
}
bool first = true;
foreach (var name in type.Interfaces.Where (i => MDocUpdater.IsPublic (i.InterfaceType.Resolve ()))
.Select (i => full.GetName (i.InterfaceType))
.OrderBy (n => n))
{
if (first)
{
buf.Append (" implements ");
first = false;
}
else
{
buf.Append (", ");
}
buf.Append (name);
}
return buf.ToString ();
}
protected override StringBuilder AppendGenericType (StringBuilder buf, TypeReference type, DynamicParserContext context, bool appendGeneric = true)
{
List<TypeReference> decls = DocUtils.GetDeclaringTypes (
type is GenericInstanceType ? type.GetElementType () : type);
bool first = true;
foreach (var decl in decls)
{
TypeReference declDef = decl.Resolve () ?? decl;
if (!first)
{
buf.Append (NestedTypeSeparator);
}
first = false;
AppendTypeName (buf, declDef, context);
}
buf.Append ('<');
first = true;
foreach (TypeReference arg in GetGenericArguments (type))
{
if (!first)
buf.Append (", ");
first = false;
_AppendTypeName (buf, arg, context);
}
buf.Append ('>');
return buf;
}
static string GetTypeVisibility (TypeAttributes ta)
{
switch (ta & TypeAttributes.VisibilityMask)
{
case TypeAttributes.Public:
case TypeAttributes.NestedPublic:
return "public";
case TypeAttributes.NestedFamily:
case TypeAttributes.NestedFamORAssem:
return "protected";
default:
return null;
}
}
protected override string GetConstructorDeclaration (MethodDefinition constructor)
{
return GetMethodDeclaration (constructor);
}
protected override string GetMethodDeclaration (MethodDefinition method)
{
if (method.IsPrivate && !DocUtils.IsExplicitlyImplemented (method))
return null;
var buf = new StringBuilder ();
buf.Append (".method ");
AppendVisibility (buf, method);
if (method.IsStatic)
buf.Append ("static ");
if (method.IsHideBySig)
buf.Append ("hidebysig ");
if (method.IsPInvokeImpl && method.PInvokeInfo != null)
{
var info = method.PInvokeInfo;
buf.Append ("pinvokeimpl (\"")
.Append (info.Module.Name)
.Append ("\" as \"")
.Append (info.EntryPoint)
.Append ("\"");
if (info.IsCharSetAuto)
buf.Append (" auto");
if (info.IsCharSetUnicode)
buf.Append (" unicode");
if (info.IsCharSetAnsi)
buf.Append (" ansi");
if (info.IsCallConvCdecl)
buf.Append (" cdecl");
if (info.IsCallConvStdCall)
buf.Append (" stdcall");
if (info.IsCallConvWinapi)
buf.Append (" winapi");
if (info.IsCallConvThiscall)
buf.Append (" thiscall");
if (info.SupportsLastError)
buf.Append (" lasterr");
buf.Append (")");
}
if (method.IsSpecialName)
buf.Append ("specialname ");
if (method.IsRuntimeSpecialName)
buf.Append ("rtspecialname ");
if (method.IsNewSlot)
buf.Append ("newslot ");
if (method.IsVirtual)
buf.Append ("virtual ");
if (!method.IsStatic)
buf.Append ("instance ");
_AppendTypeName (buf, method.ReturnType, new DynamicParserContext (method.MethodReturnType));
buf.Append (' ')
.Append (method.Name);
if (method.IsGenericMethod ())
{
var state = MemberFormatterState;
MemberFormatterState = MemberFormatterState.WithinGenericTypeParameters;
IList<GenericParameter> args = method.GenericParameters;
if (args.Count > 0)
{
buf.Append ("<");
_AppendTypeName (buf, args[0], null);
for (int i = 1; i < args.Count; ++i)
_AppendTypeName (buf.Append (", "), args[i], null);
buf.Append (">");
}
MemberFormatterState = state;
}
buf.Append ('(');
bool first = true;
for (int i = 0; i < method.Parameters.Count; ++i)
{
var param = method.Parameters[i];
if (!first)
buf.Append (", ");
first = false;
if (param.IsOut) buf.Append ("[out] ");
else if (param.IsIn) buf.Append ("[in]");
_AppendTypeName (buf, param.ParameterType, new DynamicParserContext (param));
if (param.ParameterType.IsByReference) buf.Append ("&");
buf.Append (' ');
buf.Append (param.Name);
}
buf.Append (')');
if (method.IsIL)
buf.Append (" cil");
if (method.IsRuntime)
buf.Append (" runtime");
if (method.IsManaged)
buf.Append (" managed");
return buf.ToString ();
}
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);
}
return base.AppendMethodName (buf, method);
}
protected override string RefTypeModifier
{
get { return ""; }
}
protected override StringBuilder AppendVisibility (StringBuilder buf, MethodDefinition method)
{
if (method.IsPublic)
return buf.Append ("public ");
if (method.IsFamilyAndAssembly)
return buf.Append ("familyandassembly");
if (method.IsFamilyOrAssembly)
return buf.Append ("familyorassembly");
if (method.IsFamily)
return buf.Append ("family");
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 = "";
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 ");
}
buf.Append (GetName (parameter.ParameterType)).Append (" ");
return buf.Append (parameter.Name);
}
protected override string GetPropertyDeclaration (PropertyDefinition property)
{
MethodDefinition gm = null, sm = null;
string get_visible = null;
if ((gm = property.GetMethod) != null &&
(DocUtils.IsExplicitlyImplemented (gm) ||
(!gm.IsPrivate && !gm.IsAssembly && !gm.IsFamilyAndAssembly)))
get_visible = AppendVisibility (new StringBuilder (), gm).ToString ();
string set_visible = null;
if ((sm = property.SetMethod) != null &&
(DocUtils.IsExplicitlyImplemented (sm) ||
(!sm.IsPrivate && !sm.IsAssembly && !sm.IsFamilyAndAssembly)))
set_visible = AppendVisibility (new StringBuilder (), sm).ToString ();
if ((set_visible == null) && (get_visible == null))
return null;
StringBuilder buf = new StringBuilder ()
.Append (".property ");
if (!(gm ?? sm).IsStatic)
buf.Append ("instance ");
_AppendTypeName (buf, property.PropertyType, new DynamicParserContext (property));
buf.Append (' ').Append (property.Name);
if (!property.HasParameters || property.Parameters.Count == 0)
return buf.ToString ();
buf.Append ('(');
bool first = true;
foreach (ParameterDefinition p in property.Parameters)
{
if (!first)
buf.Append (", ");
first = false;
_AppendTypeName (buf, p.ParameterType, new DynamicParserContext (p));
}
buf.Append (')');
return buf.ToString ();
}
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;
buf.Insert (0, ".field ");
if (field.IsStatic)
buf.Append ("static ");
if (field.IsInitOnly)
buf.Append ("initonly ");
if (field.IsLiteral)
buf.Append ("literal ");
_AppendTypeName (buf, field.FieldType, new DynamicParserContext (field));
buf.Append (' ').Append (field.Name);
AppendFieldValue (buf, field);
return buf.ToString ();
}
static StringBuilder AppendFieldVisibility (StringBuilder buf, FieldDefinition field)
{
if (field.IsPublic)
return buf.Append ("public ");
if (field.IsFamilyAndAssembly)
return buf.Append ("familyandassembly ");
if (field.IsFamilyOrAssembly)
return buf.Append ("familyorassembly ");
if (field.IsFamily)
return buf.Append ("family ");
return buf;
}
static StringBuilder AppendFieldValue (StringBuilder buf, FieldDefinition field)
{
// enums have a value__ field, which we ignore
if (field.DeclaringType.IsGenericType ())
return buf;
if (field.HasConstant && field.IsLiteral)
{
object val = null;
try
{
val = field.Constant;
}
catch
{
return buf;
}
if (val == null)
buf.Append (" = ").Append ("null");
else if (val is Enum)
buf.Append (" = ")
.Append (GetBuiltinType (field.DeclaringType.GetUnderlyingType ().FullName))
.Append ('(')
.Append (val.ToString ())
.Append (')');
else if (val is IFormattable)
{
string value = ((IFormattable)val).ToString (null, CultureInfo.InvariantCulture);
buf.Append (" = ");
if (val is string)
buf.Append ("\"" + value + "\"");
else
buf.Append (GetBuiltinType (field.DeclaringType.GetUnderlyingType ().FullName))
.Append ('(')
.Append (value)
.Append (')');
}
}
return buf;
}
protected override string GetEventDeclaration (EventDefinition e)
{
StringBuilder buf = new StringBuilder ();
if (AppendVisibility (buf, e.AddMethod).Length == 0 && !IsPublicEII (e))
{
return null;
}
buf.Length = 0;
buf.Append (".event ")
.Append (GetName (e.EventType))
.Append (' ')
.Append (e.Name);
return buf.ToString ();
}
}
}