This version of the SonarQube documentation is no longer maintained. It relates to a version of SonarQube that is not active.

See latest version
Start Free
9.6 | Extension Guide | Developing a plugin | Executable lines

Executable lines

On this page

These are the guidelines that SonarSource uses internally when defining executable lines for a language. Community plugins are not required to adhere to these guidelines. They are provided here only in case they are useful.

Things that are executable

Executable lines data is used to calculate missing test coverage for files that are not included in coverage reports. Ideally, executable line counts will be at or just under what coverage engines would calculate.

Generally, each line containing a statement should count as an executable line, with the exception that compound statements ({}) are ignored, although their contents are not. So, for example:

void doTheThing ()        // +0
{                         // +0
  String fname="Finn";    // +1
  etc();                  // +1
}                         // +0

Things that are ignored

!Statement: +0

Since some coverage engines mark these things as executable, it's worth stating explicitly that we will ignore them:

  • the method signature of a method definition.
  • the method signature of a method definition

Imports, Declarations: +0

Imports, package and namespace statements, declarations, and a few other things demonstrated below are ignored.

package foo;     // +0
namespace bar {  // +0
  ...
}
  
import java.util.ArrayList;  // +0
#include <stdio>             // +0
  
public interface FooFace {  // +0
  void doFoo();             // +0
}
public class Foo1 implements FooFace {  // +0
  private String name;                  // +0
}
struct PairWithOperator { // +0
  int x;                  // +0
  int y;                  // +0
  
  bool operator==(PairWithOperator rhs) const {  // +0
    return x == rhs.x && y == rhs.y;             // +1
  }
}
  
class C {
  C(const C&) =default;  // +0 (explicit inheritance of parent method)
}
 
using Vec = std::vector<T,MyAllocator<T>>;       // +0
  
static {                 // +0
  ...
}
 
01  ERROR-MESSAGE.                                      *> +0
        02  ERROR-TEXT  PIC X(132) OCCURS 10 TIMES      *> +0
                                   INDEXED BY ERROR-INDEX.
77  ERROR-TEXT-LEN      PIC S9(9)  COMP VALUE +132.     *> +0

Location

The presence of executable code on a line makes the entire line executable. If a statement is split over multiple lines, the line to be marked executable is the first one with executable code. Given that, a for loop is considered executable:

for         // +1
  (         // +0
   int i=0; // +0
   i < 10;  // +0
   i++      // +0
  )         // +0
{           // +0
}

Regardless of the number of lines across which nested statements are spread, the executable line count should only be incremented by one, since typically the execution of one naturally follows from the other.

foo(1, bar());  // +1
foo(1,          // +1
    bar());     // +0

We ignore here the possibility that bar() could throw an exception, preventing foo from being executed.

Exceptions

Python

# pragma: no cover exempts a block from coverage. For example:

Exempt a block of Python code from coverage

JavaScript

We mark variable declarations as executable. For example:

var a;  // +1

Was this page helpful?

© 2008-2024 SonarSource SA. All rights reserved. SONAR, SONARSOURCE, SONARLINT, SONARQUBE, SONARCLOUD, and CLEAN AS YOU CODE are trademarks of SonarSource SA.

Creative Commons License