public static ProductionRule GenerateRule(MethodInfo method) { ProductionAttribute production = (ProductionAttribute)Attribute.GetCustomAttribute(method, typeof(ProductionAttribute), false); if (production == null) { return(null); } Type[] newLeft, left, strict, right, newRight; production.GetTypes(method, out newLeft, out left, out strict, out right, out newRight); var ignoreList = IgnoreAttribute.GetIgnoredTypes(method); foreach (var p in method.GetParameters()) { if (ignoreList.Contains(p.ParameterType)) { throw new InvalidOperationException(string.Format( "ProductionRule: Ignored type is production function parameters list (class: {0}, method: {1}).", method.DeclaringType.Name, method.ToString())); } } Array.Reverse(newLeft); Array.Reverse(left); return(new ProductionRule() { Method = method, NewLeft = newLeft, Left = left, Strict = strict, Right = right, NewRight = newRight, IgnoreList = ignoreList }); }
internal void GetTypes( MethodInfo method, out Type[] newLeftTypes, out Type[] leftTypes, out Type[] strictTypes, out Type[] rightTypes, out Type[] newRightTypes) { if (method.ReturnType == typeof(void)) { throw new InvalidOperationException(string.Format( "ProductionAttribute: Production rule must return object (class: {0}, method: {1}).", method.DeclaringType.Name, method.ToString())); } if (0 == method.GetParameters().Count()) { throw new InvalidOperationException(string.Format( "ProductionAttribute: Production rule must have parameters (class: {0}, method: {1}).", method.DeclaringType.Name, method.ToString())); } string[] newLeft, left, strict, right, newRight; if (this.Schema == string.Empty) { newLeft = left = right = newRight = new string[] {}; strict = (from ParameterInfo p in method.GetParameters() select p.Name).ToArray(); } else { Match match = productionRegex.Match(this.Schema); if (!match.Success) { throw new InvalidOperationException(string.Format( "ProductionAttribute: Production string is not correct (Regex match failure, class: {0}, method: {1}).", method.DeclaringType.Name, method.ToString())); } if (match.Groups.Count != 6) { throw new InvalidOperationException(string.Format( "ProductionAttribute: Internal error while parsing production (class: {0}, method: {1}).", method.DeclaringType.Name, method.ToString())); } newLeft = FindNames(match.Groups[1].Value, "<<"); left = FindNames(match.Groups[2].Value, "<"); strict = FindNames(match.Groups[3].Value, String.Empty); right = FindNames(match.Groups[4].Value, ">"); newRight = FindNames(match.Groups[5].Value, ">>"); var allItems = newLeft.Concat(left).Concat(strict).Concat(right).Concat(newRight).ToArray(); var methodParametersNames = (from ParameterInfo info in method.GetParameters() select info.Name).ToArray(); if (!allItems.SequenceEqual(methodParametersNames)) { throw new InvalidOperationException(string.Format( "ProductionAttribute: List of parameters in production do not match to list of method parameters (class: {0}, method: {1}).", method.DeclaringType.Name, method.ToString())); } } var parametersList = method.GetParameters().ToList(); var ignoreList = IgnoreAttribute.GetIgnoredTypes(method); foreach (var p in parametersList) { if (ignoreList.Contains(p.ParameterType)) { throw new InvalidOperationException(string.Format( "ProductionAttribute: Ignored type is production function parameters list (class: {0}, method: {1}).", method.DeclaringType.Name, method.ToString())); } } newLeftTypes = (from string l in newLeft select parametersList.Find(p => p.Name == l).ParameterType).ToArray(); leftTypes = (from string l in left select parametersList.Find(p => p.Name == l).ParameterType).ToArray(); strictTypes = (from string l in strict select parametersList.Find(p => p.Name == l).ParameterType).ToArray(); rightTypes = (from string l in right select parametersList.Find(p => p.Name == l).ParameterType).ToArray(); newRightTypes = (from string l in newRight select parametersList.Find(p => p.Name == l).ParameterType).ToArray(); }