Beispiel #1
0
 /// <summary>
 /// Analyzes class declaration.
 /// </summary>
 /// <param name="context">Syntax node analysis context.</param>
 private static void AnalyzeClassDeclaration(SyntaxNodeAnalysisContext context)
 {
     if (BTAnalyzer.IsGenerated(context))
     {
         return;
     }
     BTAnalyzer.AnalyzeSummaryComments(context);
 }
Beispiel #2
0
        /// <summary>
        /// Analyzes items inside methods.
        /// </summary>
        /// <param name="context">Code block analysis context.</param>
        private static void AnalyzeInsideMethod(SyntaxNodeAnalysisContext context)
        {
            if (BTAnalyzer.IsGenerated(context))
            {
                return;
            }

            // Analyze comments inside methods
            BTAnalyzer.AnalyzeInsideMethodComment(context);
            BTAnalyzer.AnalyzeLogicalExpressions(context);
        }
Beispiel #3
0
        /// <summary>
        /// Analyzes empty lines inside blocks.
        /// </summary>
        /// <param name="context">Context.</param>
        private static void AnalyzeBlockEmptyLines(SyntaxNodeAnalysisContext context)
        {
            // Return early
            if (BTAnalyzer.IsGenerated(context))
            {
                return;
            }

            // Get the block
            ClassDeclarationSyntax classDeclarationSyntax = context.Node as ClassDeclarationSyntax;

            // Check method spacing
            SyntaxNode[] nodes    = classDeclarationSyntax.ChildNodes().Where(node => SyntaxKind.BaseList != node.Kind() && SyntaxKind.AttributeList != node.Kind()).ToArray();
            Location     location = default(Location);

            for (int i = 0; i < nodes.Length; i++)
            {
                SyntaxNode method = nodes[i];
                IEnumerable <SyntaxTrivia> trivias = method.GetFirstToken().LeadingTrivia;
                int count = 0;
                int j     = 0;
                foreach (SyntaxTrivia trivia in trivias)
                {
                    if (j == 0)
                    {
                        location = BTAnalyzer.GetLocation(trivia.SyntaxTree, trivia.GetLocation(), Position.Origin);
                        j++;
                    }

                    if (SyntaxKind.EndOfLineTrivia == trivia.Kind())
                    {
                        count++;
                    }
                    else if (!(SyntaxKind.WhitespaceTrivia == trivia.Kind()))
                    {
                        break;
                    }
                }
                if ((i == 0 && count > 0) || (i > 0 && count > 1))
                {
                    context.ReportDiagnostic(Diagnostic.Create(BTAnalyzer.Rule, location, ErrorCode.ExtraLine));
                }
                if (i > 0 && count < 1)
                {
                    context.ReportDiagnostic(Diagnostic.Create(BTAnalyzer.Rule, location, ErrorCode.MissingEmptyLine));
                }
            }


            // Check blocks
            IEnumerable <BlockSyntax> blocks = classDeclarationSyntax.DescendantNodes().Where(node => SyntaxKind.Block == node.Kind()).OfType <BlockSyntax>();

            // Iterate through each block
            foreach (BlockSyntax block in blocks)
            {
                // Get a list of node, single line comment and end of line
                List <Tuple <object, SyntaxKind> > blockObjectList = new List <Tuple <object, SyntaxKind> >();
                foreach (SyntaxNode node in block.ChildNodes())
                {
                    // Check whether the node is a block node
                    bool isBlockNode = node.ChildNodes().Any(nodee => SyntaxKind.Block == nodee.Kind());

                    // Get all trivias
                    SyntaxTrivia[] allTrivias = node.DescendantTrivia().Where(trivia => (SyntaxKind.SingleLineCommentTrivia == trivia.Kind()) ||
                                                                              (SyntaxKind.EndOfLineTrivia == trivia.Kind())).ToArray();

                    // Add trivias before the node
                    foreach (SyntaxTrivia trivia in allTrivias)
                    {
                        if (trivia.Span.End <= node.SpanStart)
                        {
                            blockObjectList.Add(Tuple.Create <object, SyntaxKind>(trivia, trivia.Kind()));
                        }
                    }

                    // Add the node
                    blockObjectList.Add(Tuple.Create <object, SyntaxKind>(node, SyntaxKind.None));

                    // Add trivia after the node
                    foreach (SyntaxTrivia trivia in allTrivias)
                    {
                        if ((trivia.SpanStart >= node.Span.End) && !isBlockNode)
                        {
                            blockObjectList.Add(Tuple.Create <object, SyntaxKind>(trivia, trivia.Kind()));
                        }
                    }

                    // Add an additional end of line trivia for block node
                    if (isBlockNode)
                    {
                        blockObjectList.Add(Tuple.Create <object, SyntaxKind>(null, SyntaxKind.EndOfLineTrivia));
                    }
                }

                // Trim the block object list
                // Remove end of line after a statement
                List <Tuple <object, SyntaxKind> > trimmedBlockObjectList = new List <Tuple <object, SyntaxKind> >();
                for (int i = 0; i < blockObjectList.Count(); i++)
                {
                    if (SyntaxKind.EndOfLineTrivia != blockObjectList[i].Item2)
                    {
                        if ((i + 1 < blockObjectList.Count()) && (SyntaxKind.EndOfLineTrivia == blockObjectList[i + 1].Item2))
                        {
                            trimmedBlockObjectList.Add(blockObjectList[i]);
                            i++;
                            continue;
                        }
                    }
                    trimmedBlockObjectList.Add(blockObjectList[i]);
                }

                // Cannot start with empty lines
                for (int i = 0; i < trimmedBlockObjectList.Count(); i++)
                {
                    if (SyntaxKind.EndOfLineTrivia == blockObjectList[i].Item2)
                    {
                        SyntaxTrivia trivia = (SyntaxTrivia)trimmedBlockObjectList[i].Item1;
                        context.ReportDiagnostic(Diagnostic.Create(BTAnalyzer.Rule, trivia.GetLocation(), ErrorCode.ExtraLine));
                    }
                    else
                    {
                        break;
                    }
                }

                // Check if there is only syntax node inside the block
                bool isOnlySyntaxNode = trimmedBlockObjectList.All(tuple => SyntaxKind.None == tuple.Item2);

                // Statement should have comments before
                for (int i = 0; i < trimmedBlockObjectList.Count(); i++)
                {
                    // Skip nodes
                    while ((i < trimmedBlockObjectList.Count()) && (SyntaxKind.None != trimmedBlockObjectList[i].Item2))
                    {
                        i++;
                    }

                    // Check for missing comment
                    if (i < trimmedBlockObjectList.Count())
                    {
                        if ((((0 < i - 1) && (SyntaxKind.SingleLineCommentTrivia != trimmedBlockObjectList[i - 1].Item2)) || i == 0) && !isOnlySyntaxNode)
                        {
                            SyntaxNode node = (SyntaxNode)trimmedBlockObjectList[i].Item1;
                            context.ReportDiagnostic(Diagnostic.Create(BTAnalyzer.Rule, Location.Create(node.SyntaxTree, new TextSpan(node.SpanStart, 10)), ErrorCode.MissingComment));
                        }
                    }
                    while ((i < trimmedBlockObjectList.Count()) && (SyntaxKind.None == trimmedBlockObjectList[i].Item2))
                    {
                        i++;
                    }

                    // Check for missing empty line
                    if ((i < trimmedBlockObjectList.Count()) && (SyntaxKind.EndOfLineTrivia != trimmedBlockObjectList[i].Item2))
                    {
                        context.ReportDiagnostic(Diagnostic.Create(BTAnalyzer.Rule, ((SyntaxTrivia)trimmedBlockObjectList[i].Item1).GetLocation(), ErrorCode.MissingEmptyLine));
                    }
                }

                // Cannot end with empty lines
                IEnumerable <SyntaxTrivia> triviaBeforeClosingBrackets = block.CloseBraceToken.LeadingTrivia;
                if (1 < triviaBeforeClosingBrackets.Count())
                {
                    context.ReportDiagnostic(Diagnostic.Create(BTAnalyzer.Rule, block.CloseBraceToken.GetLocation(), ErrorCode.UnexpectedComponentsBeforeClosingBracket));
                }
            }
        }