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.
                }
            }
        }
예제 #2
0
        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);
                        }
                    }
                }
        }
예제 #3
0
        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++;
                        }
                    }
                }
        }
예제 #4
0
        /// <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);
        }
예제 #5
0
        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++;
                        }
                    }
                }
        }
예제 #6
0
        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;
                        }
                    }
                }
        }
예제 #7
0
        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;
                        }
                    }
                }
        }