- 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