Exemplo n.º 1
0
        /// <summary>
        /// Checks the order of child elements of the given element.
        /// </summary>
        /// <param name="element">The element to check.</param>
        /// <param name="checkGeneratedCode">Indicates whether to check the order of elenents
        /// within generated blocks of code.</param>
        private void CheckChildElementOrdering(Element element, bool checkGeneratedCode)
        {
            Param.AssertNotNull(element, "element");
            Param.Ignore(checkGeneratedCode);

            // Check the ordering of this element compared with other elements at the same level.
            if (element.Children.ElementCount > 0)
            {
                bool firstValid = true;

                List<Element> elementsList = new List<Element>(element.Children.ElementCount);
                elementsList.AddRange(element.GetChildren<Element>());

                for (int i = 0; i < elementsList.Count; ++i)
                {
                    Element first = elementsList[i];

                    if (first.GetAnalyzerTag() == null)
                    {
                        for (int j = i + 1; j < elementsList.Count; ++j)
                        {
                            Element second = elementsList[j];

                            if (second.GetAnalyzerTag() == null)
                            {
                                // If we're supposed to be checking the order of generated code as well,
                                // then only perform this check if at least one of the two elements is not 
                                // generated code. Otherwise, only perform this check if both of the two 
                                // elements is not generated code.
                                if ((checkGeneratedCode && (!first.Generated || !second.Generated)) || 
                                    (!checkGeneratedCode && !first.Generated && !second.Generated))
                                {
                                    // Determine whether first is actually supposed to come before second
                                    if (!this.CompareItems(first, second, !firstValid))
                                    {
                                        // Determine whether this means that first is out of order or second
                                        // is out of order. If we have not found the first item in the list that
                                        // is in the correct order, then first is marked out of order, otherwise
                                        // second is marked out of order.
                                        if (firstValid)
                                        {
                                            first.SetAnalyzerTag(false);
                                        }
                                        else
                                        {
                                            second.SetAnalyzerTag(false);
                                        }
                                    }
                                    else
                                    {
                                        // At this point we know that we've found an item that is in the correct order.
                                        if (firstValid)
                                        {
                                            firstValid = false;
                                        }
                                    }

                                    // If both of the elements are accessors, check that they appear in the correct order.
                                    if (first.ElementType == ElementType.Accessor && second.ElementType == ElementType.Accessor)
                                    {
                                        Accessor firstAccessor = (Accessor)first;
                                        Accessor secondAccessor = (Accessor)second;

                                        if (firstAccessor.AccessorType == AccessorType.Set && secondAccessor.AccessorType == AccessorType.Get)
                                        {
                                            this.AddViolation(first, Rules.PropertyAccessorsMustFollowOrder);
                                        }
                                        else if (firstAccessor.AccessorType == AccessorType.Remove && secondAccessor.AccessorType == AccessorType.Add)
                                        {
                                            this.AddViolation(first, Rules.EventAccessorsMustFollowOrder);
                                        }
                                    }
                                }
                            }
                        }
                    }

                    this.CheckElementOrder(first, checkGeneratedCode);
                }
            }
        }