Browse Source

Support "where T : unmanaged" constraints.

pull/1425/head
Daniel Grunwald 6 years ago
parent
commit
2f35374d7d
  1. 3
      ICSharpCode.Decompiler.Tests/Helpers/RemoveCompilerAttribute.cs
  2. 2
      ICSharpCode.Decompiler.Tests/Helpers/Tester.cs
  3. 6
      ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj
  4. 17
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.cs
  5. 68
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.opt.roslyn.il
  6. 88
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.roslyn.il
  7. 6
      ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs
  8. 20
      ICSharpCode.Decompiler/DecompilerSettings.cs
  9. 12
      ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs
  10. 7
      ICSharpCode.Decompiler/TypeSystem/ITypeParameter.cs
  11. 1
      ICSharpCode.Decompiler/TypeSystem/Implementation/AbstractTypeParameter.cs
  12. 14
      ICSharpCode.Decompiler/TypeSystem/Implementation/AttributeListBuilder.cs
  13. 1
      ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultTypeParameter.cs
  14. 20
      ICSharpCode.Decompiler/TypeSystem/Implementation/DummyTypeParameter.cs
  15. 5
      ICSharpCode.Decompiler/TypeSystem/Implementation/KnownAttributes.cs
  16. 2
      ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataEvent.cs
  17. 2
      ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataField.cs
  18. 4
      ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataMethod.cs
  19. 2
      ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataParameter.cs
  20. 2
      ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataProperty.cs
  21. 2
      ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeDefinition.cs
  22. 21
      ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeParameter.cs
  23. 1
      ICSharpCode.Decompiler/TypeSystem/Implementation/NullabilityAnnotatedType.cs
  24. 15
      ICSharpCode.Decompiler/TypeSystem/Implementation/SpecializedMethod.cs
  25. 4
      ICSharpCode.Decompiler/TypeSystem/MetadataModule.cs

3
ICSharpCode.Decompiler.Tests/Helpers/RemoveCompilerAttribute.cs

@ -33,11 +33,12 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
} }
} }
public class RemoveEmbeddedAtttributes : DepthFirstAstVisitor, IAstTransform public class RemoveEmbeddedAttributes : DepthFirstAstVisitor, IAstTransform
{ {
HashSet<string> attributeNames = new HashSet<string>() { HashSet<string> attributeNames = new HashSet<string>() {
"System.Runtime.CompilerServices.IsReadOnlyAttribute", "System.Runtime.CompilerServices.IsReadOnlyAttribute",
"System.Runtime.CompilerServices.IsByRefLikeAttribute", "System.Runtime.CompilerServices.IsByRefLikeAttribute",
"System.Runtime.CompilerServices.IsUnmanagedAttribute",
"Microsoft.CodeAnalysis.EmbeddedAttribute", "Microsoft.CodeAnalysis.EmbeddedAttribute",
}; };

2
ICSharpCode.Decompiler.Tests/Helpers/Tester.cs

@ -412,7 +412,7 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
resolver.AddSearchDirectory(Path.GetDirectoryName(typeof(Span<>).Assembly.Location)); resolver.AddSearchDirectory(Path.GetDirectoryName(typeof(Span<>).Assembly.Location));
var typeSystem = new DecompilerTypeSystem(module, resolver, settings); var typeSystem = new DecompilerTypeSystem(module, resolver, settings);
CSharpDecompiler decompiler = new CSharpDecompiler(typeSystem, settings); CSharpDecompiler decompiler = new CSharpDecompiler(typeSystem, settings);
decompiler.AstTransforms.Insert(0, new RemoveEmbeddedAtttributes()); decompiler.AstTransforms.Insert(0, new RemoveEmbeddedAttributes());
decompiler.AstTransforms.Insert(0, new RemoveCompilerAttribute()); decompiler.AstTransforms.Insert(0, new RemoveCompilerAttribute());
decompiler.AstTransforms.Add(new EscapeInvalidIdentifiers()); decompiler.AstTransforms.Add(new EscapeInvalidIdentifiers());
var syntaxTree = decompiler.DecompileWholeModuleAsSingleFile(); var syntaxTree = decompiler.DecompileWholeModuleAsSingleFile();

6
ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj

@ -32,7 +32,11 @@
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DefineConstants>TRACE;DEBUG;NET46;ROSLYN;CS60;CS70</DefineConstants> <DefineConstants>TRACE;DEBUG;NET46;ROSLYN;CS60;CS70;CS71;CS72;CS73</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<DefineConstants>TRACE;NET46;ROSLYN;CS60;CS70;CS71;CS72;CS73</DefineConstants>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

17
ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.cs

@ -96,5 +96,22 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
{ {
return new T[size1, size2]; return new T[size1, size2];
} }
#if CS73
public static object CallDelegate<T>(T input) where T : Delegate
{
return input.DynamicInvoke();
}
public static int CountEnumerators<T>() where T : Enum
{
return typeof(T).GetEnumValues().Length;
}
public unsafe static int UnmanagedConstraint<T>() where T : unmanaged
{
return sizeof(T);
}
#endif
} }
} }

