private List <CustomAttribute> HandleCustomAttributes(Cts.Ecma.EcmaModule module, Ecma.CustomAttributeHandleCollection attributes) { List <CustomAttribute> customAttributes = new List <CustomAttribute>(attributes.Count); var attributeTypeProvider = new Cts.Ecma.CustomAttributeTypeProvider(module); foreach (var attributeHandle in attributes) { Ecma.MetadataReader reader = module.MetadataReader; Ecma.CustomAttribute attribute = reader.GetCustomAttribute(attributeHandle); // TODO-NICE: We can intern the attributes based on the CA constructor and blob bytes try { Cts.MethodDesc constructor = module.GetMethod(attribute.Constructor); var decodedValue = attribute.DecodeValue(attributeTypeProvider); if (IsBlockedCustomAttribute(constructor, decodedValue)) { continue; } customAttributes.Add(HandleCustomAttribute(constructor, decodedValue)); } catch (Cts.TypeSystemException) { // TODO: We should emit unresolvable custom attributes instead of skipping these } } return(customAttributes); }
static decimal?TryDecodeDecimalConstantAttribute(MetadataModule module, System.Reflection.Metadata.CustomAttribute attribute) { var attrValue = attribute.DecodeValue(module.TypeProvider); if (attrValue.FixedArguments.Length != 5) { return(null); } // DecimalConstantAttribute has the arguments (byte scale, byte sign, uint hi, uint mid, uint low) or (byte scale, byte sign, int hi, int mid, int low) // Both of these invoke the Decimal constructor (int lo, int mid, int hi, bool isNegative, byte scale) with explicit argument conversions if required. if (!(attrValue.FixedArguments[0].Value is byte scale && attrValue.FixedArguments[1].Value is byte sign)) { return(null); } unchecked { if (attrValue.FixedArguments[2].Value is uint hi && attrValue.FixedArguments[3].Value is uint mid && attrValue.FixedArguments[4].Value is uint lo) { return(new decimal((int)lo, (int)mid, (int)hi, sign != 0, scale)); } } { if (attrValue.FixedArguments[2].Value is int hi && attrValue.FixedArguments[3].Value is int mid && attrValue.FixedArguments[4].Value is int lo) { return(new decimal(lo, mid, hi, sign != 0, scale)); } } return(null); }
private List <CustomAttribute> HandleCustomAttributes(Cts.Ecma.EcmaModule module, Ecma.CustomAttributeHandleCollection attributes) { List <CustomAttribute> customAttributes = new List <CustomAttribute>(attributes.Count); var attributeTypeProvider = new Cts.Ecma.CustomAttributeTypeProvider(module); Ecma.MetadataReader reader = module.MetadataReader; foreach (var attributeHandle in attributes) { if (!_policy.GeneratesMetadata(module, attributeHandle)) { continue; } Ecma.CustomAttribute attribute = reader.GetCustomAttribute(attributeHandle); // TODO-NICE: We can intern the attributes based on the CA constructor and blob bytes Cts.MethodDesc constructor = module.GetMethod(attribute.Constructor); var decodedValue = attribute.DecodeValue(attributeTypeProvider); customAttributes.Add(HandleCustomAttribute(constructor, decodedValue)); } return(customAttributes); }