Skip to content

SONARPHP-1816 fix: resolve 5 SonarQube issues with visibility and singleton pattern#1698

Closed
sonarqube-agent[bot] wants to merge 1 commit into
masterfrom
remediate-master-20260514-050253-eaddd65d
Closed

SONARPHP-1816 fix: resolve 5 SonarQube issues with visibility and singleton pattern#1698
sonarqube-agent[bot] wants to merge 1 commit into
masterfrom
remediate-master-20260514-050253-eaddd65d

Conversation

@sonarqube-agent
Copy link
Copy Markdown
Contributor

Removes unnecessary 'public' modifiers from JUnit5 lifecycle methods in three test classes and converts two enum-based Singletons to final utility classes. These changes improve code quality by following JUnit5 conventions and eliminating the enum Singleton pattern where it was unnecessary.

View Project in SonarCloud


Fixed Issues

java:S5786 - Remove this 'public' modifier. • INFOView issue

Location: php:php-checks/src/test/java/org/sonar/php/checks/NonLFCharAsEOLCheckTest.java:41

Why is this an issue?

JUnit5 is more tolerant regarding the visibility of test classes and methods than JUnit4, which required everything to be public. Test classes and methods can have any visibility except private. It is however recommended to use the default package visibility to improve readability.

What changed

This hunk removes the 'public' modifier from the setUp() lifecycle method in the JUnit5 test class NonLFCharAsEOLCheckTest, changing it from 'public void setUp()' to 'void setUp()'. JUnit5 test classes and lifecycle methods should use default package visibility rather than 'public', as JUnit5 does not require public visibility. This directly addresses the code smell about unnecessary 'public' modifier on a JUnit5 lifecycle method at line 41 of NonLFCharAsEOLCheckTest.java.

