|
|
@ -20,9 +20,11 @@ using System; |
|
|
|
using System.Collections.Generic; |
|
|
|
using System.Collections.Generic; |
|
|
|
using System.Reflection.Metadata; |
|
|
|
using System.Reflection.Metadata; |
|
|
|
using System.Reflection.PortableExecutable; |
|
|
|
using System.Reflection.PortableExecutable; |
|
|
|
|
|
|
|
using System.Text; |
|
|
|
using ICSharpCode.Decompiler; |
|
|
|
using ICSharpCode.Decompiler; |
|
|
|
using ICSharpCode.Decompiler.Metadata; |
|
|
|
using ICSharpCode.Decompiler.Metadata; |
|
|
|
using ICSharpCode.Decompiler.TypeSystem; |
|
|
|
using ICSharpCode.Decompiler.TypeSystem; |
|
|
|
|
|
|
|
using ICSharpCode.Decompiler.TypeSystem.Implementation; |
|
|
|
using ICSharpCode.Decompiler.Util; |
|
|
|
using ICSharpCode.Decompiler.Util; |
|
|
|
|
|
|
|
|
|
|
|
using SRM = System.Reflection.Metadata; |
|
|
|
using SRM = System.Reflection.Metadata; |
|
|
@ -152,21 +154,177 @@ namespace ICSharpCode.ILSpy |
|
|
|
output.WriteLine("// " + comment); |
|
|
|
output.WriteLine("// " + comment); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#region TypeToString
|
|
|
|
/// <summary>
|
|
|
|
/// <summary>
|
|
|
|
/// Converts a type definition, reference or specification into a string. This method is used by tree nodes and search results.
|
|
|
|
/// Converts a type definition, reference or specification into a string. This method is used by tree nodes and search results.
|
|
|
|
/// </summary>
|
|
|
|
/// </summary>
|
|
|
|
public virtual string TypeToString(IType type, bool includeNamespace) |
|
|
|
public virtual string TypeToString(IType type, bool includeNamespace) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (includeNamespace) |
|
|
|
var visitor = new TypeToStringVisitor(includeNamespace); |
|
|
|
return type.ReflectionName; |
|
|
|
type.AcceptVisitor(visitor); |
|
|
|
else { |
|
|
|
return visitor.ToString(); |
|
|
|
int index = type.ReflectionName.LastIndexOf('.'); |
|
|
|
} |
|
|
|
if (index > 0) { |
|
|
|
|
|
|
|
return type.ReflectionName.Substring(index + 1); |
|
|
|
class TypeToStringVisitor : TypeVisitor |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
readonly bool includeNamespace; |
|
|
|
|
|
|
|
readonly StringBuilder builder; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public override string ToString() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
return builder.ToString(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public TypeToStringVisitor(bool includeNamespace) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
this.includeNamespace = includeNamespace; |
|
|
|
|
|
|
|
this.builder = new StringBuilder(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public override IType VisitArrayType(ArrayType type) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
base.VisitArrayType(type); |
|
|
|
|
|
|
|
builder.Append('['); |
|
|
|
|
|
|
|
builder.Append(',', type.Dimensions - 1); |
|
|
|
|
|
|
|
builder.Append(']'); |
|
|
|
|
|
|
|
return type; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public override IType VisitByReferenceType(ByReferenceType type) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
base.VisitByReferenceType(type); |
|
|
|
|
|
|
|
builder.Append('&'); |
|
|
|
|
|
|
|
return type; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public override IType VisitModOpt(ModifiedType type) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
type.ElementType.AcceptVisitor(this); |
|
|
|
|
|
|
|
builder.Append(" modopt("); |
|
|
|
|
|
|
|
type.Modifier.AcceptVisitor(this); |
|
|
|
|
|
|
|
builder.Append(")"); |
|
|
|
|
|
|
|
return type; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public override IType VisitModReq(ModifiedType type) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
type.ElementType.AcceptVisitor(this); |
|
|
|
|
|
|
|
builder.Append(" modreq("); |
|
|
|
|
|
|
|
type.Modifier.AcceptVisitor(this); |
|
|
|
|
|
|
|
builder.Append(")"); |
|
|
|
|
|
|
|
return type; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public override IType VisitPointerType(PointerType type) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
base.VisitPointerType(type); |
|
|
|
|
|
|
|
builder.Append('*'); |
|
|
|
|
|
|
|
return type; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public override IType VisitTypeParameter(ITypeParameter type) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
base.VisitTypeParameter(type); |
|
|
|
|
|
|
|
builder.Append(type.Name); |
|
|
|
|
|
|
|
return type; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public override IType VisitParameterizedType(ParameterizedType type) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
type.GenericType.AcceptVisitor(this); |
|
|
|
|
|
|
|
builder.Append('<'); |
|
|
|
|
|
|
|
for (int i = 0; i < type.TypeArguments.Count; i++) { |
|
|
|
|
|
|
|
if (i > 0) |
|
|
|
|
|
|
|
builder.Append(','); |
|
|
|
|
|
|
|
type.TypeArguments[i].AcceptVisitor(this); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
builder.Append('>'); |
|
|
|
|
|
|
|
return type; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public override IType VisitTupleType(TupleType type) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
type.UnderlyingType.AcceptVisitor(this); |
|
|
|
|
|
|
|
return type; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public override IType VisitOtherType(IType type) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (includeNamespace) |
|
|
|
|
|
|
|
builder.Append(type.FullName); |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
builder.Append(type.Name); |
|
|
|
|
|
|
|
return type; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public override IType VisitTypeDefinition(ITypeDefinition type) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
switch (type.KnownTypeCode) { |
|
|
|
|
|
|
|
case KnownTypeCode.Object: |
|
|
|
|
|
|
|
builder.Append("object"); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case KnownTypeCode.Boolean: |
|
|
|
|
|
|
|
builder.Append("bool"); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case KnownTypeCode.Char: |
|
|
|
|
|
|
|
builder.Append("char"); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case KnownTypeCode.SByte: |
|
|
|
|
|
|
|
builder.Append("int8"); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case KnownTypeCode.Byte: |
|
|
|
|
|
|
|
builder.Append("uint8"); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case KnownTypeCode.Int16: |
|
|
|
|
|
|
|
builder.Append("int16"); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case KnownTypeCode.UInt16: |
|
|
|
|
|
|
|
builder.Append("uint16"); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case KnownTypeCode.Int32: |
|
|
|
|
|
|
|
builder.Append("int32"); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case KnownTypeCode.UInt32: |
|
|
|
|
|
|
|
builder.Append("uint32"); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case KnownTypeCode.Int64: |
|
|
|
|
|
|
|
builder.Append("int64"); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case KnownTypeCode.UInt64: |
|
|
|
|
|
|
|
builder.Append("uint64"); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case KnownTypeCode.Single: |
|
|
|
|
|
|
|
builder.Append("float32"); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case KnownTypeCode.Double: |
|
|
|
|
|
|
|
builder.Append("float64"); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case KnownTypeCode.String: |
|
|
|
|
|
|
|
builder.Append("string"); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case KnownTypeCode.Void: |
|
|
|
|
|
|
|
builder.Append("void"); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case KnownTypeCode.IntPtr: |
|
|
|
|
|
|
|
builder.Append("native int"); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case KnownTypeCode.UIntPtr: |
|
|
|
|
|
|
|
builder.Append("native uint"); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case KnownTypeCode.TypedReference: |
|
|
|
|
|
|
|
builder.Append("typedref"); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
default: |
|
|
|
|
|
|
|
if (includeNamespace) |
|
|
|
|
|
|
|
builder.Append(type.FullName); |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
builder.Append(type.Name); |
|
|
|
|
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
return type.ReflectionName; |
|
|
|
return type; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <summary>
|
|
|
|
/// Converts a member signature to a string.
|
|
|
|
/// Converts a member signature to a string.
|
|
|
|