diff --git a/ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs b/ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs index 02416b7e0..589f1042c 100644 --- a/ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs @@ -206,13 +206,18 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax if (type == null) throw new ArgumentNullException("type"); AstType astType = ConvertTypeHelper(type); + AddTypeAnnotation(astType, type); + return astType; + } + + private void AddTypeAnnotation(AstType astType, IType type) + { if (AddTypeReferenceAnnotations) astType.AddAnnotation(type); if (AddResolveResultAnnotations) astType.AddAnnotation(new TypeResolveResult(type)); - return astType; } - + public AstType ConvertType(FullTypeName fullTypeName) { if (resolver != null) { @@ -235,11 +240,10 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax } return type; } - + AstType ConvertTypeHelper(IType type) { - TypeWithElementType typeWithElementType = type as TypeWithElementType; - if (typeWithElementType != null) { + if (type is TypeWithElementType typeWithElementType) { if (typeWithElementType is PointerType) { return ConvertType(typeWithElementType.ElementType).MakePointerType(); } else if (typeWithElementType is ArrayType) { @@ -254,20 +258,12 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax // not supported as type in C# return ConvertType(typeWithElementType.ElementType); } - } - if (type is ParameterizedType pt) { - if (AlwaysUseBuiltinTypeNames && pt.IsKnownType(KnownTypeCode.NullableOfT)) { - return ConvertType(pt.TypeArguments[0]).MakeNullableType(); - } - return ConvertTypeHelper(pt.GenericType, pt.TypeArguments); - } - if (type is NullabilityAnnotatedType nat) { + } else if (type is NullabilityAnnotatedType nat) { var astType = ConvertType(nat.TypeWithoutAnnotation); if (nat.Nullability == Nullability.Nullable) astType = astType.MakeNullableType(); return astType; - } - if (type is TupleType tuple) { + } else if (type is TupleType tuple) { var astType = new TupleAstType(); foreach (var (etype, ename) in tuple.ElementTypes.Zip(tuple.ElementNames)) { astType.Elements.Add(new TupleTypeElement { @@ -276,23 +272,35 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax }); } return astType; - } - if (type is ITypeDefinition typeDef) { - if (ShowTypeParametersForUnboundTypes) - return ConvertTypeHelper(typeDef, typeDef.TypeArguments); - if (typeDef.TypeParameterCount > 0) { - // Unbound type - IType[] typeArguments = new IType[typeDef.TypeParameterCount]; - for (int i = 0; i < typeArguments.Length; i++) { - typeArguments[i] = SpecialType.UnboundTypeArgument; + } else { + AstType astType; + if (type is ITypeDefinition typeDef) { + if (ShowTypeParametersForUnboundTypes) { + astType = ConvertTypeHelper(typeDef, typeDef.TypeArguments); + } else if (typeDef.TypeParameterCount > 0) { + // Unbound type + IType[] typeArguments = new IType[typeDef.TypeParameterCount]; + for (int i = 0; i < typeArguments.Length; i++) { + typeArguments[i] = SpecialType.UnboundTypeArgument; + } + astType = ConvertTypeHelper(typeDef, typeArguments); + } else { + astType = ConvertTypeHelper(typeDef, EmptyList.Instance); + } + } else if (type is ParameterizedType pt) { + if (AlwaysUseBuiltinTypeNames && pt.IsKnownType(KnownTypeCode.NullableOfT)) { + return ConvertType(pt.TypeArguments[0]).MakeNullableType(); } - return ConvertTypeHelper(typeDef, typeArguments); + astType = ConvertTypeHelper(pt.GenericType, pt.TypeArguments); } else { - return ConvertTypeHelper(typeDef, EmptyList.Instance); + astType = MakeSimpleType(type.Name); } - + if (type.Nullability == Nullability.Nullable) { + AddTypeAnnotation(astType, type.ChangeNullability(Nullability.Oblivious)); + astType = astType.MakeNullableType(); + } + return astType; } - return MakeSimpleType(type.Name); } AstType ConvertTypeHelper(IType genericType, IReadOnlyList typeArguments) @@ -304,11 +312,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax if (AlwaysUseBuiltinTypeNames && typeDef != null) { string keyword = KnownTypeReference.GetCSharpNameByTypeCode(typeDef.KnownTypeCode); if (keyword != null) { - if (genericType.Nullability == Nullability.Nullable) { - return new PrimitiveType(keyword).MakeNullableType(); - } else { - return new PrimitiveType(keyword); - } + return new PrimitiveType(keyword); } } @@ -352,11 +356,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax if (AlwaysUseShortTypeNames || (typeDef == null && genericType.DeclaringType == null)) { var shortResult = MakeSimpleType(genericType.Name); AddTypeArguments(shortResult, genericType.TypeParameters, typeArguments, outerTypeParameterCount, genericType.TypeParameterCount); - if (genericType.Nullability == Nullability.Nullable) { - return shortResult.MakeNullableType(); - } else { - return shortResult; - } + return shortResult; } MemberType result = new MemberType(); if (genericType.DeclaringType != null) { @@ -375,11 +375,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax } result.MemberName = genericType.Name; AddTypeArguments(result, genericType.TypeParameters, typeArguments, outerTypeParameterCount, genericType.TypeParameterCount); - if (genericType.Nullability == Nullability.Nullable) { - return result.MakeNullableType(); - } else { - return result; - } + return result; } /// @@ -604,11 +600,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax } else if (resolver != null) { ApplyShortAttributeNameIfPossible(type, astType, shortName); } + AddTypeAnnotation(astType, type); - if (AddTypeReferenceAnnotations) - astType.AddAnnotation(type); - if (AddResolveResultAnnotations) - astType.AddAnnotation(new TypeResolveResult(type)); return astType; } diff --git a/ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultTypeParameter.cs b/ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultTypeParameter.cs index 8ff30441a..4333be38d 100644 --- a/ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultTypeParameter.cs +++ b/ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultTypeParameter.cs @@ -28,7 +28,6 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation readonly bool hasReferenceTypeConstraint; readonly bool hasDefaultConstructorConstraint; readonly Nullability nullabilityConstraint; - readonly IReadOnlyList constraints; readonly IReadOnlyList attributes; public DefaultTypeParameter(