68
ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.opt.roslyn.il

@ -33,6 +33,40 @@
// =============== CLASS MEMBERS DECLARATION =================== // =============== CLASS MEMBERS DECLARATION ===================
.class private auto ansi sealed beforefieldinit Microsoft.CodeAnalysis.EmbeddedAttribute
extends [mscorlib]System.Attribute
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
.custom instance void Microsoft.CodeAnalysis.EmbeddedAttribute::.ctor() = ( 01 00 00 00 )
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Attribute::.ctor()
IL_0006: ret
} // end of method EmbeddedAttribute::.ctor
} // end of class Microsoft.CodeAnalysis.EmbeddedAttribute
.class private auto ansi sealed beforefieldinit System.Runtime.CompilerServices.IsUnmanagedAttribute
extends [mscorlib]System.Attribute
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
.custom instance void Microsoft.CodeAnalysis.EmbeddedAttribute::.ctor() = ( 01 00 00 00 )
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Attribute::.ctor()
IL_0006: ret
} // end of method IsUnmanagedAttribute::.ctor
} // end of class System.Runtime.CompilerServices.IsUnmanagedAttribute
.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.Generics .class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.Generics
extends [mscorlib]System.Object extends [mscorlib]System.Object
{ {
@ -222,6 +256,40 @@
IL_0007: ret IL_0007: ret
} // end of method Generics::NewArray } // end of method Generics::NewArray
.method public hidebysig static object
CallDelegate<([mscorlib]System.Delegate) T>(!!T input) cil managed
{
// Code size 18 (0x12)
.maxstack 8
IL_0000: ldarg.0
IL_0001: box !!T
IL_0006: ldc.i4.0
IL_0007: newarr [mscorlib]System.Object
IL_000c: callvirt instance object [mscorlib]System.Delegate::DynamicInvoke(object[])
IL_0011: ret
} // end of method Generics::CallDelegate
.method public hidebysig static int32 CountEnumerators<([mscorlib]System.Enum) T>() cil managed
{
// Code size 21 (0x15)
.maxstack 8
IL_0000: ldtoken !!T
IL_0005: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_000a: callvirt instance class [mscorlib]System.Array [mscorlib]System.Type::GetEnumValues()
IL_000f: callvirt instance int32 [mscorlib]System.Array::get_Length()
IL_0014: ret
} // end of method Generics::CountEnumerators
.method public hidebysig static int32 UnmanagedConstraint<valuetype .ctor (class [mscorlib]System.ValueType modreq([mscorlib]System.Runtime.InteropServices.UnmanagedType)) T>() cil managed
{
.param type T
.custom instance void System.Runtime.CompilerServices.IsUnmanagedAttribute::.ctor() = ( 01 00 00 00 )
// Code size 7 (0x7)
.maxstack 8
IL_0000: sizeof !!T
IL_0006: ret
} // end of method Generics::UnmanagedConstraint
.method public hidebysig specialname rtspecialname .method public hidebysig specialname rtspecialname
instance void .ctor() cil managed instance void .ctor() cil managed
{ {

88
ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.roslyn.il

@ -33,6 +33,42 @@
// =============== CLASS MEMBERS DECLARATION =================== // =============== CLASS MEMBERS DECLARATION ===================
.class private auto ansi sealed beforefieldinit Microsoft.CodeAnalysis.EmbeddedAttribute
extends [mscorlib]System.Attribute
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
.custom instance void Microsoft.CodeAnalysis.EmbeddedAttribute::.ctor() = ( 01 00 00 00 )
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Attribute::.ctor()
IL_0006: nop
IL_0007: ret
} // end of method EmbeddedAttribute::.ctor
} // end of class Microsoft.CodeAnalysis.EmbeddedAttribute
.class private auto ansi sealed beforefieldinit System.Runtime.CompilerServices.IsUnmanagedAttribute
extends [mscorlib]System.Attribute
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
.custom instance void Microsoft.CodeAnalysis.EmbeddedAttribute::.ctor() = ( 01 00 00 00 )
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Attribute::.ctor()
IL_0006: nop
IL_0007: ret
} // end of method IsUnmanagedAttribute::.ctor
} // end of class System.Runtime.CompilerServices.IsUnmanagedAttribute
.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.Generics .class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.Generics
extends [mscorlib]System.Object extends [mscorlib]System.Object
{ {
@ -298,6 +334,58 @@
IL_000c: ret IL_000c: ret
} // end of method Generics::NewArray } // end of method Generics::NewArray
.method public hidebysig static object
CallDelegate<([mscorlib]System.Delegate) T>(!!T input) cil managed
{
// Code size 23 (0x17)
.maxstack 2
.locals init (object V_0)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: box !!T
IL_0007: ldc.i4.0
IL_0008: newarr [mscorlib]System.Object
IL_000d: callvirt instance object [mscorlib]System.Delegate::DynamicInvoke(object[])
IL_0012: stloc.0
IL_0013: br.s IL_0015
IL_0015: ldloc.0
IL_0016: ret
} // end of method Generics::CallDelegate
.method public hidebysig static int32 CountEnumerators<([mscorlib]System.Enum) T>() cil managed
{
// Code size 26 (0x1a)
.maxstack 1
.locals init (int32 V_0)
IL_0000: nop
IL_0001: ldtoken !!T
IL_0006: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_000b: callvirt instance class [mscorlib]System.Array [mscorlib]System.Type::GetEnumValues()
IL_0010: callvirt instance int32 [mscorlib]System.Array::get_Length()
IL_0015: stloc.0
IL_0016: br.s IL_0018
IL_0018: ldloc.0
IL_0019: ret
} // end of method Generics::CountEnumerators
.method public hidebysig static int32 UnmanagedConstraint<valuetype .ctor (class [mscorlib]System.ValueType modreq([mscorlib]System.Runtime.InteropServices.UnmanagedType)) T>() cil managed
{
.param type T
.custom instance void System.Runtime.CompilerServices.IsUnmanagedAttribute::.ctor() = ( 01 00 00 00 )
// Code size 12 (0xc)
.maxstack 1
.locals init (int32 V_0)
IL_0000: nop
IL_0001: sizeof !!T
IL_0007: stloc.0
IL_0008: br.s IL_000a
IL_000a: ldloc.0
IL_000b: ret
} // end of method Generics::UnmanagedConstraint
.method public hidebysig specialname rtspecialname .method public hidebysig specialname rtspecialname
instance void .ctor() cil managed instance void .ctor() cil managed
{ {

6
ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs

@ -1730,7 +1730,11 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
c.BaseTypes.Add(new PrimitiveType("class")); c.BaseTypes.Add(new PrimitiveType("class"));
} }
} else if (tp.HasValueTypeConstraint) { } else if (tp.HasValueTypeConstraint) {
c.BaseTypes.Add(new PrimitiveType("struct")); if (tp.HasUnmanagedConstraint) {
c.BaseTypes.Add(new PrimitiveType("unmanaged"));
} else {
c.BaseTypes.Add(new PrimitiveType("struct"));
}
} }
foreach (IType t in tp.DirectBaseTypes) { foreach (IType t in tp.DirectBaseTypes) {
if (!IsObjectOrValueType(t)) if (!IsObjectOrValueType(t))

20
ICSharpCode.Decompiler/DecompilerSettings.cs

@ -89,7 +89,7 @@ namespace ICSharpCode.Decompiler
nonTrailingNamedArguments = false; nonTrailingNamedArguments = false;
} }
if (languageVersion < CSharp.LanguageVersion.CSharp7_3) { if (languageVersion < CSharp.LanguageVersion.CSharp7_3) {
//introduceUnmanagedTypeConstraint = false; introduceUnmanagedConstraint = false;
stackAllocInitializers = false; stackAllocInitializers = false;
tupleComparisons = false; tupleComparisons = false;
} }
@ -100,7 +100,7 @@ namespace ICSharpCode.Decompiler
public CSharp.LanguageVersion GetMinimumRequiredVersion() public CSharp.LanguageVersion GetMinimumRequiredVersion()
{ {
if (tupleComparisons || stackAllocInitializers) if (introduceUnmanagedConstraint || tupleComparisons || stackAllocInitializers)
return CSharp.LanguageVersion.CSharp7_3; return CSharp.LanguageVersion.CSharp7_3;
if (introduceRefModifiersOnStructs || introduceReadonlyAndInModifiers || nonTrailingNamedArguments) if (introduceRefModifiersOnStructs || introduceReadonlyAndInModifiers || nonTrailingNamedArguments)
return CSharp.LanguageVersion.CSharp7_2; return CSharp.LanguageVersion.CSharp7_2;
@ -687,6 +687,22 @@ namespace ICSharpCode.Decompiler
} }
} }
bool introduceUnmanagedConstraint = true;
/// <summary>
/// If this option is active, [IsUnmanagedAttribute] on type parameters
/// is replaced with "T : unmanaged" constraints.
/// </summary>
public bool IntroduceUnmanagedConstraint {
get { return introduceUnmanagedConstraint; }
set {
if (introduceUnmanagedConstraint != value) {
introduceUnmanagedConstraint = value;
OnPropertyChanged();
}
}
}
bool stackAllocInitializers = true; bool stackAllocInitializers = true;
/// <summary> /// <summary>

