Browse Source

Use C# syntax for generic types in the tree view.

pull/100/head
Daniel Grunwald 15 years ago
parent
commit
99f5c45a16
  1. 72
      ICSharpCode.Decompiler/Ast/AstBuilder.cs
  2. 33
      ILSpy/CSharpLanguage.cs
  3. 2
      ILSpy/TreeNodes/TypeTreeNode.cs

72
ICSharpCode.Decompiler/Ast/AstBuilder.cs

@ -20,6 +20,14 @@ namespace ICSharpCode.Decompiler.Ast @@ -20,6 +20,14 @@ namespace ICSharpCode.Decompiler.Ast
using ClassType = ICSharpCode.NRefactory.TypeSystem.ClassType;
using VarianceModifier = ICSharpCode.NRefactory.TypeSystem.VarianceModifier;
[Flags]
public enum ConvertTypeOptions
{
None = 0,
IncludeNamespace = 1,
IncludeTypeParameterDefinitions = 2
}
public class AstBuilder
{
DecompilerContext context = new DecompilerContext();
@ -270,13 +278,13 @@ namespace ICSharpCode.Decompiler.Ast @@ -270,13 +278,13 @@ namespace ICSharpCode.Decompiler.Ast
/// a type system type reference.</param>
/// <param name="typeAttributes">Attributes associated with the Cecil type reference.
/// This is used to support the 'dynamic' type.</param>
public static AstType ConvertType(TypeReference type, ICustomAttributeProvider typeAttributes = null)
public static AstType ConvertType(TypeReference type, ICustomAttributeProvider typeAttributes = null, ConvertTypeOptions options = ConvertTypeOptions.None)
{
int typeIndex = 0;
return ConvertType(type, typeAttributes, ref typeIndex);
return ConvertType(type, typeAttributes, ref typeIndex, options);
}
static AstType ConvertType(TypeReference type, ICustomAttributeProvider typeAttributes, ref int typeIndex)
static AstType ConvertType(TypeReference type, ICustomAttributeProvider typeAttributes, ref int typeIndex, ConvertTypeOptions options)
{
while (type is OptionalModifierType || type is RequiredModifierType) {
type = ((TypeSpecification)type).ElementType;
@ -288,39 +296,44 @@ namespace ICSharpCode.Decompiler.Ast @@ -288,39 +296,44 @@ namespace ICSharpCode.Decompiler.Ast
if (type is Mono.Cecil.ByReferenceType) {
typeIndex++;
// by reference type cannot be represented in C#; so we'll represent it as a pointer instead
return ConvertType((type as Mono.Cecil.ByReferenceType).ElementType, typeAttributes, ref typeIndex)
return ConvertType((type as Mono.Cecil.ByReferenceType).ElementType, typeAttributes, ref typeIndex, options)
.MakePointerType();
} else if (type is Mono.Cecil.PointerType) {
typeIndex++;
return ConvertType((type as Mono.Cecil.PointerType).ElementType, typeAttributes, ref typeIndex)
return ConvertType((type as Mono.Cecil.PointerType).ElementType, typeAttributes, ref typeIndex, options)
.MakePointerType();
} else if (type is Mono.Cecil.ArrayType) {
typeIndex++;
return ConvertType((type as Mono.Cecil.ArrayType).ElementType, typeAttributes, ref typeIndex)
return ConvertType((type as Mono.Cecil.ArrayType).ElementType, typeAttributes, ref typeIndex, options)
.MakeArrayType((type as Mono.Cecil.ArrayType).Rank);
} else if (type is GenericInstanceType) {
GenericInstanceType gType = (GenericInstanceType)type;
if (gType.ElementType.Namespace == "System" && gType.ElementType.Name == "Nullable`1" && gType.GenericArguments.Count == 1) {
typeIndex++;
return new ComposedType {
BaseType = ConvertType(gType.GenericArguments[0], typeAttributes, ref typeIndex),
BaseType = ConvertType(gType.GenericArguments[0], typeAttributes, ref typeIndex, options),
HasNullableSpecifier = true
};
}
AstType baseType = ConvertType(gType.ElementType, typeAttributes, ref typeIndex);
AstType baseType = ConvertType(gType.ElementType, typeAttributes, ref typeIndex, options & ~ConvertTypeOptions.IncludeTypeParameterDefinitions);
List<AstType> typeArguments = new List<AstType>();
foreach (var typeArgument in gType.GenericArguments) {
typeIndex++;
typeArguments.Add(ConvertType(typeArgument, typeAttributes, ref typeIndex));
typeArguments.Add(ConvertType(typeArgument, typeAttributes, ref typeIndex, options));
}
ApplyTypeArgumentsTo(baseType, typeArguments);
return baseType;
} else if (type is GenericParameter) {
return new SimpleType(type.Name);
} else if (type.IsNested) {
AstType typeRef = ConvertType(type.DeclaringType, typeAttributes, ref typeIndex);
AstType typeRef = ConvertType(type.DeclaringType, typeAttributes, ref typeIndex, options & ~ConvertTypeOptions.IncludeTypeParameterDefinitions);
string namepart = ICSharpCode.NRefactory.TypeSystem.ReflectionHelper.SplitTypeParameterCountFromReflectionName(type.Name);
return new MemberType { Target = typeRef, MemberName = namepart }.WithAnnotation(type);
MemberType memberType = new MemberType { Target = typeRef, MemberName = namepart };
memberType.AddAnnotation(type);
if ((options & ConvertTypeOptions.IncludeTypeParameterDefinitions) == ConvertTypeOptions.IncludeTypeParameterDefinitions) {
AddTypeParameterDefininitionsTo(type, memberType);
}
return memberType;
} else {
string ns = type.Namespace ?? string.Empty;
string name = type.Name;
@ -369,18 +382,35 @@ namespace ICSharpCode.Decompiler.Ast @@ -369,18 +382,35 @@ namespace ICSharpCode.Decompiler.Ast
name = ICSharpCode.NRefactory.TypeSystem.ReflectionHelper.SplitTypeParameterCountFromReflectionName(name);
// TODO: Until we can simplify type with 'using', use just the name without namesapce
return new SimpleType(name).WithAnnotation(type);
AstType astType;
if ((options & ConvertTypeOptions.IncludeNamespace) == ConvertTypeOptions.IncludeNamespace && ns.Length > 0) {
string[] parts = ns.Split('.');
AstType nsType = new SimpleType(parts[0]);
for (int i = 1; i < parts.Length; i++) {
nsType = new MemberType { Target = nsType, MemberName = parts[i] };
}
astType = new MemberType { Target = nsType, MemberName = name };
} else {
astType = new SimpleType(name);
}
astType.AddAnnotation(type);
if ((options & ConvertTypeOptions.IncludeTypeParameterDefinitions) == ConvertTypeOptions.IncludeTypeParameterDefinitions) {
AddTypeParameterDefininitionsTo(type, astType);
}
return astType;
}
}
}
// if (ns.Length == 0)
// return new SimpleType(name).WithAnnotation(type);
// string[] parts = ns.Split('.');
// AstType nsType = new SimpleType(parts[0]);
// for (int i = 1; i < parts.Length; i++) {
// nsType = new MemberType { Target = nsType, MemberName = parts[i] };
// }
// return new MemberType { Target = nsType, MemberName = name }.WithAnnotation(type);
static void AddTypeParameterDefininitionsTo(TypeReference type, AstType astType)
{
if (type.HasGenericParameters) {
List<AstType> typeArguments = new List<AstType>();
foreach (GenericParameter gp in type.GenericParameters) {
typeArguments.Add(new SimpleType(gp.Name));
}
ApplyTypeArgumentsTo(astType, typeArguments);
}
}

33
ILSpy/CSharpLanguage.cs

@ -387,13 +387,10 @@ namespace ICSharpCode.ILSpy @@ -387,13 +387,10 @@ namespace ICSharpCode.ILSpy
public override string TypeToString(TypeReference type, bool includeNamespace, ICustomAttributeProvider typeAttributes = null)
{
AstType astType = AstBuilder.ConvertType(type, typeAttributes);
if (includeNamespace) {
// embed the type in TypeReferenceExpression so that the whole type can get replaced
var tre = new TypeReferenceExpression { Type = astType };
tre.AcceptVisitor(new AddNamespaceToType(), null);
astType = tre.Type;
}
ConvertTypeOptions options = ConvertTypeOptions.IncludeTypeParameterDefinitions;
if (includeNamespace)
options |= ConvertTypeOptions.IncludeNamespace;
AstType astType = AstBuilder.ConvertType(type, typeAttributes, options);
StringWriter w = new StringWriter();
if (type.IsByReference) {
@ -411,28 +408,6 @@ namespace ICSharpCode.ILSpy @@ -411,28 +408,6 @@ namespace ICSharpCode.ILSpy
return w.ToString();
}
sealed class AddNamespaceToType : DepthFirstAstVisitor<object, object>
{
public override object VisitSimpleType(SimpleType simpleType, object data)
{
base.VisitSimpleType(simpleType, data); // handle type arguments
TypeReference tr = simpleType.Annotation<TypeReference>();
if (tr != null && !string.IsNullOrEmpty(tr.Namespace)) {
string[] parts = tr.Namespace.Split('.');
AstType nsType = new SimpleType(parts[0]);
for (int i = 1; i < parts.Length; i++) {
nsType = new MemberType { Target = nsType, MemberName = parts[i] };
}
MemberType memberType = new MemberType();
memberType.Target = nsType;
memberType.MemberName = simpleType.Identifier;
simpleType.TypeArguments.MoveTo(memberType.TypeArguments);
simpleType.ReplaceWith(memberType);
}
return null;
}
}
public override bool ShowMember(MemberReference member)
{
return showAllMembers || !AstBuilder.MemberIsHidden(member, new DecompilationOptions().DecompilerSettings);

2
ILSpy/TreeNodes/TypeTreeNode.cs

@ -59,7 +59,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -59,7 +59,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
}
public override object Text {
get { return HighlightSearchMatch(type.Name); }
get { return HighlightSearchMatch(this.Language.TypeToString(type, includeNamespace: false)); }
}
public bool IsPublicAPI {

Loading…
Cancel
Save