Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PHPStan breaks custom autoloader from loading dependencies for anonymous classes #4836

Closed
rrazor opened this issue Apr 10, 2021 · 5 comments
Closed

Comments

@rrazor
Copy link

rrazor commented Apr 10, 2021

Bug report

Version

$ vendor/bin/phpstan --version
PHPStan - PHP Static Analysis Tool 0.12.83

Description

When using a custom autoloader, dependencies of anonymous classes that must be autoloaded will fail on require or require_once with a file not found, despite the file existing and following a successful \file_exists() check beforehand.

This defect does not appear when an anonymous class's dependencies are discovered by scanning prior to analyzing the file in question, or if you explicitly import the symbols with use directives.

Technical hunch

I'm guessing this has something to do with intercepting the stream read hooks inside of BetterReflection.

Code snippet that reproduces the problem

See my sample repository that reproduces this error. I'm not sure it would be possible using only phpstan.org since it relies on filesystem operations.

Expected output

PHPStan should allow anonymous class dependencies declared with fully qualified class names to autoload properly using a custom autoloader.

This works (from the linked repo above):

vendor/bin/phpstan analyse --debug tests/ClassATestWithUse.php
Note: Using configuration file /Volumes/Work/git/phpstan-autoload-error-example/phpstan.neon.
/Volumes/Work/git/phpstan-autoload-error-example/tests/ClassATestWithUse.php


 [OK] No errors

This doesn't:

