AntiTiming
AntiTiming

Reputation: 2294

How to avoid sonarqube marking a code region as duplicate which is not a (harmful) repetition?

I have the following code setup (not all parts are shown in detail):

There are several specific implementations of AbstractClassToBuild based on different object types.

A simplified example of such an iplementation is the following ClassToBuild. The relevant region which is marked as duplicate by sonarqube for all implementations looks the same for all of these implementations. The following code snippet uses comments to highlight the relevant region:

public final ClassToBuild extends AbstractClassToBuild {

// ... whatever belongs to the class ClassToBuild

// START OF DUPLICATE REGION
public static final class Builder extends AbstractBuilder {

private Builder() {
super();
}

private Builder(Object object) {
super(object);
}

public static final Builder newInstance() {
return new Builder();
}

@Override
public final BuilderInterface cloneInstance() {
return new Builder(this.object);
}

@Override
@SuppressWarnings("unchecked")
protected final <T extends ClassInterface> Class<T> myClass() {
// END OF DUPLICATE REGION
return (Class<T>) ClassToBuild.class;
}

@Override
protected final ClassInterface create() {
return new ClassToBuild(this.object);
}
}

}

IMHO this kind of scenario is a valid, non-repetitive implementation as there is no real (harmful) code duplication because each Builder class belongs to a specific class. Please correct me if you smell a design or implementation issue here.

Technical setup:

Anyways, what can be done to prevent sonarqube marking these regions as duplicate?


Addition:

According to the sonarqube documentation:

"A piece of code is considered as duplicated as soon as there is the same sequence of 10 successive statements whatever the number of tokens and lines."

and the explanation of what a (java) statement is:

"Number of statements as defined in the Java Language Specification but without block definitions. Statements counter gets incremented by one each time a following keyword is encountered: if, else, while, do, for, switch, break, continue, return, throw, synchronized, catch, finally. Statements counter is not incremented by a class, method, field, annotation definition, package declaration and import declaration."

With this, for me an additional question comes up: Does sonarqube mark these region as duplicate by mistake?

Upvotes: 3

Views: 17436

Answers (2)

G. Ann - SonarSource Team
G. Ann - SonarSource Team

Reputation: 22804

Anyways, what can be done to prevent sonarqube marking these regions as duplicate?

On the code side, perhaps you could add some of this boilerplate to the abstract class?

On the SonarQube side, you could update the project settings to Ignore Duplications on those files.

Does sonarqube mark these region as duplicate by mistake?

No. The two sections of documentation use a slightly different meaning of the word "statement". These (admitted) duplications are reported on purpose.

Upvotes: 3

AntiTiming
AntiTiming

Reputation: 2294

In this case, a workaround is to add the specific class prefix to each builder class in the methods 'newInstance()' and 'cloneInstance()', for the example this would be ClassToBuild.. The code will do the same and sonarqube does not complain any more.

The updated example looks like this:

public final ClassToBuild extends AbstractClassToBuild {

// ... whatever belongs to the class ClassToBuild

public static final class Builder extends AbstractBuilder {

private Builder() {
super();
}

private Builder(Object object) {
super(object);
}

public static final ClassToBuild.Builder newInstance() {
return new ClassToBuild.Builder();
}

@Override
public final BuilderInterface cloneInstance() {
return new ClassToBuild.Builder(this.object);
}

@Override
@SuppressWarnings("unchecked")
protected final <T extends ClassInterface> Class<T> myClass() {
return (Class<T>) ClassToBuild.class;
}

@Override
protected final ClassInterface create() {
return new ClassToBuild(this.object);
}
}

}

Upvotes: 1

Related Questions