Skip to content

SONARPHP-1797 S4833: suppress false positives for require/include of non-namespaced files#1643

Merged
nils-werner-sonarsource merged 3 commits intomasterfrom
claude/task/c562e398
Feb 27, 2026
Merged

SONARPHP-1797 S4833: suppress false positives for require/include of non-namespaced files#1643
nils-werner-sonarsource merged 3 commits intomasterfrom
claude/task/c562e398

Conversation

@nils-werner-sonarsource
Copy link
Contributor

Summary

  • Rule S4833 was flagging require/include on files that contain no namespaced symbols (config arrays, HTML templates, procedural scripts), where the use keyword cannot replace the include
  • The fix checks the project-wide ProjectSymbolData symbol index: if the included file is not known to define any namespaced class, the issue is suppressed
  • Dynamic paths (non-string-literal arguments like $var or __DIR__ . '/file.php') are now treated as compliant since the path cannot be resolved
  • SymbolTableImpl exposes a new projectSymbolData() getter to make the project symbol index accessible to checks

Implementation approach

Under PSR-4/Composer conventions, every namespaced class lives in its own file. The ProjectSymbolData already contains a map of all classes found across the project, each with its source file path (ClassSymbolData.location().filePath()). On first visit, the check builds a Set<String> of all such file paths once per analysis run. When a require/include is encountered, the included path is resolved relative to the current file and looked up in this set.

Test plan

  • New test file RequireIncludeInstructionsUsageCheckNamespaceDetection.php covers: files with namespace (Noncompliant), files without namespace (Compliant), non-existent files (Compliant), dynamic paths (Compliant), return-value-used (Compliant)
  • Existing test() updated to pass included files as additional analysis inputs so ProjectSymbolData is populated
  • All unit tests pass: ./gradlew :php-checks:test :php-frontend:test

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

🤖 Generated with Claude Code

…no namespaced symbols

The rule previously flagged all require/include calls for PHP files,
even when the included file contained no namespaced class, function,
or trait — making the `use` keyword replacement impossible.

The fix uses the project-wide `ProjectSymbolData` (already built during
analysis) to resolve the included file path and check whether any
namespaced class is declared in that file. If none is found (or if the
path is dynamic), the issue is suppressed. Dynamic paths and
unknown/unresolvable files are treated as compliant.

`SymbolTableImpl` now exposes a `projectSymbolData()` getter so checks
can query the full project symbol index.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@hashicorp-vault-sonar-prod
Copy link
Contributor

hashicorp-vault-sonar-prod bot commented Feb 26, 2026

SONARPHP-1797

…on logic

With the new symbol-based approach, S4833 no longer flags require/include
when the path is dynamic or the target file has no namespaced classes.
Update ruling snapshots to remove false positives from:
- Dynamic paths (__DIR__ concatenation, variables, expressions)
- Static paths whose target files contain no namespaced symbols

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@sonarqube-next
Copy link

Copy link
Contributor

Choose a reason for hiding this comment

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

LGTM!

@nils-werner-sonarsource nils-werner-sonarsource merged commit 8a92c0b into master Feb 27, 2026
20 checks passed
@nils-werner-sonarsource nils-werner-sonarsource deleted the claude/task/c562e398 branch February 27, 2026 15:59
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.

2 participants