Skip to content

SONARJAVA-6358 Implement quickfix for S8688#5612

Open
NoemieBenard wants to merge 2 commits intomasterfrom
nb/sonarjava-6358-quickfix-S8688
Open

SONARJAVA-6358 Implement quickfix for S8688#5612
NoemieBenard wants to merge 2 commits intomasterfrom
nb/sonarjava-6358-quickfix-S8688

Conversation

@NoemieBenard
Copy link
Copy Markdown
Contributor

No description provided.

@hashicorp-vault-sonar-prod
Copy link
Copy Markdown
Contributor

hashicorp-vault-sonar-prod Bot commented May 8, 2026

SONARJAVA-6358

@sonar-review-alpha
Copy link
Copy Markdown
Contributor

sonar-review-alpha Bot commented May 8, 2026

Summary

Implements quickfix for rule S8688 (NowWithoutParametersCheck). When developers call .now() on LocalDateTime, ZonedDateTime, etc. without specifying a timezone, the rule now offers an automatic fix that adds ZoneId.systemDefault() as an argument.

Changes:

  • Refactored check to use QuickFixHelper API instead of direct reportIssue()
  • Added computeQuickFix() method that generates the fix suggestion
  • Updated rule metadata from "quickfix: unknown" to "quickfix: covered"
  • Added test cases demonstrating the quickfix for both LocalDateTime.now() and ZonedDateTime.now() scenarios

What reviewers should know

Where to start:

  • Core logic: NowWithoutParametersCheck.java - see the refactored onMethodInvocationFound() method and new computeQuickFix() helper
  • Test coverage: NowWithoutParametersCheckSample.java - two test cases with quickfix metadata showing expected transformations

Key points:

  • The quickfix replaces the entire .now() argument list with (ZoneId.systemDefault()) — verify this is the intended fix for both LocalDateTime and ZonedDateTime variants
  • Test samples use the standard quickfix annotation format (// fix@qf1, // edit@qf1) to declare expected transformations
  • The text edit targets the argument range (positions 47-49 and 41-43 in the samples), not the method name itself

Non-obvious decisions:

  • The quickfix message is generic ("Explicitly use the system default...") for both cases, which may be intentional for consistency
  • The fix always adds ZoneId.systemDefault() rather than leaving it to user choice

  • Generate Walkthrough
  • Generate Diagram

🗣️ Give feedback

@sonarqube-next
Copy link
Copy Markdown

sonarqube-next Bot commented May 8, 2026

Copy link
Copy Markdown
Contributor

@sonar-review-alpha sonar-review-alpha Bot left a comment

Choose a reason for hiding this comment

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

One real bug needs fixing before merge: the quickfix doesn't add the import java.time.ZoneId; statement when it is missing from the user's file. The test passes only because the sample file already imports ZoneId (line 13). In real user code that only calls LocalDateTime.now() without any other ZoneId usage, the applied fix will produce non-compiling code.

🗣️ Give feedback

Comment on lines +61 to +63
private static JavaQuickFix computeQuickFix(MethodInvocationTree mit) {
return JavaQuickFix.newQuickFix("Explicitly use the system default by adding \"ZoneId.systemDefault()\"")
.addTextEdit(JavaTextEdit.replaceTree(mit.arguments(), "(ZoneId.systemDefault())"))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The quickfix inserts ZoneId.systemDefault() as a literal string but never adds import java.time.ZoneId;. Users whose file doesn't already import ZoneId will get non-compiling code after applying the fix.

The test passes today only because NowWithoutParametersCheckSample.java happens to import ZoneId already (line 13). A new quickfix-specific test file without that import would surface this failure.

The established pattern in this codebase uses QuickFixHelper.newImportSupplier to conditionally inject the import. See ReturnEmptyArrayNotNullCheck (lines 45, 178–182) for the reference implementation. The fix here requires:

  1. Add a QuickFixHelper.ImportSupplier importSupplier field (lazily initialised, reset in scanFile).
  2. Pass it (or context) into computeQuickFix so it can call importSupplier.newImportEdit("java.time.ZoneId").ifPresent(builder::addTextEdit).
  • Mark as noise

Comment on lines 30 to 31
.withCheck(new NowWithoutParametersCheck())
.verifyIssues();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The quickfix annotations in the sample file (fix@qf1, edit@qf1, etc.) are only validated when the verifier runs against a file that does not pre-import ZoneId. Add a dedicated quickfix test file (without import java.time.ZoneId;) and a separate test method for it — following the pattern in ReturnEmptyArrayNotNullCheckTest.quick_fixes(). This will catch the missing-import bug described in the check implementation comment, and matches the convention used by other checks with quickfixes.

  • Mark as noise

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