$ vendor/bin/phpstan analyse --debug tests/ClassATest.php
Note: Using configuration file /Volumes/Work/git/phpstan-autoload-error-example/phpstan.neon.
/Volumes/Work/git/phpstan-autoload-error-example/tests/ClassATest.php
PHP Fatal error:  Uncaught Error: Failed opening required '/Volumes/Work/git/phpstan-autoload-error-example/src/ClassA.php' (include_path='.:/usr/local/Cellar/php/8.0.3/share/php/pear') in /Volumes/Work/git/phpstan-autoload-error-example/src/bootstrap.php:29
Stack trace:
#0 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Reflection/BetterReflection/SourceLocator/AutoloadSourceLocator.php(229): PHPStan\Command\CommandHelper::{closure}('Example\\ClassA')
#1 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Reflection/BetterReflection/SourceLocator/FileReadTrapStreamWrapper.php(46): PHPStan\Reflection\BetterReflection\SourceLocator\AutoloadSourceLocator::PHPStan\Reflection\BetterReflection\SourceLocator\{closure}()
#2 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Reflection/BetterReflection/SourceLocator/AutoloadSourceLocator.php(241): PHPStan\Reflection\BetterReflection\SourceLocator\FileReadTrapStreamWrapper::withStreamWrapperOverride(Object(Closure))
#3 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Reflection/BetterReflection/SourceLocator/AutoloadSourceLocator.php(123): PHPStan\Reflection\BetterReflection\SourceLocator\AutoloadSourceLocator->locateClassByName('Example\\ClassA')
#4 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Reflection/BetterReflection/SourceLocator/ClassBlacklistSourceLocator.php(36): PHPStan\Reflection\BetterReflection\SourceLocator\AutoloadSourceLocator->locateIdentifier(Object(PHPStan\Reflection\BetterReflection\Reflector\MemoizingClassReflector), Object(PHPStan\BetterReflection\Identifier\Identifier))
#5 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/vendor/ondrejmirtes/better-reflection/src/SourceLocator/Type/AggregateSourceLocator.php(31): PHPStan\Reflection\BetterReflection\SourceLocator\ClassBlacklistSourceLocator->locateIdentifier(Object(PHPStan\Reflection\BetterReflection\Reflector\MemoizingClassReflector), Object(PHPStan\BetterReflection\Identifier\Identifier))
#6 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/vendor/ondrejmirtes/better-reflection/src/SourceLocator/Type/MemoizingSourceLocator.php(31): PHPStan\BetterReflection\SourceLocator\Type\AggregateSourceLocator->locateIdentifier(Object(PHPStan\Reflection\BetterReflection\Reflector\MemoizingClassReflector), Object(PHPStan\BetterReflection\Identifier\Identifier))
#7 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/vendor/ondrejmirtes/better-reflection/src/Reflector/ClassReflector.php(39): PHPStan\BetterReflection\SourceLocator\Type\MemoizingSourceLocator->locateIdentifier(Object(PHPStan\Reflection\BetterReflection\Reflector\MemoizingClassReflector), Object(PHPStan\BetterReflection\Identifier\Identifier))
#8 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Reflection/BetterReflection/Reflector/MemoizingClassReflector.php(29): PHPStan\BetterReflection\Reflector\ClassReflector->reflect('Example\\ClassA')
#9 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/vendor/ondrejmirtes/better-reflection/src/Reflection/ReflectionClass.php(645): PHPStan\Reflection\BetterReflection\Reflector\MemoizingClassReflector->reflect('Example\\ClassA')
#10 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/vendor/ondrejmirtes/better-reflection/src/Reflection/ReflectionClass.php(227): PHPStan\BetterReflection\Reflection\ReflectionClass->getParentClass()
#11 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/vendor/ondrejmirtes/better-reflection/src/Reflection/ReflectionClass.php(269): PHPStan\BetterReflection\Reflection\ReflectionClass->getParentMethods()
#12 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/vendor/ondrejmirtes/better-reflection/src/Reflection/ReflectionClass.php(315): PHPStan\BetterReflection\Reflection\ReflectionClass->getMethodsIndexedByName()
#13 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/vendor/ondrejmirtes/better-reflection/src/Reflection/ReflectionClass.php(487): PHPStan\BetterReflection\Reflection\ReflectionClass->getMethods()
#14 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/vendor/ondrejmirtes/better-reflection/src/Reflection/Adapter/ReflectionClass.php(155): PHPStan\BetterReflection\Reflection\ReflectionClass->getConstructor()
#15 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Reflection/ClassReflection.php(352): PHPStan\BetterReflection\Reflection\Adapter\ReflectionClass->getConstructor()
#16 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Reflection/ClassReflection.php(340): PHPStan\Reflection\ClassReflection->findConstructor()
#17 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Rules/Classes/InstantiationRule.php(108): PHPStan\Reflection\ClassReflection->hasConstructor()
#18 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Rules/Classes/InstantiationRule.php(45): PHPStan\Rules\Classes\InstantiationRule->checkClassName('AnonymousClass4...', true, Object(PhpParser\Node\Expr\New_), Object(PHPStan\Analyser\MutatingScope))
#19 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/FileAnalyser.php(69): PHPStan\Rules\Classes\InstantiationRule->processNode(Object(PhpParser\Node\Expr\New_), Object(PHPStan\Analyser\MutatingScope))
#20 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Node/ClassStatementsGatherer.php(91): PHPStan\Analyser\FileAnalyser->PHPStan\Analyser\{closure}(Object(PhpParser\Node\Expr\New_), Object(PHPStan\Analyser\MutatingScope))
#21 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(391): PHPStan\Node\ClassStatementsGatherer->__invoke(Object(PhpParser\Node\Expr\New_), Object(PHPStan\Analyser\MutatingScope))
#22 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(2060): PHPStan\Analyser\NodeScopeResolver::PHPStan\Analyser\{closure}(Object(PhpParser\Node\Expr\New_), Object(PHPStan\Analyser\MutatingScope))
#23 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(1313): PHPStan\Analyser\NodeScopeResolver->callNodeCallbackWithExpression(Object(Closure), Object(PhpParser\Node\Expr\New_), Object(PHPStan\Analyser\MutatingScope), Object(PHPStan\Analyser\ExpressionContext))
#24 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(1329): PHPStan\Analyser\NodeScopeResolver->processExprNode(Object(PhpParser\Node\Expr\New_), Object(PHPStan\Analyser\MutatingScope), Object(Closure), Object(PHPStan\Analyser\ExpressionContext))
#25 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(2315): PHPStan\Analyser\NodeScopeResolver->PHPStan\Analyser\{closure}(Object(PHPStan\Analyser\MutatingScope))
#26 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(1337): PHPStan\Analyser\NodeScopeResolver->processAssignVar(Object(PHPStan\Analyser\MutatingScope), Object(PhpParser\Node\Expr\Variable), Object(PhpParser\Node\Expr\New_), Object(Closure), Object(PHPStan\Analyser\ExpressionContext), Object(Closure), true)
#27 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(438): PHPStan\Analyser\NodeScopeResolver->processExprNode(Object(PhpParser\Node\Expr\Assign), Object(PHPStan\Analyser\MutatingScope), Object(Closure), Object(PHPStan\Analyser\ExpressionContext))
#28 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(248): PHPStan\Analyser\NodeScopeResolver->processStmtNode(Object(PhpParser\Node\Stmt\Expression), Object(PHPStan\Analyser\MutatingScope), Object(Closure))
#29 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(402): PHPStan\Analyser\NodeScopeResolver->processStmtNodes(Object(PhpParser\Node\Stmt\ClassMethod), Array, Object(PHPStan\Analyser\MutatingScope), Object(Closure))
#30 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(248): PHPStan\Analyser\NodeScopeResolver->processStmtNode(Object(PhpParser\Node\Stmt\ClassMethod), Object(PHPStan\Analyser\MutatingScope), Object(PHPStan\Node\ClassStatementsGatherer))
#31 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(485): PHPStan\Analyser\NodeScopeResolver->processStmtNodes(Object(PhpParser\Node\Stmt\Class_), Array, Object(PHPStan\Analyser\MutatingScope), Object(PHPStan\Node\ClassStatementsGatherer))
#32 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(248): PHPStan\Analyser\NodeScopeResolver->processStmtNode(Object(PhpParser\Node\Stmt\Class_), Object(PHPStan\Analyser\MutatingScope), Object(Closure))
#33 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(451): PHPStan\Analyser\NodeScopeResolver->processStmtNodes(Object(PhpParser\Node\Stmt\Namespace_), Array, Object(PHPStan\Analyser\MutatingScope), Object(Closure))
#34 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(216): PHPStan\Analyser\NodeScopeResolver->processStmtNode(Object(PhpParser\Node\Stmt\Namespace_), Object(PHPStan\Analyser\MutatingScope), Object(Closure))
#35 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/FileAnalyser.php(149): PHPStan\Analyser\NodeScopeResolver->processNodes(Array, Object(PHPStan\Analyser\MutatingScope), Object(Closure))
#36 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/Analyser.php(52): PHPStan\Analyser\FileAnalyser->analyseFile('/Volumes/Work', Array, Object(PHPStan\Rules\Registry), NULL)
#37 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Command/AnalyserRunner.php(57): PHPStan\Analyser\Analyser->analyse(Array, Object(Closure), NULL, true, Array)
#38 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Command/AnalyseApplication.php(148): PHPStan\Command\AnalyserRunner->runAnalyser(Array, Array, Object(Closure), NULL, true, true, '/Volumes/Work', NULL, NULL, Object(_HumbugBox5ccdb2ccdb35\Symfony\Component\Console\Input\ArgvInput))
#39 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Command/AnalyseApplication.php(79): PHPStan\Command\AnalyseApplication->runAnalyser(Array, Array, true, '/Volumes/Work', Object(PHPStan\Command\Symfony\SymfonyOutput), Object(PHPStan\Command\Symfony\SymfonyOutput), Object(_HumbugBox5ccdb2ccdb35\Symfony\Component\Console\Input\ArgvInput))
#40 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Command/AnalyseCommand.php(156): PHPStan\Command\AnalyseApplication->analyse(Array, true, Object(PHPStan\Command\Symfony\SymfonyOutput), Object(PHPStan\Command\Symfony\SymfonyOutput), false, true, '/Volumes/Work', Array, Object(_HumbugBox5ccdb2ccdb35\Symfony\Component\Console\Input\ArgvInput))
#41 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/vendor/symfony/console/Command/Command.php(228): PHPStan\Command\AnalyseCommand->execute(Object(_HumbugBox5ccdb2ccdb35\Symfony\Component\Console\Input\ArgvInput), Object(_HumbugBox5ccdb2ccdb35\Symfony\Component\Console\Output\ConsoleOutput))
#42 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/vendor/symfony/console/Application.php(856): _HumbugBox5ccdb2ccdb35\Symfony\Component\Console\Command\Command->run(Object(_HumbugBox5ccdb2ccdb35\Symfony\Component\Console\Input\ArgvInput), Object(_HumbugBox5ccdb2ccdb35\Symfony\Component\Console\Output\ConsoleOutput))
#43 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/vendor/symfony/console/Application.php(237): _HumbugBox5ccdb2ccdb35\Symfony\Component\Console\Application->doRunCommand(Object(PHPStan\Command\AnalyseCommand), Object(_HumbugBox5ccdb2ccdb35\Symfony\Component\Console\Input\ArgvInput), Object(_HumbugBox5ccdb2ccdb35\Symfony\Component\Console\Output\ConsoleOutput))
#44 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/vendor/symfony/console/Application.php(138): _HumbugBox5ccdb2ccdb35\Symfony\Component\Console\Application->doRun(Object(_HumbugBox5ccdb2ccdb35\Symfony\Component\Console\Input\ArgvInput), Object(_HumbugBox5ccdb2ccdb35\Symfony\Component\Console\Output\ConsoleOutput))
#45 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/bin/phpstan(77): _HumbugBox5ccdb2ccdb35\Symfony\Component\Console\Application->run()
#46 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/bin/phpstan(78): _HumbugBox5ccdb2ccdb35\{closure}()
#47 /Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan(8): require('phar:///Volumes...')
#48 {main}
  thrown in /Volumes/Work/git/phpstan-autoload-error-example/src/bootstrap.php on line 29
