- Add genNewClosure method to handle closure creation with correct scope - Preserve lexical class scope and late static binding for closures - Handle trait method flattening correctly when creating closures in traits - Update arrow function and fiber generator closure creation to use new method - Fix strict scalar parameter checking to run inside argument expressions - Correct trait name resolution in class definition processing - Add comprehensive test coverage for closure lexical scope behaviorpull/45/head
parent
db4b7f9e28
commit
8dd33c1400
6 changed files with 94 additions and 20 deletions
@ -0,0 +1,55 @@ |
|||||||
|
--TEST-- |
||||||
|
closures preserve lexical class scope and late static binding scope |
||||||
|
--FILE-- |
||||||
|
<?php |
||||||
|
|
||||||
|
class ClosureScopeParent |
||||||
|
{ |
||||||
|
private static string $secret = 'private'; |
||||||
|
|
||||||
|
public function callbacks(): array |
||||||
|
{ |
||||||
|
return [ |
||||||
|
fn(): string => self::$secret, |
||||||
|
static fn(): string => self::$secret, |
||||||
|
static fn(): string => static::class, |
||||||
|
]; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class ClosureScopeChild extends ClosureScopeParent |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
trait ClosureScopeTrait |
||||||
|
{ |
||||||
|
public function traitCallback(): Closure |
||||||
|
{ |
||||||
|
return static fn(): string => self::$traitSecret; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class ClosureScopeTraitUser |
||||||
|
{ |
||||||
|
use ClosureScopeTrait; |
||||||
|
|
||||||
|
private static string $traitSecret = 'trait-private'; |
||||||
|
} |
||||||
|
|
||||||
|
function main(): void |
||||||
|
{ |
||||||
|
foreach ((new ClosureScopeChild())->callbacks() as $callback) { |
||||||
|
$scope = (new ReflectionFunction($callback))->getClosureScopeClass(); |
||||||
|
echo $scope?->getName(), ':', $callback(), "\n"; |
||||||
|
} |
||||||
|
|
||||||
|
$traitCallback = (new ClosureScopeTraitUser())->traitCallback(); |
||||||
|
$traitScope = (new ReflectionFunction($traitCallback))->getClosureScopeClass(); |
||||||
|
echo $traitScope?->getName(), ':', $traitCallback(), "\n"; |
||||||
|
} |
||||||
|
?> |
||||||
|
--EXPECT-- |
||||||
|
ClosureScopeParent:private |
||||||
|
ClosureScopeParent:private |
||||||
|
ClosureScopeParent:ClosureScopeChild |
||||||
|
ClosureScopeTraitUser:trait-private |
||||||
Loading…
Reference in new issue