Browse Source

Fix #1237: ILLanguage incorrectly displays modopt types when using short type names

pull/1243/head
Siegfried Pammer 7 years ago
parent
commit
1d937bc47f
  1. 2
      ICSharpCode.Decompiler/TypeSystem/ModifiedType.cs
  2. 172
      ILSpy/Languages/Language.cs

2
ICSharpCode.Decompiler/TypeSystem/ModifiedType.cs

@ -38,7 +38,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public IType Modifier => modifier; public IType Modifier => modifier;
public override TypeKind Kind => kind; public override TypeKind Kind => kind;
public override string NameSuffix => (kind == TypeKind.ModReq ? "modreq" : "modopt") + $"({modifier.FullName})"; public override string NameSuffix => (kind == TypeKind.ModReq ? " modreq" : " modopt") + $"({modifier.FullName})";
public override bool? IsReferenceType => elementType.IsReferenceType; public override bool? IsReferenceType => elementType.IsReferenceType;
public override bool IsByRefLike => elementType.IsByRefLike; public override bool IsByRefLike => elementType.IsByRefLike;

172
ILSpy/Languages/Language.cs

@ -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.

Loading…
Cancel
Save