Skip to content

SONARJAVA-6827: Implement S9357 Anonymous classes on functional interfaces should be lambdas - #5995

Draft
romainbrenguier wants to merge 1 commit into
masterfrom
romain/new-rule-s9357-sonarjava-6827
Draft

SONARJAVA-6827: Implement S9357 Anonymous classes on functional interfaces should be lambdas#5995
romainbrenguier wants to merge 1 commit into
masterfrom
romain/new-rule-s9357-sonarjava-6827

Conversation

@romainbrenguier

Copy link
Copy Markdown
Contributor

Summary

  • Implements rule S9357 which detects anonymous inner classes implementing functional interfaces that can be replaced with lambda expressions
  • Mirrors the detection logic of existing rule S1604 (AnonymousClassShouldBeLambdaCheck) but with scope "All" (main + test code) instead of "Main" only
  • Includes comprehensive test coverage for noncompliant patterns (simple SAM, inherited interfaces, redeclared methods) and compliant patterns (abstract classes, this usage, checked exceptions, annotations, default methods, recursion, generic methods, enum constants)

Test plan

  • Unit tests pass with semantic analysis (Java 8)
  • Unit tests pass without semantic analysis
  • CI pipeline passes
  • Ruling tests verify no unexpected regressions

🤖 Generated with Claude Code

…faces should be lambdas

Detects anonymous inner classes implementing functional interfaces (single
abstract method) that can be replaced with lambda expressions. Mirrors the
detection logic of S1604 but applies to all code (main and test scope).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@hashicorp-vault-sonar-prod

hashicorp-vault-sonar-prod Bot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

SONARJAVA-6827

