@@ -123,12 +123,13 @@ public static function transformSource(string $source, string $filePath = ''): s
123123
124124 $ parser = (new ParserFactory ())->createForNewestSupportedVersion ();
125125
126- try {
126+ try {
127127 $ oldStmts = $ parser ->parse ($ source );
128128 if ($ oldStmts === null ) {
129129 return $ source ;
130130 }
131131 } catch (\Throwable $ e ) {
132+ fwrite (STDERR , "[TYPEPHP_DEBUG AST_PARSE_ERROR] File: $ filePath | Error: " . $ e ->getMessage () . " on line " . $ e ->getLine () . "\n" );
132133 return $ source ;
133134 }
134135
@@ -191,14 +192,30 @@ public function stream_open(string $path, string $mode, int $options, ?string &$
191192 }
192193
193194 self ::unregister ();
194- $ exists = self ::silent (fn () => file_exists ($ path ));
195- $ resolvedPath = $ exists ? realpath ($ path ) : '' ;
195+ $ exists = self ::silent (fn () => file_exists ($ path ));
196+ $ resolvedPath = $ exists ? realpath ($ path ) : false ;
196197 self ::register ();
197198
198- $ isAppFile = $ exists && ! self ::isReadOnlyCall () && self ::isApplicationFile ($ path , $ resolvedPath );
199+ if (! $ exists || $ resolvedPath === false ) {
200+ return $ this ->openDirectHandle ($ path , $ mode );
201+ }
202+
203+ $ normalizedResolved = str_replace ('\\' , '/ ' , $ resolvedPath );
204+
205+ $ isApp = self ::isApplicationFile ($ path , $ resolvedPath );
206+ $ isReadOnly = self ::isReadOnlyCall ();
199207
200- if (! $ isAppFile || $ resolvedPath === false ) {
201- return $ this ->openDirectHandle (($ resolvedPath !== false && $ resolvedPath !== '' ) ? $ resolvedPath : $ path , $ mode );
208+ // >>> DEBUG PROBE <<<
209+ if (str_contains ($ path , 'Container ' ) || str_contains ($ path , 'Producer ' ) || str_contains ($ path , 'GenericsAndInheritance ' )) {
210+ fwrite (STDERR , "[TYPEPHP_DEBUG stream_open] Path: $ path | isApp: " . ($ isApp ? 'TRUE ' : 'FALSE ' ) . " | isReadOnly: " . ($ isReadOnly ? 'TRUE ' : 'FALSE ' ) . " | CacheEnabled: " . (self ::$ cacheEnabled ? 'TRUE ' : 'FALSE ' ) . "\n" );
211+ }
212+
213+ if (! $ isApp ) {
214+ return $ this ->openDirectHandle ($ normalizedResolved , $ mode );
215+ }
216+
217+ if ($ isReadOnly ) {
218+ return $ this ->openDirectHandle ($ normalizedResolved , $ mode );
202219 }
203220
204221 self ::unregister ();
@@ -219,7 +236,7 @@ private function openDirectHandle(string $targetFile, string $mode): bool
219236 {
220237 self ::unregister ();
221238 /** @var resource|false $handle */
222- $ handle = self ::silent (fn () => fopen ($ targetFile , $ mode ));
239+ $ handle = self ::silent (fn () => fopen ($ targetFile , $ mode ));
223240 $ this ->handle = $ handle !== false ? $ handle : null ;
224241 self ::register ();
225242
@@ -359,7 +376,7 @@ public function url_stat(string $path, int $flags): array|false
359376
360377 self ::unregister ();
361378 /** @var array<int|string, int>|false $result */
362- $ result = self ::silent (fn () => stat ($ path ));
379+ $ result = self ::silent (fn () => stat ($ path ));
363380 self ::register ();
364381
365382 // Only cache positive results (existing files/dirs)
@@ -382,11 +399,11 @@ public function stream_metadata(string $path, int $option, mixed $value): bool
382399 $ valueArray = \is_array ($ value ) ? $ value : [];
383400 $ time = $ valueArray [0 ] ?? time ();
384401 $ atime = $ valueArray [1 ] ?? $ time ;
385- $ result = (bool ) self ::silent (fn () => touch ($ path , (int ) $ time , (int ) $ atime ));
402+ $ result = (bool ) self ::silent (fn () => touch ($ path , (int ) $ time , (int ) $ atime ));
386403 } elseif ($ option === STREAM_META_ACCESS ) {
387404 /** @var int $mode */
388405 $ mode = \is_int ($ value ) ? $ value : 0777 ;
389- $ result = (bool ) self ::silent (fn () => chmod ($ path , $ mode ));
406+ $ result = (bool ) self ::silent (fn () => chmod ($ path , $ mode ));
390407 }
391408 self ::register ();
392409
@@ -397,7 +414,7 @@ public function dir_opendir(string $path, int $options): bool
397414 {
398415 self ::unregister ();
399416 /** @var resource|false $dh */
400- $ dh = self ::silent (fn () => opendir ($ path ));
417+ $ dh = self ::silent (fn () => opendir ($ path ));
401418 $ this ->dirHandle = $ dh !== false ? $ dh : null ;
402419 self ::register ();
403420
@@ -440,7 +457,7 @@ public function mkdir(string $path, int $mode, int $options): bool
440457 unset(self ::$ statCache [$ normalized ]);
441458
442459 self ::unregister ();
443- $ result = (bool ) self ::silent (fn () => mkdir ($ path , $ mode , (bool ) ($ options & STREAM_MKDIR_RECURSIVE )));
460+ $ result = (bool ) self ::silent (fn () => mkdir ($ path , $ mode , (bool ) ($ options & STREAM_MKDIR_RECURSIVE )));
444461 self ::register ();
445462
446463 return $ result ;
@@ -452,7 +469,7 @@ public function rmdir(string $path, int $options): bool
452469 unset(self ::$ statCache [$ normalized ]);
453470
454471 self ::unregister ();
455- $ result = (bool ) self ::silent (fn () => rmdir ($ path ));
472+ $ result = (bool ) self ::silent (fn () => rmdir ($ path ));
456473 self ::register ();
457474
458475 return $ result ;
@@ -464,7 +481,7 @@ public function unlink(string $path): bool
464481 unset(self ::$ statCache [$ normalized ]);
465482
466483 self ::unregister ();
467- $ result = (bool ) self ::silent (fn () => unlink ($ path ));
484+ $ result = (bool ) self ::silent (fn () => unlink ($ path ));
468485 self ::register ();
469486
470487 return $ result ;
@@ -477,7 +494,7 @@ public function rename(string $pathFrom, string $pathTo): bool
477494 unset(self ::$ statCache [$ normFrom ], self ::$ statCache [$ normTo ]);
478495
479496 self ::unregister ();
480- $ result = (bool ) self ::silent (fn () => rename ($ pathFrom , $ pathTo ));
497+ $ result = (bool ) self ::silent (fn () => rename ($ pathFrom , $ pathTo ));
481498 self ::register ();
482499
483500 return $ result ;
@@ -490,7 +507,7 @@ public function rename(string $pathFrom, string $pathTo): bool
490507 private static function isReadOnlyCall (): bool
491508 {
492509 $ trace = debug_backtrace (DEBUG_BACKTRACE_IGNORE_ARGS , 3 );
493-
510+
494511 $ caller1 = strtolower ($ trace [1 ]['function ' ] ?? '' );
495512 $ caller2 = strtolower ($ trace [2 ]['function ' ] ?? '' );
496513
@@ -508,7 +525,7 @@ private static function isReadOnlyCall(): bool
508525 */
509526 private static function silent (callable $ callback ): mixed
510527 {
511- set_error_handler (fn () => true );
528+ set_error_handler (fn () => true );
512529
513530 try {
514531 return $ callback ();
@@ -581,7 +598,7 @@ private function openCachedStream(string $resolvedPath, string $mode): bool
581598 {
582599 $ cacheDir = self ::$ cacheDir ;
583600 if (! is_dir ($ cacheDir )) {
584- self ::silent (fn () => mkdir ($ cacheDir , 0777 , true ));
601+ self ::silent (fn () => mkdir ($ cacheDir , 0777 , true ));
585602 }
586603
587604 $ cachedFile = CacheManager::getCachedFilePath ($ resolvedPath );
@@ -663,4 +680,4 @@ private static function extractAndSeedFileMetadata(array $stmts, string $filePat
663680
664681 SpecialTypeResolver::seedFileMetadata ($ filePath , $ namespace , $ imports , $ classTraitUseDocs );
665682 }
666- }
683+ }
0 commit comments