"Method Overrides should not change contracts" does not catch all cases

  • Using SonarQube + GitHub PR integration
  • S2638 will enforce coherent contracts up the inheritance hierarchy but not down

To reproduce, create an interface with two implementations:

interface Foo {
  Integer add(@Nonnull Integer num1, @Nonnull Integer num2);
}

class FooA implements Foo {
  Integer add(@Nonnull Integer num1, @Nonnull Integer num2) { return num1 + num2; }
}

class FooB implements Foo {
  Integer add(@Nonnull Integer num1, @Nonnull Integer num2) { return 0; }
}

Now, create a PR that just changes FooB to trigger S2638:

class FooB implements Foo {
  Integer add(@Nullable Integer num1, @Nullable Integer num2) { return 0; }
}

This correctly triggers S2638 to which a developer can “fix” by changing the interface:

interface Foo {
  Integer add(@Nullable Integer num1, @Nullable Integer num2);
}

However, FooA is now left in an inconsistent state that does not match Foo.

Hi,
Sorry for the vert late reply.
Only files modified in the pull request are shown in SonarQube.
So if you only modify the base class, the derived classes (and their potential issues) won’t be shown in the pull request.
Once you merge the code, the issue might come up in the target branch, where all files are analyzed and shown.
It’s a limitation we currently have that we are aware of.