|
|
|
@ -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; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|