12
ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs

@ -94,14 +94,20 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// </summary> /// </summary>
RefStructs = 0x100, RefStructs = 0x100,
/// <summary> /// <summary>
/// If this option is active, [IsUnmanagedAttribute] is removed from type parameters,
/// and HasUnmanagedConstraint is set instead.
/// </summary>
UnmanagedConstraints = 0x200,
/// <summary>
/// If this option is active, [NullableAttribute] is removed and reference types with /// If this option is active, [NullableAttribute] is removed and reference types with
/// nullability annotations are used instead. /// nullability annotations are used instead.
/// </summary> /// </summary>
NullabilityAnnotations = 0x200, NullabilityAnnotations = 0x400,
/// <summary> /// <summary>
/// Default settings: typical options for the decompiler, with all C# languages features enabled. /// Default settings: typical options for the decompiler, with all C# languages features enabled.
/// </summary> /// </summary>
Default = Dynamic | Tuple | ExtensionMethods | DecimalConstants | ReadOnlyStructsAndParameters | RefStructs Default = Dynamic | Tuple | ExtensionMethods | DecimalConstants | ReadOnlyStructsAndParameters
| RefStructs | UnmanagedConstraints | NullabilityAnnotations
} }
/// <summary> /// <summary>
@ -127,6 +133,8 @@ namespace ICSharpCode.Decompiler.TypeSystem
typeSystemOptions |= TypeSystemOptions.RefStructs; typeSystemOptions |= TypeSystemOptions.RefStructs;
if (settings.IntroduceReadonlyAndInModifiers) if (settings.IntroduceReadonlyAndInModifiers)
typeSystemOptions |= TypeSystemOptions.ReadOnlyStructsAndParameters; typeSystemOptions |= TypeSystemOptions.ReadOnlyStructsAndParameters;
if (settings.IntroduceUnmanagedConstraint)
typeSystemOptions |= TypeSystemOptions.UnmanagedConstraints;
if (settings.NullableReferenceTypes) if (settings.NullableReferenceTypes)
typeSystemOptions |= TypeSystemOptions.NullabilityAnnotations; typeSystemOptions |= TypeSystemOptions.NullabilityAnnotations;
return typeSystemOptions; return typeSystemOptions;

