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 @@ @@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using System.Reflection.Metadata;
using ICSharpCode.Decompiler.CSharp.Syntax;
@ -8,6 +9,7 @@ using ICSharpCode.Decompiler.Metadata; @@ -8,6 +9,7 @@ using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.Util;
using FullTypeName = ICSharpCode.Decompiler.TypeSystem.FullTypeName;
using TopLevelTypeName = ICSharpCode.Decompiler.TypeSystem.TopLevelTypeName;
namespace ICSharpCode.Decompiler.CSharp
{
@ -23,7 +25,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -23,7 +25,7 @@ namespace ICSharpCode.Decompiler.CSharp
public class AstTypeBuilder : ISignatureTypeProvider<AstType, GenericContext>
{
ConvertTypeOptions options;
readonly ConvertTypeOptions options;
public AstTypeBuilder(ConvertTypeOptions options)
{
@ -47,20 +49,30 @@ namespace ICSharpCode.Decompiler.CSharp @@ -47,20 +49,30 @@ namespace ICSharpCode.Decompiler.CSharp
return AstType.Create("System.IntPtr");
}
static readonly FullTypeName systemNullable = new TopLevelTypeName("System", "Nullable", 1);
public AstType GetGenericInstantiation(AstType genericType, ImmutableArray<AstType> typeArguments)
{
switch (genericType) {
case SimpleType st:
st.TypeArguments.AddRange(typeArguments);
return st;
case MemberType mt:
mt.TypeArguments.AddRange(typeArguments);
return mt;
default:
throw new NotImplementedException();
var typeName = genericType.Annotations.OfType<FullTypeName>().FirstOrDefault();
if (typeName == systemNullable && typeArguments.Length == 1) {
return typeArguments[0].MakeNullableType();
}
if (typeName.IsNested && genericType is MemberType mt && typeArguments.Length > typeName.TypeParameterCount) {
// Some type arguments belong to the outer type:
int outerTpc = typeArguments.Length - typeName.TypeParameterCount;
Debug.Assert(outerTpc > 0);
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)
{
return new SimpleType(genericContext.GetGenericMethodTypeParameterName(index));
@ -88,122 +100,16 @@ namespace ICSharpCode.Decompiler.CSharp @@ -88,122 +100,16 @@ namespace ICSharpCode.Decompiler.CSharp
public AstType GetPrimitiveType(PrimitiveTypeCode typeCode)
{
switch (typeCode) {
case PrimitiveTypeCode.Boolean:
if ((options & ConvertTypeOptions.DoNotUsePrimitiveTypeNames) != 0) {
if ((options & ConvertTypeOptions.IncludeNamespace) == 0)
return AstType.Create("Boolean");
return AstType.Create("System.Boolean");
}
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();
var knownTypeCode = typeCode.ToKnownTypeCode();
var ktr = Decompiler.TypeSystem.KnownTypeReference.Get(knownTypeCode);
if ((options & ConvertTypeOptions.DoNotUsePrimitiveTypeNames) == 0) {
string keyword = Decompiler.TypeSystem.KnownTypeReference.GetCSharpNameByTypeCode(knownTypeCode);
if (keyword != null)
return new PrimitiveType(keyword);
}
if ((options & ConvertTypeOptions.IncludeNamespace) == 0)
return new SimpleType(ktr.Name);
return AstType.Create(ktr.Namespace).MemberType(ktr.Name);
}
public AstType GetSZArrayType(AstType elementType)
@ -231,12 +137,12 @@ namespace ICSharpCode.Decompiler.CSharp @@ -231,12 +137,12 @@ namespace ICSharpCode.Decompiler.CSharp
{
if (fullTypeName.IsNested) {
int count = fullTypeName.GetNestedTypeAdditionalTypeParameterCount(fullTypeName.NestingLevel - 1);
if ((options & (ConvertTypeOptions.IncludeOuterTypeName | ConvertTypeOptions.IncludeNamespace)) != 0) {
var outerType = MakeAstType(fullTypeName.GetDeclaringType());
return new MemberType(outerType, fullTypeName.Name);
} else {
return new SimpleType(fullTypeName.Name);
}
var outerType = MakeAstType(fullTypeName.GetDeclaringType());
// Note: we must always emit the outer type name here;
// if not desired it can only be cleaned up after InsertDynamicTypeVisitor.
var nestedType = new MemberType(outerType, fullTypeName.Name);
nestedType.AddAnnotation(fullTypeName);
return nestedType;
}
AstType baseType;
var topLevel = fullTypeName.TopLevelTypeName;
@ -245,6 +151,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -245,6 +151,7 @@ namespace ICSharpCode.Decompiler.CSharp
} else {
baseType = AstType.Create(topLevel.Name);
}
baseType.AddAnnotation(fullTypeName);
return baseType;
}
}

3
ICSharpCode.Decompiler/IL/ILReader.cs

@ -57,7 +57,6 @@ namespace ICSharpCode.Decompiler.IL @@ -57,7 +57,6 @@ namespace ICSharpCode.Decompiler.IL
MethodSignature<ITypeReference> methodSignature;
StackType methodReturnStackType;
BlobReader reader;
int currentInstructionOffset;
ImmutableStack<ILVariable> currentStack;
ILVariable[] parameterVariables;
ILVariable[] localVariables;
@ -210,7 +209,7 @@ namespace ICSharpCode.Decompiler.IL @@ -210,7 +209,7 @@ namespace ICSharpCode.Decompiler.IL
/// </summary>
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)

3
ICSharpCode.Decompiler/Metadata/Dom.cs

@ -824,7 +824,8 @@ namespace ICSharpCode.Decompiler.Metadata @@ -824,7 +824,8 @@ namespace ICSharpCode.Decompiler.Metadata
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)

Loading…
Cancel
Save