Always resolve __DIR__ and __FILE__ to constant strings instead of generalizing them#5711
Open
phpstan-bot wants to merge 1 commit into
Open
Always resolve __DIR__ and __FILE__ to constant strings instead of generalizing them#5711phpstan-bot wants to merge 1 commit into
__DIR__ and __FILE__ to constant strings instead of generalizing them#5711phpstan-bot wants to merge 1 commit into
Conversation
…f generalizing them - Remove `usePathConstantsAsConstantString` parameter from `InitializerExprTypeResolver` constructor - `__DIR__` and `__FILE__` now always resolve to `ConstantStringType` with the actual path, instead of being generalized to `non-empty-string` when the (undocumented) `usePathConstantsAsConstantString` option was `false` - This makes `RequireFileExistsRule` correctly report missing files in `require __DIR__ . '/path.php'` without needing any config - Remove the extra constructor argument from `ValidateIgnoredErrorsExtension` and `PHPStanTestCase` - Update tests that asserted the old generalized type (`literal-string&non-falsy-string`) to use `substr()` for machine-independent assertions - The `usePathConstantsAsConstantString` config parameter is kept in the schema for backward compatibility but is now a no-op
Member
|
How can you resolve these to constant values when the code is usually executed on multiple machines from multiple paths? |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
require __DIR__ . '/path.php'and similar constructs did not reportfileNotFounderrors because__DIR__and__FILE__were generalized fromConstantStringTypetonon-empty-stringby default. This meantRequireFileExistsRulecould not resolve the actual file path. The undocumentedusePathConstantsAsConstantString: trueconfig option was required to get the correct behavior.This PR makes
__DIR__and__FILE__always resolve to their actual constant string values, removing the need for the config option entirely.Changes
src/Reflection/InitializerExprTypeResolver.php: RemoveusePathConstantsAsConstantStringconstructor parameter and its#[AutowiredParameter]attribute. Always returnConstantStringTypefor__DIR__and__FILE__magic constants instead of conditionally generalizing. Remove unusedGeneralizePrecisionandAutowiredParameterimports.src/DependencyInjection/ValidateIgnoredErrorsExtension.php: Remove the 7th argument (true) passed toInitializerExprTypeResolverconstructor.src/Testing/PHPStanTestCase.php: Remove$container->getParameter('usePathConstantsAsConstantString')argument fromInitializerExprTypeResolverconstruction.tests/PHPStan/Rules/Keywords/RequireFileExistsRuleTest.php: RemovegetAdditionalConfigFiles()that loadedusePathConstantsAsConstantString.neon— no longer needed.tests/PHPStan/Analyser/PathConstantsTest.php: RemovegetAdditionalConfigFiles()for the same reason.tests/PHPStan/Analyser/usePathConstantsAsConstantString.neon: Deleted — no longer referenced.tests/PHPStan/Analyser/nsrt/binary.php: Updated__DIR__/__FILE__type assertions fromliteral-string&non-falsy-stringto usesubstr()for machine-independent constant string checks.tests/PHPStan/Analyser/Fiber/data/fnsr.php: Same update for__DIR__/__FILE__assertions.tests/PHPStan/Reflection/BetterReflection/SourceLocator/OptimizedSingleFileSourceLocatorTest.php: Updated expected type forconst_with_dir_constfrom generalized type to the actual constant string path.Root cause
In
InitializerExprTypeResolver::getType(), when processing__DIR__(Dir) and__FILE__(File) AST nodes, the code created aConstantStringTypewith the actual path but then called->generalize(GeneralizePrecision::moreSpecific())whenusePathConstantsAsConstantStringwasfalse(the default). This turned the precise constant type intonon-empty-string, losing the actual path information.RequireFileExistsRule::resolveFilePaths()calls$type->getConstantStrings()on the include expression's type. With a generalizednon-empty-string,getConstantStrings()returns an empty array, so the rule silently skips file existence checking for any path built using__DIR__or__FILE__.The fix simply always returns the
ConstantStringTypewithout generalizing.Analogous cases probed
dirname(__DIR__): Still resolves tonon-empty-stringbecausedirname()has a stub that mapsnon-empty-string -> non-empty-string, not a dynamic return type extension that constant-folds. This is a separate enhancement opportunity, not the same bug.__LINE__,__CLASS__,__FUNCTION__,__METHOD__,__TRAIT__,__NAMESPACE__): Already resolve to constant types and are not affected by this change.__FILE__: Fixed in the same change as__DIR__— same code path.Test
The existing
testBug12203regression test inRequireFileExistsRuleTestnow works without theusePathConstantsAsConstantStringconfig option, proving the fix. Additional test updates ensure the new constant string types are correctly asserted throughout the test suite.Fixes phpstan/phpstan#12203