Contenuto principale

Detect Multiline Comments That Start on an Expression Line

This example shows how to use Polyspace Query Language (PQL) to check for violation of this rule: If a comment exists on the same line as an expression, that comment shall exist entirely on that line.

This topic focuses on application of PQL. For more details about creating syntax defect checkers, see Detect Syntactic Issues Using Polyspace Query Language Syntactic Classes.

Analyze Rule

Analyze the rule and define components of the rule that you implement in PQL.

  • Comment — You can identify comments using the class Comment. You can get the nodes where the comment starts and ends by using the nodeLocation predicate.

  • Span of the comment — The rule states that the comment must exist entirely on one line if it exists on the same line as an expression. The span of the comment can be verified by comparing the starting and ending position of the comment.

  • Expression — The rule is specifically about comments that start on the same line as an expression. It is not explicitly stated what as expression means. In this implementation, assume an expression includes these classes:

Implement Rule in PQL

To implement the rule in PQL, start by creating a helper predicate that identifies the expression nodes:

#[NoInline]
predicate isStatement(Cpp.Node.Node &node) {
	return (Cpp.ExpressionStatement.is(&expression) and expression.toNode(&node))
        or (Cpp.InitDeclarator.is(&initDeclarator) and initDeclarator.toNode(&node))
        or (Cpp.GotoStatement.is(&gotoStatement) and gotoStatement.toNode(&node))
}
Then, define a defect that:

  • Identifies the statement node

  • Finds comments and their locations.

  • Checks if a comment starts on the same line as the statement node.

  • Reports a violation if, for these comments, the starting and ending are on the same line.

defect MultilineCommentForAnExpression =
		when isStatement(&stmtNode)
			and stmtNode.nodeLocation(&stmtFile, &stmtStartLine, &, &, &, &, &)
			and Cpp.Comment.is(&comment)
			and comment.nodeLocation(&file, &commentStartLine, &commentStartColumn, &commentEndLine, &, &, &)
			and commentStartLine != commentEndLine
			and file == stmtFile
			and commentStartLine == stmtStartLine
        raise "Commenting expression on multiple lines."
        at {file , commentStartLine , commentStartColumn }

Test Defect

To test and verify the defect,

  1. Initialize a test standard in a writable location:

    polyspace-query-language init

  2. In main.pql, insert the defect in a test standard:

    package main
    
    // Main PQL file defines the catalog of your PQL project.
    // The catalog is a collection of sections.
    catalog PQL_Expression_example = {
    	#[Description("MySection")]
        section mysection = {
            #[Description("myRule"), Id(Rule1)]
            rule myRule = {
                defect MultilineCommentForAnExpression =
    		when isStatement(&stmtNode)
    			and stmtNode.nodeLocation(&stmtFile, &stmtStartLine, &, &, &, &, &)
    			and Cpp.Comment.is(&comment)
    			and comment.nodeLocation(&file, &commentStartLine, &commentStartColumn, &commentEndLine, &, &, &)
    			and commentStartLine != commentEndLine
    			and file == stmtFile
    			and commentStartLine == stmtStartLine
            raise "Commenting expression on multiple lines."
            at {file , commentStartLine , commentStartColumn }
            }
        }
    }
    
    #[NoInline]
    predicate isStatement(Cpp.Node.Node &node) {
    	return (Cpp.ExpressionStatement.is(&expression) and expression.toNode(&node))
            or (Cpp.InitDeclarator.is(&initDeclarator) and initDeclarator.toNode(&node))
            or (Cpp.GotoStatement.is(&gotoStatement) and gotoStatement.toNode(&node))
    }
    
    

  3. Package the standard in a pschk file:

    polyspace-query-language package

  4. Create example.cpp in the same folder:

    /* If a comment exists on the same line as an expression, that comment shall exist entirely on that line.
     */
    
    /* expect-0-Rule1
     */
    int test1(int x) {
        int i = x + 3; /* expect-1-Rule1
                        */
        int j = x + 2; /* expect-0-Rule1 */
        goto eof;      /* expect-1-Rule1
                        */
        /* expect-0-Rule1 */ return i * j;
    eof:
        return 0;
    }
    This code explicitly states where a violation of the rule is expected using annotation expect-1-Rule1. Absence of the violation is also annotated using expect-0-Rule1.

  5. Run a test for the defect on the example code:

    polyspace-query-language test example.cpp
    The test verifies the expected violations as well as the expected absence of violations:
    Number of actual defects: 2
    Number of expected annotations: 5 (including 3 expected absence of defects).
    _______________________________________________
      Checking expected defects with actuals...
      -----------------------------------------
    _______________________________________________
      Looking for unexpected defects...
    -------------------------------------------
    _______________________________________________
    Tests passed

See Also

Topics