Fatal error: Uncaught Error: Failed opening required '/Volumes/Work/git/phpstan-autoload-error-example/src/ClassA.php' (include_path='.:/usr/local/Cellar/php/8.0.3/share/php/pear') in /Volumes/Work/git/phpstan-autoload-error-example/src/bootstrap.php:29
Stack trace:
#0 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Reflection/BetterReflection/SourceLocator/AutoloadSourceLocator.php(229): PHPStan\Command\CommandHelper::{closure}('Example\\ClassA')
#1 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Reflection/BetterReflection/SourceLocator/FileReadTrapStreamWrapper.php(46): PHPStan\Reflection\BetterReflection\SourceLocator\AutoloadSourceLocator::PHPStan\Reflection\BetterReflection\SourceLocator\{closure}()
#2 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Reflection/BetterReflection/SourceLocator/AutoloadSourceLocator.php(241): PHPStan\Reflection\BetterReflection\SourceLocator\FileReadTrapStreamWrapper::withStreamWrapperOverride(Object(Closure))
#3 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Reflection/BetterReflection/SourceLocator/AutoloadSourceLocator.php(123): PHPStan\Reflection\BetterReflection\SourceLocator\AutoloadSourceLocator->locateClassByName('Example\\ClassA')
#4 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Reflection/BetterReflection/SourceLocator/ClassBlacklistSourceLocator.php(36): PHPStan\Reflection\BetterReflection\SourceLocator\AutoloadSourceLocator->locateIdentifier(Object(PHPStan\Reflection\BetterReflection\Reflector\MemoizingClassReflector), Object(PHPStan\BetterReflection\Identifier\Identifier))
#5 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/vendor/ondrejmirtes/better-reflection/src/SourceLocator/Type/AggregateSourceLocator.php(31): PHPStan\Reflection\BetterReflection\SourceLocator\ClassBlacklistSourceLocator->locateIdentifier(Object(PHPStan\Reflection\BetterReflection\Reflector\MemoizingClassReflector), Object(PHPStan\BetterReflection\Identifier\Identifier))
#6 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/vendor/ondrejmirtes/better-reflection/src/SourceLocator/Type/MemoizingSourceLocator.php(31): PHPStan\BetterReflection\SourceLocator\Type\AggregateSourceLocator->locateIdentifier(Object(PHPStan\Reflection\BetterReflection\Reflector\MemoizingClassReflector), Object(PHPStan\BetterReflection\Identifier\Identifier))
#7 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/vendor/ondrejmirtes/better-reflection/src/Reflector/ClassReflector.php(39): PHPStan\BetterReflection\SourceLocator\Type\MemoizingSourceLocator->locateIdentifier(Object(PHPStan\Reflection\BetterReflection\Reflector\MemoizingClassReflector), Object(PHPStan\BetterReflection\Identifier\Identifier))
#8 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Reflection/BetterReflection/Reflector/MemoizingClassReflector.php(29): PHPStan\BetterReflection\Reflector\ClassReflector->reflect('Example\\ClassA')
#9 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/vendor/ondrejmirtes/better-reflection/src/Reflection/ReflectionClass.php(645): PHPStan\Reflection\BetterReflection\Reflector\MemoizingClassReflector->reflect('Example\\ClassA')
#10 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/vendor/ondrejmirtes/better-reflection/src/Reflection/ReflectionClass.php(227): PHPStan\BetterReflection\Reflection\ReflectionClass->getParentClass()
#11 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/vendor/ondrejmirtes/better-reflection/src/Reflection/ReflectionClass.php(269): PHPStan\BetterReflection\Reflection\ReflectionClass->getParentMethods()
#12 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/vendor/ondrejmirtes/better-reflection/src/Reflection/ReflectionClass.php(315): PHPStan\BetterReflection\Reflection\ReflectionClass->getMethodsIndexedByName()
#13 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/vendor/ondrejmirtes/better-reflection/src/Reflection/ReflectionClass.php(487): PHPStan\BetterReflection\Reflection\ReflectionClass->getMethods()
#14 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/vendor/ondrejmirtes/better-reflection/src/Reflection/Adapter/ReflectionClass.php(155): PHPStan\BetterReflection\Reflection\ReflectionClass->getConstructor()
#15 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Reflection/ClassReflection.php(352): PHPStan\BetterReflection\Reflection\Adapter\ReflectionClass->getConstructor()
#16 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Reflection/ClassReflection.php(340): PHPStan\Reflection\ClassReflection->findConstructor()
#17 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Rules/Classes/InstantiationRule.php(108): PHPStan\Reflection\ClassReflection->hasConstructor()
#18 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Rules/Classes/InstantiationRule.php(45): PHPStan\Rules\Classes\InstantiationRule->checkClassName('AnonymousClass4...', true, Object(PhpParser\Node\Expr\New_), Object(PHPStan\Analyser\MutatingScope))
#19 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/FileAnalyser.php(69): PHPStan\Rules\Classes\InstantiationRule->processNode(Object(PhpParser\Node\Expr\New_), Object(PHPStan\Analyser\MutatingScope))
#20 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Node/ClassStatementsGatherer.php(91): PHPStan\Analyser\FileAnalyser->PHPStan\Analyser\{closure}(Object(PhpParser\Node\Expr\New_), Object(PHPStan\Analyser\MutatingScope))
#21 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(391): PHPStan\Node\ClassStatementsGatherer->__invoke(Object(PhpParser\Node\Expr\New_), Object(PHPStan\Analyser\MutatingScope))
#22 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(2060): PHPStan\Analyser\NodeScopeResolver::PHPStan\Analyser\{closure}(Object(PhpParser\Node\Expr\New_), Object(PHPStan\Analyser\MutatingScope))
#23 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(1313): PHPStan\Analyser\NodeScopeResolver->callNodeCallbackWithExpression(Object(Closure), Object(PhpParser\Node\Expr\New_), Object(PHPStan\Analyser\MutatingScope), Object(PHPStan\Analyser\ExpressionContext))
#24 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(1329): PHPStan\Analyser\NodeScopeResolver->processExprNode(Object(PhpParser\Node\Expr\New_), Object(PHPStan\Analyser\MutatingScope), Object(Closure), Object(PHPStan\Analyser\ExpressionContext))
#25 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(2315): PHPStan\Analyser\NodeScopeResolver->PHPStan\Analyser\{closure}(Object(PHPStan\Analyser\MutatingScope))
#26 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(1337): PHPStan\Analyser\NodeScopeResolver->processAssignVar(Object(PHPStan\Analyser\MutatingScope), Object(PhpParser\Node\Expr\Variable), Object(PhpParser\Node\Expr\New_), Object(Closure), Object(PHPStan\Analyser\ExpressionContext), Object(Closure), true)
#27 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(438): PHPStan\Analyser\NodeScopeResolver->processExprNode(Object(PhpParser\Node\Expr\Assign), Object(PHPStan\Analyser\MutatingScope), Object(Closure), Object(PHPStan\Analyser\ExpressionContext))
#28 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(248): PHPStan\Analyser\NodeScopeResolver->processStmtNode(Object(PhpParser\Node\Stmt\Expression), Object(PHPStan\Analyser\MutatingScope), Object(Closure))
#29 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(402): PHPStan\Analyser\NodeScopeResolver->processStmtNodes(Object(PhpParser\Node\Stmt\ClassMethod), Array, Object(PHPStan\Analyser\MutatingScope), Object(Closure))
#30 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(248): PHPStan\Analyser\NodeScopeResolver->processStmtNode(Object(PhpParser\Node\Stmt\ClassMethod), Object(PHPStan\Analyser\MutatingScope), Object(PHPStan\Node\ClassStatementsGatherer))
#31 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(485): PHPStan\Analyser\NodeScopeResolver->processStmtNodes(Object(PhpParser\Node\Stmt\Class_), Array, Object(PHPStan\Analyser\MutatingScope), Object(PHPStan\Node\ClassStatementsGatherer))
#32 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(248): PHPStan\Analyser\NodeScopeResolver->processStmtNode(Object(PhpParser\Node\Stmt\Class_), Object(PHPStan\Analyser\MutatingScope), Object(Closure))
#33 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(451): PHPStan\Analyser\NodeScopeResolver->processStmtNodes(Object(PhpParser\Node\Stmt\Namespace_), Array, Object(PHPStan\Analyser\MutatingScope), Object(Closure))
#34 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(216): PHPStan\Analyser\NodeScopeResolver->processStmtNode(Object(PhpParser\Node\Stmt\Namespace_), Object(PHPStan\Analyser\MutatingScope), Object(Closure))
#35 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/FileAnalyser.php(149): PHPStan\Analyser\NodeScopeResolver->processNodes(Array, Object(PHPStan\Analyser\MutatingScope), Object(Closure))
#36 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/Analyser.php(52): PHPStan\Analyser\FileAnalyser->analyseFile('/Volumes/Work', Array, Object(PHPStan\Rules\Registry), NULL)
#37 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Command/AnalyserRunner.php(57): PHPStan\Analyser\Analyser->analyse(Array, Object(Closure), NULL, true, Array)
#38 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Command/AnalyseApplication.php(148): PHPStan\Command\AnalyserRunner->runAnalyser(Array, Array, Object(Closure), NULL, true, true, '/Volumes/Work', NULL, NULL, Object(_HumbugBox5ccdb2ccdb35\Symfony\Component\Console\Input\ArgvInput))
#39 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Command/AnalyseApplication.php(79): PHPStan\Command\AnalyseApplication->runAnalyser(Array, Array, true, '/Volumes/Work', Object(PHPStan\Command\Symfony\SymfonyOutput), Object(PHPStan\Command\Symfony\SymfonyOutput), Object(_HumbugBox5ccdb2ccdb35\Symfony\Component\Console\Input\ArgvInput))
#40 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/src/Command/AnalyseCommand.php(156): PHPStan\Command\AnalyseApplication->analyse(Array, true, Object(PHPStan\Command\Symfony\SymfonyOutput), Object(PHPStan\Command\Symfony\SymfonyOutput), false, true, '/Volumes/Work', Array, Object(_HumbugBox5ccdb2ccdb35\Symfony\Component\Console\Input\ArgvInput))
#41 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/vendor/symfony/console/Command/Command.php(228): PHPStan\Command\AnalyseCommand->execute(Object(_HumbugBox5ccdb2ccdb35\Symfony\Component\Console\Input\ArgvInput), Object(_HumbugBox5ccdb2ccdb35\Symfony\Component\Console\Output\ConsoleOutput))
#42 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/vendor/symfony/console/Application.php(856): _HumbugBox5ccdb2ccdb35\Symfony\Component\Console\Command\Command->run(Object(_HumbugBox5ccdb2ccdb35\Symfony\Component\Console\Input\ArgvInput), Object(_HumbugBox5ccdb2ccdb35\Symfony\Component\Console\Output\ConsoleOutput))
#43 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/vendor/symfony/console/Application.php(237): _HumbugBox5ccdb2ccdb35\Symfony\Component\Console\Application->doRunCommand(Object(PHPStan\Command\AnalyseCommand), Object(_HumbugBox5ccdb2ccdb35\Symfony\Component\Console\Input\ArgvInput), Object(_HumbugBox5ccdb2ccdb35\Symfony\Component\Console\Output\ConsoleOutput))
#44 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/vendor/symfony/console/Application.php(138): _HumbugBox5ccdb2ccdb35\Symfony\Component\Console\Application->doRun(Object(_HumbugBox5ccdb2ccdb35\Symfony\Component\Console\Input\ArgvInput), Object(_HumbugBox5ccdb2ccdb35\Symfony\Component\Console\Output\ConsoleOutput))
#45 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/bin/phpstan(77): _HumbugBox5ccdb2ccdb35\Symfony\Component\Console\Application->run()
#46 phar:///Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan.phar/bin/phpstan(78): _HumbugBox5ccdb2ccdb35\{closure}()
#47 /Volumes/Work/git/phpstan-autoload-error-example/vendor/phpstan/phpstan/phpstan(8): require('phar:///Volumes...')
#48 {main}
  thrown in /Volumes/Work/git/phpstan-autoload-error-example/src/bootstrap.php on line 29
