Browse Source

Fix #3094: look for `[NullableAttribute]` both on the property getter and property itself

pull/3111/head
Daniel Grunwald 2 years ago
parent
commit
a14cc0234e
  1. 25
      ICSharpCode.Decompiler/TypeSystem/ApplyAttributeTypeVisitor.cs
  2. 14
      ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataMethod.cs
  3. 2
      ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataProperty.cs

25
ICSharpCode.Decompiler/TypeSystem/ApplyAttributeTypeVisitor.cs

@ -40,7 +40,8 @@ namespace ICSharpCode.Decompiler.TypeSystem
SRM.MetadataReader metadata, SRM.MetadataReader metadata,
TypeSystemOptions options, TypeSystemOptions options,
Nullability nullableContext, Nullability nullableContext,
bool typeChildrenOnly = false) bool typeChildrenOnly = false,
SRM.CustomAttributeHandleCollection? additionalAttributes = null)
{ {
bool hasDynamicAttribute = false; bool hasDynamicAttribute = false;
bool[] dynamicAttributeData = null; bool[] dynamicAttributeData = null;
@ -57,10 +58,8 @@ namespace ICSharpCode.Decompiler.TypeSystem
{ {
nullability = Nullability.Oblivious; nullability = Nullability.Oblivious;
} }
const TypeSystemOptions relevantOptions = TypeSystemOptions.Dynamic | TypeSystemOptions.Tuple | TypeSystemOptions.NullabilityAnnotations | TypeSystemOptions.NativeIntegers;
if (attributes != null && (options & relevantOptions) != 0) void ProcessAttribute(SRM.CustomAttributeHandle attrHandle)
{
foreach (var attrHandle in attributes.Value)
{ {
var attr = metadata.GetCustomAttribute(attrHandle); var attr = metadata.GetCustomAttribute(attrHandle);
var attrType = attr.GetAttributeType(metadata); var attrType = attr.GetAttributeType(metadata);
@ -123,6 +122,22 @@ namespace ICSharpCode.Decompiler.TypeSystem
} }
} }
} }
const TypeSystemOptions relevantOptions = TypeSystemOptions.Dynamic | TypeSystemOptions.Tuple | TypeSystemOptions.NullabilityAnnotations | TypeSystemOptions.NativeIntegers;
if (attributes != null && (options & relevantOptions) != 0)
{
foreach (var attrHandle in attributes.Value)
{
ProcessAttribute(attrHandle);
}
}
if (additionalAttributes != null && (options & relevantOptions) != 0)
{
// Note: additional attributes will override the values from the normal attributes.
foreach (var attrHandle in additionalAttributes.Value)
{
ProcessAttribute(attrHandle);
}
} }
if (hasDynamicAttribute || hasNativeIntegersAttribute || nullability != Nullability.Oblivious || nullableAttributeData != null if (hasDynamicAttribute || hasNativeIntegersAttribute || nullability != Nullability.Oblivious || nullableAttributeData != null
|| (options & (TypeSystemOptions.Tuple | TypeSystemOptions.KeepModifiers)) != TypeSystemOptions.KeepModifiers) || (options & (TypeSystemOptions.Tuple | TypeSystemOptions.KeepModifiers)) != TypeSystemOptions.KeepModifiers)

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

@ -209,13 +209,14 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
MetadataModule module, IParameterizedMember owner, MetadataModule module, IParameterizedMember owner,
MethodSignature<IType> signature, ParameterHandleCollection? parameterHandles, MethodSignature<IType> signature, ParameterHandleCollection? parameterHandles,
Nullability nullableContext, TypeSystemOptions typeSystemOptions, Nullability nullableContext, TypeSystemOptions typeSystemOptions,
CustomAttributeHandleCollection? returnTypeAttributes = null) CustomAttributeHandleCollection? additionalReturnTypeAttributes = null)
{ {
var metadata = module.metadata; var metadata = module.metadata;
int i = 0; int i = 0;
IParameter[] parameters = new IParameter[signature.RequiredParameterCount IParameter[] parameters = new IParameter[signature.RequiredParameterCount
+ (signature.Header.CallingConvention == SignatureCallingConvention.VarArgs ? 1 : 0)]; + (signature.Header.CallingConvention == SignatureCallingConvention.VarArgs ? 1 : 0)];
IType parameterType; IType parameterType;
CustomAttributeHandleCollection? returnTypeAttributes = null;
if (parameterHandles != null) if (parameterHandles != null)
{ {
foreach (var parameterHandle in parameterHandles) foreach (var parameterHandle in parameterHandles)
@ -225,14 +226,13 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
{ {
// "parameter" holds return type attributes. // "parameter" holds return type attributes.
// Note: for properties, the attributes normally stored on a method's return type // Note: for properties, the attributes normally stored on a method's return type
// are instead stored as normal attributes on the property. // are instead typically stored as normal attributes on the property.
// So MetadataProperty provides a non-null value for returnTypeAttributes, // So MetadataProperty provides a non-null value for additionalReturnTypeAttributes,
// which then should be preferred over the attributes on the accessor's parameters. // which then will be preferred over the attributes on the accessor's parameters.
if (returnTypeAttributes == null) // However if an attribute only exists on the accessor's parameters, we still want
{ // to process it here.
returnTypeAttributes = par.GetCustomAttributes(); returnTypeAttributes = par.GetCustomAttributes();
} }
}
else if (i < par.SequenceNumber && par.SequenceNumber <= signature.RequiredParameterCount) else if (i < par.SequenceNumber && par.SequenceNumber <= signature.RequiredParameterCount)
{ {
// "Successive rows of the Param table that are owned by the same method shall be // "Successive rows of the Param table that are owned by the same method shall be

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

@ -169,7 +169,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
(returnType, parameters, _) = MetadataMethod.DecodeSignature( (returnType, parameters, _) = MetadataMethod.DecodeSignature(
module, this, signature, module, this, signature,
parameterHandles, nullableContext, typeOptions, parameterHandles, nullableContext, typeOptions,
returnTypeAttributes: propertyDef.GetCustomAttributes()); additionalReturnTypeAttributes: propertyDef.GetCustomAttributes());
} }
catch (BadImageFormatException) catch (BadImageFormatException)
{ {

Loading…
Cancel
Save