7
ICSharpCode.Decompiler/TypeSystem/ITypeParameter.cs

@ -83,10 +83,15 @@ namespace ICSharpCode.Decompiler.TypeSystem
bool HasReferenceTypeConstraint { get; } bool HasReferenceTypeConstraint { get; }
/// <summary> /// <summary>
/// Gets if the type parameter has the 'struct' constraint. /// Gets if the type parameter has the 'struct' or 'unmanaged' constraint.
/// </summary> /// </summary>
bool HasValueTypeConstraint { get; } bool HasValueTypeConstraint { get; }
/// <summary>
/// Gets if the type parameter has the 'unmanaged' constraint.
/// </summary>
bool HasUnmanagedConstraint { get; }
/// <summary> /// <summary>
/// Nullability of the reference type constraint. (e.g. "where T : class?"). /// Nullability of the reference type constraint. (e.g. "where T : class?").
/// ///

1
ICSharpCode.Decompiler/TypeSystem/Implementation/AbstractTypeParameter.cs

@ -158,6 +158,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public abstract bool HasDefaultConstructorConstraint { get; } public abstract bool HasDefaultConstructorConstraint { get; }
public abstract bool HasReferenceTypeConstraint { get; } public abstract bool HasReferenceTypeConstraint { get; }
public abstract bool HasValueTypeConstraint { get; } public abstract bool HasValueTypeConstraint { get; }
public abstract bool HasUnmanagedConstraint { get; }
public abstract Nullability NullabilityConstraint { get; } public abstract Nullability NullabilityConstraint { get; }
public TypeKind Kind { public TypeKind Kind {

14
ICSharpCode.Decompiler/TypeSystem/Implementation/AttributeListBuilder.cs

@ -169,7 +169,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
#endregion #endregion
#region Custom Attributes (ReadAttribute) #region Custom Attributes (ReadAttribute)
public void Add(CustomAttributeHandleCollection attributes) public void Add(CustomAttributeHandleCollection attributes, SymbolKind target)
{ {
var metadata = module.metadata; var metadata = module.metadata;
foreach (var handle in attributes) { foreach (var handle in attributes) {
@ -177,14 +177,14 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
// Attribute types shouldn't be generic (and certainly not open), so we don't need a generic context. // Attribute types shouldn't be generic (and certainly not open), so we don't need a generic context.
var ctor = module.ResolveMethod(attribute.Constructor, new GenericContext()); var ctor = module.ResolveMethod(attribute.Constructor, new GenericContext());
var type = ctor.DeclaringType; var type = ctor.DeclaringType;
if (IgnoreAttribute(type)) { if (IgnoreAttribute(type, target)) {
continue; continue;
} }
Add(new CustomAttribute(module, ctor, handle)); Add(new CustomAttribute(module, ctor, handle));
} }
} }
bool IgnoreAttribute(IType attributeType) bool IgnoreAttribute(IType attributeType, SymbolKind target)
{ {
if (attributeType.DeclaringType != null || attributeType.TypeParameterCount != 0) if (attributeType.DeclaringType != null || attributeType.TypeParameterCount != 0)
return false; return false;
@ -199,18 +199,20 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
case "ExtensionAttribute": case "ExtensionAttribute":
return (options & TypeSystemOptions.ExtensionMethods) != 0; return (options & TypeSystemOptions.ExtensionMethods) != 0;
case "DecimalConstantAttribute": case "DecimalConstantAttribute":
return (options & TypeSystemOptions.DecimalConstants) != 0; return (options & TypeSystemOptions.DecimalConstants) != 0 && target == SymbolKind.Field;
case "IsReadOnlyAttribute": case "IsReadOnlyAttribute":
return (options & TypeSystemOptions.ReadOnlyStructsAndParameters) != 0; return (options & TypeSystemOptions.ReadOnlyStructsAndParameters) != 0;
case "IsByRefLikeAttribute": case "IsByRefLikeAttribute":
return (options & TypeSystemOptions.RefStructs) != 0; return (options & TypeSystemOptions.RefStructs) != 0 && target == SymbolKind.TypeDefinition;
case "IsUnmanagedAttribute":
return (options & TypeSystemOptions.UnmanagedConstraints) != 0 && target == SymbolKind.TypeParameter;
case "NullableAttribute": case "NullableAttribute":
return (options & TypeSystemOptions.NullabilityAnnotations) != 0; return (options & TypeSystemOptions.NullabilityAnnotations) != 0;
default: default:
return false; return false;
} }
case "System": case "System":
return attributeType.Name == "ParamArrayAttribute"; return attributeType.Name == "ParamArrayAttribute" && target == SymbolKind.Parameter;
default: default:
return false; return false;
} }

