mirror of
https://github.com/php/php-src.git
synced 2025-08-17 14:38:49 +02:00
Implemented AST pretty-printer to capture expression passed to assert()
This commit is contained in:
parent
7a059b66d5
commit
4a2d9c0953
5 changed files with 1264 additions and 7 deletions
240
Zend/tests/assert/expect_015.phpt
Normal file
240
Zend/tests/assert/expect_015.phpt
Normal file
|
@ -0,0 +1,240 @@
|
||||||
|
--TEST--
|
||||||
|
AST pretty-peinter
|
||||||
|
--INI--
|
||||||
|
zend.assertions=1
|
||||||
|
assert.exception=0
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
assert(0 && ($a = function () {
|
||||||
|
global $a, $$b;
|
||||||
|
static $c, $d = 0;
|
||||||
|
unset($e);
|
||||||
|
$x = isset($a) && !empty($b) || eval($c);
|
||||||
|
$x = $a ? $b : $c;
|
||||||
|
$x = $a ?: $c;
|
||||||
|
$x = $a ?? $b;
|
||||||
|
list($a, $b, $c) = [1, 2=>'x', 'z'=>'c'];
|
||||||
|
@foo();
|
||||||
|
$y = clone $x;
|
||||||
|
yield 1 => 2;
|
||||||
|
}));
|
||||||
|
|
||||||
|
assert(0 && ($a = function &(array &$a, X $b = null) use ($c,&$d) : X {
|
||||||
|
abstract class A extends B implements C, D {
|
||||||
|
const X = 12;
|
||||||
|
const Y = self::X, Z = "aaa";
|
||||||
|
|
||||||
|
public $a = 1, $b;
|
||||||
|
protected $c;
|
||||||
|
static private $d = null;
|
||||||
|
|
||||||
|
abstract function foo();
|
||||||
|
|
||||||
|
static private function f1() {
|
||||||
|
for ($i = 0, $j = 100; $i < $j; $i++, --$j) {
|
||||||
|
$s[$i] = $a[$j];
|
||||||
|
}
|
||||||
|
foreach ($a as $key => &$val) {
|
||||||
|
print "$key => $val\n";
|
||||||
|
}
|
||||||
|
while ($s[$i]) {
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
$i--;
|
||||||
|
} while ($s[$i]);
|
||||||
|
$x = foo($a + 1, 4, ...[1,2,3]);
|
||||||
|
$x = ${$a . "_1"}();
|
||||||
|
$x = A::foo();
|
||||||
|
$x = ${$a . "_1"}::foo();
|
||||||
|
$x = A::${$a . "_1"}();
|
||||||
|
$x = $x->foo();
|
||||||
|
$x = ${$a . "_1"}->foo();
|
||||||
|
$x = $x->{$a . "_1"}();
|
||||||
|
$x->a = C::C;
|
||||||
|
${$a . "_1"}->a = ${$a . "_1"}::C;
|
||||||
|
$x->{a . "_1"} = C::C;
|
||||||
|
$x = C::$z;
|
||||||
|
$x = ${$a . "_1"}::$z;
|
||||||
|
$x = C::${$z . "_1"};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
assert(0 && ($a = function &(array &$a, X $b = null) use ($c,&$d) : X {
|
||||||
|
final class A {
|
||||||
|
final protected function f2() {
|
||||||
|
if (!$x) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ($x == 1) {
|
||||||
|
return 1;
|
||||||
|
} else if ($x == 2) {
|
||||||
|
return 2;
|
||||||
|
} else if ($x == 3) {
|
||||||
|
return 3;
|
||||||
|
} else {
|
||||||
|
if ($x == 9) {
|
||||||
|
return 9;
|
||||||
|
}
|
||||||
|
L0:
|
||||||
|
switch ($x) {
|
||||||
|
case 4: break;
|
||||||
|
case 5: continue;
|
||||||
|
case 6: break 2;
|
||||||
|
case 7: continue 2;
|
||||||
|
case 8: goto L0;
|
||||||
|
default: return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
assert(0 && ($a = function &(array &$a, X $b = null) use ($c,&$d) : X {
|
||||||
|
class A {
|
||||||
|
use T1, T2 {
|
||||||
|
T1::foo insteadof foo;
|
||||||
|
T2::foo as bar;
|
||||||
|
}
|
||||||
|
use T3;
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
assert(0 && ($a = function &(array &$a, X $b = null) use ($c,&$d) : X {
|
||||||
|
declare(A=1,B=2);
|
||||||
|
try {
|
||||||
|
$i++;
|
||||||
|
} catch (MyException $e) {
|
||||||
|
echo 1;
|
||||||
|
} catch (Exception $e) {
|
||||||
|
echo 2;
|
||||||
|
} finally {
|
||||||
|
echo 3;
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
Warning: Unsupported declare 'A' in %sexpect_015.php on line %d
|
||||||
|
|
||||||
|
Warning: Unsupported declare 'B' in %sexpect_015.php on line %d
|
||||||
|
|
||||||
|
Warning: assert(): assert(0 && ($a = function () {
|
||||||
|
global $a;
|
||||||
|
global $$b;
|
||||||
|
static $c;
|
||||||
|
static $d = 0;
|
||||||
|
unset($e);
|
||||||
|
$x = isset($a) && !empty($b) || eval($c);
|
||||||
|
$x = $a ? $b : $c;
|
||||||
|
$x = $a ?: $c;
|
||||||
|
$x = $a ?? $b;
|
||||||
|
list($a, $b, $c) = [1, 2 => 'x', 'z' => 'c'];
|
||||||
|
@foo();
|
||||||
|
$y = clone $x;
|
||||||
|
yield 1 => 2;
|
||||||
|
})) failed in %sexpect_015.php on line %d
|
||||||
|
|
||||||
|
Warning: assert(): assert(0 && ($a = function &(array &$a, X $b = null) use($c, &$d): X {
|
||||||
|
abstract class A extends B implements C, D {
|
||||||
|
const X = 12;
|
||||||
|
const Y = self::X, Z = 'aaa';
|
||||||
|
public $a = 1, $b;
|
||||||
|
protected $c;
|
||||||
|
private static $d = null;
|
||||||
|
public abstract function foo();
|
||||||
|
|
||||||
|
private static function f1() {
|
||||||
|
for ($i = 0, $j = 100; $i < $j; $i++, --$j) {
|
||||||
|
$s[$i] = $a[$j];
|
||||||
|
}
|
||||||
|
foreach ($a as $key => & $val) {
|
||||||
|
print "$key => $val\n";
|
||||||
|
}
|
||||||
|
while ($s[$i]) {
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
$i--;
|
||||||
|
} while ($s[$i]);
|
||||||
|
$x = foo($a + 1, 4, ... [1, 2, 3]);
|
||||||
|
$x = ${$a . '_1'}();
|
||||||
|
$x = A::foo();
|
||||||
|
$x = ${$a . '_1'}::foo();
|
||||||
|
$x = A::${$a . '_1'}();
|
||||||
|
$x = $x->foo();
|
||||||
|
$x = ${$a . '_1'}->foo();
|
||||||
|
$x = $x->{$a . '_1'}();
|
||||||
|
$x->a = C::C;
|
||||||
|
${$a . '_1'}->a = ${$a . '_1'}::C;
|
||||||
|
$x->{a . '_1'} = C::C;
|
||||||
|
$x = C::$z;
|
||||||
|
$x = ${$a . '_1'}::$z;
|
||||||
|
$x = C::${$z . '_1'};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
})) failed in %sexpect_015.php on line %d
|
||||||
|
|
||||||
|
Warning: assert(): assert(0 && ($a = function &(array &$a, X $b = null) use($c, &$d): X {
|
||||||
|
final class A {
|
||||||
|
protected final function f2() {
|
||||||
|
if (!$x) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ($x == 1) {
|
||||||
|
return 1;
|
||||||
|
} else if ($x == 2) {
|
||||||
|
return 2;
|
||||||
|
} else if ($x == 3) {
|
||||||
|
return 3;
|
||||||
|
} else {
|
||||||
|
if ($x == 9) {
|
||||||
|
return 9;
|
||||||
|
}
|
||||||
|
L0:
|
||||||
|
switch ($x) {
|
||||||
|
case 4:
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
continue;
|
||||||
|
case 6:
|
||||||
|
break 2;
|
||||||
|
case 7:
|
||||||
|
continue 2;
|
||||||
|
case 8:
|
||||||
|
goto L0;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
})) failed in %sexpect_015.php on line %d
|
||||||
|
|
||||||
|
Warning: assert(): assert(0 && ($a = function &(array &$a, X $b = null) use($c, &$d): X {
|
||||||
|
class A {
|
||||||
|
use T1, T2 {
|
||||||
|
T1::foo insteadof foo;
|
||||||
|
T2::foo as bar;
|
||||||
|
}
|
||||||
|
use T3;
|
||||||
|
}
|
||||||
|
|
||||||
|
})) failed in %sexpect_015.php on line %d
|
||||||
|
|
||||||
|
Warning: assert(): assert(0 && ($a = function &(array &$a, X $b = null) use($c, &$d): X {
|
||||||
|
declare(A = 1, B = 2);
|
||||||
|
try {
|
||||||
|
$i++;
|
||||||
|
} catch ('MyException''e') {
|
||||||
|
echo 1;
|
||||||
|
} catch ('Exception''e') {
|
||||||
|
echo 2;
|
||||||
|
} finally {
|
||||||
|
echo 3;
|
||||||
|
}
|
||||||
|
})) failed in %sexpect_015.php on line %d
|
1011
Zend/zend_ast.c
1011
Zend/zend_ast.c
File diff suppressed because it is too large
Load diff
|
@ -203,6 +203,7 @@ ZEND_API zend_ast *zend_ast_create_list(uint32_t init_children, zend_ast_kind ki
|
||||||
ZEND_API zend_ast *zend_ast_list_add(zend_ast *list, zend_ast *op);
|
ZEND_API zend_ast *zend_ast_list_add(zend_ast *list, zend_ast *op);
|
||||||
|
|
||||||
ZEND_API void zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *scope);
|
ZEND_API void zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *scope);
|
||||||
|
ZEND_API zend_string *zend_ast_export(const char *prefix, zend_ast *ast, const char *suffix);
|
||||||
|
|
||||||
ZEND_API zend_ast *zend_ast_copy(zend_ast *ast);
|
ZEND_API zend_ast *zend_ast_copy(zend_ast *ast);
|
||||||
ZEND_API void zend_ast_destroy(zend_ast *ast);
|
ZEND_API void zend_ast_destroy(zend_ast *ast);
|
||||||
|
|
|
@ -2832,11 +2832,16 @@ static int zend_compile_assert(znode *result, zend_ast_list *args, zend_string *
|
||||||
opline = zend_emit_op(NULL, ZEND_INIT_FCALL, NULL, &name_node);
|
opline = zend_emit_op(NULL, ZEND_INIT_FCALL, NULL, &name_node);
|
||||||
zend_alloc_cache_slot(opline->op2.constant);
|
zend_alloc_cache_slot(opline->op2.constant);
|
||||||
|
|
||||||
if (args->children == 1) {
|
if (args->children == 1 &&
|
||||||
/* TODO: add "assert(condition) as assertion message ??? */
|
(args->child[0]->kind != ZEND_AST_ZVAL ||
|
||||||
|
Z_TYPE_P(zend_ast_get_zval(args->child[0])) != IS_STRING)) {
|
||||||
|
/* add "assert(condition) as assertion message */
|
||||||
|
zend_ast_list_add((zend_ast*)args,
|
||||||
|
zend_ast_create_zval_from_str(
|
||||||
|
zend_ast_export("assert(", args->child[0], ")")));
|
||||||
}
|
}
|
||||||
|
|
||||||
zend_compile_call_common(result, args, fbc);
|
zend_compile_call_common(result, (zend_ast*)args, fbc);
|
||||||
|
|
||||||
CG(active_op_array)->opcodes[check_op_number].op2.opline_num = get_next_op_number(CG(active_op_array));
|
CG(active_op_array)->opcodes[check_op_number].op2.opline_num = get_next_op_number(CG(active_op_array));
|
||||||
}
|
}
|
||||||
|
|
|
@ -188,7 +188,7 @@ warning_count = 'NULL'
|
||||||
Magic, magic properties:
|
Magic, magic properties:
|
||||||
mysqli->affected_rows = ''/NULL (''/NULL)
|
mysqli->affected_rows = ''/NULL (''/NULL)
|
||||||
|
|
||||||
Warning: assert(): Assertion failed in %s on line %d
|
Warning: assert(): assert(@mysqli_get_client_info() === @$mysqli->client_info) failed in %s on line %d
|
||||||
mysqli->client_info = ''/NULL ('%s'/%s)
|
mysqli->client_info = ''/NULL ('%s'/%s)
|
||||||
mysqli->client_version = '%s'/integer ('%s'/integer)
|
mysqli->client_version = '%s'/integer ('%s'/integer)
|
||||||
mysqli->errno = ''/NULL (''/NULL)
|
mysqli->errno = ''/NULL (''/NULL)
|
||||||
|
@ -199,7 +199,7 @@ mysqli->sqlstate = ''/NULL (''/NULL)
|
||||||
mysqli->host_info = ''/NULL (''/NULL)
|
mysqli->host_info = ''/NULL (''/NULL)
|
||||||
mysqli->info = ''/NULL (''/NULL)
|
mysqli->info = ''/NULL (''/NULL)
|
||||||
|
|
||||||
Warning: assert(): Assertion failed in %s on line %d
|
Warning: assert(): assert(@mysqli_thread_id($mysqli) > @$mysqli->thread_id) failed in %s on line %d
|
||||||
mysqli->thread_id = ''/NULL (''/NULL)
|
mysqli->thread_id = ''/NULL (''/NULL)
|
||||||
mysqli->protocol_version = ''/NULL (''/NULL)
|
mysqli->protocol_version = ''/NULL (''/NULL)
|
||||||
mysqli->server_info = ''/NULL (''/NULL)
|
mysqli->server_info = ''/NULL (''/NULL)
|
||||||
|
@ -261,7 +261,7 @@ warning_count = 'NULL'
|
||||||
Magic, magic properties:
|
Magic, magic properties:
|
||||||
mysqli->affected_rows = ''/NULL (''/NULL)
|
mysqli->affected_rows = ''/NULL (''/NULL)
|
||||||
|
|
||||||
Warning: assert(): Assertion failed in %s on line %d
|
Warning: assert(): assert(@mysqli_get_client_info() === @$mysqli->client_info) failed in %s on line %d
|
||||||
mysqli->client_info = ''/NULL ('%s'/%s)
|
mysqli->client_info = ''/NULL ('%s'/%s)
|
||||||
mysqli->client_version = '%s'/integer ('%s'/integer)
|
mysqli->client_version = '%s'/integer ('%s'/integer)
|
||||||
mysqli->errno = ''/NULL (''/NULL)
|
mysqli->errno = ''/NULL (''/NULL)
|
||||||
|
@ -272,7 +272,7 @@ mysqli->sqlstate = ''/NULL (''/NULL)
|
||||||
mysqli->host_info = ''/NULL (''/NULL)
|
mysqli->host_info = ''/NULL (''/NULL)
|
||||||
mysqli->info = ''/NULL (''/NULL)
|
mysqli->info = ''/NULL (''/NULL)
|
||||||
|
|
||||||
Warning: assert(): Assertion failed in %s on line %d
|
Warning: assert(): assert(@mysqli_thread_id($mysqli) > @$mysqli->thread_id) failed in %s on line %d
|
||||||
mysqli->thread_id = ''/NULL (''/NULL)
|
mysqli->thread_id = ''/NULL (''/NULL)
|
||||||
mysqli->protocol_version = ''/NULL (''/NULL)
|
mysqli->protocol_version = ''/NULL (''/NULL)
|
||||||
mysqli->server_info = ''/NULL (''/NULL)
|
mysqli->server_info = ''/NULL (''/NULL)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue