Skip to content

chore: Qodana code-quality sweep (clear 71 static-analysis alerts) - #135

Merged
benjamineckstein merged 4 commits into
mainfrom
chore/qodana-code-quality-sweep
Jun 13, 2026
Merged

chore: Qodana code-quality sweep (clear 71 static-analysis alerts)#135
benjamineckstein merged 4 commits into
mainfrom
chore/qodana-code-quality-sweep

Conversation

@benjamineckstein

Copy link
Copy Markdown
Contributor

Context

GitHub code-scanning reported 71 Qodana (QDPHP) static-analysis alerts. Security and dependencies were confirmed clean first: composer audit reports no advisories and there are 0 Dependabot alerts. All 71 were code-quality notes/warnings. This PR clears them.

Bucket 1 - generator output quality

The emitter now emits self:: instead of a redundant static:: return type in the fromQuery/fromRoute/fromHeaders factory methods of final generated Data classes (PhpUnnecessaryStaticReferenceInspection, ~13 classes). Downstream artifacts regenerated byte-identical: petstore examples, the writable drift fixture, and the server-scaffold snapshot. The single-element foreach finding was deliberately left: it is a general-purpose loop over an operation's custom headers that just happens to carry one element for petstore, so special-casing it would special-case spec data.

Bucket 2 - source cleanups

array_filter loop conversions in OperationCollector, ternary simplification, final readonly EnumEmitter, completed PHPDoc in RequestDataSynthesizer, and one inlined same-parameter-value. Load-bearing casts and deliberate seams were kept and suppressed in qodana.yaml with rationale: the two (string) casts are load-bearing (numeric-string array-key invariant; collapsing json_encode's string|false), and the remaining same-parameter-value cases are a generic config resolver and an argv parser that should not be coupled to one option name. The @internal StandaloneApplication usage in bin/openapi-laravel is correct (the class API is internal by design per ROADMAP; the bin script is the package's own first-party entrypoint), so the annotation stays and the bin-only usage is suppressed.

Bucket 3 - coverage warnings

The 37 PhpCoverageInspection warnings were false positives: the Qodana workflow runs the suite with --exclude-group=slow, so lines covered only by the slow corpus gate looked uncovered. Coverage is already enforced by the full composer test run plus the dedicated 100% type-coverage gate, so PhpCoverageInspection is disabled in qodana.yaml with that rationale. No throwaway tests written; no genuine uncovered core branches found.

Corpus rebaseline

The one-token self:: change shifts generated output for 116 corpus specs, so the frozen v0.11.0 reader baseline was refreshed via the project's documented intentional-rebaseline mechanism. The 5 post-freeze OpenAPI 3.2 specs are untouched.

Local gates (all green)

  • composer test: 2183 passed, 5 skipped (the 5 post-freeze 3.2 exemptions)
  • composer test:type: 100.0%
  • composer stan: no errors
  • composer lint (Pint): passed
  • composer deptrac: 0 violations
  • Drift check (bin/openapi-laravel check on petstore): exit 0, in sync
  • composer-require-checker runs in CI only (not installed locally)

Reviewer note

Several findings were intentionally suppressed rather than rewritten because they are false positives or load-bearing. The rationale is in the commit messages and inline in qodana.yaml.

…nerated Data factories

The fromQuery/fromRoute/fromHeaders factory methods on the per-operation
query/path/header Data classes declared a ': static' return type. Those classes
are always emitted final, so 'static' is redundant (QDPHP
PhpUnnecessaryStaticReferenceInspection); 'self' is the correct, equivalent
declaration. Regenerated the petstore and writable examples and updated the
server-scaffold snapshot so the drift gates stay byte-identical.
- OperationCollector: convert the three component-map accumulate-with-if
  loops (parameters, requestBodies, responses) to array_filter with
  ARRAY_FILTER_USE_BOTH (PhpLoopCanBeConvertedToArrayFilter); PHPStan max
  still narrows the value type from the instanceof in each callback.
- CommandRequestFactory: inline the single-caller configMiddlewareMap key
  (PhpSameParameterValue) and rewrite the resolveBoolean ternary as
  '$configured === null || (bool) $configured'
  (PhpTernaryExpressionCanBeReplacedWithCondition).
- RequestDataSynthesizer: complete generateParamData's PHPDoc to cover every
  parameter and the return (PhpDocSignatureIsNotComplete).
- EnumEmitter: mark the class final readonly; its only property is the
  promoted readonly GenerationState (PhpClassCanBeReadonly).
- PhpUnnecessaryStringCast: the remaining '(string) ...' casts are
  load-bearing (numeric-string array-key coercion guard, and collapsing
  json_encode's string|false return for sprintf %s), the same rationale as
  the already-disabled PhpCastIsUnnecessaryInspection.
- PhpSameParameterValue (scoped to the two CLI files): repeatedOption and
  resolveRepeatable are deliberate general-purpose argv/config helpers, not
  dead generality.
- PhpInternalEntityUsed (scoped to bin/openapi-laravel): the bin script is
  the package's own framework-free entrypoint and the legitimate consumer of
  the @internal StandaloneApplication (#69: the whole PHP class API is
  internal; the supported surface is the CLI and artisan command).
- PhpCoverageInspection: the Clover report fed to Qodana (#89) comes from the
  fast suite only, so lines exercised solely by the slow corpus gate show as
  uncovered noise; full line coverage is enforced by composer test:type.
…n type

The self:: instead of static:: emitter fix changes one token on every
generated fromQuery() signature, so 116 corpus specs diverge from the frozen
v0.11.0 baseline. This is an intentional, auditable post-freeze rebaseline:
add READER_BASELINE_REBASELINED_SELF_STATIC documenting every affected spec,
refresh exactly those hashes in corpus-baseline-v0.11.0.json (key order and
format preserved, the 5 post-freeze 3.2 specs untouched), and pin the new
list in the coverage test so it cannot rot. Every spec outside the rebaseline
lists stays the frozen freeze, byte for byte.
@github-actions

Copy link
Copy Markdown
Contributor

Qodana for PHP

It seems all right 👌

No new problems were found according to the checks applied

💡 Qodana analysis was run in the pull request mode: only the changed files were checked
☁️ View the detailed Qodana report

Detected 12 dependencies

Third-party software list

This page lists the third-party software dependencies used in project

Dependency Version Licenses
doctrine/deprecations 1.1.6 MIT
phpdocumentor/reflection-common 2.2.0 MIT
phpdocumentor/reflection-docblock 6.0.3 MIT
phpdocumentor/type-resolver 2.0.0 MIT
phpstan/phpdoc-parser 2.3.2 MIT
spatie/laravel-data 4.23.0 MIT
spatie/laravel-package-tools 1.93.1 MIT
spatie/php-structure-discoverer 2.4.2 MIT
symfony/finder v8.1.0 MIT
symfony/polyfill-ctype v1.37.0 MIT
symfony/yaml v8.1.0 MIT
webmozart/assert 2.4.0 MIT
Contact Qodana team

Contact us at qodana-support@jetbrains.com

@benjamineckstein
benjamineckstein merged commit 08e0240 into main Jun 13, 2026
14 checks passed
@benjamineckstein
benjamineckstein deleted the chore/qodana-code-quality-sweep branch June 13, 2026 20:33
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