示例#1
0
 private void ProcessCodeUnit(CodeUnit item, XmlNode parentNode)
 {
     XmlNode elementNode = RecordItem(item, parentNode);
     for (CodeUnit child = item.Children.First; child != null; child = child.LinkNode.Next)
     {
         ProcessCodeUnit(child, elementNode);
     }
 }
示例#2
0
 /// <summary>
 /// Initializes a new instance of the LocalFunctionStatement class.
 /// </summary>
 /// <param name="tokens">
 /// The list of tokens that form the statement.
 /// </param>
 /// <param name="returnType">
 /// The return type of this local function.
 /// </param>
 /// <param name="returnTypeIsRef">
 /// The return type of this local function is ref.
 /// </param>
 /// <param name="identifier">
 /// The identifier of this local function.
 /// </param>
 /// <param name="parameters">
 /// The parameter information of this local function.
 /// </param>
 /// <param name="functionBodyExpression">
 /// An expression that represents the body of this local function.
 /// </param>
 public LocalFunctionStatement(
     CsTokenList tokens,
     TypeToken returnType,
     bool returnTypeIsRef,
     LiteralExpression identifier,
     IList <Parameter> parameters,
     Expression functionBodyExpression)
     : this(tokens, returnType, returnTypeIsRef, identifier, parameters)
 {
     Param.AssertNotNull(functionBodyExpression, nameof(functionBodyExpression));
     this.functionBody = functionBodyExpression;
     this.AddExpression(functionBodyExpression);
 }
 /// <summary>
 /// Initializes a new instance of the LocalFunctionStatement class.
 /// </summary>
 /// <param name="tokens">
 /// The list of tokens that form the statement.
 /// </param>
 /// <param name="returnType">
 /// The return type of this local function.
 /// </param>
 /// <param name="returnTypeIsRef">
 /// The return type of this local function is ref.
 /// </param>
 /// <param name="identifier">
 /// The identifier of this local function.
 /// </param>
 /// <param name="parameters">
 /// The parameter information of this local function.
 /// </param>
 /// <param name="typeConstraints">
 /// The list of type constraints on the element.
 /// </param>
 /// <param name="functionBodyExpression">
 /// An expression that represents the body of this local function.
 /// </param>
 internal LocalFunctionStatement(
     CsTokenList tokens,
     TypeToken returnType,
     bool returnTypeIsRef,
     LiteralExpression identifier,
     IList <Parameter> parameters,
     ICollection <TypeParameterConstraintClause> typeConstraints,
     Expression functionBodyExpression)
     : this(tokens, returnType, returnTypeIsRef, identifier, parameters, typeConstraints)
 {
     Param.AssertNotNull(functionBodyExpression, nameof(functionBodyExpression));
     this.functionBody = functionBodyExpression;
     this.AddExpression(functionBodyExpression);
 }
        /// <summary>
        /// Determines the amount of offset to add to the line number of the next argument
        /// for a comment or attribute. 
        /// </summary>
        /// <param name="item">The starting item.</param>
        /// <returns>Returns the amount of offset to add.</returns>
        private static int ParameterPrewordOffset(CodeUnit item)
        {
            Param.AssertNotNull(item, "tokenNode");

            Debug.Assert(item.Is(CodeUnitType.Attribute) || item.Is(LexicalElementType.Comment), "The item must be an attribute or a comment.");

            // Find the start of the next argument.
            for (CodeUnit next = item.FindLast().FindNext(); next != null; next = next.FindNext())
            {
                if (next.Is(LexicalElementType.EndOfLine))
                {
                    return item.Location.LineSpan;
                }
                else if (!next.Is(LexicalElementType.WhiteSpace) &&
                    !next.Is(LexicalElementType.WhiteSpace) &&
                    !next.Is(CodeUnitType.Attribute))
                {
                    return Math.Max(0, next.Location.StartPoint.LineNumber - item.Location.StartPoint.LineNumber);
                }
            }

            return 0;
        }
