Skip to content

SONARPHP-1806 Fix S117 FP and S116 FN on PHP 8 constructor property promotion#1674

Open
karim-ouerghemmi-sonarsource wants to merge 3 commits intomasterfrom
karim/SONARPHP-1806
Open

SONARPHP-1806 Fix S117 FP and S116 FN on PHP 8 constructor property promotion#1674
karim-ouerghemmi-sonarsource wants to merge 3 commits intomasterfrom
karim/SONARPHP-1806

Conversation

@karim-ouerghemmi-sonarsource
Copy link
Copy Markdown
Contributor

Summary

  • S117 false positive: LocalVariableAndParameterNameCheck was checking promoted constructor properties as regular parameters. Fixed by skipping parameters where isPropertyPromotion() is true — their naming is governed by S116 instead.
  • S116 false negative: FieldNameCheck only visited CLASS_PROPERTY_DECLARATION nodes, missing promoted properties entirely. Fixed by also visiting METHOD_DECLARATION nodes and checking promoted constructor parameters against the field naming pattern.

Fixes: https://sonarsource.atlassian.net/browse/SONARPHP-1806

Test plan

  • FieldNameCheckTest — default and custom format tests pass, including new promoted property cases
  • LocalVariableAndParameterNameCheckTest — default and custom format tests pass, promoted properties no longer flagged

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

hashicorp-vault-sonar-prod bot commented Apr 13, 2026

SONARPHP-1806

@sonar-review-alpha
Copy link
Copy Markdown

sonar-review-alpha bot commented Apr 13, 2026

Summary

This PR fixes two issues with PHP 8 constructor property promotion:

  1. S117 false positive: Parameters that are promoted properties were being flagged for naming violations. Fixed by skipping promoted parameters in LocalVariableAndParameterNameCheck — their naming is governed by S116 instead.

  2. S116 false negative: Promoted properties weren't being checked at all because FieldNameCheck only visited CLASS_PROPERTY_DECLARATION nodes. Fixed by also visiting METHOD_DECLARATION nodes and checking promoted constructor parameters.

Both fixes are minimal and surgical: they add a check for isPropertyPromotion() to redirect traffic to the correct rule, and consolidate the field-name validation logic into a reusable helper method.

What reviewers should know

Where to start:

  • Look at the test file changes first (FieldNameCheckTest.php and LocalVariableAndParameterNameCheck.php) to see what cases are now covered, especially the constructor promotion examples.
  • The logic in both check classes is straightforward: skip promoted params in one rule, add a visitor for promoted params in the other.

Key points:

  • checkPropertyName() is a new helper that consolidates the regex matching logic for both regular and promoted properties — this eliminates duplication and makes future maintenance easier.
  • The __construct name check in checkPromotedConstructorProperties() is intentional (only check promoted props in constructors, not arbitrary methods).
  • Test cases cover edge cases like readonly, final-only promoted properties (PHP 8.5), and show that non-promoted parameters in the same constructor are handled by S117, not S116.
  • Minor cleanup: removed unused Collections import and switched to List.of().

No gotchas: the fix is additive and focused — no existing behavior is changed beyond fixing the two reported issues.


  • Generate Walkthrough
  • Generate Diagram

🗣️ Give feedback

…romotion

S117 was raising false positives on promoted constructor properties by treating
them as regular parameters. S116 was missing them entirely since it only visited
CLASS_PROPERTY_DECLARATION nodes.

- S117: skip parameters where isPropertyPromotion() is true; their naming is
  governed by S116 (FieldNameCheck)
- S116: also visit METHOD_DECLARATION nodes and check promoted constructor
  parameters against the field naming pattern

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
…HP 8.5)

isPropertyPromotion() also returns true when finalToken() != null.
Add test cases for final-only (no visibility modifier) promoted properties
to cover this path in both S116 and S117.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
sonar-review-alpha[bot]

This comment was marked as resolved.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
@sonarqube-next
Copy link
Copy Markdown

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.

LGTM! ✅

🗣️ Give feedback

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