Skip to content

Track define()'d constants as exported nodes#6036

Merged
staabm merged 1 commit into
phpstan:2.2.xfrom
SanderMuller:define-constant-dependency
Jul 11, 2026
Merged

Track define()'d constants as exported nodes#6036
staabm merged 1 commit into
phpstan:2.2.xfrom
SanderMuller:define-constant-dependency

Conversation

@SanderMuller

@SanderMuller SanderMuller commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Follow-up to #6023.

Global constants declared with define() have the same result-cache staleness that #6023 fixed for const. A file reading a define()'d constant records a dependency on the defining file (via the ConstFetch handling from #6023), but a define() is a function call rather than a declaration, so it produced no exported node. The result cache re-analyses a changed file's dependents only when its exported nodes change, so changing the define()'s value did not re-analyse the reading files.

This exports define('NAME', <value>) calls that have a literal name, reusing the ExportedConstantNode from #6023, so changing the value re-analyses the dependents.

Reproducing the staleness

// define.php
define('SOME_DEFINED_MODE', 1);
// consumer.php
namespace App;
function usesDefinedMode(): int { return SOME_DEFINED_MODE; }
vendor/bin/phpstan analyse define.php consumer.php   # no errors; cache warm
# change define.php to: define('SOME_DEFINED_MODE', 'str');
vendor/bin/phpstan analyse define.php consumer.php   # before: stale, still no error

Before this change the second run keeps consumer.php cached and reports nothing; with it, the consumer is re-analysed and reports the return-type error, matching a cold run. Covered by the result-cache-define e2e test.

@SanderMuller SanderMuller marked this pull request as draft July 11, 2026 12:23
Global constants declared with define() have the same result-cache staleness
as `const` had: a file reading a define()'d constant records a dependency on
the defining file (via the ConstFetch handling), but a define() is a function
call rather than a declaration, so it produced no exported node. Changing the
define()'s value therefore did not re-analyse the reading files.

Export define('NAME', <value>) calls with a literal name, reusing
ExportedConstantNode, so changing the value re-analyses the dependents.
Covered by a result-cache e2e test.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@SanderMuller SanderMuller force-pushed the define-constant-dependency branch from b84866e to dff37cf Compare July 11, 2026 12:29
@SanderMuller SanderMuller marked this pull request as ready for review July 11, 2026 12:30
@phpstan-bot

Copy link
Copy Markdown
Collaborator

This pull request has been marked as ready for review.

@staabm staabm requested a review from VincentLanglet July 11, 2026 14:53
@staabm staabm merged commit 57063b4 into phpstan:2.2.x Jul 11, 2026
676 checks passed
@staabm

staabm commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

thank you!

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.

3 participants