Browse Source

AstTypeBuilder: Distribute type arguments on outer types and nested type.

pull/1198/head
Daniel Grunwald 7 years ago
parent
commit
c79b29ab41
  1. 171
      ICSharpCode.Decompiler/CSharp/AstTypeBuilder.cs
  2. 3
      ICSharpCode.Decompiler/IL/ILReader.cs
  3. 3
      ICSharpCode.Decompiler/Metadata/Dom.cs

171
ICSharpCode.Decompiler/CSharp/AstTypeBuilder.cs

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Reflection.Metadata; using System.Reflection.Metadata;
using ICSharpCode.Decompiler.CSharp.Syntax; using ICSharpCode.Decompiler.CSharp.Syntax;
@ -8,6 +9,7 @@ using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.Util; using ICSharpCode.Decompiler.Util;
using FullTypeName = ICSharpCode.Decompiler.TypeSystem.FullTypeName; using FullTypeName = ICSharpCode.Decompiler.TypeSystem.FullTypeName;
using TopLevelTypeName = ICSharpCode.Decompiler.TypeSystem.TopLevelTypeName;
namespace ICSharpCode.Decompiler.CSharp namespace ICSharpCode.Decompiler.CSharp
{ {
@ -23,7 +25,7 @@ namespace ICSharpCode.Decompiler.CSharp
public class AstTypeBuilder : ISignatureTypeProvider<AstType, GenericContext> public class AstTypeBuilder : ISignatureTypeProvider<AstType, GenericContext>
{ {
ConvertTypeOptions options; readonly ConvertTypeOptions options;
public AstTypeBuilder(ConvertTypeOptions options) public AstTypeBuilder(ConvertTypeOptions options)
{ {
@ -47,20 +49,30 @@ namespace ICSharpCode.Decompiler.CSharp
return AstType.Create("System.IntPtr"); return AstType.Create("System.IntPtr");
} }
static readonly FullTypeName systemNullable = new TopLevelTypeName("System", "Nullable", 1);
public AstType GetGenericInstantiation(AstType genericType, ImmutableArray<AstType> typeArguments) public AstType GetGenericInstantiation(AstType genericType, ImmutableArray<AstType> typeArguments)
{ {
switch (genericType) { var typeName = genericType.Annotations.OfType<FullTypeName>().FirstOrDefault();
case SimpleType st: if (typeName == systemNullable && typeArguments.Length == 1) {
st.TypeArguments.AddRange(typeArguments); return typeArguments[0].MakeNullableType();
return st; }
case MemberType mt: if (typeName.IsNested && genericType is MemberType mt && typeArguments.Length > typeName.TypeParameterCount) {
mt.TypeArguments.AddRange(typeArguments); // Some type arguments belong to the outer type:
return mt; int outerTpc = typeArguments.Length - typeName.TypeParameterCount;
default: Debug.Assert(outerTpc > 0);
throw new NotImplementedException(); GetGenericInstantiation(mt.Target, typeArguments.Slice(0, outerTpc).ToImmutableArray());
foreach (var ta in typeArguments.Slice(typeArguments.Length - typeName.TypeParameterCount)) {
mt.AddChild(ta, Roles.TypeArgument);
}
} else {
foreach (var ta in typeArguments) {
genericType.AddChild(ta, Roles.TypeArgument);
}
} }
return genericType;
} }
public AstType GetGenericMethodParameter(GenericContext genericContext, int index) public AstType GetGenericMethodParameter(GenericContext genericContext, int index)
{ {
return new SimpleType(genericContext.GetGenericMethodTypeParameterName(index)); return new SimpleType(genericContext.GetGenericMethodTypeParameterName(index));
@ -88,122 +100,16 @@ namespace ICSharpCode.Decompiler.CSharp
public AstType GetPrimitiveType(PrimitiveTypeCode typeCode) public AstType GetPrimitiveType(PrimitiveTypeCode typeCode)
{ {
switch (typeCode) { var knownTypeCode = typeCode.ToKnownTypeCode();
case PrimitiveTypeCode.Boolean: var ktr = Decompiler.TypeSystem.KnownTypeReference.Get(knownTypeCode);
if ((options & ConvertTypeOptions.DoNotUsePrimitiveTypeNames) != 0) { if ((options & ConvertTypeOptions.DoNotUsePrimitiveTypeNames) == 0) {
if ((options & ConvertTypeOptions.IncludeNamespace) == 0) string keyword = Decompiler.TypeSystem.KnownTypeReference.GetCSharpNameByTypeCode(knownTypeCode);
return AstType.Create("Boolean"); if (keyword != null)
return AstType.Create("System.Boolean"); return new PrimitiveType(keyword);
}
return new PrimitiveType("bool");
case PrimitiveTypeCode.Byte:
if ((options & ConvertTypeOptions.DoNotUsePrimitiveTypeNames) != 0) {
if ((options & ConvertTypeOptions.IncludeNamespace) == 0)
return AstType.Create("Byte");
return AstType.Create("System.Byte");
}
return new PrimitiveType("byte");
case PrimitiveTypeCode.SByte:
if ((options & ConvertTypeOptions.DoNotUsePrimitiveTypeNames) != 0) {
if ((options & ConvertTypeOptions.IncludeNamespace) == 0)
return AstType.Create("SByte");
return AstType.Create("System.SByte");
}
return new PrimitiveType("sbyte");
case PrimitiveTypeCode.Char:
if ((options & ConvertTypeOptions.DoNotUsePrimitiveTypeNames) != 0) {
if ((options & ConvertTypeOptions.IncludeNamespace) == 0)
return AstType.Create("Char");
return AstType.Create("System.Char");
}
return new PrimitiveType("char");
case PrimitiveTypeCode.Int16:
if ((options & ConvertTypeOptions.DoNotUsePrimitiveTypeNames) != 0) {
if ((options & ConvertTypeOptions.IncludeNamespace) == 0)
return AstType.Create("Int16");
return AstType.Create("System.Int16");
}
return new PrimitiveType("short");
case PrimitiveTypeCode.UInt16:
if ((options & ConvertTypeOptions.DoNotUsePrimitiveTypeNames) != 0) {
if ((options & ConvertTypeOptions.IncludeNamespace) == 0)
return AstType.Create("UInt16");
return AstType.Create("System.UInt16");
}
return new PrimitiveType("ushort");
case PrimitiveTypeCode.Int32:
if ((options & ConvertTypeOptions.DoNotUsePrimitiveTypeNames) != 0) {
if ((options & ConvertTypeOptions.IncludeNamespace) == 0)
return AstType.Create("Int32");
return AstType.Create("System.In32");
}
return new PrimitiveType("int");
case PrimitiveTypeCode.UInt32:
if ((options & ConvertTypeOptions.DoNotUsePrimitiveTypeNames) != 0) {
if ((options & ConvertTypeOptions.IncludeNamespace) == 0)
return AstType.Create("UInt32");
return AstType.Create("System.UInt32");
}
return new PrimitiveType("uint");
case PrimitiveTypeCode.Int64:
if ((options & ConvertTypeOptions.DoNotUsePrimitiveTypeNames) != 0) {
if ((options & ConvertTypeOptions.IncludeNamespace) == 0)
return AstType.Create("Int64");
return AstType.Create("System.Int64");
}
return new PrimitiveType("long");
case PrimitiveTypeCode.UInt64:
if ((options & ConvertTypeOptions.DoNotUsePrimitiveTypeNames) != 0) {
if ((options & ConvertTypeOptions.IncludeNamespace) == 0)
return AstType.Create("UInt64");
return AstType.Create("System.UInt64");
}
return new PrimitiveType("ulong");
case PrimitiveTypeCode.Single:
if ((options & ConvertTypeOptions.DoNotUsePrimitiveTypeNames) != 0) {
if ((options & ConvertTypeOptions.IncludeNamespace) == 0)
return AstType.Create("Single");
return AstType.Create("System.Single");
}
return new PrimitiveType("float");
case PrimitiveTypeCode.Double:
if ((options & ConvertTypeOptions.DoNotUsePrimitiveTypeNames) != 0) {
if ((options & ConvertTypeOptions.IncludeNamespace) == 0)
return AstType.Create("Double");
return AstType.Create("System.Double");
}
return new PrimitiveType("double");
case PrimitiveTypeCode.IntPtr:
if ((options & ConvertTypeOptions.IncludeNamespace) == 0)
return AstType.Create("IntPtr");
return AstType.Create("System.IntPtr");
case PrimitiveTypeCode.UIntPtr:
if ((options & ConvertTypeOptions.IncludeNamespace) == 0)
return AstType.Create("UIntPtr");
return AstType.Create("System.UIntPtr");
case PrimitiveTypeCode.Object:
if ((options & ConvertTypeOptions.DoNotUsePrimitiveTypeNames) != 0) {
if ((options & ConvertTypeOptions.IncludeNamespace) == 0)
return AstType.Create("Object");
return AstType.Create("System.Object");
}
return new PrimitiveType("object");
case PrimitiveTypeCode.String:
if ((options & ConvertTypeOptions.DoNotUsePrimitiveTypeNames) != 0) {
if ((options & ConvertTypeOptions.IncludeNamespace) == 0)
return AstType.Create("String");
return AstType.Create("System.String");
}
return new PrimitiveType("string");
case PrimitiveTypeCode.TypedReference:
if ((options & ConvertTypeOptions.IncludeNamespace) == 0)
return AstType.Create("TypedReference");
return AstType.Create("System.TypedReference");
case PrimitiveTypeCode.Void:
return new PrimitiveType("void");
default:
throw new NotSupportedException();
} }
if ((options & ConvertTypeOptions.IncludeNamespace) == 0)
return new SimpleType(ktr.Name);
return AstType.Create(ktr.Namespace).MemberType(ktr.Name);
} }
public AstType GetSZArrayType(AstType elementType) public AstType GetSZArrayType(AstType elementType)
@ -231,12 +137,12 @@ namespace ICSharpCode.Decompiler.CSharp
{ {
if (fullTypeName.IsNested) { if (fullTypeName.IsNested) {
int count = fullTypeName.GetNestedTypeAdditionalTypeParameterCount(fullTypeName.NestingLevel - 1); int count = fullTypeName.GetNestedTypeAdditionalTypeParameterCount(fullTypeName.NestingLevel - 1);
if ((options & (ConvertTypeOptions.IncludeOuterTypeName | ConvertTypeOptions.IncludeNamespace)) != 0) { var outerType = MakeAstType(fullTypeName.GetDeclaringType());
var outerType = MakeAstType(fullTypeName.GetDeclaringType()); // Note: we must always emit the outer type name here;
return new MemberType(outerType, fullTypeName.Name); // if not desired it can only be cleaned up after InsertDynamicTypeVisitor.
} else { var nestedType = new MemberType(outerType, fullTypeName.Name);
return new SimpleType(fullTypeName.Name); nestedType.AddAnnotation(fullTypeName);
} return nestedType;
} }
AstType baseType; AstType baseType;
var topLevel = fullTypeName.TopLevelTypeName; var topLevel = fullTypeName.TopLevelTypeName;
@ -245,6 +151,7 @@ namespace ICSharpCode.Decompiler.CSharp
} else { } else {
baseType = AstType.Create(topLevel.Name); baseType = AstType.Create(topLevel.Name);
} }
baseType.AddAnnotation(fullTypeName);
return baseType; return baseType;
} }
} }

3
ICSharpCode.Decompiler/IL/ILReader.cs

@ -57,7 +57,6 @@ namespace ICSharpCode.Decompiler.IL
MethodSignature<ITypeReference> methodSignature; MethodSignature<ITypeReference> methodSignature;
StackType methodReturnStackType; StackType methodReturnStackType;
BlobReader reader; BlobReader reader;
int currentInstructionOffset;
ImmutableStack<ILVariable> currentStack; ImmutableStack<ILVariable> currentStack;
ILVariable[] parameterVariables; ILVariable[] parameterVariables;
ILVariable[] localVariables; ILVariable[] localVariables;
@ -210,7 +209,7 @@ namespace ICSharpCode.Decompiler.IL
/// </summary> /// </summary>
void Warn(string message) void Warn(string message)
{ {
Warnings.Add(string.Format("IL_{0:x4}: {1}", currentInstructionOffset, message)); Warnings.Add(string.Format("IL_{0:x4}: {1}", reader.Offset, message));
} }
ImmutableStack<ILVariable> MergeStacks(ImmutableStack<ILVariable> a, ImmutableStack<ILVariable> b) ImmutableStack<ILVariable> MergeStacks(ImmutableStack<ILVariable> a, ImmutableStack<ILVariable> b)

3
ICSharpCode.Decompiler/Metadata/Dom.cs

@ -824,7 +824,8 @@ namespace ICSharpCode.Decompiler.Metadata
public FullTypeName GetPrimitiveType(PrimitiveTypeCode typeCode) public FullTypeName GetPrimitiveType(PrimitiveTypeCode typeCode)
{ {
return new TopLevelTypeName("System", typeCode.ToString()); var ktr = KnownTypeReference.Get(typeCode.ToKnownTypeCode());
return new TopLevelTypeName(ktr.Namespace, ktr.Name, ktr.TypeParameterCount);
} }
public FullTypeName GetSZArrayType(FullTypeName elementType) public FullTypeName GetSZArrayType(FullTypeName elementType)

Loading…
Cancel
Save