1
ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultTypeParameter.cs

@ -69,6 +69,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public override bool HasValueTypeConstraint => hasValueTypeConstraint; public override bool HasValueTypeConstraint => hasValueTypeConstraint;
public override bool HasReferenceTypeConstraint => hasReferenceTypeConstraint; public override bool HasReferenceTypeConstraint => hasReferenceTypeConstraint;
public override bool HasDefaultConstructorConstraint => hasDefaultConstructorConstraint; public override bool HasDefaultConstructorConstraint => hasDefaultConstructorConstraint;
public override bool HasUnmanagedConstraint => false;
public override Nullability NullabilityConstraint => nullabilityConstraint; public override Nullability NullabilityConstraint => nullabilityConstraint;
public override IEnumerable<IType> DirectBaseTypes { public override IEnumerable<IType> DirectBaseTypes {

20
ICSharpCode.Decompiler/TypeSystem/Implementation/DummyTypeParameter.cs

@ -162,21 +162,11 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
IReadOnlyCollection<IType> ITypeParameter.EffectiveInterfaceSet { IReadOnlyCollection<IType> ITypeParameter.EffectiveInterfaceSet {
get { return EmptyList<IType>.Instance; } get { return EmptyList<IType>.Instance; }
} }
bool ITypeParameter.HasDefaultConstructorConstraint {
get { return false; }
}
bool ITypeParameter.HasReferenceTypeConstraint {
get { return false; }
}
bool ITypeParameter.HasValueTypeConstraint {
get { return false; }
}
Nullability ITypeParameter.NullabilityConstraint { bool ITypeParameter.HasDefaultConstructorConstraint => false;
get { return Nullability.Oblivious; } bool ITypeParameter.HasReferenceTypeConstraint => false;
} bool ITypeParameter.HasValueTypeConstraint => false;
bool ITypeParameter.HasUnmanagedConstraint => false;
Nullability ITypeParameter.NullabilityConstraint => Nullability.Oblivious;
} }
} }

