private static bool IsComVisible(MetadataReader metadataReader, TypeDefinition definition, bool assemblyComVisible) { // We need to ensure that all parent scopes of the given type are not explicitly non-ComVisible. bool?IsComVisibleCore(TypeDefinition typeDefinition) { CustomAttributeHandle handle = GetComVisibleAttribute(metadataReader, typeDefinition.GetCustomAttributes()); if (handle.IsNil) { return(null); } CustomAttribute comVisibleAttribute = metadataReader.GetCustomAttribute(handle); CustomAttributeValue <KnownType> data = comVisibleAttribute.DecodeValue(new TypeResolver()); return((bool)data.FixedArguments[0].Value); } if (!definition.GetDeclaringType().IsNil) { return(IsComVisible(metadataReader, metadataReader.GetTypeDefinition(definition.GetDeclaringType()), assemblyComVisible) && (IsComVisibleCore(definition) ?? assemblyComVisible)); } return(IsComVisibleCore(definition) ?? assemblyComVisible); }
internal static string GetRequiresAttributeMessage(CustomAttributeValue <TypeDesc> attribute) { if (attribute.FixedArguments.Length != 0) { return((string)attribute.FixedArguments[0].Value); } return(null); }
internal static string GetRequiresAttributeUrl(CustomAttributeValue <TypeDesc> attribute) { if (attribute.NamedArguments.Length != 0 && attribute.NamedArguments[0].Name == "Url") { return((string)attribute.NamedArguments[0].Value); } return(null); }
protected override void AllocAndTransformManagedToNative(ILCodeStream codeStream) { ILEmitter emitter = _ilCodeStreams.Emitter; LoadManagedValue(codeStream); var parameterType = this.ManagedParameterType; if (parameterType.IsByRef) { parameterType = ((ByRefType)this.ManagedParameterType).ParameterType; } CustomAttributeValue <TypeDesc>?guidAttributeValue = (parameterType as EcmaType)? .GetDecodedCustomAttribute("System.Runtime.InteropServices", "GuidAttribute"); if (guidAttributeValue != null) { var guidValue = (string)guidAttributeValue.Value.FixedArguments[0].Value; Span <byte> bytes = Guid.Parse(guidValue).ToByteArray(); codeStream.EmitLdc(BinaryPrimitives.ReadInt32LittleEndian(bytes)); codeStream.EmitLdc(BinaryPrimitives.ReadInt16LittleEndian(bytes.Slice(4))); codeStream.EmitLdc(BinaryPrimitives.ReadInt16LittleEndian(bytes.Slice(6))); for (int i = 8; i < 16; i++) { codeStream.EmitLdc(bytes[i]); } MetadataType guidType = Context.SystemModule.GetKnownType("System", "Guid"); var int32Type = Context.GetWellKnownType(WellKnownType.Int32); var int16Type = Context.GetWellKnownType(WellKnownType.Int16); var byteType = Context.GetWellKnownType(WellKnownType.Byte); var sig = new MethodSignature( MethodSignatureFlags.None, genericParameterCount: 0, returnType: Context.GetWellKnownType(WellKnownType.Void), parameters: new TypeDesc[] { int32Type, int16Type, int16Type, byteType, byteType, byteType, byteType, byteType, byteType, byteType, byteType }); MethodDesc guidCtorHandleMethod = guidType.GetKnownMethod(".ctor", sig); codeStream.Emit(ILOpcode.newobj, emitter.NewToken(guidCtorHandleMethod)); MethodDesc helper = Context.GetHelperEntryPoint("InteropHelpers", "ConvertManagedComInterfaceToNative"); codeStream.Emit(ILOpcode.call, emitter.NewToken(helper)); } else { if (!parameterType.IsObject) { throw new NotSupportedException(); } MethodDesc helper = Context.GetHelperEntryPoint("InteropHelpers", "ConvertManagedComInterfaceToIUnknown"); codeStream.Emit(ILOpcode.call, emitter.NewToken(helper)); } StoreNativeValue(codeStream); }
/// <summary> /// Updates the custom attribute value /// </summary> /// <param name="customAttributeValue">Custom attribute value</param> public virtual void UpdateCustomAttributeValue(CustomAttributeValue customAttributeValue) { if (customAttributeValue == null) throw new ArgumentNullException("customAttributeValue"); _unitOfWork.Complete(); _cacheManager.RemoveByPattern(CUSTOMATTRIBUTES_PATTERN_KEY); _cacheManager.RemoveByPattern(CUSTOMATTRIBUTEVALUES_PATTERN_KEY); }
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. } } }
static void enforceNamedArgName(NamespaceAndName name, CustomAttributeValue <CustomAttrType> args, string expected, int index) { string?actual = args.NamedArguments[index].Name; assertData(actual == expected, string.Format( "expected attribute '{0}' to have named argument at index {1} to be named '{2}' but got '{3}'", name, index, expected, actual)); }
static void enforceAttrNamedArgCount(NamespaceAndName name, CustomAttributeValue <CustomAttrType> args, uint expected) { if (args.NamedArguments.Length != expected) { throw new InvalidDataException(string.Format( "expected attribute '{0}' to have {1} named arguments but got {2}", name.name, expected, args.NamedArguments.Length)); } }
private static string GetFirstFixedArgAsStringValue(ICustomAttributeTypeProvider <KnownType> typeResolver, CustomAttribute attribute) { CustomAttributeValue <KnownType> data = attribute.DecodeValue(typeResolver); if (data.FixedArguments.Length == 1) { return((string)data.FixedArguments[0].Value); } return(null); }
private MethodImportAttributes GetImportAttributesFromBestFitMappingAttribute(CustomAttributeHandleCollection attributeHandles) { // Look for the [BestFitMapping(BestFitMapping: x, ThrowOnUnmappableChar = y)] attribute and // translate that to MethodImportAttributes MethodImportAttributes result = 0; MetadataReader reader = MetadataReader; CustomAttributeHandle attributeHandle = reader.GetCustomAttributeHandle( attributeHandles, "System.Runtime.InteropServices", "BestFitMappingAttribute"); if (!attributeHandle.IsNil) { CustomAttribute attribute = reader.GetCustomAttribute(attributeHandle); CustomAttributeValue <TypeDesc> decoded = attribute.DecodeValue( new CustomAttributeTypeProvider(_type.EcmaModule)); if (decoded.FixedArguments.Length != 1 || !(decoded.FixedArguments[0].Value is bool)) { ThrowHelper.ThrowBadImageFormatException(); } if ((bool)decoded.FixedArguments[0].Value) { result |= MethodImportAttributes.BestFitMappingEnable; } else { result |= MethodImportAttributes.BestFitMappingDisable; } foreach (CustomAttributeNamedArgument <TypeDesc> namedArg in decoded.NamedArguments) { if (namedArg.Name == "ThrowOnUnmappableChar") { if (!(namedArg.Value is bool)) { ThrowHelper.ThrowBadImageFormatException(); } if ((bool)namedArg.Value) { result |= MethodImportAttributes.ThrowOnUnmappableCharEnable; } else { result |= MethodImportAttributes.ThrowOnUnmappableCharDisable; } break; } } } return(result); }
/// <summary> /// Updates the custom attribute value /// </summary> /// <param name="customAttributeValue">Custom attribute value</param> public virtual void UpdateCustomAttributeValue(CustomAttributeValue customAttributeValue) { if (customAttributeValue == null) { throw new ArgumentNullException("customAttributeValue"); } _customAttributeValueRepository.Save(customAttributeValue); _cacheManager.RemoveByPattern(CUSTOMATTRIBUTES_PATTERN_KEY); _cacheManager.RemoveByPattern(CUSTOMATTRIBUTEVALUES_PATTERN_KEY); }
private static string GetProgId(MetadataReader reader, TypeDefinition type) { foreach (CustomAttributeHandle attr in type.GetCustomAttributes()) { CustomAttribute attribute = reader.GetCustomAttribute(attr); if (IsTargetAttribute(reader, attribute, "System.Runtime.InteropServices", "ProgIdAttribute")) { CustomAttributeValue <KnownType> data = attribute.DecodeValue(new TypeResolver()); return((string)data.FixedArguments[0].Value); } } return(GetTypeName(reader, type)); }
public void TestCustomAttributeDecoderGenericArray() { Type type = typeof(HasGenericArrayAttributes); using (FileStream stream = File.OpenRead(AssemblyPathHelper.GetAssemblyLocation(type.GetTypeInfo().Assembly))) using (PEReader peReader = new PEReader(stream)) { MetadataReader reader = peReader.GetMetadataReader(); CustomAttributeTypeProvider provider = new CustomAttributeTypeProvider(); TypeDefinitionHandle typeDefHandle = TestMetadataResolver.FindTestType(reader, type); IList <CustomAttributeData> attributes = type.GetCustomAttributesData(); foreach (CustomAttributeHandle attributeHandle in reader.GetCustomAttributes(typeDefHandle)) { CustomAttribute attribute = reader.GetCustomAttribute(attributeHandle); CustomAttributeValue <string> value = attribute.DecodeValue(provider); if (value.FixedArguments.Length == 2) { Assert.Equal(2, value.FixedArguments.Length); ImmutableArray <CustomAttributeTypedArgument <string> > array1 = (ImmutableArray <CustomAttributeTypedArgument <string> >)(value.FixedArguments[0].Value); Assert.Equal("int32[]", value.FixedArguments[0].Type); Assert.Equal(1, array1[0].Value); Assert.Equal(3, array1[2].Value); ImmutableArray <CustomAttributeTypedArgument <string> > array2 = (ImmutableArray <CustomAttributeTypedArgument <string> >)(value.FixedArguments[1].Value); Assert.Equal("uint8[]", value.FixedArguments[1].Type); Assert.Equal((byte)4, array2[0].Value); Assert.Equal((byte)5, array2[1].Value); Assert.Empty(value.NamedArguments); } else { Assert.Equal(1, value.FixedArguments.Length); Assert.Equal("uint8", value.FixedArguments[0].Type); Assert.Equal((byte)1, value.FixedArguments[0].Value); Assert.Equal(2, value.NamedArguments.Length); Assert.Equal("uint8", value.NamedArguments[0].Type); Assert.Equal((byte)2, value.NamedArguments[0].Value); ImmutableArray <CustomAttributeTypedArgument <string> > array = (ImmutableArray <CustomAttributeTypedArgument <string> >)(value.NamedArguments[1].Value); Assert.Equal("uint8[]", value.NamedArguments[1].Type); Assert.Equal((byte)3, array[0].Value); } } } }
protected sealed override Guid?ComputeGuidFromCustomAttributes() { // // Look for a [Guid] attribute. If found, return that. // foreach (CustomAttributeHandle cah in _typeDefinition.GetCustomAttributes()) { // We can't reference the GuidAttribute class directly as we don't have an official dependency on System.Runtime.InteropServices. // Following age-old CLR tradition, we search for the custom attribute using a name-based search. Since this makes it harder // to be sure we won't run into custom attribute constructors that comply with the GuidAttribute(String) signature, // we'll check that it does and silently skip the CA if it doesn't match the expected pattern. CustomAttribute attribute = Reader.GetCustomAttribute(cah); EntityHandle ctorType; EcmaMetadataHelpers.GetAttributeTypeDefRefOrSpecHandle(_reader, attribute.Constructor, out ctorType); StringHandle typeNameHandle; StringHandle typeNamespaceHandle; if (EcmaMetadataHelpers.GetAttributeNamespaceAndName(Reader, ctorType, out typeNamespaceHandle, out typeNameHandle)) { MetadataStringComparer stringComparer = Reader.StringComparer; if (stringComparer.Equals(typeNamespaceHandle, "System.Runtime.InteropServices")) { if (stringComparer.Equals(typeNameHandle, "GuidAttribute")) { ReflectionTypeProvider typeProvider = new ReflectionTypeProvider(throwOnError: false); CustomAttributeValue <RuntimeTypeInfo> customAttributeValue = attribute.DecodeValue(typeProvider); if (customAttributeValue.FixedArguments.Length != 1) { continue; } CustomAttributeTypedArgument <RuntimeTypeInfo> firstArg = customAttributeValue.FixedArguments[0]; if (firstArg.Value == null) { continue; } string guidString = firstArg.Value as string; if (guidString == null) { continue; } return(new Guid(guidString)); } } } } return(null); }
private static bool IsComVisible(MetadataReader reader, AssemblyDefinition assembly) { CustomAttributeHandle handle = GetComVisibleAttribute(reader, assembly.GetCustomAttributes()); if (handle.IsNil) { return(false); } CustomAttribute comVisibleAttribute = reader.GetCustomAttribute(handle); CustomAttributeValue <KnownType> data = comVisibleAttribute.DecodeValue(new TypeResolver()); return((bool)data.FixedArguments[0].Value); }
private static string GetProgId(MetadataReader reader, TypeDefinition type) { foreach (CustomAttributeHandle attr in type.GetCustomAttributes()) { 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, "ProgIdAttribute")) { CustomAttributeValue <KnownType> data = attribute.DecodeValue(new TypeResolver()); return((string)data.FixedArguments[0].Value); } } return(GetTypeName(reader, type)); }
private static Guid GetTypeGuid(MetadataReader reader, TypeDefinition type) { // Find the class' GUID by reading the GuidAttribute value. // We do not support implicit runtime-generated GUIDs for the .NET Core COM host. foreach (CustomAttributeHandle attr in type.GetCustomAttributes()) { CustomAttribute attribute = reader.GetCustomAttribute(attr); if (IsTargetAttribute(reader, attribute, "System.Runtime.InteropServices", "GuidAttribute")) { CustomAttributeValue <KnownType> data = attribute.DecodeValue(new TypeResolver()); return(Guid.Parse((string)data.FixedArguments[0].Value)); } } throw new MissingGuidException(GetTypeName(reader, type)); }
public void TestCustomAttributeDecoderGenericUsingReflection() { Type type = typeof(HasGenericAttributes); using (FileStream stream = File.OpenRead(AssemblyPathHelper.GetAssemblyLocation(type.GetTypeInfo().Assembly))) using (PEReader peReader = new PEReader(stream)) { MetadataReader reader = peReader.GetMetadataReader(); CustomAttributeTypeProvider provider = new CustomAttributeTypeProvider(); TypeDefinitionHandle typeDefHandle = TestMetadataResolver.FindTestType(reader, type); IList <CustomAttributeData> attributes = type.GetCustomAttributesData(); int i = 0; foreach (CustomAttributeHandle attributeHandle in reader.GetCustomAttributes(typeDefHandle)) { CustomAttribute attribute = reader.GetCustomAttribute(attributeHandle); CustomAttributeValue <string> value = attribute.DecodeValue(provider); CustomAttributeData reflectionAttribute = attributes[i++]; Assert.Equal(reflectionAttribute.ConstructorArguments.Count, value.FixedArguments.Length); Assert.Equal(reflectionAttribute.NamedArguments.Count, value.NamedArguments.Length); int j = 0; foreach (CustomAttributeTypedArgument <string> arguments in value.FixedArguments) { Assert.Equal(TypeToString(reflectionAttribute.ConstructorArguments[j].ArgumentType), arguments.Type); if (reflectionAttribute.ConstructorArguments[j].Value.ToString() != arguments.Value.ToString()) { Assert.Equal(reflectionAttribute.ConstructorArguments[j].Value, arguments.Value); } j++; } j = 0; foreach (CustomAttributeNamedArgument <string> arguments in value.NamedArguments) { Assert.Equal(TypeToString(reflectionAttribute.NamedArguments[j].TypedValue.ArgumentType), arguments.Type); if (reflectionAttribute.NamedArguments[j].TypedValue.Value.ToString() != arguments.Value.ToString()) { Assert.Equal(reflectionAttribute.NamedArguments[j].TypedValue.Value, arguments.Value); } j++; } } } }
public AssemblyInfo(string file) { using var stream = File.OpenRead(file); using var pe = new PEReader(stream); var reader = pe.GetMetadataReader(); var assembly = reader.GetAssemblyDefinition(); Name = assembly.GetSafeAssemblyName(); foreach (var attribute in assembly.GetCustomAttributes().Select(reader.GetCustomAttribute)) { if (attribute.Constructor.Kind != HandleKind.MemberReference) { continue; } var constructor = reader.GetMemberReference((MemberReferenceHandle)attribute.Constructor); var typeReference = reader.GetTypeReference((TypeReferenceHandle)constructor.Parent); var typeName = reader.GetString(typeReference.Namespace) + "." + reader.GetString(typeReference.Name); var resolutionScope = typeReference.ResolutionScope; if (resolutionScope.Kind == HandleKind.AssemblyReference) { var assemblyReference = reader.GetAssemblyReference((AssemblyReferenceHandle)resolutionScope); typeName += ", " + assemblyReference.GetSafeAssemblyName(); } CustomAttributeValue <object>?value = null; try { value = attribute.DecodeValue(new DummyProvider()); } catch (Exception) { // ignored } Attributes.Add(new EasyCustomAttribute(typeName, Type.GetType(typeName, false), value)); } var versionAttribute = GetCustomAttribute <AssemblyInformationalVersionAttribute>() ?? GetCustomAttribute <AssemblyVersionAttribute>(); Version = versionAttribute?.Value?.FixedArguments.Single().Value as string ?? Name.Version.ToString(3); }
private static Guid GetTypeGuid(MetadataReader reader, TypeDefinition type) { // Find the class' GUID by reading the GuidAttribute value. // We do not support implicit runtime-generated GUIDs for the .NET Core COM host. foreach (CustomAttributeHandle attr in type.GetCustomAttributes()) { 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, "GuidAttribute")) { CustomAttributeValue <KnownType> data = attribute.DecodeValue(new TypeResolver()); return(Guid.Parse((string)data.FixedArguments[0].Value)); } } throw new MissingGuidException(GetTypeName(reader, type)); }
private static bool AnalyzeCustomAttributeValue(CustomAttributeValue <TokenSearchResult> attribute) { foreach (var fa in attribute.FixedArguments) { if (CheckAttributeValue(fa.Value)) { return(true); } } foreach (var na in attribute.NamedArguments) { if (CheckAttributeValue(na.Value)) { return(true); } } return(false); bool CheckAttributeValue(object value) { if (value is TokenSearchResult typeofType) { if ((typeofType & TokenSearchResult.Found) != 0) { return(true); } } else if (value is ImmutableArray <CustomAttributeTypedArgument <IType> > arr) { foreach (var element in arr) { if (CheckAttributeValue(element.Value)) { return(true); } } } return(false); } }
void DecodeValue() { lock (this) { try { if (!valueDecoded) { var metadata = module.metadata; var attr = metadata.GetCustomAttribute(handle); value = attr.DecodeValue(module.TypeProvider); valueDecoded = true; } } catch (EnumUnderlyingTypeResolveException) { value = new CustomAttributeValue <IType>( ImmutableArray <CustomAttributeTypedArgument <IType> > .Empty, ImmutableArray <CustomAttributeNamedArgument <IType> > .Empty ); hasDecodeErrors = true; valueDecoded = true; // in case of errors, never try again. } } }
public static UnmanagedCallingConventions GetPInvokeMethodCallingConventions(this MethodDesc method) { Debug.Assert(method.IsPInvoke); UnmanagedCallingConventions result; if (method is Internal.IL.Stubs.PInvokeTargetNativeMethod pinvokeTarget) { method = pinvokeTarget.Target; } MethodSignatureFlags unmanagedCallConv = method.GetPInvokeMethodMetadata().Flags.UnmanagedCallingConvention; if (unmanagedCallConv != MethodSignatureFlags.None) { Debug.Assert((int)MethodSignatureFlags.UnmanagedCallingConventionCdecl == (int)UnmanagedCallingConventions.Cdecl && (int)MethodSignatureFlags.UnmanagedCallingConventionStdCall == (int)UnmanagedCallingConventions.Stdcall && (int)MethodSignatureFlags.UnmanagedCallingConventionThisCall == (int)UnmanagedCallingConventions.Thiscall); result = (UnmanagedCallingConventions)unmanagedCallConv; } else { CustomAttributeValue <TypeDesc>?unmanagedCallConvAttribute = ((EcmaMethod)method).GetDecodedCustomAttribute("System.Runtime.InteropServices", "UnmanagedCallConvAttribute"); if (unmanagedCallConvAttribute != null) { result = GetUnmanagedCallingConventionFromAttribute(unmanagedCallConvAttribute.Value, method.Context); } else { result = GetPlatformDefaultUnmanagedCallingConvention(method.Context); } } if (method.HasCustomAttribute("System.Runtime.InteropServices", "SuppressGCTransitionAttribute")) { result |= UnmanagedCallingConventions.IsSuppressGcTransition; } return(result); }
// Equals/GetHashCode no need to override (they just implement reference equality but desktop never unified these things.) private void LoadArgumentInfo(bool throwIfMissingMetadata, out IList <CustomAttributeNamedArgument> namedArguments, out IList <CustomAttributeTypedArgument> fixedArguments, out bool metadataWasMissing) { LowLevelListWithIList <CustomAttributeNamedArgument> newNamedArguments = new LowLevelListWithIList <CustomAttributeNamedArgument>(); LowLevelListWithIList <CustomAttributeTypedArgument> newFixedArguments = new LowLevelListWithIList <CustomAttributeTypedArgument>(); ReflectionTypeProvider typeProvider = new ReflectionTypeProvider(throwIfMissingMetadata); CustomAttributeValue <RuntimeTypeInfo> customAttributeValue = _customAttribute.DecodeValue(typeProvider); foreach (CustomAttributeTypedArgument <RuntimeTypeInfo> fixedArgument in customAttributeValue.FixedArguments) { newFixedArguments.Add(WrapInCustomAttributeTypedArgument(fixedArgument.Value, fixedArgument.Type)); } foreach (CustomAttributeNamedArgument <RuntimeTypeInfo> ecmaNamedArgument in customAttributeValue.NamedArguments) { bool isField = ecmaNamedArgument.Kind == CustomAttributeNamedArgumentKind.Field; CustomAttributeTypedArgument typedArgument = WrapInCustomAttributeTypedArgument(ecmaNamedArgument.Value, ecmaNamedArgument.Type); newNamedArguments.Add(ReflectionAugments.CreateCustomAttributeNamedArgument(this.AttributeType, ecmaNamedArgument.Name, isField, typedArgument)); } if (newFixedArguments.Count == 0) { fixedArguments = Array.Empty <CustomAttributeTypedArgument>(); } else { fixedArguments = newFixedArguments; } if (newNamedArguments.Count == 0) { namedArguments = Array.Empty <CustomAttributeNamedArgument>(); } else { namedArguments = newNamedArguments; } metadataWasMissing = typeProvider.ExceptionOccurred; }
public void UpdateModel(Models.TreatmentBMP treatmentBMP, Person currentPerson, CustomAttributeTypePurpose customAttributeTypePurpose, List <Models.CustomAttributeType> allCustomAttributeTypes) { var customAttributeSimplesWithValues = CustomAttributes.Where(x => x.CustomAttributeValues != null && x.CustomAttributeValues.Count > 0); var customAttributesToUpdate = new List <CustomAttribute>(); var customAttributeValuesToUpdate = new List <CustomAttributeValue>(); foreach (var x in customAttributeSimplesWithValues) { var customAttribute = new CustomAttribute(treatmentBMP.TreatmentBMPID, x.TreatmentBMPTypeCustomAttributeTypeID, treatmentBMP.TreatmentBMPTypeID, x.CustomAttributeTypeID); customAttributesToUpdate.Add(customAttribute); foreach (var value in x.CustomAttributeValues) { var valueParsedForDataType = allCustomAttributeTypes.Single(y => y.CustomAttributeTypeID == x.CustomAttributeTypeID).CustomAttributeDataType.ValueParsedForDataType(value); var customAttributeValue = new CustomAttributeValue(customAttribute, valueParsedForDataType); customAttributeValuesToUpdate.Add(customAttributeValue); } } var customAttributesInDatabase = HttpRequestStorage.DatabaseEntities.CustomAttributes.Local; var customAttributeValuesInDatabase = HttpRequestStorage.DatabaseEntities.CustomAttributeValues.Local; var existingCustomAttributes = treatmentBMP.CustomAttributes.Where(x => x.CustomAttributeType.CustomAttributeTypePurposeID == customAttributeTypePurpose.CustomAttributeTypePurposeID).ToList(); var existingCustomAttributeValues = existingCustomAttributes.SelectMany(x => x.CustomAttributeValues).ToList(); existingCustomAttributes.Merge(customAttributesToUpdate, customAttributesInDatabase, (x, y) => x.TreatmentBMPID == y.TreatmentBMPID && x.TreatmentBMPTypeID == y.TreatmentBMPTypeID && x.CustomAttributeTypeID == y.CustomAttributeTypeID && x.CustomAttributeID == y.CustomAttributeID); existingCustomAttributeValues.Merge(customAttributeValuesToUpdate, customAttributeValuesInDatabase, (x, y) => x.CustomAttributeValueID == y.CustomAttributeValueID && x.CustomAttributeID == y.CustomAttributeID, (x, y) => { x.AttributeValue = y.AttributeValue; }); }
public void UpdateModel(Models.FieldVisit fieldVisit, Person currentPerson) { var treatmentBMP = fieldVisit.TreatmentBMP; var customAttributeSimplesWithValues = CustomAttributes.Where(x => x.CustomAttributeValues != null && x.CustomAttributeValues.Count > 0); var customAttributesToUpdate = new List <CustomAttribute>(); var customAttributeValuesToUpdate = new List <CustomAttributeValue>(); foreach (var x in customAttributeSimplesWithValues) { var customAttribute = new CustomAttribute(treatmentBMP.TreatmentBMPID, x.TreatmentBMPTypeCustomAttributeTypeID, treatmentBMP.TreatmentBMPTypeID, x.CustomAttributeTypeID); customAttributesToUpdate.Add(customAttribute); foreach (var value in x.CustomAttributeValues) { var customAttributeValue = new CustomAttributeValue(customAttribute, value); customAttributeValuesToUpdate.Add(customAttributeValue); } } var customAttributesInDatabase = HttpRequestStorage.DatabaseEntities.CustomAttributes.Local; var customAttributeValuesInDatabase = HttpRequestStorage.DatabaseEntities.CustomAttributeValues.Local; var existingCustomAttributes = treatmentBMP.CustomAttributes.ToList(); var existingCustomAttributeValues = existingCustomAttributes.SelectMany(x => x.CustomAttributeValues).ToList(); existingCustomAttributes.Merge(customAttributesToUpdate, customAttributesInDatabase, (x, y) => x.TreatmentBMPID == y.TreatmentBMPID && x.TreatmentBMPTypeID == y.TreatmentBMPTypeID && x.CustomAttributeTypeID == y.CustomAttributeTypeID && x.CustomAttributeID == y.CustomAttributeID); existingCustomAttributeValues.Merge(customAttributeValuesToUpdate, customAttributeValuesInDatabase, (x, y) => x.CustomAttributeValueID == y.CustomAttributeValueID && x.CustomAttributeID == y.CustomAttributeID, (x, y) => { x.AttributeValue = y.AttributeValue; }); }
/// <summary> /// Gets a value indicating whether '<paramref name="module"/>' is a framework assembly. /// </summary> public static bool IsFrameworkAssembly(EcmaModule module) { MetadataReader reader = module.MetadataReader; // We look for [assembly:AssemblyMetadata(".NETFrameworkAssembly", "")] foreach (CustomAttributeHandle attributeHandle in reader.GetAssemblyDefinition().GetCustomAttributes()) { if (!reader.GetAttributeNamespaceAndName(attributeHandle, out StringHandle namespaceHandle, out StringHandle nameHandle)) { continue; } if (!reader.StringComparer.Equals(namespaceHandle, "System.Reflection") || !reader.StringComparer.Equals(nameHandle, "AssemblyMetadataAttribute")) { continue; } var attributeTypeProvider = new CustomAttributeTypeProvider(module); CustomAttribute attribute = reader.GetCustomAttribute(attributeHandle); CustomAttributeValue <TypeDesc> decodedAttribute = attribute.DecodeValue(attributeTypeProvider); if (decodedAttribute.FixedArguments.Length != 2) { continue; } if (decodedAttribute.FixedArguments[0].Value is string s && s == ".NETFrameworkAssembly") { return(true); } } return(false); }
public void Emit(TextWriter outputStream) { var additionalCodeStatements = new List <string>(); var exportedMethods = new List <ExportedMethod>(); foreach (var methodDefHandle in this.mdReader.MethodDefinitions) { MethodDefinition methodDef = this.mdReader.GetMethodDefinition(methodDefHandle); // Only check public static functions if (!methodDef.Attributes.HasFlag(MethodAttributes.Public | MethodAttributes.Static)) { continue; } var callConv = SignatureCallingConvention.Unmanaged; var exportAttrType = ExportType.None; string managedMethodName = this.mdReader.GetString(methodDef.Name); string exportName = managedMethodName; // Check for target attribute foreach (var customAttrHandle in methodDef.GetCustomAttributes()) { CustomAttribute customAttr = this.mdReader.GetCustomAttribute(customAttrHandle); var currAttrType = this.GetExportAttributeType(customAttr); if (currAttrType == ExportType.None) { // Check if method has "additional code" attributes. if (TryGetC99DeclCodeAttributeValue(customAttr, out string c99Decl)) { additionalCodeStatements.Add(c99Decl); } continue; } exportAttrType = currAttrType; if (exportAttrType == ExportType.Export) { CustomAttributeValue <KnownType> data = customAttr.DecodeValue(this.typeResolver); if (data.NamedArguments.Length == 1) { exportName = (string)data.NamedArguments[0].Value; } } else { Debug.Assert(exportAttrType == ExportType.UnmanagedCallersOnly); CustomAttributeValue <KnownType> data = customAttr.DecodeValue(this.typeResolver); foreach (var arg in data.NamedArguments) { switch (arg.Type) { case KnownType.I4: case KnownType.CallingConvention: callConv = (CallingConvention)arg.Value switch { CallingConvention.Winapi => SignatureCallingConvention.Unmanaged, CallingConvention.Cdecl => SignatureCallingConvention.CDecl, CallingConvention.StdCall => SignatureCallingConvention.StdCall, CallingConvention.ThisCall => SignatureCallingConvention.ThisCall, CallingConvention.FastCall => SignatureCallingConvention.FastCall, _ => throw new NotSupportedException($"Unknown CallingConvention: {arg.Value}") }; break; case KnownType.SystemTypeArray: if (arg.Value != null) { foreach (var cct in (ImmutableArray <CustomAttributeTypedArgument <KnownType> >)arg.Value) { Debug.Assert(cct.Type == KnownType.SystemType); switch ((KnownType)cct.Value) { case KnownType.CallConvCdecl: callConv = SignatureCallingConvention.CDecl; break; case KnownType.CallConvStdcall: callConv = SignatureCallingConvention.StdCall; break; case KnownType.CallConvThiscall: callConv = SignatureCallingConvention.ThisCall; break; case KnownType.CallConvFastcall: callConv = SignatureCallingConvention.FastCall; break; } } } break; case KnownType.String: exportName = (string)arg.Value; break; default: throw new GeneratorException(this.assemblyPath, $"Method '{this.mdReader.GetString(methodDef.Name)}' has unknown Attribute value type."); } } } } // Didn't find target attribute. Move onto next method. if (exportAttrType == ExportType.None) { continue; } // Extract method details var typeDef = this.mdReader.GetTypeDefinition(methodDef.GetDeclaringType()); var classString = this.mdReader.GetString(typeDef.Name); // Exporting from nested types is not supported. if (typeDef.IsNested) { throw new GeneratorException(this.assemblyPath, $"Method '{this.mdReader.GetString(methodDef.Name)}' is being exported by nested type {classString}."); } // Process method signature. MethodSignature <string> signature; try { signature = methodDef.DecodeSignature(typeProvider, null); } catch (NotSupportedTypeException nste) { throw new GeneratorException(this.assemblyPath, $"Method '{this.mdReader.GetString(methodDef.Name)}' has non-exportable type '{nste.Type}'"); } var returnType = signature.ReturnType; var argumentTypes = signature.ParameterTypes.ToArray(); var argumentNames = new string[signature.ParameterTypes.Length]; // Process each parameter. foreach (ParameterHandle paramHandle in methodDef.GetParameters()) { Parameter param = this.mdReader.GetParameter(paramHandle); // Sequence number starts from 1 for arguments. // Number of 0 indicates return value. // Update arg index to be from [0..n-1] // Return index is -1. const int ReturnIndex = -1; var argIndex = param.SequenceNumber - 1; if (argIndex != ReturnIndex) { Debug.Assert(argIndex >= 0); argumentNames[argIndex] = this.mdReader.GetString(param.Name); } // Check custom attributes for additional code. foreach (var attr in param.GetCustomAttributes()) { CustomAttribute custAttr = this.mdReader.GetCustomAttribute(attr); if (TryGetC99TypeAttributeValue(custAttr, out string c99Type)) { // Overridden type defined. if (argIndex == ReturnIndex) { returnType = c99Type; } else { Debug.Assert(argIndex >= 0); argumentTypes[argIndex] = c99Type; } } else if (TryGetC99DeclCodeAttributeValue(custAttr, out string c99Decl)) { additionalCodeStatements.Add(c99Decl); } } } var namespaceString = this.mdReader.GetString(typeDef.Namespace); exportedMethods.Add(new ExportedMethod() { Type = exportAttrType, EnclosingTypeName = namespaceString + Type.Delimiter + classString, MethodName = managedMethodName, ExportName = exportName, CallingConvention = callConv, ReturnType = returnType, ArgumentTypes = ImmutableArray.Create(argumentTypes), ArgumentNames = ImmutableArray.Create(argumentNames), }); } if (exportedMethods.Count == 0) { throw new GeneratorException(this.assemblyPath, "Nothing to export."); } string assemblyName = this.mdReader.GetString(this.mdReader.GetAssemblyDefinition().Name); EmitC99(outputStream, assemblyName, exportedMethods, additionalCodeStatements); }
public void Emit(TextWriter outputStream) { var exportedMethods = new List <ExportedMethod>(); foreach (var methodDefHandle in this.mdReader.MethodDefinitions) { MethodDefinition methodDef = this.mdReader.GetMethodDefinition(methodDefHandle); // Only check public static functions if (!methodDef.Attributes.HasFlag(MethodAttributes.Public | MethodAttributes.Static)) { continue; } var callConv = CallingConvention.Winapi; var attrType = ExportType.None; string managedMethodName = this.mdReader.GetString(methodDef.Name); string exportName = managedMethodName; // Check for target attribute foreach (var customAttrHandle in methodDef.GetCustomAttributes()) { CustomAttribute customAttr = this.mdReader.GetCustomAttribute(customAttrHandle); attrType = this.GetExportAttributeType(customAttr); if (attrType == ExportType.None) { continue; } if (attrType == ExportType.Export) { CustomAttributeValue <KnownType> data = customAttr.DecodeValue(this.typeResolver); if (data.NamedArguments.Length == 1) { exportName = (string)data.NamedArguments[0].Value; } } else { Debug.Assert(attrType == ExportType.UnmanagedCallersOnly); CustomAttributeValue <KnownType> data = customAttr.DecodeValue(this.typeResolver); foreach (var arg in data.NamedArguments) { switch (arg.Type) { case KnownType.I4: case KnownType.CallingConvention: callConv = (CallingConvention)arg.Value; break; case KnownType.SystemTypeArray: if (arg.Value != null) { foreach (var cct in (ImmutableArray <CustomAttributeTypedArgument <KnownType> >)arg.Value) { Debug.Assert(cct.Type == KnownType.SystemType); switch ((KnownType)cct.Value) { case KnownType.CallConvCdecl: callConv = CallingConvention.Cdecl; break; case KnownType.CallConvStdcall: callConv = CallingConvention.StdCall; break; case KnownType.CallConvThiscall: callConv = CallingConvention.ThisCall; break; case KnownType.CallConvFastcall: callConv = CallingConvention.FastCall; break; } } } break; case KnownType.String: exportName = (string)arg.Value; break; default: throw new GeneratorException(this.assemblyPath, $"Method '{this.mdReader.GetString(methodDef.Name)}' has unknown Attribute value type."); } } } break; } // Didn't find target attribute. Move onto next method. if (attrType == ExportType.None) { continue; } // Extract method details var typeDef = this.mdReader.GetTypeDefinition(methodDef.GetDeclaringType()); var classString = this.mdReader.GetString(typeDef.Name); // Exporting from nested types is not supported. if (typeDef.IsNested) { throw new GeneratorException(this.assemblyPath, $"Method '{this.mdReader.GetString(methodDef.Name)}' is being exported by nested type {classString}."); } var namespaceString = this.mdReader.GetString(typeDef.Namespace); var method = new ExportedMethod() { Type = attrType, EnclosingTypeName = namespaceString + Type.Delimiter + classString, MethodName = managedMethodName, ExportName = exportName, CallingConvention = callConv, }; // Process method signature. MethodSignature <string> signature; try { signature = methodDef.DecodeSignature(typeProvider, null); } catch (NotSupportedTypeException nste) { throw new GeneratorException(this.assemblyPath, $"Method '{this.mdReader.GetString(methodDef.Name)}' has non-exportable type '{nste.Type}'"); } // Add method types. method.ArgumentTypes.AddRange(signature.ParameterTypes); // Process each method argument name. foreach (ParameterHandle paramHandle in methodDef.GetParameters()) { Parameter param = this.mdReader.GetParameter(paramHandle); method.ArgumentNames.Add(this.mdReader.GetString(param.Name)); } // Set the return type method.ReturnType = signature.ReturnType; exportedMethods.Add(method); } if (exportedMethods.Count == 0) { throw new GeneratorException(this.assemblyPath, "Nothing to export."); } string assemblyName = this.mdReader.GetString(this.mdReader.GetAssemblyDefinition().Name); EmitC99(outputStream, assemblyName, exportedMethods); }
public void TestCustomAttributeDecoderUsingReflection() { Type type = typeof(HasAttributes); using (FileStream stream = File.OpenRead(AssemblyPathHelper.GetAssemblyLocation(type.GetTypeInfo().Assembly))) using (PEReader peReader = new PEReader(stream)) { MetadataReader reader = peReader.GetMetadataReader(); CustomAttributeTypeProvider provider = new CustomAttributeTypeProvider(); TypeDefinitionHandle typeDefHandle = TestMetadataResolver.FindTestType(reader, type); IList <CustomAttributeData> attributes = type.GetCustomAttributesData(); int i = 0; foreach (CustomAttributeHandle attributeHandle in reader.GetCustomAttributes(typeDefHandle)) { CustomAttribute attribute = reader.GetCustomAttribute(attributeHandle); CustomAttributeValue <string> value = attribute.DecodeValue(provider); CustomAttributeData reflectionAttribute = attributes[i++]; Assert.Equal(reflectionAttribute.ConstructorArguments.Count, value.FixedArguments.Length); Assert.Equal(reflectionAttribute.NamedArguments.Count, value.NamedArguments.Length); int j = 0; foreach (CustomAttributeTypedArgument <string> arguments in value.FixedArguments) { Type t = reflectionAttribute.ConstructorArguments[j].ArgumentType; Assert.Equal(TypeToString(t), arguments.Type); if (t.IsArray && arguments.Value is not null) { ImmutableArray <CustomAttributeTypedArgument <string> > array = (ImmutableArray <CustomAttributeTypedArgument <string> >)(arguments.Value); IList <CustomAttributeTypedArgument> refArray = (IList <CustomAttributeTypedArgument>)reflectionAttribute.ConstructorArguments[j].Value; int k = 0; foreach (CustomAttributeTypedArgument <string> element in array) { if (refArray[k].ArgumentType.IsArray) { ImmutableArray <CustomAttributeTypedArgument <string> > innerArray = (ImmutableArray <CustomAttributeTypedArgument <string> >)(element.Value); IList <CustomAttributeTypedArgument> refInnerArray = (IList <CustomAttributeTypedArgument>)refArray[k].Value; int a = 0; foreach (CustomAttributeTypedArgument <string> el in innerArray) { if (refInnerArray[a].Value?.ToString() != el.Value?.ToString()) { Assert.Equal(refInnerArray[a].Value, el.Value); } a++; } } else if (refArray[k].Value?.ToString() != element.Value?.ToString()) { if (refArray[k].ArgumentType == typeof(Type)) // TODO: check if it is expected { Assert.Contains(refArray[k].Value.ToString(), element.Value.ToString()); } else { Assert.Equal(refArray[k].Value, element.Value); } } k++; } } else if (reflectionAttribute.ConstructorArguments[j].Value?.ToString() != arguments.Value?.ToString()) { if (reflectionAttribute.ConstructorArguments[j].ArgumentType == typeof(Type)) { Assert.Contains(reflectionAttribute.ConstructorArguments[j].Value.ToString(), arguments.Value.ToString()); } else { Assert.Equal(reflectionAttribute.ConstructorArguments[j].Value, arguments.Value); } } j++; } j = 0; foreach (CustomAttributeNamedArgument <string> arguments in value.NamedArguments) { Type t = reflectionAttribute.NamedArguments[j].TypedValue.ArgumentType; Assert.Equal(TypeToString(t), arguments.Type); if (t.IsArray && arguments.Value is not null) { ImmutableArray <CustomAttributeTypedArgument <string> > array = (ImmutableArray <CustomAttributeTypedArgument <string> >)(arguments.Value); IList <CustomAttributeTypedArgument> refArray = (IList <CustomAttributeTypedArgument>)reflectionAttribute.NamedArguments[j].TypedValue.Value; int k = 0; foreach (CustomAttributeTypedArgument <string> element in array) { if (refArray[k].Value?.ToString() != element.Value?.ToString()) { Assert.Equal(refArray[k].Value, element.Value); } k++; } } else if (reflectionAttribute.NamedArguments[j].TypedValue.Value?.ToString() != arguments.Value?.ToString()) { if (reflectionAttribute.NamedArguments[j].TypedValue.ArgumentType == typeof(Type)) // typeof operator used for named parameter, like [Test(TypeField = typeof(string))], check if it is expected { Assert.Contains(reflectionAttribute.NamedArguments[j].TypedValue.Value.ToString(), arguments.Value.ToString()); } else { Assert.Equal(reflectionAttribute.NamedArguments[j].TypedValue.Value, arguments.Value); } } j++; } } } }