Skip to content

Commit 5a09b9f

Browse files
committed
Add PhpToken class
RFC: https://wiki.php.net/rfc/token_as_object Relative to the RFC, this also adds a __toString() method, as discussed on list. Closes GH-5176.
1 parent f74e30c commit 5a09b9f

13 files changed

+1001
-50
lines changed

UPGRADING

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,12 @@ PHP 8.0 UPGRADE NOTES
533533
7. New Classes and Interfaces
534534
========================================
535535

536+
- Tokenizer:
537+
. The new PhpToken class adds an object-based interface to the tokenizer.
538+
It provides a more uniform and ergonomic representation, while being more
539+
memory efficient and faster.
540+
RFC: https://wiki.php.net/rfc/token_as_object
541+
536542
========================================
537543
8. Removed Extensions and SAPIs
538544
========================================
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
--TEST--
2+
PhpToken constructor
3+
--SKIPIF--
4+
<?php if (!extension_loaded("tokenizer")) print "skip tokenizer extension not enabled"; ?>
5+
--FILE--
6+
<?php
7+
8+
$token = new PhpToken(300, 'function');
9+
var_dump($token);
10+
$token = new PhpToken(300, 'function', 10);
11+
var_dump($token);
12+
$token = new PhpToken(300, 'function', 10, 100);
13+
var_dump($token);
14+
15+
?>
16+
--EXPECT--
17+
object(PhpToken)#1 (4) {
18+
["id"]=>
19+
int(300)
20+
["text"]=>
21+
string(8) "function"
22+
["line"]=>
23+
int(-1)
24+
["pos"]=>
25+
int(-1)
26+
}
27+
object(PhpToken)#2 (4) {
28+
["id"]=>
29+
int(300)
30+
["text"]=>
31+
string(8) "function"
32+
["line"]=>
33+
int(10)
34+
["pos"]=>
35+
int(-1)
36+
}
37+
object(PhpToken)#1 (4) {
38+
["id"]=>
39+
int(300)
40+
["text"]=>
41+
string(8) "function"
42+
["line"]=>
43+
int(10)
44+
["pos"]=>
45+
int(100)
46+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
--TEST--
2+
Extending the PhpToken class
3+
--SKIPIF--
4+
<?php if (!extension_loaded("tokenizer")) print "skip tokenizer extension not enabled"; ?>
5+
--FILE--
6+
<?php
7+
8+
$code = <<<'PHP'
9+
<?PHP
10+
FUNCTION FOO() {
11+
ECHO "bar";
12+
}
13+
PHP;
14+
15+
class MyPhpToken extends PhpToken {
16+
public int $extra = 123;
17+
18+
public function getLoweredText(): string {
19+
return strtolower($this->text);
20+
}
21+
}
22+
23+
foreach (MyPhpToken::getAll($code) as $token) {
24+
echo $token->getLoweredText();
25+
26+
if ($token->extra !== 123) {
27+
echo "Missing property!\n";
28+
}
29+
}
30+
31+
?>
32+
--EXPECT--
33+
<?php
34+
function foo() {
35+
echo "bar";
36+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
--TEST--
2+
PhpToken extensions that throw during construction
3+
--SKIPIF--
4+
<?php if (!extension_loaded("tokenizer")) print "skip tokenizer extension not enabled"; ?>
5+
--FILE--
6+
<?php
7+
8+
class MyPhpToken1 extends PhpToken {
9+
public $extra = UNKNOWN;
10+
}
11+
12+
try {
13+
var_dump(MyPhpToken1::getAll("<?php foo"));
14+
} catch (Error $e) {
15+
echo $e->getMessage(), "\n";
16+
}
17+
18+
abstract class MyPhpToken2 extends PhpToken {
19+
}
20+
21+
try {
22+
var_dump(MyPhpToken2::getAll("<?php foo"));
23+
} catch (Error $e) {
24+
echo $e->getMessage(), "\n";
25+
}
26+
27+
?>
28+
--EXPECT--
29+
Undefined constant 'UNKNOWN'
30+
Cannot instantiate abstract class MyPhpToken2
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
--TEST--
2+
Check that the PhpToken constructor is final
3+
--SKIPIF--
4+
<?php if (!extension_loaded("tokenizer")) print "skip tokenizer extension not enabled"; ?>
5+
--FILE--
6+
<?php
7+
8+
class MyPhpToken extends PhpToken {
9+
public function __construct() {
10+
}
11+
}
12+
13+
?>
14+
--EXPECTF--
15+
Fatal error: Cannot override final method PhpToken::__construct() in %s on line %d

0 commit comments

Comments
 (0)