2222use PHPStan \Rules \TipRuleError ;
2323use function array_key_exists ;
2424use function array_keys ;
25+ use function array_merge ;
2526use function array_unique ;
2627use function array_values ;
28+ use function error_reporting ;
2729use function get_class ;
2830use function is_dir ;
2931use function is_file ;
3032use function is_string ;
33+ use function restore_error_handler ;
34+ use function set_error_handler ;
3135use function sprintf ;
3236use function strpos ;
37+ use const E_DEPRECATED ;
3338
3439class FileAnalyser
3540{
3641
42+ /** @var Error[] */
43+ private array $ collectedErrors = [];
44+
3745public function __construct (
3846private ScopeFactory $ scopeFactory ,
3947private NodeScopeResolver $ nodeScopeResolver ,
@@ -60,6 +68,7 @@ public function analyseFile(
6068$ exportedNodes = [];
6169if (is_file ($ file )) {
6270try {
71+ $ this ->collectErrors ($ analysedFiles );
6372$ parserNodes = $ this ->parser ->parseFile ($ file );
6473$ linesToIgnore = $ this ->getLinesToIgnoreFromTokens ($ file , $ parserNodes );
6574$ temporaryFileErrors = [];
@@ -257,6 +266,10 @@ public function analyseFile(
257266$ fileErrors [] = new Error (sprintf ('File %s does not exist. ' , $ file ), $ file , null , false );
258267}
259268
269+ $ this ->restoreCollectErrorsHandler ();
270+
271+ $ fileErrors = array_merge ($ fileErrors , $ this ->collectedErrors );
272+
260273return new FileAnalyserResult ($ fileErrors , array_values (array_unique ($ fileDependencies )), $ exportedNodes );
261274}
262275
@@ -328,4 +341,35 @@ private function findLineToIgnoreComment(Comment $comment): ?int
328341return null ;
329342}
330343
344+ /**
345+ * @param array<string, true> $analysedFiles
346+ */
347+ private function collectErrors (array $ analysedFiles ): void
348+ {
349+ $ this ->collectedErrors = [];
350+ set_error_handler (function (int $ errno , string $ errstr , string $ errfile , int $ errline ) use ($ analysedFiles ): bool {
351+ if ((error_reporting () & $ errno ) === 0 ) {
352+ // silence @ operator
353+ return true ;
354+ }
355+
356+ if ($ errno === E_DEPRECATED ) {
357+ return true ;
358+ }
359+
360+ if (!isset ($ analysedFiles [$ errfile ])) {
361+ return true ;
362+ }
363+
364+ $ this ->collectedErrors [] = new Error ($ errstr , $ errfile , $ errline , true );
365+
366+ return true ;
367+ });
368+ }
369+
370+ private function restoreCollectErrorsHandler (): void
371+ {
372+ restore_error_handler ();
373+ }
374+
331375}
0 commit comments