@mergeable
Copy link

mergeable bot commented Apr 10, 2021

This bug report is missing a link to reproduction on phpstan.org.

It will most likely be closed after manual review.

@ondrejmirtes
Copy link
Member

Thank you, this is a well done bug report. The problem is that your autoloader uses require_once. If it used include_once you wouldn't bump into this issue. The problem is that FileReadTrapStreamWrapper isn't able to intercept require_once call, but is able to intercept include_once call. I don't know what to do about this, I was attempting to solve it back when implementing static reflection but was unable to do so.

@rrazor
Copy link
Author

rrazor commented Apr 10, 2021

Hey @ondrejmirtes, I think I have a fix for this. If you're interested, I'm happy to submit a PR.

I see that you were detecting the autoloaded file paths by overriding stream_open and capturing the filename. This is fine for include{,_once} because it is okay if opening the file fails. It is not fine for require{,_once}.

To make it work with require, I went ahead and returned true from stream_open and simulated reading an empty file with an overridden stream_read() and stream_close(). This allows require to be happy and still passes along the autoloaded file name to the closure, allowing PHPStan to detect the file location without errors or loading unexpected code into the runtime.

If that sounds sensible, I'll submit a PR.

@rrazor
Copy link
Author

rrazor commented Apr 10, 2021

I went ahead and made a PR; hope that is OK.

ondrejmirtes added a commit that referenced this issue Apr 11, 2021
phpstan/phpstan-src@161c383 Allow autoloaders to require/require_once for #4836 via a fake read
@github-actions
Copy link

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 12, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants