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); }
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); } }