Comment on lines +43 to +57
public class AnonymousClassOnFunctionalInterfaceCheck extends BaseTreeVisitor implements JavaFileScanner, JavaVersionAwareVisitor {

private static final String JAVA_LANG_OBJECT = "java.lang.Object";
private JavaFileScannerContext context;
private final Set<IdentifierTree> enumConstants = new HashSet<>();

@Override
public boolean isCompatibleWithJavaVersion(JavaVersion version) {
return version.isJava8Compatible();
}

@Override
public void scanFile(JavaFileScannerContext context) {
this.context = context;
enumConstants.clear();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Quality: New check duplicates S1604 logic verbatim

AnonymousClassOnFunctionalInterfaceCheck is a byte-for-byte copy of AnonymousClassShouldBeLambdaCheck (S1604), differing only in the @rule key and class name. This duplicates ~150 lines including the UsesThisInstanceVisitor, isSAM/hasSingleAbstractMethodInHierarchy logic, so any future bug fix or improvement must be applied twice and will drift. Extract the shared detection logic into a common base/utility class that both S1604 and S9357 delegate to, so the two rules only differ in their @rule key and scope metadata.

Was this helpful? React with 👍 / 👎

"defaultSeverity": "Major",
"ruleSpecification": "RSPEC-9357",
"sqKey": "S9357",
"scope": "All",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Bug: S9357 double-reports with S1604 on main code

S9357 has scope "All" (main + test) while S1604 has scope "Main", and both implement identical detection with an identical message. When both rules are active in a quality profile, every anonymous-class-to-lambda opportunity in main code will be flagged twice (once as S1604, once as S9357), producing duplicate issues for users. Confirm this is intended; if S9357 is only meant to extend S1604's coverage to test code, its scope/activation should avoid overlapping with S1604 on main code (or S1604 should be deprecated in favor of S9357).

Was this helpful? React with 👍 / 👎

@gitar-bot

gitar-bot Bot commented Aug 21, 2026

Copy link
Copy Markdown
CI failed: Integration test failures in JavaRulingTest due to issue differences (42 differences on Windows and diff reports on Linux) caused by the newly introduced rule S9357.

Overview

All 3 analyzed CI logs across Linux and Windows runners failed during the ruling integration tests (JavaRulingTest) because introducing the new rule S9357 ("Anonymous classes on functional interfaces should be lambdas") produced a mismatch between the actual analysis results and the expected reference outputs.

Failures

Ruling Integration Test Mismatch (confidence: high)

  • Type: test
  • Affected jobs: 96823725977, 96823725988, 96823725984
  • Related to change: yes
  • Root cause: The new rule S9357 flags anonymous classes that can be converted to lambdas across the ruling integration test suite, causing 42 issue differences and test assertions to fail against the outdated expected test resources.
  • Suggested fix: Review the generated diff reports and update the expected test resources/dumps in its/ruling/src/test/resources to incorporate the new findings for rule S9357.

Summary

  • Change-related failures: 3 integration test failures directly caused by the new rule implementation producing different analysis output than expected.
  • Infrastructure/flaky failures: None.
  • Recommended action: Verify the correctness of the findings produced by rule S9357 and update the ruling test reference files accordingly.
Code Review ⚠️ Changes requested 0 resolved / 2 findings

Implements rule S9357 to detect anonymous classes on functional interfaces, but AnonymousClassOnFunctionalInterfaceCheck duplicates S1604 logic verbatim and double-reports on main code.

⚠️ Quality: New check duplicates S1604 logic verbatim

📄 java-checks/src/main/java/org/sonar/java/checks/AnonymousClassOnFunctionalInterfaceCheck.java:43-57

AnonymousClassOnFunctionalInterfaceCheck is a byte-for-byte copy of AnonymousClassShouldBeLambdaCheck (S1604), differing only in the @Rule key and class name. This duplicates ~150 lines including the UsesThisInstanceVisitor, isSAM/hasSingleAbstractMethodInHierarchy logic, so any future bug fix or improvement must be applied twice and will drift. Extract the shared detection logic into a common base/utility class that both S1604 and S9357 delegate to, so the two rules only differ in their @Rule key and scope metadata.

⚠️ Bug: S9357 double-reports with S1604 on main code

📄 sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S9357.json:17 📄 java-checks/src/main/java/org/sonar/java/checks/AnonymousClassOnFunctionalInterfaceCheck.java:74-76

S9357 has scope "All" (main + test) while S1604 has scope "Main", and both implement identical detection with an identical message. When both rules are active in a quality profile, every anonymous-class-to-lambda opportunity in main code will be flagged twice (once as S1604, once as S9357), producing duplicate issues for users. Confirm this is intended; if S9357 is only meant to extend S1604's coverage to test code, its scope/activation should avoid overlapping with S1604 on main code (or S1604 should be deprecated in favor of S9357).

🤖 Prompt for agents
Code Review: Implements rule S9357 to detect anonymous classes on functional interfaces, but AnonymousClassOnFunctionalInterfaceCheck duplicates S1604 logic verbatim and double-reports on main code.

1. ⚠️ Quality: New check duplicates S1604 logic verbatim
   Files: java-checks/src/main/java/org/sonar/java/checks/AnonymousClassOnFunctionalInterfaceCheck.java:43-57

   AnonymousClassOnFunctionalInterfaceCheck is a byte-for-byte copy of AnonymousClassShouldBeLambdaCheck (S1604), differing only in the @Rule key and class name. This duplicates ~150 lines including the UsesThisInstanceVisitor, isSAM/hasSingleAbstractMethodInHierarchy logic, so any future bug fix or improvement must be applied twice and will drift. Extract the shared detection logic into a common base/utility class that both S1604 and S9357 delegate to, so the two rules only differ in their @Rule key and scope metadata.

2. ⚠️ Bug: S9357 double-reports with S1604 on main code
   Files: sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S9357.json:17, java-checks/src/main/java/org/sonar/java/checks/AnonymousClassOnFunctionalInterfaceCheck.java:74-76

   S9357 has scope "All" (main + test) while S1604 has scope "Main", and both implement identical detection with an identical message. When both rules are active in a quality profile, every anonymous-class-to-lambda opportunity in main code will be flagged twice (once as S1604, once as S9357), producing duplicate issues for users. Confirm this is intended; if S9357 is only meant to extend S1604's coverage to test code, its scope/activation should avoid overlapping with S1604 on main code (or S1604 should be deprecated in favor of S9357).

Implementation Status ✅ 1 / 1 issues implemented
SONARJAVA-6827 — 1 / 1 objectives

The PR successfully implements the S9357 rule checking for anonymous classes on functional interfaces that should be lambdas, including the rule implementation, rule metadata, localization files, and corresponding test cases.

✅ 1 complete
  • ✅ Implement rule S9357 to detect anonymous classes on functional interfaces that should be lambdas

Tip

Comment Gitar fix CI or enable auto-apply: gitar auto-apply:on

Options

Auto-apply is off → Gitar will not commit updates to this branch.
Display: compact → Showing less information.
Unblock → Override a blocking verdict and allow merging.

Comment with these commands to change the behavior for this request:

Auto-apply Compact Unblock
gitar auto-apply:on         
gitar display:verbose         
gitar unblock         

Was this helpful? React with 👍 / 👎 | Gitar

@datadog-sonarsource

datadog-sonarsource Bot commented Aug 21, 2026

Copy link
Copy Markdown

Pipelines

⚠️ Warnings

🚦 4 Pipeline jobs failed

Build | Ruling QA (warp-custom-ubuntu-24-04, only-sonarqube-project, LATEST_RELEASE)

View in Datadog · View in GitHub Actions

1 failed test. AssertionError: Expecting empty but was: "Issues differences: 42" in JavaRulingTest.sonarqube_server.

Build | Ruling QA (warp-custom-ubuntu-24-04, without-sonarqube-project, LATEST_RELEASE)

View in Datadog · View in GitHub Actions

4 failed tests due to assertion errors indicating issues differences: 9, 35, 2, and 84

Build | Ruling QA (warp-custom-windows-2022-l, without-sonarqube-project, LATEST_RELEASE)

View in Datadog · View in GitHub Actions

4 failed tests in JavaRulingTest due to assertion errors: issues differences not empty.

View all 4 failed jobs.

Useful? React with 👍 / 👎

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: d439596 | Docs | View more details | Give us feedback!

@sonarqube-next

Copy link
Copy Markdown
Contributor

Quality Gate failed Quality Gate failed

Failed conditions
54.7% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube

@github-actions

Copy link
Copy Markdown
Contributor

Ruling needs updating. A fix PR has been created: #5996

Please review and merge it into your branch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant