/// <summary>
        /// Checks the items within the given element.
        /// </summary>
        /// <param name="element">The element to check.</param>
        /// <param name="parentClass">The class that the element belongs to.</param>
        /// <param name="members">The collection of members of the parent class.</param>
        /// <returns>Returns false if the analyzer should quit.</returns>
        private bool CheckClassMemberRulesForElements(Element element, ClassBase parentClass, Dictionary<string, List<Element>> members)
        {
            Param.AssertNotNull(element, "element");
            Param.Ignore(parentClass);
            Param.Ignore(members);

            // Check whether processing has been cancelled by the user.
            if (this.Cancel)
            {
                return false;
            }

            if (element.ElementType == ElementType.Class ||
                element.ElementType == ElementType.Struct ||
                element.ElementType == ElementType.Interface)
            {
                parentClass = element as ClassBase;
                members = CollectClassMembers(parentClass);
            }

            for (Element child = element.FindFirstChildElement(); child != null; child = child.FindNextSiblingElement())
            {
                if (!child.Generated)
                {
                    if (child.ElementType == ElementType.Method ||
                        child.ElementType == ElementType.Constructor ||
                        child.ElementType == ElementType.Destructor ||
                        child.ElementType == ElementType.Accessor)
                    {
                        // If the parent class is null, then this element is sitting outside of a class.
                        // This is illegal in C# so the code will not compile, but we still attempt to
                        // parse it. In this case there is no use of this prefixes since there is no class.
                        if (parentClass != null)
                        {
                            this.CheckClassMemberRulesForStatements(child, child, parentClass, members);
                        }
                    }
                    else
                    {
                        if (child.ElementType == ElementType.Class || child.ElementType == ElementType.Struct)
                        {
                            ClassBase elementContainer = child as ClassBase;
                            Debug.Assert(elementContainer != null, "The element is not a class.");

                            this.CheckClassMemberRulesForElements(child, elementContainer, members);
                        }
                        else if (!this.CheckClassMemberRulesForElements(child, parentClass, members))
                        {
                            return false;
                        }
                    }
                }
            }

            return true;
        }
        /// <summary>
        /// Determines whether the given element contains any partial members.
        /// </summary>
        /// <param name="element">The element to check.</param>
        /// <returns>Returns true if the element contains at least one partial member.</returns>
        private bool ContainsPartialMembers(Element element)
        {
            Param.AssertNotNull(element, "element");

            if (element.ElementType == ElementType.Class ||
                element.ElementType == ElementType.Struct ||
                element.ElementType == ElementType.Interface)
            {
                if (element.ContainsModifier(TokenType.Partial))
                {
                    return true;
                }
            }

            if (element.ElementType == ElementType.Document ||
                element.ElementType == ElementType.Namespace ||
                element.ElementType == ElementType.Class ||
                element.ElementType == ElementType.Struct)
            {
                for (Element child = element.FindFirstChildElement(); child != null; child = child.FindNextSiblingElement())
                {
                    if (this.ContainsPartialMembers(child))
                    {
                        return true;
                    }
                }
            }

            return false;
        }
Esempio n. 3
0
        private bool ProcessElement(Element element, Dictionary<string, string> validPrefixes, bool nativeMethods)
        {
            Param.AssertNotNull(element, "element");
            Param.AssertNotNull(validPrefixes, "validPrefixes");
            Param.Ignore(nativeMethods);

            if (this.Cancel)
            {
                return false;
            }

            if (!element.Generated && element.Name != null)
            {
                switch (element.ElementType)
                {
                    case ElementType.Namespace:
                    case ElementType.Class:
                    case ElementType.Enum:
                    case ElementType.Struct:
                    case ElementType.Delegate:
                    case ElementType.Property:
                        if (!nativeMethods)
                        {
                            this.CheckCase(element, element.Name, element.LineNumber, true);
                        }

                        break;

                    case ElementType.Event:
                        if (!nativeMethods)
                        { 
                            for (EventDeclaratorExpression declarator = element.FindFirstChild<EventDeclaratorExpression>(); declarator != null; declarator = declarator.FindNextSibling<EventDeclaratorExpression>())
                            {
                                this.CheckCase(element, declarator.Identifier.Text, declarator.LineNumber, true);
                            }
                        }

                        break;

                    case ElementType.Method:
                        if (!nativeMethods &&
                            !element.Name.StartsWith("operator", StringComparison.Ordinal) &&
                            element.Name != "foreach")
                        {
                            this.CheckCase(element, element.Name, element.LineNumber, true);
                        }

                        break;

                    case ElementType.Interface:
                        if (element.Name.Length < 1 || element.Name[0] != 'I')
                        {
                            this.AddViolation(element, Rules.InterfaceNamesMustBeginWithI, element.Name);
                        }

                        break;

                    case ElementType.Field:
                        if (!nativeMethods)
                        {
                            this.CheckFieldUnderscores(element);
                            this.CheckFieldPrefix(element as Field, validPrefixes);
                        }

                        break;

                    default:
                        break;
                }
            }

            if (!nativeMethods &&
                (element.ElementType == ElementType.Class || element.ElementType == ElementType.Struct) &&
                element.Name.EndsWith("NativeMethods", StringComparison.Ordinal))
            {
                nativeMethods = true;
            }

            if (element.Children.ElementCount > 0)
            {
                for (Element child = element.FindFirstChildElement(); child != null; child = child.FindNextSiblingElement())
                {
                    if (!this.ProcessElement(child, validPrefixes, nativeMethods))
                    {
                        return false;
                    }
                }
            }

            if (!nativeMethods)
            {
                this.ProcessStatementContainer(element, validPrefixes);
            }

            return true;
        }
Esempio n. 4
0
        /// <summary>
        /// Checks the order of any using directives found under this element.
        /// </summary>
        /// <param name="element">The element containing the using directives.</param>
        private void CheckOrderOfUsingDirectivesUnderElement(Element element)
        {
            Param.AssertNotNull(element, "element");

            // Add each of the using directives to an array.
            List<UsingDirective> usings = null;

            for (Element childElement = element.FindFirstChildElement(); childElement != null; childElement = childElement.FindNextSiblingElement())
            {
                if (childElement.ElementType == ElementType.UsingDirective)
                {
                    if (usings == null)
                    {
                        usings = new List<UsingDirective>();
                    }

                    usings.Add((UsingDirective)childElement);
                }
                else if (childElement.ElementType != ElementType.ExternAliasDirective)
                {
                    break;
                }
            }

            if (usings != null)
            {
                this.CheckOrderOfUsingDirectivesInList(usings);
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Checks the order of using directives within the document.
        /// </summary>
        /// <param name="rootElement">The root element containing the using directives.</param>
        private void CheckUsingDirectiveOrder(Element rootElement)
        {
            Param.AssertNotNull(rootElement, "rootElement");

            if (!rootElement.Generated)
            {
                this.CheckOrderOfUsingDirectivesUnderElement(rootElement);

                // Find any namespace elements within this element.
                for (Element childElement = rootElement.FindFirstChildElement(); childElement != null; childElement = childElement.FindNextSiblingElement())
                {
                    if (childElement.ElementType == ElementType.Namespace)
                    {
                        this.CheckUsingDirectiveOrder(childElement);
                    }
                }
            }
        }
        /// <summary>
        /// Checks the placement of statements within the given element.
        /// </summary>
        /// <param name="element">The element to check.</param>
        private void CheckStatementFormattingRulesForElement(Element element)
        {
            Param.AssertNotNull(element, "element");

            if (!element.Generated)
            {
                if (element.ElementType == ElementType.EmptyElement)
                {
                    this.AddViolation(element, element.LineNumber, Rules.CodeMustNotContainEmptyStatements);
                }
                else
                {
                    this.CheckStatementFormattingRulesForStatements(element, element);

                    for (Element child = element.FindFirstChildElement(); child != null; child = child.FindNextSiblingElement())
                    {
                        this.CheckStatementFormattingRulesForElement(child);
                    }
                }
            }
        }
Esempio n. 7
0
        /// <summary>
        /// Checks the spacing of child elements of the given element, to ensure that elements
        /// are separated by a blank line.
        /// </summary>
        /// <param name="element">The element being visited.</param>
        private void CheckChildElementSpacing(Element element)
        {
            Param.AssertNotNull(element, "element");

            Element previousElement = null;

            if (element.Children.ElementCount > 0)
            {
                for (Element childElement = element.FindFirstChildElement(); childElement != null; childElement = childElement.FindNextSiblingElement())
                {
                    // Check the line spacing between the two elements if:
                    // - There was a previous element
                    // - AND neither of the elements are generated
                    // - AND the previous element and the current element are of different types
                    // - - OR the current element has a header
                    // - - OR the previous element spans multiple lines
                    // - - OR the elements are not using directives, extern alias directives, accessors, enum items, or fields.
                    if (previousElement != null && 
                        !previousElement.Generated &&
                        !childElement.Generated &&
                        (previousElement.ElementType != childElement.ElementType ||
                         childElement.Header != null ||
                         previousElement.Location.LineSpan > 1 ||
                         (childElement.ElementType != ElementType.UsingDirective &&
                          childElement.ElementType != ElementType.ExternAliasDirective &&
                          childElement.ElementType != ElementType.Accessor &&
                          childElement.ElementType != ElementType.EnumItem &&
                          childElement.ElementType != ElementType.Field)))
                    {
                        // The start line of this element is the first line of the header if there is one,
                        // or the first line of the element itself if there is no header.
                        int startLine = childElement.LineNumber;
                        if (childElement.Header != null)
                        {
                            startLine = childElement.Header.LineNumber;
                        }

                        if (startLine == previousElement.Location.EndPoint.LineNumber || 
                            startLine == previousElement.Location.EndPoint.LineNumber + 1)
                        {
                            this.AddViolation(childElement, Rules.ElementsMustBeSeparatedByBlankLine);
                        }
                    }

                    previousElement = childElement;
                }
            }
        }