public void PinnedAndUnpinnedLocals() { using (FileStream stream = File.OpenRead(AssemblyPathHelper.GetAssemblyLocation(typeof(PinnedAndUnpinnedLocalsToDecode).GetTypeInfo().Assembly))) using (var peReader = new PEReader(stream)) { MetadataReader reader = peReader.GetMetadataReader(); var provider = new DisassemblingTypeProvider(); TypeDefinitionHandle typeDefHandle = TestMetadataResolver.FindTestType(reader, typeof(PinnedAndUnpinnedLocalsToDecode)); TypeDefinition typeDef = reader.GetTypeDefinition(typeDefHandle); MethodDefinition methodDef = reader.GetMethodDefinition(typeDef.GetMethods().First()); Assert.Equal("DoSomething", reader.GetString(methodDef.Name)); MethodBodyBlock body = peReader.GetMethodBody(methodDef.RelativeVirtualAddress); StandaloneSignature localSignature = reader.GetStandaloneSignature(body.LocalSignature); ImmutableArray <string> localTypes = localSignature.DecodeLocalSignature(provider, genericContext: null); // Compiler can generate temporaries or re-order so just check the ones we expect are there. // (They could get optimized away too. If that happens in practice, change this test to use hard-coded signatures.) Assert.Contains("uint8[] pinned", localTypes); Assert.Contains("uint8[]", localTypes); } }
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); } } } }
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 void DecodeVarArgsDefAndRef() { using (FileStream stream = File.OpenRead(AssemblyPathHelper.GetAssemblyLocation(typeof(VarArgsToDecode).GetTypeInfo().Assembly))) using (var peReader = new PEReader(stream)) { MetadataReader metadataReader = peReader.GetMetadataReader(); TypeDefinitionHandle typeDefHandle = TestMetadataResolver.FindTestType(metadataReader, typeof(VarArgsToDecode)); TypeDefinition typeDef = metadataReader.GetTypeDefinition(typeDefHandle); MethodDefinition methodDef = metadataReader.GetMethodDefinition(typeDef.GetMethods().First()); Assert.Equal("VarArgsCallee", metadataReader.GetString(methodDef.Name)); var provider = new OpaqueTokenTypeProvider(); MethodSignature <string> defSignature = methodDef.DecodeSignature(provider, null); Assert.Equal(SignatureCallingConvention.VarArgs, defSignature.Header.CallingConvention); Assert.Equal(1, defSignature.RequiredParameterCount); Assert.Equal(new[] { "int32" }, defSignature.ParameterTypes); int refCount = 0; foreach (MemberReferenceHandle memberRefHandle in metadataReader.MemberReferences) { MemberReference memberRef = metadataReader.GetMemberReference(memberRefHandle); if (metadataReader.StringComparer.Equals(memberRef.Name, "VarArgsCallee")) { Assert.Equal(MemberReferenceKind.Method, memberRef.GetKind()); MethodSignature <string> refSignature = memberRef.DecodeMethodSignature(provider, null); Assert.Equal(SignatureCallingConvention.VarArgs, refSignature.Header.CallingConvention); Assert.Equal(1, refSignature.RequiredParameterCount); Assert.Equal(new[] { "int32", "bool", "string", "float64" }, refSignature.ParameterTypes); refCount++; } } Assert.Equal(1, refCount); } }
public void SimpleSignatureProviderCoverage() { using (FileStream stream = File.OpenRead(AssemblyPathHelper.GetAssemblyLocation(typeof(SignaturesToDecode <>).GetTypeInfo().Assembly))) using (var peReader = new PEReader(stream)) { MetadataReader reader = peReader.GetMetadataReader(); var provider = new DisassemblingTypeProvider(); TypeDefinitionHandle typeHandle = TestMetadataResolver.FindTestType(reader, typeof(SignaturesToDecode <>)); Assert.Equal("System.Reflection.Metadata.Decoding.Tests.SignatureDecoderTests/SignaturesToDecode`1", provider.GetTypeFromHandle(reader, genericContext: null, handle: typeHandle)); TypeDefinition type = reader.GetTypeDefinition(typeHandle); Dictionary <string, string> expectedFields = GetExpectedFieldSignatures(); ImmutableArray <string> genericTypeParameters = type.GetGenericParameters().Select(h => reader.GetString(reader.GetGenericParameter(h).Name)).ToImmutableArray(); var genericTypeContext = new DisassemblingGenericContext(genericTypeParameters, ImmutableArray <string> .Empty); foreach (var fieldHandle in type.GetFields()) { FieldDefinition field = reader.GetFieldDefinition(fieldHandle); string fieldName = reader.GetString(field.Name); string expected; Assert.True(expectedFields.TryGetValue(fieldName, out expected), "Unexpected field: " + fieldName); Assert.Equal(expected, field.DecodeSignature(provider, genericTypeContext)); } Dictionary <string, string> expectedMethods = GetExpectedMethodSignatures(); foreach (var methodHandle in type.GetMethods()) { MethodDefinition method = reader.GetMethodDefinition(methodHandle); ImmutableArray <string> genericMethodParameters = method.GetGenericParameters().Select(h => reader.GetString(reader.GetGenericParameter(h).Name)).ToImmutableArray(); var genericMethodContext = new DisassemblingGenericContext(genericTypeParameters, genericMethodParameters); string methodName = reader.GetString(method.Name); string expected; Assert.True(expectedMethods.TryGetValue(methodName, out expected), "Unexpected method: " + methodName); MethodSignature <string> signature = method.DecodeSignature(provider, genericMethodContext); Assert.True(signature.Header.Kind == SignatureKind.Method); if (methodName.StartsWith("Generic")) { Assert.Equal(1, signature.GenericParameterCount); } else { Assert.Equal(0, signature.GenericParameterCount); } Assert.True(signature.GenericParameterCount <= 1 && (methodName != "GenericMethodParameter" || signature.GenericParameterCount == 1)); Assert.Equal(expected, provider.GetFunctionPointerType(signature)); } Dictionary <string, string> expectedProperties = GetExpectedPropertySignatures(); foreach (var propertyHandle in type.GetProperties()) { PropertyDefinition property = reader.GetPropertyDefinition(propertyHandle); string propertyName = reader.GetString(property.Name); string expected; Assert.True(expectedProperties.TryGetValue(propertyName, out expected), "Unexpected property: " + propertyName); MethodSignature <string> signature = property.DecodeSignature(provider, genericTypeContext); Assert.True(signature.Header.Kind == SignatureKind.Property); Assert.Equal(expected, provider.GetFunctionPointerType(signature)); } Dictionary <string, string> expectedEvents = GetExpectedEventSignatures(); foreach (var eventHandle in type.GetEvents()) { EventDefinition @event = reader.GetEventDefinition(eventHandle); string eventName = reader.GetString(@event.Name); string expected; Assert.True(expectedEvents.TryGetValue(eventName, out expected), "Unexpected event: " + eventName); Assert.Equal(expected, provider.GetTypeFromHandle(reader, genericTypeContext, @event.Type)); } Assert.Equal($"[{CollectionsAssemblyName}]System.Collections.Generic.List`1<!T>", provider.GetTypeFromHandle(reader, genericTypeContext, handle: type.BaseType)); } }
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++; } } } }
public void TestCustomAttributeDecoder() { using (FileStream stream = File.OpenRead(AssemblyPathHelper.GetAssemblyLocation(typeof(HasAttributes).GetTypeInfo().Assembly))) using (var peReader = new PEReader(stream)) { MetadataReader reader = peReader.GetMetadataReader(); var provider = new CustomAttributeTypeProvider(); TypeDefinitionHandle typeDefHandle = TestMetadataResolver.FindTestType(reader, typeof(HasAttributes)); int i = 0; foreach (CustomAttributeHandle attributeHandle in reader.GetCustomAttributes(typeDefHandle)) { CustomAttribute attribute = reader.GetCustomAttribute(attributeHandle); CustomAttributeValue <string> value = attribute.DecodeValue(provider); switch (i++) { case 0: Assert.Empty(value.FixedArguments); Assert.Empty(value.NamedArguments); break; case 1: Assert.Equal(3, value.FixedArguments.Length); Assert.Equal("string", value.FixedArguments[0].Type); Assert.Equal("0", value.FixedArguments[0].Value); Assert.Equal("int32", value.FixedArguments[1].Type); Assert.Equal(1, value.FixedArguments[1].Value); Assert.Equal("float64", value.FixedArguments[2].Type); Assert.Equal(2.0, value.FixedArguments[2].Value); Assert.Empty(value.NamedArguments); break; case 2: Assert.Equal(3, value.NamedArguments.Length); Assert.Equal(CustomAttributeNamedArgumentKind.Field, value.NamedArguments[0].Kind); Assert.Equal("StringField", value.NamedArguments[0].Name); Assert.Equal("string", value.NamedArguments[0].Type); Assert.Equal("0", value.NamedArguments[0].Value); Assert.Equal(CustomAttributeNamedArgumentKind.Field, value.NamedArguments[1].Kind); Assert.Equal("Int32Field", value.NamedArguments[1].Name); Assert.Equal("int32", value.NamedArguments[1].Type); Assert.Equal(1, value.NamedArguments[1].Value); Assert.Equal(CustomAttributeNamedArgumentKind.Property, value.NamedArguments[2].Kind); Assert.Equal("SByteEnumArrayProperty", value.NamedArguments[2].Name); Assert.Equal(typeof(SByteEnum).FullName + "[]", value.NamedArguments[2].Type); var array = (ImmutableArray <CustomAttributeTypedArgument <string> >)(value.NamedArguments[2].Value); Assert.Equal(1, array.Length); Assert.Equal(typeof(SByteEnum).FullName, array[0].Type); Assert.Equal((sbyte)SByteEnum.Value, array[0].Value); break; default: // TODO: https://github.com/dotnet/runtime/issues/73593 // This method only tests first 3 attriubtes because the complete test 'TestCustomAttributeDecoderUsingReflection' fails on mono // Leaving this hard coded test only for mono, until the issue fixed on mono break; } } } }
public void TestCustomAttributeDecoder() { using (FileStream stream = File.OpenRead(typeof(HasAttributes).GetTypeInfo().Assembly.Location)) using (var peReader = new PEReader(stream)) { MetadataReader reader = peReader.GetMetadataReader(); var provider = new CustomAttributeTypeProvider(); TypeDefinitionHandle typeDefHandle = TestMetadataResolver.FindTestType(reader, typeof(HasAttributes)); int i = 0; foreach (CustomAttributeHandle attributeHandle in reader.GetCustomAttributes(typeDefHandle)) { CustomAttribute attribute = reader.GetCustomAttribute(attributeHandle); CustomAttributeValue <string> value = attribute.DecodeValue(provider); switch (i++) { case 0: Assert.Empty(value.FixedArguments); Assert.Empty(value.NamedArguments); break; case 1: Assert.Equal(3, value.FixedArguments.Length); Assert.Equal("string", value.FixedArguments[0].Type); Assert.Equal("0", value.FixedArguments[0].Value); Assert.Equal("int32", value.FixedArguments[1].Type); Assert.Equal(1, value.FixedArguments[1].Value); Assert.Equal("float64", value.FixedArguments[2].Type); Assert.Equal(2.0, value.FixedArguments[2].Value); Assert.Empty(value.NamedArguments); break; case 2: Assert.Equal(3, value.NamedArguments.Length); Assert.Equal(CustomAttributeNamedArgumentKind.Field, value.NamedArguments[0].Kind); Assert.Equal("StringField", value.NamedArguments[0].Name); Assert.Equal("string", value.NamedArguments[0].Type); Assert.Equal("0", value.NamedArguments[0].Value); Assert.Equal(CustomAttributeNamedArgumentKind.Field, value.NamedArguments[1].Kind); Assert.Equal("Int32Field", value.NamedArguments[1].Name); Assert.Equal("int32", value.NamedArguments[1].Type); Assert.Equal(1, value.NamedArguments[1].Value); Assert.Equal(CustomAttributeNamedArgumentKind.Property, value.NamedArguments[2].Kind); Assert.Equal("SByteEnumArrayProperty", value.NamedArguments[2].Name); Assert.Equal(typeof(SByteEnum).FullName + "[]", value.NamedArguments[2].Type); var array = (ImmutableArray <CustomAttributeTypedArgument <string> >)(value.NamedArguments[2].Value); Assert.Equal(1, array.Length); Assert.Equal(typeof(SByteEnum).FullName, array[0].Type); Assert.Equal((sbyte)SByteEnum.Value, array[0].Value); break; default: // TODO: https://github.com/dotnet/corefx/issues/6534 // The other cases are missing corresponding assertions. This needs some refactoring to // be data-driven. A better approach would probably be to generically compare reflection // CustomAttributeData to S.R.M CustomAttributeValue for every test attribute applied. break; } } } }