5
ICSharpCode.Decompiler/TypeSystem/Implementation/KnownAttributes.cs

@ -86,6 +86,9 @@ namespace ICSharpCode.Decompiler.TypeSystem
CallerFilePath, CallerFilePath,
CallerLineNumber, CallerLineNumber,
// Type parameter attributes:
IsUnmanaged,
// Marshalling attributes: // Marshalling attributes:
MarshalAs, MarshalAs,
@ -143,6 +146,8 @@ namespace ICSharpCode.Decompiler.TypeSystem
new TopLevelTypeName("System.Runtime.CompilerServices", nameof(CallerMemberNameAttribute)), new TopLevelTypeName("System.Runtime.CompilerServices", nameof(CallerMemberNameAttribute)),
new TopLevelTypeName("System.Runtime.CompilerServices", nameof(CallerFilePathAttribute)), new TopLevelTypeName("System.Runtime.CompilerServices", nameof(CallerFilePathAttribute)),
new TopLevelTypeName("System.Runtime.CompilerServices", nameof(CallerLineNumberAttribute)), new TopLevelTypeName("System.Runtime.CompilerServices", nameof(CallerLineNumberAttribute)),
// Type parameter attributes:
new TopLevelTypeName("System.Runtime.CompilerServices", "IsUnmanagedAttribute"),
// Marshalling attributes: // Marshalling attributes:
new TopLevelTypeName("System.Runtime.InteropServices", nameof(MarshalAsAttribute)), new TopLevelTypeName("System.Runtime.InteropServices", nameof(MarshalAsAttribute)),
// Security attributes: // Security attributes:

2
ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataEvent.cs

@ -107,7 +107,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
var b = new AttributeListBuilder(module); var b = new AttributeListBuilder(module);
var metadata = module.metadata; var metadata = module.metadata;
var eventDef = metadata.GetEventDefinition(handle); var eventDef = metadata.GetEventDefinition(handle);
b.Add(eventDef.GetCustomAttributes()); b.Add(eventDef.GetCustomAttributes(), SymbolKind.Event);
return b.Build(); return b.Build();
} }
#endregion #endregion

2
ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataField.cs

@ -146,7 +146,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
} }
b.AddMarshalInfo(fieldDef.GetMarshallingDescriptor()); b.AddMarshalInfo(fieldDef.GetMarshallingDescriptor());
b.Add(fieldDef.GetCustomAttributes()); b.Add(fieldDef.GetCustomAttributes(), SymbolKind.Field);
return b.Build(); return b.Build();
} }

4
ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataMethod.cs