示例#5
0
        /// <summary>
        /// Visits one code unit in the document.
        /// </summary>
        /// <param name="codeUnit">The item being visited.</param>
        /// <param name="parentElement">The parent element, if any.</param>
        /// <param name="parentStatement">The parent statement, if any.</param>
        /// <param name="parentExpression">The parent expression, if any.</param>
        /// <param name="parentClause">The parent query clause, if any.</param>
        /// <param name="parentToken">The parent token, if any.</param>
        /// <param name="settings">The settings.</param>
        /// <returns>Returns true to continue, or false to stop the walker.</returns>
        private bool VisitCodeUnit(
            CodeUnit codeUnit,
            Element parentElement,
            Statement parentStatement,
            Expression parentExpression,
            QueryClause parentClause,
            Token parentToken,
            Settings settings)
        {
            Param.AssertNotNull(codeUnit, "codeUnit");
            Param.Ignore(parentElement, parentStatement, parentExpression, parentClause, parentToken);
            Param.AssertNotNull(settings, "settings");

            if (codeUnit.CodeUnitType == CodeUnitType.Element)
            {
                return this.VisitElement((Element)codeUnit, settings);
            }
            else if (codeUnit.CodeUnitType == CodeUnitType.Expression)
            {
                return this.VisitExpression((Expression)codeUnit, parentElement);
            }
            else if (codeUnit.Is(LexicalElementType.Token))
            {
                Token token = (Token)codeUnit;
                if (token.TokenType == TokenType.Type && !token.Parent.Is(TokenType.Type))
                {
                    // Check that the type is using the built-in types, if applicable.
                    this.CheckBuiltInType((TypeToken)token, parentElement);
                }
                else if (token.TokenType == TokenType.String)
                {
                    // Check that the string is not using the empty string "" syntax.
                    this.CheckEmptyString(token, parentElement);
                }
            }
            else if (codeUnit.Is(PreprocessorType.Region))
            {
                this.CheckRegion((RegionDirective)codeUnit, parentElement, settings);
            }
            else if (codeUnit.Is(LexicalElementType.Comment))
            {
                this.CheckForEmptyComments((Comment)codeUnit, parentElement);
            }

            return !this.Cancel;
        }
        /// <summary>
        /// Analyzes the given query clauses.
        /// </summary>
        /// <param name="element">The element containing the clauses.</param>
        /// <param name="expression">The expression containing the clauses.</param>
        /// <param name="clauseParent">The direct parent of the collection of clauses to analyze.</param>
        /// <param name="previousClause">The previous clause in the expression, if any.</param>
        /// <param name="clauseOnSameLine">Indicates whether any clause has been seen previously which
        /// starts on the same line as the clause before it.</param>
        /// <param name="clauseOnSeparateLine">Indicates whether any clause has been seen previously which
        /// starts on the line after the clause before it.</param>
        /// <returns>Returns true to continue checking the query clause, or false to quit.</returns>
        private bool ProcessQueryClauses(
            Element element,
            QueryExpression expression,
            CodeUnit clauseParent,
            ref QueryClause previousClause,
            ref bool clauseOnSameLine,
            ref bool clauseOnSeparateLine)
        {
            Param.AssertNotNull(element, "element");
            Param.AssertNotNull(expression, "expression");
            Param.AssertNotNull(clauseParent, "clauseParent");
            Param.Ignore(previousClause);
            Param.Ignore(clauseOnSameLine);
            Param.Ignore(clauseOnSeparateLine);

            for (QueryClause clause = clauseParent.FindFirstChildQueryClause(); clause != null; clause = clause.FindNextSiblingQueryClause())
            {
                if (previousClause != null)
                {
                    // Figure out the line number that the previous clause ends on. For most 
                    // clauses, this is simply the end point of the clause location property,
                    // but for continuation clauses we want to use the location of the 'into' variable,
                    // which conceptually represents the end of the continuation line.
                    int previousClauseEndLineNumber = previousClause.Location.EndPoint.LineNumber;

                    if (previousClause.QueryClauseType == QueryClauseType.Continuation)
                    {
                        previousClauseEndLineNumber = ((QueryContinuationClause)previousClause).Variable.Location.LineNumber;
                    }

                    // Ensure that the clause either starts on the same line as the expression, or 
                    // on the very next line.
                    if (clause.LineNumber == previousClauseEndLineNumber)
                    {
                        // This is only ok if the previous clause does not span multiple lines.
                        if (previousClause.Location.LineSpan > 1)
                        {
                            this.AddViolation(element, clause.LineNumber, Rules.QueryClauseMustBeginOnNewLineWhenPreviousClauseSpansMultipleLines);
                            return false;
                        }

                        // The rest of the checks are only applied when the clause is not a query continuation clause. A continuation
                        // clause is allowed to begin at the end of the previous clause, on the same line.
                        if (clause.QueryClauseType != QueryClauseType.Continuation)
                        {
                            // The clause starts on the same line as the ending of the previous clause.
                            // This is ok as long as we have not previously seen a clause which starts
                            // on its own line. The one exception is that query continuation clauses
                            // are allowed to be inserted at the end of the previous claus.
                            if (clauseOnSeparateLine)
                            {
                                this.AddViolation(element, clause.LineNumber, Rules.QueryClausesMustBeOnSeparateLinesOrAllOnOneLine);
                                return false;
                            }

                            // If the clause spans multiple lines, it must begin on its own line. The exception is query continuation
                            // clauses, which are allowed to begin at the end of the previous claus.
                            if (clause.Location.LineSpan > 1)
                            {
                                this.AddViolation(element, clause.LineNumber, Rules.QueryClausesSpanningMultipleLinesMustBeginOnOwnLine);
                                return false;
                            }

                            // Indicate that we have seen a clause which starts on the same line as the
                            // previous clause.
                            clauseOnSameLine = true;
                        }
                    }
                    else if (clause.LineNumber == previousClauseEndLineNumber + 1)
                    {
                        // The clause starts on the line just after the previous clause. 
                        // This is fine unless we have previously seen two clauses on the same line.
                        if (clauseOnSameLine)
                        {
                            this.AddViolation(element, clause.LineNumber, Rules.QueryClausesMustBeOnSeparateLinesOrAllOnOneLine);
                            return false;
                        }

                        // Indicate that we have seen a clause which begins on the line after
                        // the previous clause.
                        clauseOnSeparateLine = true;
                    }
                    else if (clause.LineNumber > previousClauseEndLineNumber + 1)
                    {
                        // The clause does not start on the line after the previous clause.
                        this.AddViolation(element, clause.LineNumber, Rules.QueryClauseMustFollowPreviousClause);
                        return false;
                    }
                }

                previousClause = clause;

                if (clause.QueryClauseType == QueryClauseType.Continuation)
                {
                    QueryContinuationClause continuationClause = (QueryContinuationClause)clause;
                    if (!this.ProcessQueryClauses(
                        element,
                        expression,
                        continuationClause,
                        ref previousClause,
                        ref clauseOnSameLine,
                        ref clauseOnSeparateLine))
                    {
                        return false;
                    }
                }
            }

            return true;
        }
        /// <summary>
        /// Checks the positioning of method parameters which are split across multiple lines.
        /// </summary>
        /// <param name="element">The element.</param>
        /// <param name="parameterList">The argument list.</param>
        /// <param name="arguments">The method arguments.</param>
        /// <param name="openingBracket">The opening bracket token.</param>
        private void CheckSplitMethodArgumentList(Element element, CodeUnit parameterList, IArgumentList arguments, OpenBracketToken openingBracket)
        {
            Param.AssertNotNull(element, "element");
            Param.AssertNotNull(parameterList, "parameterList");
            Param.AssertNotNull(arguments, "arguments");
            Param.AssertNotNull(openingBracket, "openingBracket");

            Token previousComma = null;
            bool commaOnSameLineAsPreviousParameterViolation = false;

            for (int i = 0; i < arguments.Count; ++i)
            {
                CodeLocation location = arguments.Location(i);
                int argumentStartLine = location.LineNumber;

                CodeUnit argument = arguments.Argument(i);

                // Some types of parameters or arguments are not allowed to span across multiple lines.
                if (location.LineSpan > 1 && !arguments.MaySpanMultipleLines(i))
                {
                    this.AddViolation(element, argumentStartLine, Rules.ParameterMustNotSpanMultipleLines);
                }

                if (i == 0)
                {
                    // The first argument must start on the line after the opening bracket
                    if (argumentStartLine != openingBracket.LineNumber + 1)
                    {
                        int commentLineSpan = MeasureCommentLinesAfter(openingBracket);

                        if (argumentStartLine != openingBracket.LineNumber + commentLineSpan + 1)
                        {
                            this.AddViolation(element, argumentStartLine, Rules.SplitParametersMustStartOnLineAfterDeclaration, element.FriendlyTypeText);
                        }
                    }
                }
                else
                {
                    // The argument must begin on the line after the previous comma.
                    Debug.Assert(previousComma != null, "The previous comma should have been set.");
                    if (!commaOnSameLineAsPreviousParameterViolation)
                    {
                        if (argumentStartLine != previousComma.LineNumber + 1)
                        {
                            int commentLineSpan = MeasureCommentLinesAfter(previousComma);

                            if (argumentStartLine != previousComma.LineNumber + commentLineSpan + 1)
                            {
                                this.AddViolation(element, argumentStartLine, Rules.ParameterMustFollowComma);
                            }
                        }
                    }
                }

                commaOnSameLineAsPreviousParameterViolation = false;

                // Find the comma after the token list.
                if (i < arguments.Count - 1)
                {
                    Token lastTokenInArgument = argument.FindLastDescendentToken();
                    if (lastTokenInArgument != null)
                    {
                        for (Token token = lastTokenInArgument.FindNextDescendentTokenOf(parameterList); token != null; token = token.FindNextDescendentTokenOf(parameterList))
                        {
                            if (token.TokenType == TokenType.Comma)
                            {
                                previousComma = token;

                                // The comma must be on the same line as the previous argument.
                                if (previousComma.LineNumber != location.EndPoint.LineNumber)
                                {
                                    int commentLineSpan = MeasureCommentLinesBetween(argument.FindLastChildToken(), previousComma, false);

                                    if (previousComma.LineNumber != location.EndPoint.LineNumber + commentLineSpan)
                                    {
                                        this.AddViolation(element, token.LineNumber, Rules.CommaMustBeOnSameLineAsPreviousParameter);
                                        commaOnSameLineAsPreviousParameterViolation = true;
                                    }
                                }

                                break;
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Checks the argument list to a method or method invocation to ensure that the arguments are 
        /// positioned correctly.
        /// </summary>
        /// <param name="element">The element containing the expression.</param>
        /// <param name="parameterList">The element's argument list.</param>
        /// <param name="arguments">The arguments to the method.</param>
        /// <param name="openingBracket">The opening bracket token.</param>
        /// <param name="methodLineNumber">The line number on which the method begins.</param>
        private void CheckMethodArgumentList(Element element, CodeUnit parameterList, IArgumentList arguments, OpenBracketToken openingBracket, int methodLineNumber)
        {
            Param.AssertNotNull(element, "element");
            Param.AssertNotNull(parameterList, "parameterList");
            Param.AssertNotNull(arguments, "arguments");
            Param.AssertNotNull(openingBracket, "openingBracket");
            Param.AssertGreaterThanZero(methodLineNumber, "methodLineNumber");

            // Determine whether all of the parameters are on the same line as one another.
            bool someParametersShareLine;
            bool someParameterOnDifferentLines;

            DetermineMethodParameterPlacementScheme(
                arguments, out someParametersShareLine, out someParameterOnDifferentLines);

            // All parameters must either be on the same line, or each argument must begin on its own line.
            if (someParametersShareLine && someParameterOnDifferentLines)
            {
                this.AddViolation(
                    element,
                    methodLineNumber,
                    Rules.ParametersMustBeOnSameLineOrSeparateLines,
                    element.FriendlyTypeText);
            }

            // Determine whether all of the parameters are on the same line as one another.
            if (someParameterOnDifferentLines)
            {
                this.CheckSplitMethodArgumentList(element, parameterList, arguments, openingBracket);
            }
            else if (arguments.Count > 0)
            {
                // The first argument must start on the same line as the opening bracket, or 
                // on the line after it.
                int firstArgumentStartLine = arguments.Location(0).LineNumber;

                if (firstArgumentStartLine != openingBracket.LineNumber &&
                    firstArgumentStartLine != openingBracket.LineNumber + 1)
                {
                    int commentLineSpan = MeasureCommentLinesAfter(openingBracket);

                    if (firstArgumentStartLine != openingBracket.LineNumber + commentLineSpan + 1)
                    {
                        this.AddViolation(element, firstArgumentStartLine, Rules.ParameterListMustFollowDeclaration);
                    }
                }
            }
        }
        /// <summary>
        /// Checks a method or method invocation to ensure that the closing bracket is
        /// on the same line as the last argument.
        /// </summary>
        /// <param name="element">The element containing the expression.</param>
        /// <param name="parameterList">The argument list.</param>
        /// <param name="openingBracket">The opening bracket.</param>
        /// <param name="closingBracketType">The type of the closing bracket.</param>
        /// <param name="arguments">The arguments to the method.</param>
        private void CheckMethodClosingBracket(
            Element element, CodeUnit parameterList, OpenBracketToken openingBracket, TokenType closingBracketType, IArgumentList arguments)
        {
            Param.AssertNotNull(element, "element");
            Param.AssertNotNull(parameterList, "parameterList");
            Param.AssertNotNull(openingBracket, "openingBracket");
            Param.Ignore(closingBracketType);
            Param.AssertNotNull(arguments, "arguments");

            // Find the closing bracket.
            CloseBracketToken closingBracket = null;

            Token next = parameterList.FindNextSiblingToken();
            if (next != null && next.Is(closingBracketType))
            {
                closingBracket = (CloseBracketToken)next;
            }

            if (closingBracket != null)
            {
                if (arguments.Count == 0)
                {
                    // The closing bracket must be on the same line as the opening bracket.
                    if (openingBracket.LineNumber != closingBracket.LineNumber)
                    {
                        // If the brackets are not on the same line, determine if this is because there are comments
                        // between the brackets.
                        int commentLineSpan = MeasureCommentLinesBetween(openingBracket, closingBracket, false);

                        if (openingBracket.LineNumber + commentLineSpan != closingBracket.LineNumber)
                        {
                            this.AddViolation(element, closingBracket.LineNumber, Rules.ClosingParenthesisMustBeOnLineOfOpeningParenthesis);
                        }
                    }
                }
                else
                {
                    // The closing bracket must be on the same line as the end of the last method argument.
                    int lastArgumentEndLine = arguments.Location(arguments.Count - 1).EndPoint.LineNumber;
                    if (lastArgumentEndLine != closingBracket.LineNumber)
                    {
                        int commentLineSpan = MeasureCommentLinesBetween(arguments.Argument(arguments.Count - 1).FindLastDescendentToken(), closingBracket, false);

                        if (lastArgumentEndLine + commentLineSpan != closingBracket.LineNumber)
                        {
                            this.AddViolation(element, closingBracket.LineNumber, Rules.ClosingParenthesisMustBeOnLineOfLastParameter);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Checks a method or method invocation to ensure that the opening bracket is
        /// on the same line as the method declaration.
        /// </summary>
        /// <param name="element">The element containing the expression.</param>
        /// <param name="parameterList">The argument list.</param>
        /// <param name="openingBracketType">The type of the bracket that opens the argument list.</param>
        /// <returns>Returns the opening bracket.</returns>
        private OpenBracketToken CheckMethodOpeningBracket(Element element, CodeUnit parameterList, TokenType openingBracketType)
        {
            Param.AssertNotNull(element, "element");
            Param.AssertNotNull(parameterList, "parameterList");
            Param.Ignore(openingBracketType);

            // Find the opening bracket.
            OpenBracketToken openingBracket = null;

            Token firstDeclarationToken = element.FirstDeclarationToken;
            if (firstDeclarationToken != null)
            {
                Token previous = parameterList.FindPreviousSiblingToken();
                if (previous != null && previous.Is(openingBracketType))
                {
                    openingBracket = (OpenBracketToken)previous;
                }

                if (openingBracket != null)
                {
                    // Find the last word before the opening bracket.
                    Token lastWord = openingBracket.FindPreviousToken();

                    if (lastWord != null && openingBracket.LineNumber != lastWord.LineNumber)
                    {
                        this.AddViolation(
                            element,
                            openingBracket.LineNumber,
                            Rules.OpeningParenthesisMustBeOnDeclarationLine,
                            element.FriendlyTypeText);
                    }
                }
            }

            return openingBracket;
        }
        /// <summary>
        /// Checks the placement and formatting of parameters to a method invocation or a method declaration.
        /// </summary>
        /// <param name="element">The element.</param>
        /// <param name="parameterList">The argument list.</param>
        /// <param name="methodArguments">The arguments or parameters to the method.</param>
        /// <param name="methodStartLineNumber">The line number on which the method begins.</param>
        /// <param name="openBracketType">The type of the argument list opening bracket.</param>
        /// <param name="closeBracketType">The type of the argument list closing bracket.</param>
        private void CheckParameters(
            Element element,
            CodeUnit parameterList,
            IArgumentList methodArguments,
            int methodStartLineNumber,
            TokenType openBracketType,
            TokenType closeBracketType)
        {
            Param.AssertNotNull(element, "element");
            Param.AssertNotNull(parameterList, "parameterList");
            Param.AssertNotNull(methodArguments, "methodArguments");
            Param.AssertGreaterThanZero(methodStartLineNumber, "methodStartLineNumber");
            Param.Ignore(openBracketType);
            Param.Ignore(closeBracketType);

            OpenBracketToken openingBracket = this.CheckMethodOpeningBracket(element, parameterList, openBracketType);

            if (openingBracket != null)
            {
                this.CheckMethodClosingBracket(element, parameterList, openingBracket, closeBracketType, methodArguments);

                if (methodArguments.Count > 0)
                {
                    this.CheckMethodArgumentList(element, parameterList, methodArguments, openingBracket, methodStartLineNumber);
                }
            }
        }
        /// <summary>
        /// Measures the number of lines taken up by comments after the start item before the first word.
        /// </summary>
        /// <param name="start">The start item.</param>
        /// <returns>Returns the number of lines takes up by comments.</returns>
        private static int MeasureCommentLinesAfter(CodeUnit start)
        {
            Param.AssertNotNull(start, "start");

            int lineSpan = 0;

            int previousLineSpan = -1;
            int previousEndLineNumber = -1;
            for (CodeUnit next = start.FindNext(); next != null; next = next.FindNext())
            {
                if (next.Is(LexicalElementType.Comment) || next.Is(CodeUnitType.Attribute))
                {
                    int itemLineSpan = ParameterPrewordOffset(next);

                    if (previousEndLineNumber > 0 && next.LineNumber == previousEndLineNumber && previousLineSpan > 0)
                    {
                        --itemLineSpan;
                    }

                    lineSpan += itemLineSpan;
                    previousLineSpan = itemLineSpan;
                    previousEndLineNumber = next.Location.EndPoint.LineNumber;
                    next = next.FindLast();
                }
                else if (!next.Is(LexicalElementType.WhiteSpace) && 
                    !next.Is(LexicalElementType.EndOfLine) &&
                    !next.Is(CodeUnitType.ParameterList) &&
                    !next.Is(CodeUnitType.ArgumentList) &&
                    !next.Is(CodeUnitType.Parameter) &&
                    !next.Is(CodeUnitType.Argument))
                {
                    break;
                }
            }

            return lineSpan;
        }
        /// <summary>
        /// Measures the number of lines taken up by comments between two tokens.
        /// </summary>
        /// <param name="start">The start token.</param>
        /// <param name="end">The end token.</param>
        /// <param name="includeAttributes">Indicates whether to also count attributes.</param>
        /// <returns>Returns the number of lines takes up by comments.</returns>
        private static int MeasureCommentLinesBetween(CodeUnit start, CodeUnit end, bool includeAttributes)
        {
            Param.AssertNotNull(start, "start");
            Param.AssertNotNull(end, "end");
            Param.Ignore(includeAttributes);

            int lineSpan = 0;

            int previousLineSpan = -1;
            int previousEndLineNumber = -1;
            for (CodeUnit next = start.FindNext(); next != null && next != end; next = next.FindNext())
            {
                if (next.Is(LexicalElementType.Comment) || (next.Is(CodeUnitType.Attribute) && includeAttributes))
                {
                    int itemLineSpan = ParameterPrewordOffset(next);

                    if (previousEndLineNumber > 0 && next.LineNumber == previousEndLineNumber && previousLineSpan > 0)
                    {
                        --itemLineSpan;
                    }

                    lineSpan += itemLineSpan;
                    previousLineSpan = itemLineSpan;
                    previousEndLineNumber = next.Location.EndPoint.LineNumber;
                }
            }

            return lineSpan;
        }
        /// <summary>
        /// Visits one code unit in the document.
        /// </summary>
        /// <param name="codeUnit">The item being visited.</param>
        /// <param name="parentElement">The parent element, if any.</param>
        /// <param name="parentStatement">The parent statement, if any.</param>
        /// <param name="parentExpression">The parent expression, if any.</param>
        /// <param name="parentClause">The parent query clause, if any.</param>
        /// <param name="parentToken">The parent token, if any.</param>
        /// <param name="topLevelElements">The number of classes and namespaces seen in the document.</param>
        /// <returns>Returns true to continue, or false to stop the walker.</returns>
        private bool VisitCodeUnit(
            CodeUnit codeUnit,
            Element parentElement,
            Statement parentStatement,
            Expression parentExpression,
            QueryClause parentClause,
            Token parentToken,
            TopLevelElements topLevelElements)
        {
            Param.AssertNotNull(codeUnit, "codeUnit");
            Param.Ignore(parentElement, parentStatement, parentExpression, parentClause, parentToken);
            Param.AssertNotNull(topLevelElements, "topLevelElements");

            if (codeUnit.CodeUnitType == CodeUnitType.Element)
            {
                return this.VisitElement((Element)codeUnit, parentElement, topLevelElements);
            }
            else if (codeUnit.CodeUnitType == CodeUnitType.Statement)
            {
                return this.VisitStatement((Statement)codeUnit, parentExpression, parentStatement, parentElement);
            }
            else if (codeUnit.CodeUnitType == CodeUnitType.Expression)
            {
                return this.VisitExpression((Expression)codeUnit, parentExpression, parentStatement, parentElement);
            }

            return !this.Cancel;
        }
示例#15
0
 internal static void Violate(this SourceAnalyzer sourceAnalyzer, CsElement element, CodeUnit codeUnit, params object[] args)
 {
     Violate(sourceAnalyzer, element, codeUnit.Location, args);
 }
示例#16
0
        /// <summary>
        /// Records information about the given item, under the given node.
        /// </summary>
        /// <param name="item">The item to record.</param>
        /// <param name="parentNode">The Xml node to record this item beneath.</param>
        /// <returns>Returns the new Xml node describing this item.</returns>
        private static XmlNode RecordItem(CodeUnit item, XmlNode parentNode)
        {
            Param.AssertNotNull(item, "item");
            Param.AssertNotNull(parentNode, "parentNode");

            // Create a new node for this item and add it to the parent.
            XmlNode codeUnitNode = parentNode.OwnerDocument.CreateElement("CodeUnit");
            parentNode.AppendChild(codeUnitNode);

            if (item.Is(CodeUnitType.LexicalElement))
            {
                XmlAttribute text = parentNode.OwnerDocument.CreateAttribute("Text");
                text.Value = ((LexicalElement)item).Text;
                codeUnitNode.Attributes.Append(text);
            }

            XmlAttribute type = parentNode.OwnerDocument.CreateAttribute("Type");
            type.Value = item.GetType().Name;
            codeUnitNode.Attributes.Append(type);

            return codeUnitNode;
        }