--- a/php-checks/src/test/java/org/sonar/php/checks/NonLFCharAsEOLCheckTest.java
+++ b/php-checks/src/test/java/org/sonar/php/checks/NonLFCharAsEOLCheckTest.java
@@ -41,1 +41,1 @@ class NonLFCharAsEOLCheckTest {
-  public void setUp() {
+  void setUp() {
java:S5786 - Remove this 'public' modifier. • INFOView issue

Location: php:php-frontend/src/test/java/org/sonar/php/tree/visitors/PHPVisitorCheckTest.java:66

Why is this an issue?

JUnit5 is more tolerant regarding the visibility of test classes and methods than JUnit4, which required everything to be public. Test classes and methods can have any visibility except private. It is however recommended to use the default package visibility to improve readability.

What changed

This hunk removes the 'public' modifier from the setUp() lifecycle method in the JUnit5 test class PHPVisitorCheckTest. JUnit5 test classes and methods should use default package visibility instead of 'public' for better readability and convention compliance. By changing 'public void setUp()' to 'void setUp()', the unnecessary 'public' modifier is removed, resolving the code smell.

--- a/php-frontend/src/test/java/org/sonar/php/tree/visitors/PHPVisitorCheckTest.java
+++ b/php-frontend/src/test/java/org/sonar/php/tree/visitors/PHPVisitorCheckTest.java
@@ -66,1 +66,1 @@ class PHPVisitorCheckTest {
-  public void setUp() throws Exception {
+  void setUp() throws Exception {
java:S6548 - An Enum-based Singleton implementation was detected. Make sure the use of the Singleton pattern is required and an Enum-based implementation is the right one for the context. • INFOView issue

Location: php:php-frontend/src/main/java/org/sonar/php/symbols/BuiltinSymbolData.java:32

Why is this an issue?

While the Singleton pattern can be useful in certain situations, overusing it can have several drawbacks:

What changed

Changes the BuiltinSymbolData from an enum to a final class, directly eliminating the Enum-based Singleton pattern that was flagged by the static analysis rule java:S6548. This removes the Singleton design pattern entirely by converting to a utility class with static methods.

--- a/php-frontend/src/main/java/org/sonar/php/symbols/BuiltinSymbolData.java
+++ b/php-frontend/src/main/java/org/sonar/php/symbols/BuiltinSymbolData.java
@@ -32,1 +32,1 @@ import static org.sonar.plugins.php.api.symbols.QualifiedName.qualifiedName;
-public enum BuiltinSymbolData {
+public final class BuiltinSymbolData {
java:S6548 - An Enum-based Singleton implementation was detected. Make sure the use of the Singleton pattern is required and an Enum-based implementation is the right one for the context. • INFOView issue

Location: php:php-frontend/src/main/java/org/sonar/php/symbols/UnknownLocationInFile.java:21

Why is this an issue?

While the Singleton pattern can be useful in certain situations, overusing it can have several drawbacks:

What changed

This hunk converts the UnknownLocationInFile from an enum to a final class, directly addressing the static analysis warning about an Enum-based Singleton implementation. By changing from 'public enum UnknownLocationInFile' to 'public final class UnknownLocationInFile', the code no longer uses the Enum Singleton pattern that was flagged by the scanner.

--- a/php-frontend/src/main/java/org/sonar/php/symbols/UnknownLocationInFile.java
+++ b/php-frontend/src/main/java/org/sonar/php/symbols/UnknownLocationInFile.java
@@ -21,1 +21,1 @@ import org.sonar.plugins.php.api.visitors.LocationInFile;
-public enum UnknownLocationInFile implements LocationInFile {
+public final class UnknownLocationInFile implements LocationInFile {
java:S5786 - Remove this 'public' modifier. • INFOView issue

Location: php:php-frontend/src/test/java/org/sonar/php/highlighter/SymbolHighlighterTest.java:54

Why is this an issue?

JUnit5 is more tolerant regarding the visibility of test classes and methods than JUnit4, which required everything to be public. Test classes and methods can have any visibility except private. It is however recommended to use the default package visibility to improve readability.

What changed

This hunk removes the 'public' modifier from the setUp() lifecycle method in the JUnit5 test class SymbolHighlighterTest. JUnit5 test classes and lifecycle methods should use default package visibility rather than 'public' for better readability and convention compliance. By changing 'public void setUp()' to 'void setUp()', the unnecessary 'public' modifier is removed as recommended by the JUnit5 User Guide.

--- a/php-frontend/src/test/java/org/sonar/php/highlighter/SymbolHighlighterTest.java
+++ b/php-frontend/src/test/java/org/sonar/php/highlighter/SymbolHighlighterTest.java
@@ -54,1 +54,1 @@ class SymbolHighlighterTest {
-  public void setUp() throws IOException {
+  void setUp() throws IOException {

Have a suggestion or found an issue? Share your feedback here.


SonarQube Remediation Agent uses AI. Check for mistakes.

Fixed issues:
- AZkoVAGjIsbR56mqmhMT for java:S5786 rule
- AZkoVAM1IsbR56mqmhMt for java:S5786 rule
- AZkoU_MlIsbR56mqmhHL for java:S5786 rule
- AZkoVACCIsbR56mqmhL6 for java:S6548 rule
- AZkoVACgIsbR56mqmhL8 for java:S6548 rule

Generated by SonarQube Agent (task: 76ff4569-725c-4b15-bafc-970165160f40)
@hashicorp-vault-sonar-prod hashicorp-vault-sonar-prod Bot changed the title fix: resolve 5 SonarQube issues with visibility and singleton pattern SONARPHP-1816 fix: resolve 5 SonarQube issues with visibility and singleton pattern May 14, 2026
@hashicorp-vault-sonar-prod
Copy link
Copy Markdown
Contributor

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

SONARPHP-1816

@sonarqube-next
Copy link
Copy Markdown

Quality Gate failed Quality Gate failed

Failed conditions
2 New issues

See analysis details on SonarQube

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE SonarQube for IDE

@sonar-review-alpha
Copy link
Copy Markdown

sonar-review-alpha Bot commented May 14, 2026

Summary

⚠️ The PR description exceeded the analysis limit and was truncated. The review may not reflect all context.

This PR fixes 5 SonarQube code quality issues through straightforward refactoring:

Test visibility (3 files): Removed public modifiers from @BeforeEach setUp() methods in NonLFCharAsEOLCheckTest, PHPVisitorCheckTest, and SymbolHighlighterTest. JUnit5 doesn't require public visibility for test lifecycle methods; package-private is the recommended convention.

Enum-to-utility class (2 files): Converted UnknownLocationInFile and BuiltinSymbolData from enum singletons to final classes with static fields/methods. The enum pattern was unnecessary for these utility-style classes.

All changes are safe refactoring with no behavioral impact—the static instances and methods provide identical access patterns.

What reviewers should know

Key files to review:

  1. UnknownLocationInFile.java: Enum → final class with static UNKNOWN_LOCATION instance. The existing static import in BuiltinSymbolData (line 29) still works correctly.

  2. BuiltinSymbolData.java: Enum with single BUILTINS instance → final class with static CLASS_SYMBOLS_BY_QUALIFIED_NAME map and static classSymbolData() method. Note that init() is now static and called during class initialization.

  3. ProjectSymbolData.java: Updated to call BuiltinSymbolData.classSymbolData() directly as a static method (line 48). The old instance field builtinSymbolData was removed.

  4. Test files (NonLFCharAsEOLCheckTest, PHPVisitorCheckTest, SymbolHighlighterTest): These changes are trivial—just remove public from setUp() signatures. No logic changes.

What to verify: Check that the enum-to-class conversions don't break any other callers of these classes. BuiltinSymbolData.BUILTINS and UnknownLocationInFile.UNKNOWN_LOCATION should have been the only usage points (and they're updated here).


  • Generate Walkthrough
  • Generate Diagram

🗣️ Give feedback

Copy link
Copy Markdown

@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.

The test-visibility changes are correct JUnit 5 idiom and the BuiltinSymbolData refactor is clean. However, the UnknownLocationInFile conversion introduces a subtle but real bug: the constructor is package-private instead of private, which breaks the singleton guarantee that the rest of the codebase relies on.

🗣️ Give feedback

Comment on lines +24 to +26

UnknownLocationInFile() {
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The constructor is package-private, not private. This breaks the singleton guarantee.

PreciseIssue.java uses identity comparison (==) against UnknownLocationInFile.UNKNOWN_LOCATION, so correctness depends on there being exactly one instance. With a package-private constructor, any class in the org.sonar.php.symbols package (e.g. a future SymbolFactory) can call new UnknownLocationInFile() and produce a second instance that is ==-unequal to UNKNOWN_LOCATION, silently causing PreciseIssue.secondary() to accept locations it should skip.

The enum pattern gave this for free; the manual conversion must replicate it explicitly.

Suggested change
UnknownLocationInFile() {
}
private UnknownLocationInFile() {
}
  • Mark as noise

@sonarqube-agent
Copy link
Copy Markdown
Contributor Author

SonarQube Remediation Agent could not fix the CI failures.

Task: 17e13f76-02ed-44a1-b258-3d9c5f2253cf
Branch: remediate-master-20260514-050253-eaddd65d
Attempt: 1 (of 3)

CI failure fix failed: No CI logs could be downloaded for any failed check run; aborting fix attempt.


Generated by SonarQube Remediation Agent

@sonarqube-agent
Copy link
Copy Markdown
Contributor Author

SonarQube Remediation Agent could not fix the CI failures.

Task: d6b412b4-b226-4fc5-ae35-2800eb19aa5a
Branch: remediate-master-20260514-050253-eaddd65d
Attempt: 2 (of 3)

CI failure fix failed: No CI logs could be downloaded for any failed check run; aborting fix attempt.


Generated by SonarQube Remediation Agent

@felix-pauck-sonarsource
Copy link
Copy Markdown
Contributor

Changes seem to be partially not necessary. In particular, the enum for UnknownLocationInFile can stay as it was. Other tiny changes look good but are not worth a PR on their own. Furthermore, the changes introduced follow-up SQ issues to be fixed. Overall, the value of this PR does not balance out the effort it would need to get through.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant