private static IEnumerable <Method> GetValidMethods(DecoratorDecription decorator, BuilderType[] methodParameters, BuilderType @class) { return(@class.Methods.Where(x => { if (x.IsPropertyGetterSetter) { return false; } if (!decorator.TargetMethodFilter.Static && x.IsStatic) { return false; } if (!decorator.TargetMethodFilter.Instanced && !x.IsStatic) { return false; } if ( decorator.TargetMethodFilter.Protected && !x.IsProtected && decorator.TargetMethodFilter.Public && !x.IsPublic && decorator.TargetMethodFilter.Private && !x.IsPrivate && decorator.TargetMethodFilter.Internal && !x.IsInternal) { return false; } if (decorator.TargetMethodFilter.ReturnTypeNames.Length > 0 && !decorator.TargetMethodFilter.ReturnTypeNames.Any(y => y == x.Fullname)) { return false; } if (decorator.TargetMethodFilter.ParameterMatch) { if (!decorator.TargetMethodFilter.ParameterStrict && decorator.TargetMethodFilter.Parameters.Length > 0 && !x.Parameters.AreReferenceAssignable(methodParameters)) { return false; } else if (decorator.TargetMethodFilter.ParameterStrict && decorator.TargetMethodFilter.Parameters.Length > 0 && !x.Parameters.SequenceEqual(methodParameters)) { return false; } } if (x.IsGenerated) { return false; } if (!string.IsNullOrEmpty(decorator.TargetMethodFilter.Name) && !Regex.IsMatch(x.Name, decorator.TargetMethodFilter.Name == "*" ? "[a-zA-Z].*" : decorator.TargetMethodFilter.Name, RegexOptions.Singleline)) { return false; } return true; })); }
private static IEnumerable <Property> GetValidProperties(DecoratorDecription decorator, BuilderType @class) { return(@class.Properties.Where(x => { if (!decorator.TargetPropertyFilter.Static && x.IsStatic) { return false; } if (!decorator.TargetPropertyFilter.Instanced && !x.IsStatic) { return false; } if ( decorator.TargetPropertyFilter.Protected && !x.IsProtected && decorator.TargetPropertyFilter.Public && !x.IsPublic && decorator.TargetPropertyFilter.Private && !x.IsPrivate && decorator.TargetPropertyFilter.Internal && !x.IsInternal) { return false; } if (decorator.TargetPropertyFilter.ReturnTypeNames.Length > 0 && !decorator.TargetPropertyFilter.ReturnTypeNames.Any(y => y == x.ReturnType.Fullname)) { return false; } if (x.IsGenerated) { return false; } if (!string.IsNullOrEmpty(decorator.TargetPropertyFilter.Name) && !Regex.IsMatch(x.Name, decorator.TargetMethodFilter.Name == "*" ? "[a-zA-Z].*" : decorator.TargetPropertyFilter.Name, RegexOptions.Singleline)) { return false; } return true; })); }
private static void ImplementDecorator(Builder builder, DecoratorDecription decorator, IEnumerable <BuilderType> classes) { var attribute = builder.GetType(decorator.TypeName); var attributeTarget = attribute.CustomAttributes.FirstOrDefault(x => x.Fullname == "System.AttributeUsageAttribute"); var parameterValues = decorator.Parameters.Select <DecoratorDecriptionParameter, object>(x => { var result = ConvertPropertyType(builder, x.TypeName, x.Value); if (result != null) { return(result); } if (x.TypeName.EndsWith("[]")) { throw new NotSupportedException($"Arrays are not supported by the attribute decorator: " + x.TypeName); } var type = builder.GetType(x.TypeName); if (type.IsEnum) { var underlyingType = type.EnumUnderlyingType; return(ConvertPropertyType(builder, underlyingType.Fullname, x.Value)); } throw new NotSupportedException($"The attribute decorator does not support this type: " + x.TypeName); }) .ToArray(); var methodParameters = decorator.TargetMethodFilter.Parameters.Select(x => builder.GetType(x)).ToArray(); AttributeTargets attributeTargets = AttributeTargets.All; if (attributeTarget != null) { Enum.TryParse(attributeTarget.ConstructorArguments[0].Value?.ToString(), out attributeTargets); } var allowMultiple = false; if (attributeTarget.Properties.TryGetValue("AllowMultiple", out CustomAttributeArgument customAttributeArgument)) { allowMultiple = (bool)customAttributeArgument.Value; } foreach (var @class in classes) { if (decorator.DecorateClass && @class.CustomAttributes.Add(attribute, parameterValues)) { builder.Log(LogTypes.Info, "- Decorating Class " + @class); } if (decorator.DecorateMethod) { foreach (var method in GetValidMethods(decorator, methodParameters, @class)) { if (method.CustomAttributes.Add(attribute, parameterValues)) { builder.Log(LogTypes.Info, "- Decorating Method " + method.Name); } } } if (decorator.DecorateProperty) { foreach (var property in GetValidProperties(decorator, @class)) { if (property.CustomAttributes.Add(attribute, parameterValues)) { builder.Log(LogTypes.Info, "- Decorating Properties " + property.Name); } } } } }