Skip to content

feat: add Yii::$app->params type inference from configuration for precise array shape typing.#85

Merged
terabytesoftw merged 4 commits into
mainfrom
fix_mini_51
Apr 5, 2026
Merged

feat: add Yii::$app->params type inference from configuration for precise array shape typing.#85
terabytesoftw merged 4 commits into
mainfrom
fix_mini_51

Conversation

@terabytesoftw
Copy link
Copy Markdown
Member

Pull Request

Q A
Is bugfix?
New feature? ✔️
Breaks BC?

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 5, 2026

Warning

Rate limit exceeded

@terabytesoftw has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 0 minutes and 34 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 0 minutes and 34 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: d9250d9d-d593-4002-8e45-b5f58dafd391

📥 Commits

Reviewing files that changed from the base of the PR and between 0f1cbd4 and 5885885.

📒 Files selected for processing (3)
  • src/StubFilesExtension.php
  • tests/StubFilesExtensionTest.php
  • tests/config/params-empty-array-config.php
📝 Walkthrough

Walkthrough

Adds config-derived type inference for Yii::$app->params: ServiceMap extracts/validates a top-level params array and exposes it via getParams(), and StubFilesExtension emits a generated $params PHPDoc with inferred array-shape types for PHPStan.

Changes

Cohort / File(s) Summary
Core implementation
src/ServiceMap.php, src/StubFilesExtension.php
ServiceMap: validate/process top-level params, store in new private $params, add getParams() and processParams(); StubFilesExtension: add buildParamsPropertyDeclaration() and recursive type inference helpers to emit typed $params PHPDoc in generated stubs.
Tests — ServiceMap
tests/ServiceMapParamsTest.php, tests/config/params-unsupported-is-null.php, tests/config/params-unsupported-is-not-array.php, tests/config/params-config.php
New unit tests and fixtures validating empty, valid, and invalid (null/non-array) params handling and exact RuntimeException messages.
Tests — Stub generation & param shapes
tests/StubFilesExtensionTest.php, tests/config/params-empty-array-config.php
New test asserting generated stub contains expected array-shape/type for empty arrays and related fixture for sparse/special-key scenarios.
PHPStan integration tests
tests/web/data/property/ApplicationParamsType.php, tests/web/property/ApplicationParamsTypeTest.php, tests/config/phpstan-config.php, tests/config/phpstan-params-config.php, tests/support/extension-params-test.neon
Added PHPStan type-assertion fixture and integration test, plus PHPStan config fixtures and neon include to drive param-based inference tests.
Docs & tooling
CHANGELOG.md, README.md, composer.json
Changelog and README updated to document params-derived typing and example config; composer.json test script now runs phpunit with -d memory_limit=-1.

Sequence Diagram

sequenceDiagram
    participant Config as Configuration File
    participant SM as ServiceMap
    participant SFE as StubFilesExtension
    participant PS as PHPStan

    Config->>SM: load config (including `params`)
    activate SM
    SM->>SM: processDefinition(config)
    SM->>SM: processParams(config) -> store $params
    SM->>SM: processSingletons(config)
    deactivate SM

    SFE->>SM: getParams()
    activate SFE
    SM-->>SFE: return params array
    SFE->>SFE: inferTypeString(params)
    SFE->>SFE: buildParamsPropertyDeclaration()
    SFE-->>PS: provide generated stub with `@var` annotation
    deactivate SFE

    activate PS
    PS->>PS: analyze Yii::$app->params usages
    PS-->>PS: infer precise array-shape types
    deactivate PS
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰 I nibbled configs through the night,

found params hidden out of sight.
Shapes and scalars now declare,
PHPStan sees them — accurate and fair. 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 61.76% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main feature: adding type inference for Yii::$app->params from configuration for precise array shape typing, which aligns with all the changeset modifications.
Description check ✅ Passed The description is related to the changeset by identifying this as a new feature (not a bugfix, not breaking BC), which matches the PR objectives of adding type inference for Yii::$app->params.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix_mini_51

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 5, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (1c42c80) to head (5885885).
⚠️ Report is 2 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@             Coverage Diff             @@
##                main       #85   +/-   ##
===========================================
  Coverage     100.00%   100.00%           
- Complexity        81       109   +28     
===========================================
  Files              2         2           
  Lines            156       224   +68     
===========================================
+ Hits             156       224   +68     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@coderabbitai coderabbitai Bot added the enhancement New feature or request label Apr 5, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/StubFilesExtension.php`:
- Around line 253-314: The inferTypeString method is too complex; split it into
small private helpers: move the scalar checks (null/string/int/float/bool) into
a new private inferScalarType(mixed): ?string that returns the scalar type or
null, extract the key formatting/preg_match logic into formatArrayKey(string):
string, and extract the array-shape assembly into a private
inferArrayType(array): string which handles empty arrays, all-string-key maps
(using formatArrayKey and recursive inferTypeString calls) and non-string-key
arrays (collecting inferred value types). Then simplify inferTypeString(mixed
$value) to first call inferScalarType and return if non-null, otherwise delegate
arrays to inferArrayType and default to 'mixed'. Ensure to use the same method
names (inferTypeString, inferScalarType, formatArrayKey, inferArrayType) so
callers are easy to update.
- Around line 280-311: The array-shape fallback drops keys when some keys are
non-string; update the logic in the same method (the inferTypeString handling of
arrays where $value is iterated) to preserve keys for sparse/mixed-key arrays by
iterating over $value with foreach ($value as $k => $v) and formatting each key
(use the same key-formatting logic used for string keys: quote strings that need
quoting, render integers as their literal digits) and push entries like
$formattedKey . ': ' . $this->inferTypeString($v); then return 'array{' .
implode(', ', $entries) . '}'; so both string-only and mixed/sparse arrays
include explicit key => type pairs rather than value-only entries.
- Around line 295-299: The array-shape key quoting in StubFilesExtension.php
currently wraps non-identifier keys as '$k' without escaping, which can produce
invalid PHPDoc when keys contain single quotes or backslashes; modify the branch
that assigns $formattedKey (the ternary using preg_match and the else that
builds "'$k'") to escape backslashes then single quotes in $k before wrapping
(so keys like O'Reilly become 'O\'Reilly' and paths like C\path become
'C\\\\path'), keeping the rest of the entry construction ($entries[] =
$formattedKey . ': ' . $this->inferTypeString($v)) unchanged.

In `@tests/ServiceMapParamsTest.php`:
- Around line 67-80: Add a regression test to assert that a params => null
configuration is treated as invalid (same as non-array scalars): in
tests/ServiceMapParamsTest.php add a new test (or extend
testThrowExceptionWhenParamsNotArray) that loads a fixture like
params-unsupported-is-null.php and expects RuntimeException with the same
message "Configuration file '{...}' must contain a valid 'params' 'array'."
Reference the ServiceMap constructor to instantiate ServiceMap with the null
fixture and ensure the test mirrors the existing
expectException/expectExceptionMessage assertions so null is rejected,
preventing silent coercion.

In `@tests/web/data/property/ApplicationParamsType.php`:
- Around line 30-58: Add a focused test that directly asserts the dotted key
access path for the quoted key (e.g. assertType('string',
Yii::$app->params['turnstile.siteKey'])); locate an appropriate test method near
testReturnStringFromParamsKey or create a new method (e.g.
testReturnTurnstileSiteKeyFromParamsKey) and use assertType with the exact
dotted key to ensure regressions in quoted-key handling are caught.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 0ff19fcc-1a32-46c5-9cc9-959ea615e894

📥 Commits

Reviewing files that changed from the base of the PR and between 8caeb88 and f8db53a.

📒 Files selected for processing (13)
  • CHANGELOG.md
  • README.md
  • composer.json
  • src/ServiceMap.php
  • src/StubFilesExtension.php
  • tests/ServiceMapParamsTest.php
  • tests/config/params-config.php
  • tests/config/params-unsupported-is-not-array.php
  • tests/config/phpstan-config.php
  • tests/config/phpstan-params-config.php
  • tests/support/extension-params-test.neon
  • tests/web/data/property/ApplicationParamsType.php
  • tests/web/property/ApplicationParamsTypeTest.php
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (17)
  • GitHub Check: phpunit / PHP 8.1-windows-2022
  • GitHub Check: phpunit / PHP 8.3-ubuntu-latest
  • GitHub Check: phpunit / PHP 8.2-windows-2022
  • GitHub Check: phpunit / PHP 8.1-ubuntu-latest
  • GitHub Check: phpunit / PHP 8.4-windows-2022
  • GitHub Check: phpunit / PHP 8.3-windows-2022
  • GitHub Check: phpunit-compatibility / PHP 8.5-windows-2022
  • GitHub Check: phpunit-compatibility / PHP 8.3-windows-2022
  • GitHub Check: phpunit-compatibility / PHP 8.2-windows-2022
  • GitHub Check: phpunit-compatibility / PHP 8.1-ubuntu-latest
  • GitHub Check: phpunit-compatibility / PHP 8.2-ubuntu-latest
  • GitHub Check: phpunit-compatibility / PHP 8.4-windows-2022
  • GitHub Check: phpunit-compatibility / PHP 8.4-ubuntu-latest
  • GitHub Check: phpunit-compatibility / PHP 8.1-windows-2022
  • GitHub Check: linter / Super Linter
  • GitHub Check: phpunit / PHP 8.4-windows-2022
  • GitHub Check: phpunit / PHP 8.4-ubuntu-latest
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: terabytesoftw
Repo: yii2-extensions/phpstan PR: 40
File: src/ServiceMap.php:0-0
Timestamp: 2025-06-14T17:41:48.820Z
Learning: The yii2-extensions/phpstan repository contains a PHPStan extension specifically designed for static analysis of Yii framework applications.
Learnt from: terabytesoftw
Repo: yii2-extensions/phpstan PR: 84
File: CHANGELOG.md:12-12
Timestamp: 2026-04-03T00:19:36.123Z
Learning: In the `yii2-extensions/phpstan` repository, Conventional Commits-style CHANGELOG entries do not include issue/PR number references. The maintainer considers issue numbers non-mandatory per the Conventional Commits specification. Do not suggest adding issue/PR numbers to changelog entries as a consistency requirement.
📚 Learning: 2025-06-14T17:41:48.820Z
Learnt from: terabytesoftw
Repo: yii2-extensions/phpstan PR: 40
File: src/ServiceMap.php:0-0
Timestamp: 2025-06-14T17:41:48.820Z
Learning: The yii2-extensions/phpstan repository contains a PHPStan extension specifically designed for static analysis of Yii framework applications.

Applied to files:

  • tests/support/extension-params-test.neon
  • tests/config/phpstan-params-config.php
  • src/ServiceMap.php
  • tests/web/property/ApplicationParamsTypeTest.php
  • README.md
  • tests/web/data/property/ApplicationParamsType.php
📚 Learning: 2025-10-10T12:54:50.152Z
Learnt from: terabytesoftw
Repo: yii2-extensions/phpstan PR: 77
File: .github/linters/actionlint.yml:5-7
Timestamp: 2025-10-10T12:54:50.152Z
Learning: In the yii2-extensions/phpstan repository, the maintainer prefers to keep the actionlint.yml configuration with the generic ignore entry `"section is alias node but mapping node is expected"` as it works correctly for their workflows, and previous suggestions to change it have failed in other repositories.

Applied to files:

  • tests/support/extension-params-test.neon
📚 Learning: 2026-04-03T00:19:36.123Z
Learnt from: terabytesoftw
Repo: yii2-extensions/phpstan PR: 84
File: CHANGELOG.md:12-12
Timestamp: 2026-04-03T00:19:36.123Z
Learning: In the `yii2-extensions/phpstan` repository, Conventional Commits-style CHANGELOG entries do not include issue/PR number references. The maintainer considers issue numbers non-mandatory per the Conventional Commits specification. Do not suggest adding issue/PR numbers to changelog entries as a consistency requirement.

Applied to files:

  • README.md
📚 Learning: 2025-06-12T16:41:20.240Z
Learnt from: terabytesoftw
Repo: yii2-extensions/phpstan PR: 36
File: src/type/ActiveQueryDynamicMethodReturnTypeExtension.php:153-157
Timestamp: 2025-06-12T16:41:20.240Z
Learning: In PHPStan extensions for this repository, `instanceof` must not be used to compare `PHPStan\Type\*` objects (e.g., `ThisType`) because it is not compatible with PHPStan’s runtime mode; instead, use `$type::class === SomeType::class` for reliable checks.

Applied to files:

  • tests/web/data/property/ApplicationParamsType.php
🪛 PHPMD (2.15.0)
src/StubFilesExtension.php

[warning] 253-314: The method inferTypeString() has a Cyclomatic Complexity of 14. The configured cyclomatic complexity threshold is 10. (undefined)

(CyclomaticComplexity)


[warning] 253-314: The method inferTypeString() has an NPath complexity of 1568. The configured NPath complexity threshold is 200. (undefined)

(NPathComplexity)

🔇 Additional comments (12)
tests/config/params-unsupported-is-not-array.php (1)

1-7: LGTM!

This test fixture correctly provides an invalid configuration (string instead of array) to verify that the ServiceMap properly validates the params type and throws an appropriate exception.

composer.json (1)

55-55: LGTM!

Appropriate approach for running PHPUnit with unlimited memory. Unlike PHPStan which has a native --memory-limit flag, PHPUnit requires setting the PHP directive directly.

tests/config/phpstan-config.php (1)

20-32: LGTM!

Good coverage of diverse param types (string, int, bool, float, null, nested array, string array) for comprehensive type inference testing. The test values align with the other params config fixtures in this PR.

CHANGELOG.md (1)

13-13: LGTM!

The changelog entry follows the project's Conventional Commits style and accurately describes the new feature.

tests/support/extension-params-test.neon (1)

1-6: LGTM!

Well-structured neon configuration that mirrors the existing extension-test.neon pattern while pointing to a dedicated params config for isolated feature testing.

README.md (2)

73-78: LGTM!

Clear and practical example for the Quick start section, demonstrating the params configuration.


145-162: LGTM!

Excellent documentation of the new params type inference feature with clear examples showing:

  • Full params array shape typing
  • Individual key access with proper scalar types
  • Nested array support

The nested example (nested.db.host) appropriately demonstrates a realistic database config use case.

tests/config/phpstan-params-config.php (1)

1-33: LGTM!

Well-structured test fixture that combines realistic component configuration with the params section needed for type inference testing. The params structure is consistent with other test fixtures in this PR.

tests/config/params-config.php (1)

1-22: LGTM!

Focused test fixture providing comprehensive type coverage (string, int, bool, float, null, nested array, list array) for unit testing the ServiceMap::getParams() extraction logic.

src/ServiceMap.php (2)

546-561: Good extraction flow for params into the service map.

processParams() cleanly captures configuration data for downstream stub generation and keeps default behavior stable when params is absent.


331-333: Technical observation is correct, but appears to be intentional design pattern.

Line 331 uses isset($config['params']), which returns false when the value is null, allowing config like ['params' => null] to bypass validation and silently coerce to [] via the null-coalescing operator on line 559. However, this same validation pattern is used consistently across all config keys (behaviors, components, container.definitions, container.singletons), suggesting this is intentional design rather than a validation bug. The functional outcome—treating missing or null values as empty arrays—is sound and non-breaking.

If stricter validation for explicit null values is desired, the proposed fix using array_key_exists() is correct. However, this would require changes across all similar config validations for consistency.

tests/web/property/ApplicationParamsTypeTest.php (1)

24-42: Test harness wiring looks solid.

Data-provider and additional config setup are clear and correctly scoped for params-type inference assertions.

Comment thread src/StubFilesExtension.php Outdated
Comment thread src/StubFilesExtension.php Outdated
Comment thread src/StubFilesExtension.php Outdated
Comment thread tests/ServiceMapParamsTest.php
Comment thread tests/web/data/property/ApplicationParamsType.php
@terabytesoftw terabytesoftw merged commit 72833fa into main Apr 5, 2026
69 checks passed
@terabytesoftw terabytesoftw deleted the fix_mini_51 branch April 5, 2026 15:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant