internal EcmaMethodDecoder(MethodDefinitionHandle handle, EcmaModule module) : this() { _handle = handle; _module = module; _neverAccessThisExceptThroughMethodDefinitionProperty = handle.GetMethodDefinition(Reader); }
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);
protected sealed override ConstructorInfo ComputeConstructor() { EntityHandle ctorHandle = CustomAttribute.Constructor; switch (ctorHandle.Kind) { case HandleKind.MethodDefinition: { MethodDefinitionHandle mh = (MethodDefinitionHandle)ctorHandle; EcmaDefinitionType declaringType = mh.GetMethodDefinition(Reader).GetDeclaringType().ResolveTypeDef(_module); return(new RoDefinitionConstructor <EcmaMethodDecoder>(declaringType, new EcmaMethodDecoder(mh, _module))); } case HandleKind.MemberReference: { TypeContext typeContext = default; MemberReference mr = ((MemberReferenceHandle)ctorHandle).GetMemberReference(Reader); MethodSignature <RoType> sig = mr.DecodeMethodSignature(_module, typeContext); Type[] parameterTypes = sig.ParameterTypes.ToArray(); Type declaringType = mr.Parent.ResolveTypeDefRefOrSpec(_module, typeContext); const BindingFlags bf = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.ExactBinding; ConstructorInfo ci = declaringType.GetConstructor(bf, null, parameterTypes, null); if (ci == null) { throw new MissingMethodException(SR.Format(SR.MissingCustomAttributeConstructor, declaringType)); } return(ci); } // Constructors can not be generic methods so this should never occur. (Not to be confused with constructors on generic types and we do now // support generic attributes. But that comes in as a MemberReference, not a MethodSpec.) case HandleKind.MethodSpecification: throw new BadImageFormatException(); default: throw new BadImageFormatException(); } }
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 ctorHandle = ca.Constructor; EntityHandle declaringTypeHandle = default; switch (ctorHandle.Kind) { case HandleKind.MethodDefinition: { MethodDefinitionHandle mh = (MethodDefinitionHandle)ctorHandle; declaringTypeHandle = mh.GetMethodDefinition(reader).GetDeclaringType(); break; } case HandleKind.MemberReference: { MemberReference mr = ((MemberReferenceHandle)ctorHandle).GetMemberReference(reader); declaringTypeHandle = mr.Parent; break; } default: break; } 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); }