fix(trait): preserve cross-instance method scope (fixes #67)
parent
24924673ec
commit
456f1a38b2
3 changed files with 137 additions and 22 deletions
@ -0,0 +1,53 @@ |
||||
--TEST-- |
||||
Private, nested and aliased trait methods retain class scope across instances |
||||
--FILE-- |
||||
<?php |
||||
|
||||
trait NestedPrivateMethod |
||||
{ |
||||
private function nestedSecret(): string |
||||
{ |
||||
return 'nested'; |
||||
} |
||||
} |
||||
|
||||
trait NestedPrivateComposition |
||||
{ |
||||
use NestedPrivateMethod; |
||||
} |
||||
|
||||
trait AliasMethodSource |
||||
{ |
||||
protected function sourceSecret(): string |
||||
{ |
||||
return 'alias'; |
||||
} |
||||
} |
||||
|
||||
class PrivateTraitConsumer |
||||
{ |
||||
use NestedPrivateComposition; |
||||
use AliasMethodSource { |
||||
sourceSecret as private aliasSecret; |
||||
} |
||||
|
||||
public function readOther(): string |
||||
{ |
||||
$other = new static(); |
||||
return $other->nestedSecret() . ':' . $other->aliasSecret(); |
||||
} |
||||
} |
||||
|
||||
class PrivateTraitChild extends PrivateTraitConsumer |
||||
{ |
||||
} |
||||
|
||||
function main(): void |
||||
{ |
||||
echo (new PrivateTraitConsumer())->readOther(), "\n"; |
||||
echo (new PrivateTraitChild())->readOther(), "\n"; |
||||
} |
||||
?> |
||||
--EXPECT-- |
||||
nested:alias |
||||
nested:alias |
||||
@ -0,0 +1,57 @@ |
||||
--TEST-- |
||||
Trait-composed protected methods retain class scope across instances |
||||
--FILE-- |
||||
<?php |
||||
|
||||
trait CrossInstanceEvents |
||||
{ |
||||
protected function fire(string $event): string |
||||
{ |
||||
return 'base:' . $event; |
||||
} |
||||
|
||||
protected function marker(): string |
||||
{ |
||||
return 'marker'; |
||||
} |
||||
} |
||||
|
||||
class CrossInstanceBase |
||||
{ |
||||
use CrossInstanceEvents; |
||||
|
||||
public function touchSelf(): string |
||||
{ |
||||
$other = new self(); |
||||
return $other->marker() . ':' . $other->fire('self'); |
||||
} |
||||
|
||||
public function touchStatic(): string |
||||
{ |
||||
$other = new static(); |
||||
return $other->marker() . ':' . $other->fire('static'); |
||||
} |
||||
} |
||||
|
||||
class CrossInstanceChild extends CrossInstanceBase |
||||
{ |
||||
protected function fire(string $event): string |
||||
{ |
||||
return 'child:' . $event; |
||||
} |
||||
} |
||||
|
||||
function main(): void |
||||
{ |
||||
$base = new CrossInstanceBase(); |
||||
echo $base->touchSelf(), "\n"; |
||||
echo $base->touchStatic(), "\n"; |
||||
|
||||
$child = new CrossInstanceChild(); |
||||
echo $child->touchStatic(), "\n"; |
||||
} |
||||
?> |
||||
--EXPECT-- |
||||
marker:base:self |
||||
marker:base:static |
||||
marker:child:static |
||||
Loading…
Reference in new issue