@ -363,7 +363,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
} }
#endregion #endregion
b.Add(def.GetCustomAttributes()); b.Add(def.GetCustomAttributes(), symbolKind);
b.AddSecurityAttributes(def.GetDeclarativeSecurityAttributes()); b.AddSecurityAttributes(def.GetDeclarativeSecurityAttributes());
return b.Build(); return b.Build();
@ -381,7 +381,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
var retParam = metadata.GetParameter(parameters.First()); var retParam = metadata.GetParameter(parameters.First());
if (retParam.SequenceNumber == 0) { if (retParam.SequenceNumber == 0) {
b.AddMarshalInfo(retParam.GetMarshallingDescriptor()); b.AddMarshalInfo(retParam.GetMarshallingDescriptor());
b.Add(retParam.GetCustomAttributes()); b.Add(retParam.GetCustomAttributes(), symbolKind);
} }
} }
return b.Build(); return b.Build();

2
ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataParameter.cs

@ -72,7 +72,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
if ((attributes & ParameterAttributes.Out) == ParameterAttributes.Out) if ((attributes & ParameterAttributes.Out) == ParameterAttributes.Out)
b.Add(KnownAttribute.Out); b.Add(KnownAttribute.Out);
} }
b.Add(parameter.GetCustomAttributes()); b.Add(parameter.GetCustomAttributes(), SymbolKind.Parameter);
b.AddMarshalInfo(parameter.GetMarshallingDescriptor()); b.AddMarshalInfo(parameter.GetMarshallingDescriptor());
return b.Build(); return b.Build();

2
ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataProperty.cs

@ -155,7 +155,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
if (IsIndexer && Name != "Item" && !IsExplicitInterfaceImplementation) { if (IsIndexer && Name != "Item" && !IsExplicitInterfaceImplementation) {
b.Add(KnownAttribute.IndexerName, KnownTypeCode.String, Name); b.Add(KnownAttribute.IndexerName, KnownTypeCode.String, Name);
} }
b.Add(propertyDef.GetCustomAttributes()); b.Add(propertyDef.GetCustomAttributes(), symbolKind);
return b.Build(); return b.Build();
} }
#endregion #endregion

2
ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeDefinition.cs

@ -372,7 +372,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
} }
#endregion #endregion
b.Add(typeDefinition.GetCustomAttributes()); b.Add(typeDefinition.GetCustomAttributes(), SymbolKind.TypeDefinition);
b.AddSecurityAttributes(typeDefinition.GetDeclarativeSecurityAttributes()); b.AddSecurityAttributes(typeDefinition.GetDeclarativeSecurityAttributes());
return b.Build(); return b.Build();

21
ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeParameter.cs

