public T GetAttribute <T>() where T : Attribute
        {
            CGFAttributeData attribute = m_Attributes.Find(attributeData => (attributeData.Attribute as T != null));

            if (attribute == null)
            {
                return(null);
            }

            return(attribute.Attribute as T);
        }
        public static CGFAttributeDataList Parse(CGFParserReporter reporter, ImmutableArray <Microsoft.CodeAnalysis.AttributeData> attributes)
        {
            List <CGFAttributeData> attributeDataList = new List <CGFAttributeData>();

            foreach (Microsoft.CodeAnalysis.AttributeData attributeData in attributes)
            {
                CGFAttributeData CGFAttributeData = CGFAttributeData.Parse(reporter, attributeData);
                if (CGFAttributeData != null)
                {
                    attributeDataList.Add(CGFAttributeData);
                }
            }

            CGFAttributeDataList CGFAttributeDataList = new CGFAttributeDataList(attributeDataList);

            return(CGFAttributeDataList);
        }
Пример #3
0
        public static CGFAttributeData Parse(CGFParserReporter reporter, Microsoft.CodeAnalysis.AttributeData attributeData)
        {
            //TODO - Add way to have custom validation for ArrayAttribute to validate variable name actually matches an serialized variable
            Type attributeType     = Type.GetType(attributeData.AttributeClass.ToString(), false);
            Type baseAttributeType = typeof(CGFAttribute);

            if (!attributeType.IsSubclassOf(baseAttributeType))
            {
                reporter.LogInfo($"Unrecognized attribute type {attributeType.Name}. Attributes are expected to be subtypes of {baseAttributeType.Name}.");
                return(null);
            }

            Attribute attribute = null;

            using (reporter.CreateContextScope(CGFParserReporterContext.Type.Type, attributeType.Name))
            {
                System.Reflection.ConstructorInfo[] constructors = attributeType.GetConstructors();
                foreach (System.Reflection.ConstructorInfo constructorInfo in constructors)
                {
                    System.Reflection.ParameterInfo[] parameters = constructorInfo.GetParameters();
                    if (attributeData.ConstructorArguments.Length != parameters.Length)
                    {
                        continue;
                    }

                    bool matchingParameters = true;
                    for (int paramIndex = 0; paramIndex < parameters.Length; ++paramIndex)
                    {
                        Microsoft.CodeAnalysis.TypedConstant cgfTypedConstant = attributeData.ConstructorArguments[paramIndex];
                        System.Reflection.ParameterInfo      parameterInfo    = parameters[paramIndex];

                        Type cgfParameterType = null;
                        if (string.IsNullOrEmpty(cgfTypedConstant.Type.Name))
                        {
                            cgfParameterType = Type.GetType(cgfTypedConstant.Type.Name, false);
                        }
                        else
                        {
                            cgfParameterType = Type.GetType($"{cgfTypedConstant.Type.ContainingSymbol.Name}.{cgfTypedConstant.Type.Name}", false);
                        }

                        if (cgfParameterType != parameterInfo.ParameterType)
                        {
                            matchingParameters = false;
                            break;
                        }
                    }

                    if (matchingParameters)
                    {
                        if (parameters.Length > 0)
                        {
                            Object[] parameterObjects = new Object[parameters.Length];
                            for (int paramIndex = 0; paramIndex < parameters.Length; ++paramIndex)
                            {
                                Microsoft.CodeAnalysis.TypedConstant cgfTypedConstant = attributeData.ConstructorArguments[paramIndex];
                                System.Reflection.ParameterInfo      parameterInfo    = parameters[paramIndex];

                                Object convertedParam = null;
                                if (parameterInfo.ParameterType.IsEnum)
                                {
                                    convertedParam = Enum.ToObject(parameterInfo.ParameterType, cgfTypedConstant.Value);
                                }
                                else
                                {
                                    convertedParam = System.Convert.ChangeType(cgfTypedConstant.Value, parameterInfo.ParameterType);
                                }

                                parameterObjects[paramIndex] = convertedParam;
                            }

                            attribute = Activator.CreateInstance(attributeType, parameterObjects) as Attribute;
                        }
                        else
                        {
                            attribute = Activator.CreateInstance(attributeType) as Attribute;
                        }
                    }
                }

                if (attribute == null)
                {
                    //TODO - Add provided constructor param list to help finding the error.
                    //       List most likely constructors.
                    reporter.LogError($"No matching constructor found for {attributeType.Name}.");
                    return(null);
                }

                CGFAttributeData CGFAttributeData = new CGFAttributeData(attribute, attributeData);
                return(CGFAttributeData);
            }
        }