private void ImportCustomAttributesNames() { _customAttributes = new List <string>(); AssemblyDefinition def = _reader.GetAssemblyDefinition(); CustomAttributeHandleCollection col = def.GetCustomAttributes(); foreach (CustomAttributeHandle handle in col) { EntityHandle ctorHandle = _reader.GetCustomAttribute(handle).Constructor; if (ctorHandle.Kind != HandleKind.MemberReference) { continue; } EntityHandle mHandle = _reader.GetMemberReference((MemberReferenceHandle)ctorHandle).Parent; if (mHandle.Kind != HandleKind.TypeReference) { continue; } string type = GetTypeName((TypeReferenceHandle)mHandle); _customAttributes.Add(type); } }
private Scope GetOSPlatformScope(CustomAttributeHandleCollection attrs) { var supported = new List <OSPlatform>(); var unsupported = new List <OSPlatform>(); foreach (var customAttrHandle in attrs) { CustomAttribute customAttr = this.mdReader.GetCustomAttribute(customAttrHandle); if (this.TryGetOSPlatformAttributeValue(customAttr, out bool isSupported, out OSPlatform scen)) { if (isSupported) { supported.Add(scen); } else { unsupported.Add(scen); } } } return(new Scope() { Support = supported, NoSupport = unsupported }); }
public static Nullability?GetNullableContext(this CustomAttributeHandleCollection customAttributes, MetadataReader metadata) { foreach (var handle in customAttributes) { var customAttribute = metadata.GetCustomAttribute(handle); if (customAttribute.IsKnownAttribute(metadata, KnownAttribute.NullableContext)) { // Decode CustomAttributeValue <IType> value; try { value = customAttribute.DecodeValue( Metadata.MetadataExtensions.MinimalAttributeTypeProvider); } catch (BadImageFormatException) { continue; } catch (Metadata.EnumUnderlyingTypeResolveException) { continue; } if (value.FixedArguments.Length == 1 && value.FixedArguments[0].Value is byte b && b <= 2) { return((Nullability)b); } } } return(null); }
internal static CustomAttributeData[] GetCustomAttributesData( MetadataReader metadata, CustomAttributeHandleCollection attributes, bool inherit = false) { return(new CustomAttributeData[0]); }
static Accessibility FindMinimumAccessibilityForNRT(MetadataReader metadata, CustomAttributeHandleCollection customAttributes) { // Determine the minimum effective accessibility an entity must have, so that the metadata stores the nullability for its type. foreach (var handle in customAttributes) { var customAttribute = metadata.GetCustomAttribute(handle); if (customAttribute.IsKnownAttribute(metadata, KnownAttribute.NullablePublicOnly)) { CustomAttributeValue <IType> value; try { value = customAttribute.DecodeValue(Metadata.MetadataExtensions.MinimalAttributeTypeProvider); } catch (BadImageFormatException) { continue; } catch (EnumUnderlyingTypeResolveException) { continue; } if (value.FixedArguments.Length == 1 && value.FixedArguments[0].Value is bool includesInternals) { return(includesInternals ? Accessibility.ProtectedAndInternal : Accessibility.Protected); } } } return(Accessibility.None); }
/// <summary> /// Converts ECMA-encoded custom attributes into a freshly allocated CustomAttributeData object suitable for direct return /// from the CustomAttributes api. /// </summary> public static IEnumerable <CustomAttributeData> ToTrueCustomAttributes(this CustomAttributeHandleCollection handles, EcmaModule module) { foreach (CustomAttributeHandle handle in handles) { yield return(handle.ToCustomAttributeData(module)); } }
public bool HasAttribute(MetadataReader reader, CustomAttributeHandleCollection attrHandles, string attributeFullName) { if (!_attributeConstructors.TryGetValue(attributeFullName, out var constructorSet)) { constructorSet = new HashSet <EntityHandle>(); _attributeConstructors[attributeFullName] = constructorSet; } var attrs = attrHandles.Select(reader.GetCustomAttribute).ToList(); if (attrs.Any(attr => constructorSet.Contains(attr.Constructor))) { return(true); } var compilerGeneratedAttr = attrs .Where(attr => reader.GetFullname(reader.GetCustomAttrClass(attr)) == attributeFullName) .Select(attr => (CustomAttribute?)attr) .FirstOrDefault(); if (compilerGeneratedAttr == null) { return(false); } constructorSet.Add(compilerGeneratedAttr.Value.Constructor); return(true); }
public static CustomAttributeData TryFindCustomAttribute(this CustomAttributeHandleCollection handles, ReadOnlySpan <byte> ns, ReadOnlySpan <byte> name, EcmaModule module) { CustomAttributeHandle handle = handles.FindCustomAttributeByName(ns, name, module); if (handle.IsNil) { return(null); } return(handle.ToCustomAttributeData(module)); }
} // Read public static uint Read(this NativeReader reader, uint offset, out CustomAttributeHandleCollection values) { values = new CustomAttributeHandleCollection(reader, offset); uint count; offset = reader.DecodeUnsigned(offset, out count); for (uint i = 0; i < count; ++i) { offset = reader.SkipInteger(offset); } return(offset); } // Read
public static bool HasKnownAttribute(this CustomAttributeHandleCollection customAttributes, MetadataReader metadata, KnownAttribute type) { foreach (var handle in customAttributes) { var customAttribute = metadata.GetCustomAttribute(handle); if (customAttribute.IsKnownAttribute(metadata, type)) { return(true); } } return(false); }
public static void AddDependenciesDueToCustomAttributes(ref DependencyList dependencies, NodeFactory factory, EcmaAssembly assembly) { AssemblyDefinition asmDef = assembly.MetadataReader.GetAssemblyDefinition(); AddDependenciesDueToCustomAttributes(ref dependencies, factory, assembly, asmDef.GetCustomAttributes()); // This is rather awkward because ModuleDefinition doesn't offer means to get to the custom attributes CustomAttributeHandleCollection moduleAttributes = assembly.MetadataReader.GetCustomAttributes(System.Reflection.Metadata.Ecma335.MetadataTokens.EntityHandle(0x1)); AddDependenciesDueToCustomAttributes(ref dependencies, factory, assembly, moduleAttributes); }
static internal List <MrCustomAttribute> GetCustomAttributesFromHandles( CustomAttributeHandleCollection customAttributeHandles, MrType declaringType) { var customAttributes = new List <MrCustomAttribute>(customAttributeHandles.Count); foreach (var customAttributeHandle in customAttributeHandles) { var customAttribute = new MrCustomAttribute(customAttributeHandle, declaringType, declaringType.Assembly); customAttributes.Add(customAttribute); } return(customAttributes); }
public static object GetDecimalConstantValue(MetadataModule module, CustomAttributeHandleCollection attributeHandles) { var metadata = module.metadata; foreach (var attributeHandle in attributeHandles) { var attribute = metadata.GetCustomAttribute(attributeHandle); if (attribute.IsKnownAttribute(metadata, KnownAttribute.DecimalConstant)) { return(TryDecodeDecimalConstantAttribute(module, attribute)); } } return(null); }
public void Add(CustomAttributeHandleCollection attributes, SymbolKind target) { var metadata = module.metadata; foreach (var handle in attributes) { var attribute = metadata.GetCustomAttribute(handle); // 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 type = ctor.DeclaringType; if (IgnoreAttribute(type, target)) { continue; } Add(new CustomAttribute(module, ctor, handle)); } }
public static bool HasCustomAttribute(this MetadataReader metadataReader, CustomAttributeHandleCollection customAttributes, string attributeNamespace, string attributeName) { foreach (var attributeHandle in customAttributes) { StringHandle namespaceHandle, nameHandle; if (!metadataReader.GetAttributeNamespaceAndName(attributeHandle, out namespaceHandle, out nameHandle)) continue; if (metadataReader.StringComparer.Equals(namespaceHandle, attributeNamespace) && metadataReader.StringComparer.Equals(nameHandle, attributeName)) { return true; } } return false; }
private static CustomAttributeHandle FindCustomAttributeByName(this CustomAttributeHandleCollection handles, ReadOnlySpan <byte> ns, ReadOnlySpan <byte> name, EcmaModule module) { MetadataReader reader = module.Reader; foreach (CustomAttributeHandle handle in handles) { CustomAttribute ca = handle.GetCustomAttribute(reader); EntityHandle declaringTypeHandle = ca.TryGetDeclaringTypeHandle(reader); if (declaringTypeHandle.IsNil) { continue; } if (declaringTypeHandle.TypeMatchesNameAndNamespace(ns, name, reader)) { return(handle); } } return(default);
public static bool HasCustomAttribute(this MetadataReader metadataReader, CustomAttributeHandleCollection customAttributes, string attributeNamespace, string attributeName) { foreach (var attributeHandle in customAttributes) { StringHandle namespaceHandle, nameHandle; if (!metadataReader.GetAttributeNamespaceAndName(attributeHandle, out namespaceHandle, out nameHandle)) { continue; } if (metadataReader.StringComparer.Equals(namespaceHandle, attributeNamespace) && metadataReader.StringComparer.Equals(nameHandle, attributeName)) { return(true); } } return(false); }
void CompareCustomAttributes(CustomAttributeHandleCollection cac1, CustomAttributeHandleCollection cac2, string padding) { var dict1 = GetCustomAttributes(reader1, cac1); var dict2 = GetCustomAttributes(reader2, cac2); foreach (var pair in dict1) { if (!dict2.ContainsKey(pair.Key)) { Console.WriteLine($"{padding} - CustomAttribute {pair.Key}"); } } foreach (var pair in dict2) { if (!dict1.ContainsKey(pair.Key)) { Console.WriteLine($"{padding} + CustomAttribute {pair.Key}"); } } }
public static bool HasCustomAttribute(this MetadataReader metadataReader, CustomAttributeHandleCollection customAttributes, string attributeNamespace, string attributeName) { foreach (var attributeHandle in customAttributes) { ConstantStringValueHandle nameHandle; string namespaceName; if (!metadataReader.GetAttributeNamespaceAndName(attributeHandle, out namespaceName, out nameHandle)) { continue; } if (namespaceName.Equals(attributeNamespace) && nameHandle.StringEquals(attributeName, metadataReader)) { return(true); } } return(false); }
private static CustomAttributeHandle FindCustomAttributeByName(this CustomAttributeHandleCollection handles, ReadOnlySpan <byte> ns, ReadOnlySpan <byte> name, EcmaModule module) { MetadataReader reader = module.Reader; foreach (CustomAttributeHandle handle in handles) { CustomAttribute ca = handle.GetCustomAttribute(module.Reader); EntityHandle ctorHandle = ca.Constructor; switch (ctorHandle.Kind) { case HandleKind.MethodDefinition: { MethodDefinitionHandle mh = (MethodDefinitionHandle)ctorHandle; EntityHandle declaringTypeHandle = mh.GetMethodDefinition(reader).GetDeclaringType(); if (declaringTypeHandle.TypeMatchesNameAndNamespace(ns, name, reader)) { return(handle); } break; } case HandleKind.MemberReference: { MemberReference mr = ((MemberReferenceHandle)ctorHandle).GetMemberReference(reader); EntityHandle declaringTypeHandle = mr.Parent; if (declaringTypeHandle.TypeMatchesNameAndNamespace(ns, name, reader)) { return(handle); } break; } default: break; } } return(default);
public static CustomAttributeHandle GetCustomAttributeHandle(this MetadataReader metadataReader, CustomAttributeHandleCollection customAttributes, string attributeNamespace, string attributeName) { foreach (var attributeHandle in customAttributes) { if (IsEqualCustomAttributeName(attributeHandle, metadataReader, attributeNamespace, attributeName)) { return(attributeHandle); } } return(default(CustomAttributeHandle)); }
public static bool IsDecimalConstant(MetadataModule module, CustomAttributeHandleCollection attributeHandles) { return(attributeHandles.HasKnownAttribute(module.metadata, KnownAttribute.DecimalConstant)); }
private static DynamicallyAccessedMemberTypes GetMemberTypesForDynamicallyAccessedMembersAttribute(MetadataReader reader, CustomAttributeHandleCollection customAttributeHandles) { CustomAttributeHandle ca = reader.GetCustomAttributeHandle(customAttributeHandles, "System.Diagnostics.CodeAnalysis", "DynamicallyAccessedMembersAttribute"); if (ca.IsNil) { return(DynamicallyAccessedMemberTypes.None); } BlobReader blobReader = reader.GetBlobReader(reader.GetCustomAttribute(ca).Value); Debug.Assert(blobReader.Length == 8); if (blobReader.Length != 8) { return(DynamicallyAccessedMemberTypes.None); } blobReader.ReadUInt16(); // Prolog return((DynamicallyAccessedMemberTypes)blobReader.ReadUInt32()); }
internal static IEnumerable <CustomAttributeData> GetCustomAttributes(MetadataReader reader, CustomAttributeHandleCollection customAttributeHandles) { foreach (CustomAttributeHandle customAttributeHandle in customAttributeHandles) { yield return(GetCustomAttributeData(reader, customAttributeHandle)); } }
private static void AddDependenciesDueToCustomAttributes(ref DependencyList dependencies, NodeFactory factory, EcmaModule module, CustomAttributeHandleCollection attributeHandles) { MetadataReader reader = module.MetadataReader; var mdManager = (UsageBasedMetadataManager)factory.MetadataManager; var attributeTypeProvider = new CustomAttributeTypeProvider(module); foreach (CustomAttributeHandle caHandle in attributeHandles) { CustomAttribute attribute = reader.GetCustomAttribute(caHandle); try { MethodDesc constructor = module.GetMethod(attribute.Constructor); if (!mdManager.GeneratesAttributeMetadata(constructor.OwningType)) { continue; } if (mdManager.IsReflectionBlocked(constructor)) { continue; } CustomAttributeValue <TypeDesc> decodedValue = attribute.DecodeValue(attributeTypeProvider); // Make a new list in case we need to abort. var caDependencies = factory.MetadataManager.GetDependenciesForCustomAttribute(factory, constructor, decodedValue) ?? new DependencyList(); caDependencies.Add(factory.ReflectableMethod(constructor), "Attribute constructor"); caDependencies.Add(factory.ConstructedTypeSymbol(constructor.OwningType), "Attribute type"); if (AddDependenciesFromCustomAttributeBlob(caDependencies, factory, constructor.OwningType, decodedValue)) { dependencies = dependencies ?? new DependencyList(); dependencies.AddRange(caDependencies); dependencies.Add(factory.CustomAttributeMetadata(new ReflectableCustomAttribute(module, caHandle)), "Attribute metadata"); } } catch (TypeSystemException) { // We could end up seeing an exception here for a multitude of reasons: // * Attribute ctor doesn't resolve // * There's a typeof() that refers to something that can't be loaded // * Attribute refers to a non-existing field // * Etc. // // If we really wanted to, we could probably come up with a way to still make this // work with the same failure modes at runtime as the CLR, but it might not be // worth the hassle: the input was invalid. The most important thing is that we // don't crash the compilation. } } }
Dictionary <string, CustomAttribute> GetCustomAttributes(MetadataReader reader, CustomAttributeHandleCollection cac) { var dict = new Dictionary <string, CustomAttribute> (); foreach (var handle in cac) { var ca = reader.GetCustomAttribute(handle); var cHandle = ca.Constructor; string typeName; switch (cHandle.Kind) { case HandleKind.MethodDefinition: var methodDef = reader.GetMethodDefinition((MethodDefinitionHandle)cHandle); typeName = GetTypeName(reader, methodDef.GetDeclaringType()); break; case HandleKind.MemberReference: var memberDef = reader.GetMemberReference((MemberReferenceHandle)cHandle); typeName = GetTypeName(reader, memberDef.Parent); break; default: Program.Warning($"Unexpected EntityHandle kind: {cHandle.Kind}"); continue; } dict [typeName] = ca; } return(dict); }
private static CustomAttributeHandle GetComVisibleAttribute(MetadataReader reader, CustomAttributeHandleCollection customAttributes) { foreach (CustomAttributeHandle attr in customAttributes) { CustomAttribute attribute = reader.GetCustomAttribute(attr); if (IsTargetAttribute(reader, attribute, "System.Runtime.InteropServices", "ComVisibleAttribute")) { return(attr); } } return(new CustomAttributeHandle()); }
internal static bool IsCompatibleWithPlatform(MetadataReader mr, MetadataIndex index, Platform?platform, CustomAttributeHandleCollection customAttributesOnMember) { if (index.SupportedArchitectureAttributeCtor == default) { // This metadata never uses the SupportedArchitectureAttribute, so we assume this member is compatible. return(true); } foreach (CustomAttributeHandle attHandle in customAttributesOnMember) { CustomAttribute att = mr.GetCustomAttribute(attHandle); if (att.Constructor.Equals(index.SupportedArchitectureAttributeCtor)) { if (platform is null) { // Without a compilation, we cannot ascertain compatibility. return(false); } var requiredPlatform = (InteropArchitecture)(int)att.DecodeValue(CustomAttributeTypeProvider.Instance).FixedArguments[0].Value !; return(platform switch { Platform.AnyCpu or Platform.AnyCpu32BitPreferred => requiredPlatform == InteropArchitecture.All, Platform.Arm64 => (requiredPlatform & InteropArchitecture.Arm64) == InteropArchitecture.Arm64, Platform.X86 => (requiredPlatform & InteropArchitecture.X86) == InteropArchitecture.X86, Platform.X64 => (requiredPlatform & InteropArchitecture.X64) == InteropArchitecture.X64, _ => false, });
public static bool IsCustomAttributeDefined(this CustomAttributeHandleCollection handles, ReadOnlySpan <byte> ns, ReadOnlySpan <byte> name, EcmaModule module) { return(!handles.FindCustomAttributeByName(ns, name, module).IsNil); }
private static CustomAttributeHandle GetComVisibleAttribute(MetadataReader reader, CustomAttributeHandleCollection customAttributes) { foreach (CustomAttributeHandle attr in customAttributes) { CustomAttribute attribute = reader.GetCustomAttribute(attr); MemberReference attributeConstructor = reader.GetMemberReference((MemberReferenceHandle)attribute.Constructor); TypeReference attributeType = reader.GetTypeReference((TypeReferenceHandle)attributeConstructor.Parent); if (reader.StringComparer.Equals(attributeType.Namespace, "System.Runtime.InteropServices") && reader.StringComparer.Equals(attributeType.Name, "ComVisibleAttribute")) { return(attr); } } return(new CustomAttributeHandle()); }
public static bool TryFindRawDefaultValueFromCustomAttributes(this CustomAttributeHandleCollection handles, EcmaModule module, out object rawDefaultValue) { rawDefaultValue = default; MetadataReader reader = module.Reader; foreach (CustomAttributeHandle handle in handles) { CustomAttribute ca = handle.GetCustomAttribute(reader); EntityHandle declaringTypeHandle = ca.TryGetDeclaringTypeHandle(reader); if (declaringTypeHandle.IsNil) { continue; } if (declaringTypeHandle.TypeMatchesNameAndNamespace(Utf8Constants.SystemRuntimeCompilerServices, Utf8Constants.DateTimeConstantAttribute, reader)) { CustomAttributeData cad = handle.ToCustomAttributeData(module); IList <CustomAttributeTypedArgument> cats = cad.ConstructorArguments; if (cats.Count != 1) { return(false); } CoreTypes ct = module.Loader.GetAllFoundCoreTypes(); if (cats[0].ArgumentType != ct[CoreType.Int64]) { return(false); } long ticks = (long)(cats[0].Value); rawDefaultValue = new DateTimeConstantAttribute(ticks).Value; return(true); } if (declaringTypeHandle.TypeMatchesNameAndNamespace(Utf8Constants.SystemRuntimeCompilerServices, Utf8Constants.DecimalConstantAttribute, reader)) { CustomAttributeData cad = handle.ToCustomAttributeData(module); IList <CustomAttributeTypedArgument> cats = cad.ConstructorArguments; if (cats.Count != 5) { return(false); } CoreTypes ct = module.Loader.GetAllFoundCoreTypes(); if (cats[0].ArgumentType != ct[CoreType.Byte] || cats[1].ArgumentType != ct[CoreType.Byte]) { return(false); } byte scale = (byte)cats[0].Value; byte sign = (byte)cats[1].Value; if (cats[2].ArgumentType == ct[CoreType.Int32] && cats[3].ArgumentType == ct[CoreType.Int32] && cats[4].ArgumentType == ct[CoreType.Int32]) { int hi = (int)cats[2].Value; int mid = (int)cats[3].Value; int lo = (int)cats[4].Value; rawDefaultValue = new DecimalConstantAttribute(scale, sign, hi, mid, lo).Value; return(true); } if (cats[2].ArgumentType == ct[CoreType.UInt32] && cats[3].ArgumentType == ct[CoreType.UInt32] && cats[4].ArgumentType == ct[CoreType.UInt32]) { uint hi = (uint)cats[2].Value; uint mid = (uint)cats[3].Value; uint lo = (uint)cats[4].Value; rawDefaultValue = new DecimalConstantAttribute(scale, sign, hi, mid, lo).Value; return(true); } return(false); } // Should we also look for CustomConstantAttribute too? Who uses that (other than DateTimeConstantAttribute which // we handled above?) CustomConstantAttribute is an abstract class which means we have to figure out how a subclass // we've never heard of would set the "Value" property which is kinda hard to do when you can't Invoke(). // Even the CLR doesn't return consistent values for this between the raw and non-raw versions. // Even doing the subclass check would open the door to resolving types and dependency assemblies and their // resulting FileNotFoundExceptions. Which is exactly what we're trying to avoid with this name-based lookup approach. } return(false); }
} // Read public static uint Read(this NativeReader reader, uint offset, out CustomAttributeHandleCollection values) { values = new CustomAttributeHandleCollection(reader, offset); uint count; offset = reader.DecodeUnsigned(offset, out count); for (uint i = 0; i < count; ++i) { offset = reader.SkipInteger(offset); } return offset; } // Read