@ -35,6 +35,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
// lazy-loaded: // lazy-loaded:
IReadOnlyList<IType> constraints; IReadOnlyList<IType> constraints;
byte unmanagedConstraint = ThreeState.Unknown;
const byte nullabilityNotYetLoaded = 255; const byte nullabilityNotYetLoaded = 255;
byte nullabilityConstraint = nullabilityNotYetLoaded; byte nullabilityConstraint = nullabilityNotYetLoaded;
@ -106,7 +107,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
var attributes = gp.GetCustomAttributes(); var attributes = gp.GetCustomAttributes();
var b = new AttributeListBuilder(module, attributes.Count); var b = new AttributeListBuilder(module, attributes.Count);
b.Add(attributes); b.Add(attributes, SymbolKind.TypeParameter);
return b.Build(); return b.Build();
} }
@ -114,6 +115,24 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public override bool HasReferenceTypeConstraint => (attr & GenericParameterAttributes.ReferenceTypeConstraint) != 0; public override bool HasReferenceTypeConstraint => (attr & GenericParameterAttributes.ReferenceTypeConstraint) != 0;
public override bool HasValueTypeConstraint => (attr & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0; public override bool HasValueTypeConstraint => (attr & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0;
public override bool HasUnmanagedConstraint {
get {
if (unmanagedConstraint == ThreeState.Unknown) {
unmanagedConstraint = ThreeState.From(LoadUnmanagedConstraint());
}
return unmanagedConstraint == ThreeState.True;
}
}
private bool LoadUnmanagedConstraint()
{
if ((module.TypeSystemOptions & TypeSystemOptions.UnmanagedConstraints) == 0)
return false;
var metadata = module.metadata;
var gp = metadata.GetGenericParameter(handle);
return gp.GetCustomAttributes().HasKnownAttribute(metadata, KnownAttribute.IsUnmanaged);
}
public override Nullability NullabilityConstraint { public override Nullability NullabilityConstraint {
get { get {
if (nullabilityConstraint == nullabilityNotYetLoaded) { if (nullabilityConstraint == nullabilityNotYetLoaded) {

1
ICSharpCode.Decompiler/TypeSystem/Implementation/NullabilityAnnotatedType.cs

@ -90,6 +90,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
bool ITypeParameter.HasDefaultConstructorConstraint => baseType.HasDefaultConstructorConstraint; bool ITypeParameter.HasDefaultConstructorConstraint => baseType.HasDefaultConstructorConstraint;
bool ITypeParameter.HasReferenceTypeConstraint => baseType.HasReferenceTypeConstraint; bool ITypeParameter.HasReferenceTypeConstraint => baseType.HasReferenceTypeConstraint;
bool ITypeParameter.HasValueTypeConstraint => baseType.HasValueTypeConstraint; bool ITypeParameter.HasValueTypeConstraint => baseType.HasValueTypeConstraint;
bool ITypeParameter.HasUnmanagedConstraint => baseType.HasUnmanagedConstraint;
Nullability ITypeParameter.NullabilityConstraint => baseType.NullabilityConstraint; Nullability ITypeParameter.NullabilityConstraint => baseType.NullabilityConstraint;
SymbolKind ISymbol.SymbolKind => SymbolKind.TypeParameter; SymbolKind ISymbol.SymbolKind => SymbolKind.TypeParameter;
IEnumerable<IAttribute> ITypeParameter.GetAttributes() => baseType.GetAttributes(); IEnumerable<IAttribute> ITypeParameter.GetAttributes() => baseType.GetAttributes();

15
ICSharpCode.Decompiler/TypeSystem/Implementation/SpecializedMethod.cs

@ -242,17 +242,10 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
return o != null && baseTp.Equals(o.baseTp) && this.Owner.Equals(o.Owner); return o != null && baseTp.Equals(o.baseTp) && this.Owner.Equals(o.Owner);
} }
public override bool HasValueTypeConstraint { public override bool HasValueTypeConstraint => baseTp.HasValueTypeConstraint;
get { return baseTp.HasValueTypeConstraint; } public override bool HasReferenceTypeConstraint => baseTp.HasReferenceTypeConstraint;
} public override bool HasDefaultConstructorConstraint => baseTp.HasDefaultConstructorConstraint;
public override bool HasUnmanagedConstraint => baseTp.HasUnmanagedConstraint;
public override bool HasReferenceTypeConstraint {
get { return baseTp.HasReferenceTypeConstraint; }
}
public override bool HasDefaultConstructorConstraint {
get { return baseTp.HasDefaultConstructorConstraint; }
}
public override Nullability NullabilityConstraint => baseTp.NullabilityConstraint; public override Nullability NullabilityConstraint => baseTp.NullabilityConstraint;

4
ICSharpCode.Decompiler/TypeSystem/MetadataModule.cs

@ -598,7 +598,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
var b = new AttributeListBuilder(this); var b = new AttributeListBuilder(this);
if (metadata.IsAssembly) { if (metadata.IsAssembly) {
var assembly = metadata.GetAssemblyDefinition(); var assembly = metadata.GetAssemblyDefinition();
b.Add(metadata.GetCustomAttributes(Handle.AssemblyDefinition)); b.Add(metadata.GetCustomAttributes(Handle.AssemblyDefinition), SymbolKind.Module);
b.AddSecurityAttributes(assembly.GetDeclarativeSecurityAttributes()); b.AddSecurityAttributes(assembly.GetDeclarativeSecurityAttributes());
// AssemblyVersionAttribute // AssemblyVersionAttribute
@ -617,7 +617,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
public IEnumerable<IAttribute> GetModuleAttributes() public IEnumerable<IAttribute> GetModuleAttributes()
{ {
var b = new AttributeListBuilder(this); var b = new AttributeListBuilder(this);
b.Add(metadata.GetCustomAttributes(Handle.ModuleDefinition)); b.Add(metadata.GetCustomAttributes(Handle.ModuleDefinition), SymbolKind.Module);
if (!metadata.IsAssembly) { if (!metadata.IsAssembly) {
AddTypeForwarderAttributes(ref b); AddTypeForwarderAttributes(ref b);
} }

Loading…
Cancel
Save