- Introduce --php-version CLI option to specify accepted PHP syntax version - Add support for PHP 8.5 pipe operator with left-to-right evaluation - Implement PHP version validation in project configuration parsing - Update parser factory usage to respect configured PHP version - Add tests for pipe operator functionality and PHP version controls - Modify stub generation to use configured PHP version - Update documentation with new --php-version option detailspull/17/head
parent
6059e07827
commit
bd2a3da14c
11 changed files with 406 additions and 13 deletions
@ -0,0 +1,15 @@ |
||||
--TEST-- |
||||
echo accepts assignment expressions |
||||
--FILE-- |
||||
<?php |
||||
|
||||
function main(): void |
||||
{ |
||||
echo $first = 'first', ':', $second = 2, "\n"; |
||||
var_dump($first, $second); |
||||
} |
||||
?> |
||||
--EXPECT-- |
||||
first:2 |
||||
string(5) "first" |
||||
int(2) |
||||
@ -0,0 +1,50 @@ |
||||
--TEST-- |
||||
PHP 8.5 pipe operator |
||||
--FILE-- |
||||
<?php |
||||
|
||||
function mark(string $value): string |
||||
{ |
||||
echo "left:$value\n"; |
||||
return $value; |
||||
} |
||||
|
||||
function suffix(string $value): string |
||||
{ |
||||
return $value . '!'; |
||||
} |
||||
|
||||
class PipeFormatter |
||||
{ |
||||
public static function wrap(string $value): string |
||||
{ |
||||
return '[' . $value . ']'; |
||||
} |
||||
|
||||
public function suffix(string $value): string |
||||
{ |
||||
return $value . '!'; |
||||
} |
||||
} |
||||
|
||||
function main(): void |
||||
{ |
||||
$callable = suffix(...); |
||||
$result = mark(' hello ') |
||||
|> trim(...) |
||||
|> PipeFormatter::wrap(...) |
||||
|> $callable |
||||
|> (fn(string $value): string => strtoupper($value)); |
||||
|
||||
$formatter = new PipeFormatter(); |
||||
$methodResult = mark('method') |> $formatter->suffix(...); |
||||
|
||||
var_dump($result); |
||||
var_dump($methodResult); |
||||
} |
||||
?> |
||||
--EXPECT-- |
||||
left: hello |
||||
left:method |
||||
string(8) "[HELLO]!" |
||||
string(7) "method!" |
||||
@ -0,0 +1,85 @@ |
||||
--TEST-- |
||||
Dynamic class, function, callback and property chain use runtime fallback |
||||
--FILE-- |
||||
<?php |
||||
|
||||
class RuntimeFallbackLeaf |
||||
{ |
||||
public string $value = 'leaf'; |
||||
} |
||||
|
||||
class RuntimeFallbackBox |
||||
{ |
||||
public RuntimeFallbackLeaf $child; |
||||
|
||||
public function __construct() |
||||
{ |
||||
$this->child = new RuntimeFallbackLeaf(); |
||||
} |
||||
|
||||
public function format(string $value): string |
||||
{ |
||||
return 'method:' . $value; |
||||
} |
||||
} |
||||
|
||||
class RuntimeFallbackStatic |
||||
{ |
||||
public static string $value = 'before'; |
||||
|
||||
public static function format(string $value): string |
||||
{ |
||||
return 'static:' . $value; |
||||
} |
||||
} |
||||
|
||||
function runtime_fallback_function(string $value): string |
||||
{ |
||||
return 'function:' . $value; |
||||
} |
||||
|
||||
function class_name(): string |
||||
{ |
||||
return RuntimeFallbackBox::class; |
||||
} |
||||
|
||||
function function_name(): string |
||||
{ |
||||
return 'runtime_fallback_function'; |
||||
} |
||||
|
||||
function main(): void |
||||
{ |
||||
$class = class_name(); |
||||
$box = new $class(); |
||||
$property = 'child'; |
||||
$nested = 'value'; |
||||
var_dump($box->$property->$nested); |
||||
$box->$property->$nested = 'changed'; |
||||
var_dump($box->$property->$nested); |
||||
|
||||
$function = function_name(); |
||||
var_dump($function('ok')); |
||||
|
||||
$method = 'format'; |
||||
$callback = [$box, $method]; |
||||
var_dump($callback('ok')); |
||||
|
||||
$staticClass = any(RuntimeFallbackStatic::class); |
||||
$staticProperty = any('value'); |
||||
var_dump($staticClass::$$staticProperty); |
||||
$staticClass::$$staticProperty = 'after'; |
||||
var_dump($staticClass::$$staticProperty); |
||||
|
||||
$staticMethod = any('format'); |
||||
var_dump($staticClass::$staticMethod('ok')); |
||||
} |
||||
?> |
||||
--EXPECT-- |
||||
string(4) "leaf" |
||||
string(7) "changed" |
||||
string(11) "function:ok" |
||||
string(9) "method:ok" |
||||
string(6) "before" |
||||
string(5) "after" |
||||
string(9) "static:ok" |
||||
@ -0,0 +1,77 @@ |
||||
--TEST-- |
||||
parent dynamic method lookup uses the lexical parent class and current call scope |
||||
--FILE-- |
||||
<?php |
||||
|
||||
class ParentDynamicMethod |
||||
{ |
||||
public function greet(string $name): string |
||||
{ |
||||
return 'parent:' . $name; |
||||
} |
||||
|
||||
protected function protectedGreet(): string |
||||
{ |
||||
return 'protected parent'; |
||||
} |
||||
} |
||||
|
||||
class ChildDynamicMethod extends ParentDynamicMethod |
||||
{ |
||||
public function greet(string $name): string |
||||
{ |
||||
return 'child:' . $name; |
||||
} |
||||
|
||||
public function callParent(string $method, mixed ...$args): mixed |
||||
{ |
||||
return parent::$method(...$args); |
||||
} |
||||
} |
||||
|
||||
class GrandchildDynamicMethod extends ChildDynamicMethod |
||||
{ |
||||
public function greet(string $name): string |
||||
{ |
||||
return 'grandchild:' . $name; |
||||
} |
||||
} |
||||
|
||||
class ParentDynamicStaticMethod |
||||
{ |
||||
public static function greet(string $name): string |
||||
{ |
||||
return 'static parent:' . $name; |
||||
} |
||||
} |
||||
|
||||
class ChildDynamicStaticMethod extends ParentDynamicStaticMethod |
||||
{ |
||||
public static function greet(string $name): string |
||||
{ |
||||
return 'static child:' . $name; |
||||
} |
||||
|
||||
public static function callParent(string $method, mixed ...$args): mixed |
||||
{ |
||||
return parent::$method(...$args); |
||||
} |
||||
} |
||||
|
||||
function main(): void |
||||
{ |
||||
$child = new ChildDynamicMethod; |
||||
var_dump($child->callParent('greet', 'Ada')); |
||||
var_dump($child->callParent('protectedGreet')); |
||||
|
||||
$grandchild = new GrandchildDynamicMethod; |
||||
var_dump($grandchild->callParent('greet', 'Lin')); |
||||
|
||||
var_dump(ChildDynamicStaticMethod::callParent('greet', 'Sam')); |
||||
} |
||||
?> |
||||
--EXPECT-- |
||||
string(10) "parent:Ada" |
||||
string(16) "protected parent" |
||||
string(10) "parent:Lin" |
||||
string(17) "static parent:Sam" |
||||
Loading…
Reference in new issue