/// <summary> /// Gets a string representation of a code element using the specified /// format. /// </summary> /// <param name="format">The format.</param> /// <param name="codeElement">The code element.</param> /// <returns>Formatted string representation of the code element.</returns> public static string Format(string format, ICodeElement codeElement) { if (format == null) { throw new ArgumentNullException("format"); } else if (codeElement == null) { throw new ArgumentNullException("codeElement"); } StringBuilder formatted = new StringBuilder(format.Length * 2); StringBuilder attributeBuilder = null; bool inAttribute = false; using (StringReader reader = new StringReader(format)) { int data = reader.Read(); while (data > 0) { char ch = (char)data; if (ch == ConditionExpressionParser.ExpressionPrefix && (char)(reader.Peek()) == ConditionExpressionParser.ExpressionStart) { reader.Read(); attributeBuilder = new StringBuilder(16); inAttribute = true; } else if (inAttribute) { if (ch == ConditionExpressionParser.ExpressionEnd) { ElementAttributeType elementAttribute = (ElementAttributeType)Enum.Parse( typeof(ElementAttributeType), attributeBuilder.ToString()); string attribute = GetAttribute(elementAttribute, codeElement); formatted.Append(attribute); attributeBuilder = new StringBuilder(16); inAttribute = false; } else { attributeBuilder.Append(ch); } } else { formatted.Append(ch); } data = reader.Read(); } } return(formatted.ToString()); }
/// <summary> /// Create a new ElementComparer. /// </summary> /// <param name="compareAttribute">The compare attribute.</param> /// <param name="sortDirection">The sort direction.</param> /// <param name="innerComparer">The inner comparer.</param> public ElementComparer( ElementAttributeType compareAttribute, SortDirection sortDirection, IComparer <ICodeElement> innerComparer) { _compareAttribute = compareAttribute; _sortDirection = sortDirection; _innerComparer = innerComparer; _comparison = CreateComparison(compareAttribute); }
/// <summary> /// Gets the name of the group the element falls into. /// </summary> /// <param name="elementFilterType">Type of the element filter.</param> /// <param name="codeElement">The code element.</param> /// <returns>The group name.</returns> private string GetGroupName(ElementAttributeType elementFilterType, ICodeElement codeElement) { string groupName = string.Empty; string attribute = ElementUtilities.GetAttribute(elementFilterType, codeElement); if (_captureRegex != null) { Match match = _captureRegex.Match(attribute); if (match != null && match.Groups.Count > 1) { groupName = match.Groups[1].Value; } } else { groupName = attribute; } return(groupName); }
/// <summary> /// Creates a new element attribute expression. /// </summary> /// <param name="elementAttribute">The element attribute.</param> /// <param name="scope">The scope.</param> public ElementAttributeExpression(ElementAttributeType elementAttribute, ElementAttributeScope scope) { _elementAttributeType = elementAttribute; _elementScope = scope; }
/// <summary> /// Creates a new element attribute expression. /// </summary> /// <param name="elementAttribute">The element attribute.</param> public ElementAttributeExpression(ElementAttributeType elementAttribute) : this(elementAttribute, ElementAttributeScope.Element) { }
/// <summary> /// Gets the string representation of a code element attribute. /// </summary> /// <param name="attributeType">Type of the attribute.</param> /// <param name="codeElement">The code element.</param> /// <returns>The code element attribute as text.</returns> public static string GetAttribute(ElementAttributeType attributeType, ICodeElement codeElement) { string attributeString = null; MemberElement memberElement; TypeElement typeElement; if (codeElement != null) { switch (attributeType) { case ElementAttributeType.Name: attributeString = codeElement.Name; break; case ElementAttributeType.Access: AttributedElement attributedElement = codeElement as AttributedElement; if (attributedElement != null) { attributeString = EnumUtilities.ToString(attributedElement.Access); } break; case ElementAttributeType.ElementType: attributeString = EnumUtilities.ToString(codeElement.ElementType); break; case ElementAttributeType.Type: attributeString = GetTypeAttribute(codeElement); break; case ElementAttributeType.Attributes: attributeString = GetAttributesAttribute(codeElement); break; case ElementAttributeType.Modifier: memberElement = codeElement as MemberElement; if (memberElement != null) { attributeString = EnumUtilities.ToString(memberElement.MemberModifiers); } else { typeElement = codeElement as TypeElement; if (typeElement != null) { attributeString = EnumUtilities.ToString(typeElement.TypeModifiers); } } break; default: attributeString = string.Empty; break; } } if (attributeString == null) { attributeString = string.Empty; } return(attributeString); }
/// <summary> /// Creates a comparison delegate based on the configuration. /// </summary> /// <param name="compareAttribute">The compare attribute.</param> /// <returns> /// Comparision delegate for two code elements. /// </returns> public Comparison <ICodeElement> CreateComparison(ElementAttributeType compareAttribute) { Comparison <ICodeElement> comparison = delegate(ICodeElement x, ICodeElement y) { int compareValue = 0; if (x == null && y != null) { compareValue = -1; } else if (x != null && y == null) { compareValue = 1; } else { switch (compareAttribute) { case ElementAttributeType.Access: AttributedElement attributedX = x as AttributedElement; AttributedElement attributedY = y as AttributedElement; if (attributedX != null && attributedY != null) { compareValue = attributedX.Access.CompareTo(attributedY.Access); } break; case ElementAttributeType.Modifier: MemberElement memberX = x as MemberElement; MemberElement memberY = y as MemberElement; if (memberX != null && memberY != null) { compareValue = memberX.MemberModifiers.CompareTo(memberY.MemberModifiers); } break; case ElementAttributeType.ElementType: compareValue = x.ElementType.CompareTo(y.ElementType); break; default: if (compareAttribute == ElementAttributeType.Type && x is TypeElement && y is TypeElement) { compareValue = ((TypeElement)x).Type.CompareTo(((TypeElement)y).Type); } else if (compareAttribute == ElementAttributeType.Type && x is UsingElement && y is UsingElement) { compareValue = ((UsingElement)x).Type.CompareTo(((UsingElement)y).Type); } else { string attributeX = ElementUtilities.GetAttribute(compareAttribute, x); string attributeY = ElementUtilities.GetAttribute(compareAttribute, y); compareValue = StringComparer.OrdinalIgnoreCase.Compare(attributeX, attributeY); } break; } } return(compareValue); }; return(comparison); }
/// <summary> /// Creates a new ElementComparer. /// </summary> /// <param name="compareAttribute">The compare attribute.</param> /// <param name="sortDirection">The sort direction.</param> public ElementComparer(ElementAttributeType compareAttribute, SortDirection sortDirection) : this(compareAttribute, sortDirection, null) { }
/// <summary> /// Parses and expression to an expression tree. /// </summary> /// <param name="expression">Condition expression text.</param> /// <returns>A condition expression instance.</returns> public IConditionExpression Parse(string expression) { const int DefaultExpressionLength = 128; IConditionExpression conditionExpression = null; if (expression == null) { throw new ArgumentNullException("expression"); } else if (expression.Trim().Length == 0) { throw new ArgumentException("expression"); } List <IConditionExpression> nodes = new List <IConditionExpression>(); StringReader reader = new StringReader(expression); StringBuilder expressionBuilder = new StringBuilder(DefaultExpressionLength); bool inString = false; bool inAttribute = false; int depth = 0; int data = reader.Read(); while (data > 0) { char ch = (char)data; char nextCh = (char)reader.Peek(); if (inString && ch != '\'') { expressionBuilder.Append(ch); } else { switch (ch) { case ' ': case '\t': case '\r': case '\n': // Eat whitespace break; case ExpressionPrefix: CheckForInvalidOperator(expression, expressionBuilder); if (nextCh == ExpressionStart) { inAttribute = true; reader.Read(); } break; case '=': if (nextCh == '=') { nodes.Add(new OperatorExpressionPlaceholder(BinaryExpressionOperator.Equal)); reader.Read(); } else if (nextCh == '~') { nodes.Add(new OperatorExpressionPlaceholder(BinaryExpressionOperator.Matches)); reader.Read(); } break; case '!': if (nextCh == '=') { nodes.Add(new OperatorExpressionPlaceholder(BinaryExpressionOperator.NotEqual)); reader.Read(); } else { expressionBuilder.Append(ch); } break; case ':': nodes.Add(new OperatorExpressionPlaceholder(BinaryExpressionOperator.Contains)); reader.Read(); break; case 'O': if (nextCh == 'r' && !inAttribute && !inString) { nodes.Add(new OperatorExpressionPlaceholder(BinaryExpressionOperator.Or)); reader.Read(); } else { expressionBuilder.Append(ch); } break; case 'A': if (nextCh == 'n' && !inAttribute && !inString) { reader.Read(); nextCh = (char)reader.Peek(); if (nextCh == 'd') { nodes.Add(new OperatorExpressionPlaceholder(BinaryExpressionOperator.And)); reader.Read(); } } else { expressionBuilder.Append(ch); } break; case ExpressionEnd: if (inAttribute) { string attribute = expressionBuilder.ToString(); expressionBuilder = new StringBuilder(DefaultExpressionLength); ElementAttributeScope elementScope = ElementAttributeScope.Element; bool isFileExpression = false; int separatorIndex = attribute.LastIndexOf(ScopeSeparator); if (separatorIndex > 0) { try { string attributeScope = attribute.Substring(0, separatorIndex); attribute = attribute.Substring(separatorIndex + 1); if (attributeScope == FileAttributeScope) { isFileExpression = true; } else { elementScope = (ElementAttributeScope) Enum.Parse(typeof(ElementAttributeScope), attributeScope); } } catch (ArgumentException ex) { OnInvalidExpression(expression, "Unknown attribute scope: {0}", ex.Message); } } if (isFileExpression) { FileAttributeType fileAttribute = FileAttributeType.None; try { fileAttribute = (FileAttributeType) Enum.Parse(typeof(FileAttributeType), attribute); } catch (ArgumentException ex) { OnInvalidExpression(expression, "Unknown attribute: {0}", ex.Message); } FileAttributeExpression attributeExpresion = new FileAttributeExpression( fileAttribute); nodes.Add(attributeExpresion); } else { ElementAttributeType elementAttribute = ElementAttributeType.None; try { elementAttribute = (ElementAttributeType) Enum.Parse(typeof(ElementAttributeType), attribute); } catch (ArgumentException ex) { OnInvalidExpression(expression, "Unknown attribute: {0}", ex.Message); } ElementAttributeExpression attributeExpresion = new ElementAttributeExpression( elementAttribute, elementScope); nodes.Add(attributeExpresion); } inAttribute = false; } else if (expressionBuilder.Length > 0 && nodes.Count > 0) { IConditionExpression innerExpression = nodes[nodes.Count - 1]; nodes.RemoveAt(nodes.Count - 1); string unaryOperatorString = expressionBuilder.ToString().Trim(); expressionBuilder = new StringBuilder(DefaultExpressionLength); UnaryExpressionOperator?unaryOperator = null; if (unaryOperatorString == "!") { unaryOperator = UnaryExpressionOperator.Negate; } else { OnInvalidExpression(expression, "Invalid operator {0}", unaryOperatorString); } UnaryOperatorExpression unaryOperatorExpression = new UnaryOperatorExpression( unaryOperator.Value, innerExpression); nodes.Add(unaryOperatorExpression); depth--; } else { depth--; } break; case ExpressionStart: IConditionExpression nestedExpression = null; StringBuilder childExpressionBuilder = new StringBuilder(DefaultExpressionLength); data = reader.Read(); ch = (char)data; nextCh = (char)reader.Peek(); depth++; while (data > 0) { if (ch == ExpressionPrefix && nextCh == ExpressionStart) { inAttribute = true; childExpressionBuilder.Append(ExpressionPrefix); data = reader.Read(); childExpressionBuilder.Append(ExpressionStart); } else if (ch == ExpressionStart && !inAttribute) { depth++; childExpressionBuilder.Append(ExpressionStart); } else if (nextCh == ExpressionEnd) { childExpressionBuilder.Append(ch); if (inAttribute || depth > 1) { if (inAttribute) { inAttribute = false; } else if (depth > 1) { depth--; } } else { break; } } else { childExpressionBuilder.Append(ch); } data = reader.Read(); ch = (char)data; nextCh = (char)reader.Peek(); } try { nestedExpression = Parse(childExpressionBuilder.ToString()); } catch (ArgumentException) { OnInvalidExpression(expression); } nodes.Add(nestedExpression); break; case '\'': if (inString) { if (nextCh == '\'') { expressionBuilder.Append(ch); reader.Read(); } else { string str = expressionBuilder.ToString(); expressionBuilder = new StringBuilder(DefaultExpressionLength); StringExpression stringExpression = new StringExpression(str); nodes.Add(stringExpression); inString = false; } } else { CheckForInvalidOperator(expression, expressionBuilder); inString = true; } break; default: expressionBuilder.Append(ch); break; } } data = reader.Read(); } if (inString) { OnInvalidExpression(expression, "Expected '"); } else if (inAttribute || depth > 0) { OnInvalidExpression(expression, "Expected )"); } else if (depth < 0) { OnInvalidExpression(expression, "Unmatched )"); } // // Assembly the flat list of expressions and expression placeholders into an // expression tree. // conditionExpression = AssembleExpressionTree(nodes.AsReadOnly(), expression); return(conditionExpression); }
/// <summary> /// Gets the string representation of a code element attribute. /// </summary> /// <param name="attributeType">Type of the attribute.</param> /// <param name="codeElement">The code element.</param> /// <returns>The code element attribute as text.</returns> public static string GetAttribute(ElementAttributeType attributeType, ICodeElement codeElement) { string attributeString = null; MemberElement memberElement; TypeElement typeElement; if (codeElement != null) { switch (attributeType) { case ElementAttributeType.Name: attributeString = codeElement.Name; break; case ElementAttributeType.Access: AttributedElement attributedElement = codeElement as AttributedElement; if (attributedElement != null) { attributeString = EnumUtilities.ToString(attributedElement.Access); } break; case ElementAttributeType.ElementType: attributeString = EnumUtilities.ToString(codeElement.ElementType); break; case ElementAttributeType.Type: attributeString = GetTypeAttribute(codeElement); break; case ElementAttributeType.Attributes: attributeString = GetAttributesAttribute(codeElement); break; case ElementAttributeType.Modifier: memberElement = codeElement as MemberElement; if (memberElement != null) { attributeString = EnumUtilities.ToString(memberElement.MemberModifiers); } else { typeElement = codeElement as TypeElement; if (typeElement != null) { attributeString = EnumUtilities.ToString(typeElement.TypeModifiers); } } break; default: attributeString = string.Empty; break; } } if (attributeString == null) { attributeString = string.Empty; } return attributeString; }
/// <summary> /// Gets the name of the group the element falls into. /// </summary> /// <param name="elementFilterType">Type of the element filter.</param> /// <param name="codeElement">The code element.</param> /// <returns>The group name.</returns> private string GetGroupName(ElementAttributeType elementFilterType, ICodeElement codeElement) { string groupName = string.Empty; string attribute = ElementUtilities.GetAttribute(elementFilterType, codeElement); if (_captureRegex != null) { Match match = _captureRegex.Match(attribute); if (match != null && match.Groups.Count > 1) { groupName = match.Groups[1].Value; } } else { groupName = attribute; } return groupName; }