@@ -206,7 +206,6 @@ public static function castFrameStub(FrameStub $frame, array $a, Stub $stub, $is
206206 $ f ['file ' ] = substr ($ f ['file ' ], 0 , -\strlen ($ match [0 ]));
207207 $ f ['line ' ] = (int ) $ match [1 ];
208208 }
209- $ caller = isset ($ f ['function ' ]) ? sprintf ('in %s() on line %d ' , (isset ($ f ['class ' ]) ? $ f ['class ' ].$ f ['type ' ] : '' ).$ f ['function ' ], $ f ['line ' ]) : null ;
210209 $ src = $ f ['line ' ];
211210 $ srcKey = $ f ['file ' ];
212211 $ ellipsis = new LinkStub ($ srcKey , 0 );
@@ -226,13 +225,13 @@ public static function castFrameStub(FrameStub $frame, array $a, Stub $stub, $is
226225 $ templatePath = null ;
227226 }
228227 if ($ templateSrc ) {
229- $ src = self ::extractSource ($ templateSrc , $ templateInfo [$ f ['line ' ]], self ::$ srcContext , $ caller , 'twig ' , $ templatePath );
228+ $ src = self ::extractSource ($ templateSrc , $ templateInfo [$ f ['line ' ]], self ::$ srcContext , 'twig ' , $ templatePath, $ f );
230229 $ srcKey = ($ templatePath ?: $ template ->getTemplateName ()).': ' .$ templateInfo [$ f ['line ' ]];
231230 }
232231 }
233232 }
234233 if ($ srcKey == $ f ['file ' ]) {
235- $ src = self ::extractSource (file_get_contents ($ f ['file ' ]), $ f ['line ' ], self ::$ srcContext , $ caller , 'php ' , $ f ['file ' ]);
234+ $ src = self ::extractSource (file_get_contents ($ f ['file ' ]), $ f ['line ' ], self ::$ srcContext , 'php ' , $ f ['file ' ], $ f );
236235 $ srcKey .= ': ' .$ f ['line ' ];
237236 if ($ ellipsis ) {
238237 $ ellipsis += 1 + \strlen ($ f ['line ' ]);
@@ -308,7 +307,7 @@ private static function traceUnshift(array &$trace, ?string $class, string $file
308307 ]);
309308 }
310309
311- private static function extractSource (string $ srcLines , int $ line , int $ srcContext , ? string $ title , string $ lang , string $ file = null ): EnumStub
310+ private static function extractSource (string $ srcLines , int $ line , int $ srcContext , string $ lang , ? string $ file, array $ frame ): EnumStub
312311 {
313312 $ srcLines = explode ("\n" , $ srcLines );
314313 $ src = [];
@@ -317,7 +316,32 @@ private static function extractSource(string $srcLines, int $line, int $srcConte
317316 $ src [] = (isset ($ srcLines [$ i ]) ? $ srcLines [$ i ] : '' )."\n" ;
318317 }
319318
320- $ srcLines = [];
319+ if ($ frame ['function ' ] ?? false ) {
320+ $ stub = new CutStub (new \stdClass ());
321+ $ stub ->class = (isset ($ frame ['class ' ]) ? $ frame ['class ' ].$ frame ['type ' ] : '' ).$ frame ['function ' ];
322+ $ stub ->type = Stub::TYPE_OBJECT ;
323+ $ stub ->attr ['cut_hash ' ] = true ;
324+ $ stub ->attr ['file ' ] = $ frame ['file ' ];
325+ $ stub ->attr ['line ' ] = $ frame ['line ' ];
326+
327+ try {
328+ $ caller = isset ($ frame ['class ' ]) ? new \ReflectionMethod ($ frame ['class ' ], $ frame ['function ' ]) : new \ReflectionFunction ($ frame ['function ' ]);
329+ $ stub ->class .= ReflectionCaster::getSignature (ReflectionCaster::castFunctionAbstract ($ caller , [], $ stub , true , Caster::EXCLUDE_VERBOSE ));
330+
331+ if ($ f = $ caller ->getFileName ()) {
332+ $ stub ->attr ['file ' ] = $ f ;
333+ $ stub ->attr ['line ' ] = $ caller ->getStartLine ();
334+ }
335+ } catch (\ReflectionException $ e ) {
336+ // ignore fake class/function
337+ }
338+
339+ $ srcLines = ["\0~separator= \0" => $ stub ];
340+ } else {
341+ $ stub = null ;
342+ $ srcLines = [];
343+ }
344+
321345 $ ltrim = 0 ;
322346 do {
323347 $ pad = null ;
@@ -344,7 +368,7 @@ private static function extractSource(string $srcLines, int $line, int $srcConte
344368 if ($ i !== $ srcContext ) {
345369 $ c = new ConstStub ('default ' , $ c );
346370 } else {
347- $ c = new ConstStub ($ c , $ title );
371+ $ c = new ConstStub ($ c , $ stub ? ' in ' . $ stub -> class : '' );
348372 if (null !== $ file ) {
349373 $ c ->attr ['file ' ] = $ file ;
350374 $ c ->attr ['line ' ] = $ line ;
0 commit comments