Duplication False Positve in Descendant classes (plus Case Sensitifity)


This feels like bug, but maybe it’s a configuration issue, but when dealing with descendant classes from an abstract there is a pattern that I’ve noticed:

(forgive the pseudo-code, but the replicating is very easy)

abstract CodeGenBase 

protected abstract GenericTypeStart {get;}
protected abstract GenericTypeEnd {get;}


CodeGenVb : CodeGenBase
types = {typeof(int), typeof(uint), typeof(string)}
names = {"Integer", "UInteger", "String"}

protected override GenericTypeStart => "(Of ";
protected override GenericTypeEnd => ")";

CodeGenCs : CodeGenBase
types = {typeof(int), typeof(uint), typeof(string)}
names = {"int, "uint", "string"}

protected override GenericTypeStart => "<";
protected override GenericTypeEnd => ">";

It’s a paltry example, but this in an abstract class being implemented for two different scenarios, albeit similar, but still unique in their own right.

The fact that GenericTypeStart/End exist in both is because they’re abstract, and the lines are not duplicated just the property def, but the value is different for both, so part of the line is duplicated by necessity of abstract implementations, but the entire line is not duplicate.

Similarly the “names” constant exists in both, but has different values in each of the descendants.

Because the values are different, even unto the simple case sensitivity differentiation between VB and C# these are considered to be duplicate lines. One Class create VB code, the other Creates C#, so Void and void may mean the same thing, but they are distinctly different and not subject to being identified as code duplication.

I don’t know if there is a case sensitive configuration to the SonarQube scanner, but especially when dealing with string values ("") and the c# language, case sensitivity should be enabled in duplicate code analysis. As well, abstract base classes should be a factor in the determination. Abstract methods and properties should never be considered in terms of duplication, especially when they return different values.

Jaeden “Sifo Dyas” al’Raec Ruiner

  • Version 6.7.5 (build 38563)

hi @JaedenRuiner - what’s the version of the sonarCsharp analyzer you are using? I believe Version 6.7.5 is the SQ version, right?

Also, could you please tell what the exact problem is? What is marked a duplicate of what? What is actual and what is expected?

Um, the sonarscanner is

As for you second question, um reread the above message. That describes exactly what’s happening and what it should be doing. SpmarQube is declaring the "override GenericType* property signatures as duplicate code. but there is no way to resolve that “duplicate”, because they cannot be considered duplicates given their base parent has those properties declared abstract. The expected behavior is with abstract members of abstract classes, the contents of the method/property must be evaluated for the duplicate, and could be implemented in an intermediary class. However, If the contents of the property/method is different (as with the above case) the method/property signature definition cannot be flagged as duplicate because the duplication can never be resolved. You will always have that duplicate signature for abstract methods/properties.

Ok, I was able to reproduce - the gray line on the left marks them as duplicates.


I opened https://github.com/SonarSource/sonar-dotnet/issues/2614 to track this issue.

What is interesting is that in our sonar-dotnet analyzer we have many abstract classes but different use cases. For example, BooleanCheckInvertedBase which is implemented:

The links above take you to the Duplicated Lines measure on SonarCloud for these classes.

There are some abstract properties and fields which are marked as duplications.

CSharp analyzer
VB .NET analyzer

Where the string is not equal (<> vs !=), there is no duplication highlighted by the bar on the left. So this is interesting, as not all the times lines are marked as duplicates.

Thanks for reporting it, @JaedenRuiner