deploy: v0.12 fix 存档key名

This commit is contained in:
2026-06-24 03:09:02 +00:00
parent 7a08d49fe3
commit e0a5281119
58743 changed files with 7297269 additions and 39505 deletions
+1
View File
@@ -0,0 +1 @@
39573
+365
View File
@@ -0,0 +1,365 @@
# Abstract class
<?php
abstract class A {
public function a() {}
abstract public function b();
}
==>
Template(
TextInterpolation(PhpOpen),
ClassDeclaration(abstract, class,
Name,
DeclarationList(
MethodDeclaration(Visibility, function,
Name,
ParamList,
Block
),
MethodDeclaration(abstract, Visibility, function,
Name,
ParamList
)
)
)
)
# Anonymous classes
<?php
new class {
public function test() {}
};
new class extends A implements B, C {};
new class() {
public $foo;
};
new class($a, $b) extends A {
use T;
};
class A {
public function test() {
return new class($this) extends A {
const A = 'B';
};
}
}
==>
Template(
TextInterpolation(PhpOpen),
ExpressionStatement(
NewExpression(new, class,
DeclarationList(
MethodDeclaration(Visibility, function,
Name,
ParamList,
Block
)
)
)
),
ExpressionStatement(
NewExpression(new, class,
BaseClause(extends, Name),
ClassInterfaceClause(implements, Name, Name),
DeclarationList
)
),
ExpressionStatement(
NewExpression(new, class,
ArgList,
DeclarationList(
PropertyDeclaration(
Visibility,
VariableDeclarator(
VariableName
)
)
)
)
),
ExpressionStatement(
NewExpression(new, class,
ArgList(VariableName, VariableName),
BaseClause(extends, Name),
DeclarationList(
UseDeclaration(use,
Name
)
)
)
),
ClassDeclaration(class,
Name,
DeclarationList(
MethodDeclaration(Visibility, function,
Name,
ParamList,
Block(
ReturnStatement(return,
NewExpression(new, class,
ArgList(VariableName),
BaseClause(extends, Name),
DeclarationList(
ConstDeclaration(const,
VariableDeclarator(Name, AssignOp, String)
)
)
)
)
)
)
)
)
)
# Conditional class definition
<?php
if (true) {
class A {}
}
==>
Template(
TextInterpolation(PhpOpen),
IfStatement(if,
ParenthesizedExpression(Boolean),
Block(
ClassDeclaration(class,
Name,
DeclarationList
)
)
)
)
# Class constant modifiers
<?php
class Foo {
const A = 1;
public const B = 2;
protected const C = 3;
private const D = 4;
final const E = 5;
}
==>
Template(
TextInterpolation(PhpOpen),
ClassDeclaration(class,
Name,
DeclarationList(
ConstDeclaration(const,
VariableDeclarator(Name, AssignOp, Integer)
),
ConstDeclaration(Visibility, const,
VariableDeclarator(Name, AssignOp, Integer)
),
ConstDeclaration(Visibility, const,
VariableDeclarator(Name, AssignOp, Integer)
),
ConstDeclaration(Visibility, const,
VariableDeclarator(Name, AssignOp, Integer)
),
ConstDeclaration(final, const,
VariableDeclarator(Name, AssignOp, Integer)
)
)
)
)
# Final class
<?php
final class A {}
==>
Template(
TextInterpolation(PhpOpen),
ClassDeclaration(final, class,
Name,
DeclarationList
)
)
# Implicitly public properties and methods
<?php
abstract class A {
var $a;
static $b;
abstract function c();
final function d() {}
static function e() {}
final static function f() {}
function g() {}
}
==>
Template(
TextInterpolation(PhpOpen),
ClassDeclaration(abstract, class,
Name,
DeclarationList(
PropertyDeclaration(
var,
VariableDeclarator(VariableName)
),
PropertyDeclaration(
static,
VariableDeclarator(VariableName)
),
MethodDeclaration(abstract, function,
Name,
ParamList
),
MethodDeclaration(final, function,
Name,
ParamList,
Block
),
MethodDeclaration(static, function,
Name,
ParamList,
Block
),
MethodDeclaration(final, static, function,
Name,
ParamList,
Block
),
MethodDeclaration(function,
Name,
ParamList,
Block
)
)
)
)
# Property Types
<?php
class A {
public string $a;
protected static D $b;
private ?float $c;
private $d;
}
==>
Template(
TextInterpolation(PhpOpen),
ClassDeclaration(class,
Name,
DeclarationList(
PropertyDeclaration(
Visibility,
NamedType(Name),
VariableDeclarator(VariableName)
),
PropertyDeclaration(
Visibility,
static,
NamedType(Name),
VariableDeclarator(VariableName)
),
PropertyDeclaration(
Visibility,
OptionalType(LogicOp, NamedType(Name)),
VariableDeclarator(VariableName)
),
PropertyDeclaration(
Visibility,
VariableDeclarator(VariableName)
)
)
)
)
# Constructor Property Promotion
<?php
class Point {
public function __construct(
public float $x = 0.0,
float $y = 0.0,
private float $z = 0.0
) {}
}
==>
Template(
TextInterpolation(PhpOpen),
ClassDeclaration(class,
Name,
DeclarationList(
MethodDeclaration(Visibility, function,
Name,
ParamList(
PropertyParameter(
Visibility,
NamedType(Name),
VariableName,
AssignOp,
Float
),
Parameter(
NamedType(Name),
VariableName,
AssignOp,
Float
),
PropertyParameter(
Visibility,
NamedType(Name),
VariableName,
AssignOp,
Float
)
),
Block
)
)
)
)
# Class constant
<?php
A::class;
==>
Template(
TextInterpolation(PhpOpen),
ExpressionStatement(
ScopedExpression(
Name,
ClassMemberName(Name)
),
";"
)
)
+535
View File
@@ -0,0 +1,535 @@
# Interface declarations
<?php
interface ThrowableInterface {
public function getMessage();
}
class Exception_foo implements ThrowableInterface {
public $foo = "foo";
public function getMessage() {
return $this->foo;
}
}
==>
Template(
TextInterpolation(PhpOpen),
InterfaceDeclaration(interface,
Name,
DeclarationList(
MethodDeclaration(
Visibility,
function,
Name,
ParamList))),
ClassDeclaration(
class,
Name,
ClassInterfaceClause(implements, Name),
DeclarationList(
PropertyDeclaration(
Visibility,
VariableDeclarator(VariableName, AssignOp, String)),
MethodDeclaration(
Visibility,
function,
Name,
ParamList,
Block(
ReturnStatement(return,MemberExpression(
VariableName,
Name)))))))
# Use declarations
<?php
trait AbstractTrait
{
use LoggerAwareTrait;
use LoggerAwareTrait, OtherTrait {}
use LoggerAwareTrait, OtherTrait;
}
class AbstractCache
{
use AbstractTrait {
deleteItems as private;
AbstractTrait::deleteItem as delete;
AbstractTrait::hasItem as has;
}
}
==>
Template(
TextInterpolation(PhpOpen),
TraitDeclaration(trait,
Name,
DeclarationList(
UseDeclaration(use,Name),
UseDeclaration(use,Name, Name, UseList),
UseDeclaration(use,Name, Name))),
ClassDeclaration(
class,
Name,
DeclarationList(
UseDeclaration(use,
Name,
UseList(
UseAsClause(Name, as, Visibility),
UseAsClause(ScopedExpression(Name, ClassMemberName(Name)), as, Name),
UseAsClause(ScopedExpression(Name, ClassMemberName(Name)), as, Name))))))
# Use Groups
<?php
use a as b;
use some\namespace\{ClassA, ClassB, ClassC as C};
use function some\namespace\{fn_a, fn_b, fn_c};
use const some\namespace\{ConstA, ConstB, ConstC};
==>
Template(
TextInterpolation(PhpOpen),
NamespaceUseDeclaration(use,Name,as,Name),
NamespaceUseDeclaration(use,NamespaceName,NamespaceName,UseGroup(UseClause(Name),UseClause(Name),UseClause(Name,as,Name))),
NamespaceUseDeclaration(use,function,NamespaceName,NamespaceName,UseGroup(UseClause(Name),UseClause(Name),UseClause(Name))),
NamespaceUseDeclaration(use,const,NamespaceName,NamespaceName,UseGroup(UseClause(Name),UseClause(Name),UseClause(Name))))
# Namespace names in namespaces
<?php
namespace Be \ ta {
class A {}
class B {}
}
==>
Template(
TextInterpolation(PhpOpen),
NamespaceDefinition(namespace,
QualifiedName(NamespaceName, Name),
Block(
ClassDeclaration(class,
Name,
DeclarationList),
ClassDeclaration(class,
Name,
DeclarationList))))
# Class declarations
<?php
class foo {
function __construct($name) {
$GLOBALS['List']= &$this;
$this->Name = $name;
$GLOBALS['List']->echoName();
}
function echoName() {
$GLOBALS['names'][]=$this->Name;
}
}
==>
Template(
TextInterpolation(PhpOpen),
ClassDeclaration(class,
Name,
DeclarationList(
MethodDeclaration(function,
Name,
ParamList(
Parameter(
VariableName)),
Block(
ExpressionStatement(AssignmentExpression(
SubscriptExpression(VariableName, String),
AssignOp,
VariableName)),
ExpressionStatement(AssignmentExpression(
MemberExpression(
VariableName,
Name),
AssignOp,
VariableName)),
ExpressionStatement(CallExpression(
MemberExpression(SubscriptExpression(VariableName, String), Name),
ArgList)))),
MethodDeclaration(function,
Name,
ParamList,
Block(
ExpressionStatement(AssignmentExpression(
SubscriptExpression(SubscriptExpression(VariableName, String)),
AssignOp,
MemberExpression(VariableName,Name))))))))
# Class declarations with base classes
<?php
class A extends B {
}
==>
Template(
TextInterpolation(PhpOpen),
ClassDeclaration(class,
Name,
BaseClause(extends, Name),
DeclarationList))
# Function parameters
<?php
function test(int $a, string ...$b)
{
}
==>
Template(
TextInterpolation(PhpOpen),
FunctionDefinition(function,
Name,
ParamList(
Parameter(
NamedType(Name),
VariableName),
VariadicParameter(
NamedType(Name),
VariableName)),
Block))
# Functions with default parameters
<?php
function a($arg = self::bar) {
echo $arg;
}
==>
Template(
TextInterpolation(PhpOpen),
FunctionDefinition(function,
Name,
ParamList(
Parameter(
VariableName,
AssignOp,
ScopedExpression(Name, ClassMemberName(Name)))),
Block(EchoStatement(echo,VariableName))))
# Static variables in functions
<?php
function blah()
{
static $hey=0, $yo=0;
}
==>
Template(
TextInterpolation(PhpOpen),
FunctionDefinition(function,
Name,
ParamList,
Block(
FunctionStaticDeclaration(static,
VariableDeclarator(VariableName, AssignOp, Integer),
VariableDeclarator(VariableName, AssignOp, Integer)))))
# Defining Constants
<?php
define("CONSTANT", "Hello world.");
const CONSTANT = 'Hello World';
const ANOTHER_CONST = CONSTANT.'; Goodbye World';
const ANIMALS = array('dog', 'cat', 'bird');
define('ANIMALS', array(
'dog',
'cat',
'bird'
));
==>
Template(
TextInterpolation(PhpOpen),
ExpressionStatement(
CallExpression(
Name,
ArgList(String,String)
)
),
ConstDeclaration(const,
VariableDeclarator(
Name,
AssignOp,
String
)
),
ConstDeclaration(const,
VariableDeclarator(
Name,
AssignOp,
BinaryExpression(
Name,
ConcatOp,
String
)
)
),
ConstDeclaration(const,
VariableDeclarator(
Name,
AssignOp,
ArrayExpression(array, ValueList(String,String,String))
)
),
ExpressionStatement(
CallExpression(
Name,
ArgList(
String,
ArrayExpression(array, ValueList(String,String,String))
)
)
)
)
# Attributes
<?php
#[Test]
function a(#[Test] $a) {
$c;
}
class PostsController
{
#[Test]
const CONSTANT = 'constant value';
#[Test]
private string $a = '';
#[Route("/api/posts/{id}", ["GET"])]
public function get(#[Test] $id) { /* ... */ }
}
#[MyAttribute]
#[\MyExample\MyAttribute]
#[MyAttribute(1234)]
#[MyAttribute(MyAttribute::VALUE)]
#[MyAttribute(array("key" => "value"))]
#[MyAttribute(100 + 200)]
class Thing
{
}
==>
Template(
TextInterpolation(PhpOpen),
FunctionDefinition(
Attributes(Attribute(Name)),
function,
Name,
ParamList(
Parameter(
Attributes(Attribute(Name)),
VariableName
)
),
Block(ExpressionStatement(VariableName))
),
ClassDeclaration(class,
Name,
DeclarationList(
ConstDeclaration(
Attributes(Attribute(Name)),
const,
VariableDeclarator(Name, AssignOp, String)
),
PropertyDeclaration(
Attributes(Attribute(Name)),
Visibility,
NamedType(Name),
VariableDeclarator(VariableName, AssignOp, String)
),
MethodDeclaration(
Attributes(
Attribute(
Name,
ArgList(
String,
ArrayExpression(String)
)
)
),
Visibility,
function,
Name,
ParamList(
Parameter(
Attributes(Attribute(Name)),
VariableName
)
),
Block(BlockComment)
)
)
),
ClassDeclaration(
Attributes(Attribute(Name)),
Attributes(Attribute(QualifiedName(NamespaceName,Name))),
Attributes(Attribute(Name,ArgList(Integer))),
Attributes(Attribute(Name,ArgList(ScopedExpression(Name,ClassMemberName(Name))))),
Attributes(Attribute(Name,ArgList(ArrayExpression(array, ValueList(Pair(String, String)))))),
Attributes(Attribute(Name,ArgList(BinaryExpression(Integer, ArithOp, Integer)))),
class,
Name,
DeclarationList
)
)
# Enums
<?php
enum A {}
enum B implements Bar, Baz {
}
enum C: int implements Bar {}
enum Suit: string
{
case Hearts = 'H';
case Diamonds;
case Clubs = 'C';
case Spades = 'S';
// Fulfills the interface contract.
public function color(): string {
return match($this) {
Suit::Hearts, Suit::Diamonds => 'Red',
Suit::Clubs, Suit::Spades => 'Black',
};
}
public const X = self::Clubs;
}
==>
Template(
TextInterpolation(PhpOpen),
EnumDeclaration(enum,
Name,
EnumBody
),
EnumDeclaration(enum,
Name,
ClassInterfaceClause(implements, Name, Name),
EnumBody
),
EnumDeclaration(enum,
Name,
NamedType(Name),
ClassInterfaceClause(implements, Name),
EnumBody
),
EnumDeclaration(enum,
Name,
NamedType(Name),
EnumBody(
EnumCase(case, Name, AssignOp, String),
EnumCase(case, Name),
EnumCase(case, Name, AssignOp, String),
EnumCase(case, Name, AssignOp, String),
LineComment,
MethodDeclaration(
Visibility,
function,
Name,
ParamList,
NamedType(Name),
Block(
ReturnStatement(return,
MatchExpression(match,
ParenthesizedExpression(
VariableName
),
MatchBlock(
MatchArm(
ScopedExpression(Name, ClassMemberName(Name)),
ScopedExpression(Name, ClassMemberName(Name)),
String
),
MatchArm(
ScopedExpression(Name, ClassMemberName(Name)),
ScopedExpression(Name, ClassMemberName(Name)),
String
)
)
)
)
)
),
ConstDeclaration(Visibility,const,VariableDeclarator(Name,AssignOp,ScopedExpression(Name,ClassMemberName(Name))))
)
)
)
# Property Hooks
<?php
class Example
{
private bool $modified = false;
public string $foo = 'default value' {
get => $this->foo . ($this->modified ? ' (modified)' : '');
set(string $value) {
$this->foo = strtolower($value);
$this->modified = true;
}
}
}
==>
Template(TextInterpolation(PhpOpen),ClassDeclaration(
class,Name,DeclarationList(
PropertyDeclaration(Visibility,NamedType(Name),VariableDeclarator(VariableName,AssignOp,Boolean)),
PropertyDeclaration(Visibility,NamedType(Name),VariableDeclarator(VariableName,AssignOp,String),PropertyHooks(
PropertyHook(Name,BinaryExpression(MemberExpression(VariableName,Name),ConcatOp,ParenthesizedExpression(
ConditionalExpression(MemberExpression(VariableName,Name),LogicOp,String,String)))),
PropertyHook(Name,ParamList(Parameter(NamedType(Name),VariableName)),Block(
ExpressionStatement(AssignmentExpression(MemberExpression(VariableName,Name),AssignOp,CallExpression(Name,ArgList( VariableName)))),
ExpressionStatement(AssignmentExpression(MemberExpression(VariableName,Name),AssignOp,Boolean)))))))))
+1024
View File
File diff suppressed because it is too large Load Diff
+166
View File
@@ -0,0 +1,166 @@
# no interpolated text
<?php
echo "hi";
==>
Template(
TextInterpolation(PhpOpen),
EchoStatement(echo,String))
# interpolated text at beginning
<div>
<?php
echo "hi";
==>
Template(
TextInterpolation(Text, PhpOpen),
EchoStatement(echo,String))
# interpolated text at end
<?php
echo "hi";
?>
<div>
==>
Template(
TextInterpolation(PhpOpen),
EchoStatement(echo,String),
TextInterpolation(PhpClose, Text))
# interpolated text in middle
<?php
echo "hi";
?>
<div>
<?php
echo "bye";
?>
==>
Template(
TextInterpolation(PhpOpen),
EchoStatement(echo,String),
TextInterpolation(PhpClose, Text, PhpOpen),
EchoStatement(echo,String),
TextInterpolation(PhpClose))
# short open tag: On
<?
echo "Used a short tag\n";
?>
Finished
==>
Template(
TextInterpolation(PhpOpen),
EchoStatement(echo,String(EscapeSequence)),
TextInterpolation(PhpClose, Text))
# short open tag: Off
<div>one</div>
<?php
$a = 'This gets echoed twice';
?>
<?= $a ?>
<div>two</div>
<? $b=3; ?>
<?php
echo "{$b}";
?>
<?= "{$b}" ?>
==>
Template(
TextInterpolation(Text,PhpOpen),
ExpressionStatement(AssignmentExpression(VariableName, AssignOp, String)),
TextInterpolation(PhpClose,Text,PhpOpen),
ExpressionStatement(VariableName),
TextInterpolation(PhpClose,Text,PhpOpen),
ExpressionStatement(AssignmentExpression(VariableName, AssignOp, Integer)),
TextInterpolation(PhpClose,Text,PhpOpen),
EchoStatement(echo,String(Interpolation(VariableName))),
TextInterpolation(PhpClose,Text,PhpOpen),
ExpressionStatement(String(Interpolation(VariableName))),
TextInterpolation(PhpClose))
# Single line php comment
<ul class="foo"><?php // this is a comment ?></ul>
<?php
// foo?
// foo? bar?
echo "hi";
==>
Template(
TextInterpolation(Text, PhpOpen),
LineComment,
TextInterpolation(PhpClose, Text, PhpOpen),
LineComment,
LineComment,
EchoStatement(echo,String))
# Single line comment without any content
<?php
# Check if PHP xml isn't compiled
#
if ( ! function_exists('xml_parser_create') ) {
echo $test;
}
==>
Template(
TextInterpolation(PhpOpen),
LineComment,
LineComment,
IfStatement(if,
ParenthesizedExpression(
UnaryExpression(LogicOp, CallExpression(Name,ArgList(String)))
),
Block(EchoStatement(echo,VariableName))
)
)
# Closing tags before the first PHP tag
a ?> b <?php c;
==>
Template(
TextInterpolation(Text, PhpOpen),
ExpressionStatement(Name))
# Text ends in a less-than char
foo<
==>
Template(Text)
+195
View File
@@ -0,0 +1,195 @@
# Booleans
<?php
True;
true;
TRUE;
false;
False;
FALSE;
?>
==>
Template(
TextInterpolation(PhpOpen),
ExpressionStatement(Boolean),
ExpressionStatement(Boolean),
ExpressionStatement(Boolean),
ExpressionStatement(Boolean),
ExpressionStatement(Boolean),
ExpressionStatement(Boolean),
TextInterpolation(PhpClose))
# Floats
<?php
1.0;
1E432;
1.0E-3432;
1423.0E3432;
.5;
6.674_083e11;
107_925_284.88;
==>
Template(
TextInterpolation(PhpOpen),
ExpressionStatement(Float),
ExpressionStatement(Float),
ExpressionStatement(Float),
ExpressionStatement(Float),
ExpressionStatement(Float),
ExpressionStatement(Float),
ExpressionStatement(Float)
)
# Integers
<?php
1234;
1_234_456;
0123;
0123_456;
0x1A;
0x1A_2B_3C;
0b111111111;
0b1111_1111_1111;
0o123;
==>
Template(
TextInterpolation(PhpOpen),
ExpressionStatement(Integer),
ExpressionStatement(Integer),
ExpressionStatement(Integer),
ExpressionStatement(Integer),
ExpressionStatement(Integer),
ExpressionStatement(Integer),
ExpressionStatement(Integer),
ExpressionStatement(Integer),
ExpressionStatement(Integer)
)
# Testing string scanner conformance
<?php echo "\"\t\\'" . '\n\\\'a\\\b\\' ?>
==>
Template(
TextInterpolation(PhpOpen),
EchoStatement(echo, BinaryExpression(String(EscapeSequence, EscapeSequence, EscapeSequence), ConcatOp, String)),
TextInterpolation(PhpClose))
# Shell command
<?php
`ls -la`;
`ls`;
==>
Template(
TextInterpolation(PhpOpen),
ExpressionStatement(ShellExpression),
ExpressionStatement(ShellExpression))
# Heredocs
<?php
<<<HERE
foo #{bar}
HERE;
?>
<?php
<<<HERE
foo #{bar}
HERE;
<<< HERE
foo #{bar}
HERE;
// Allow Heredoc as function argument
read(<<< HERE
foo #{bar}
HERE);
read(<<< HERE
foo #{bar}
HERE , true);
==>
Template(
TextInterpolation(PhpOpen),
ExpressionStatement(HeredocString),
TextInterpolation(PhpClose,Text,PhpOpen),
ExpressionStatement(HeredocString),
ExpressionStatement(HeredocString),
LineComment,
ExpressionStatement(
CallExpression(
Name,
ArgList(HeredocString)
)
),
ExpressionStatement(
CallExpression(
Name,
ArgList(
HeredocString,
Boolean
)
)
)
)
# Nowdocs
<?php
<<<'PHP'
<?php echo phpversion().PHP_SAPI;
PHP
?>
==>
Template(
TextInterpolation(PhpOpen),
ExpressionStatement(HeredocString),
TextInterpolation(PhpClose))
# Unicode escape sequences
<?php
"\u{61}"; // ASCII "a" - characters below U+007F just encode as ASCII, as it's UTF-8
"\u{FF}"; // y with diaeresis
"\u{ff}"; // case-insensitive
"\u{2603}"; // Unicode snowman
"\u{1F602}"; // FACE WITH TEARS OF JOY emoji
"\u{0000001F602}"; // Leading zeroes permitted
==>
Template(
TextInterpolation(PhpOpen),
ExpressionStatement(String(EscapeSequence)), LineComment,
ExpressionStatement(String(EscapeSequence)), LineComment,
ExpressionStatement(String(EscapeSequence)), LineComment,
ExpressionStatement(String(EscapeSequence)), LineComment,
ExpressionStatement(String(EscapeSequence)), LineComment,
ExpressionStatement(String(EscapeSequence)), LineComment)
+364
View File
@@ -0,0 +1,364 @@
# If statements
<?php
if ($a > 0) {
echo "Yes";
}
if ($a==0) {
echo "bad";
} else {
echo "good";
}
if ($a==0) {
echo "bad";
} elseif ($a==3) {
echo "bad";
} else {
echo "good";
}
==>
Template(
TextInterpolation(PhpOpen),
IfStatement(if,
ParenthesizedExpression(BinaryExpression(
VariableName,
CompareOp,
Integer)),
Block(EchoStatement(echo,String))),
IfStatement(if,
ParenthesizedExpression(BinaryExpression(
VariableName,
CompareOp,
Integer)),
Block(EchoStatement(echo,String)),
else, Block(EchoStatement(echo,String))),
IfStatement(if,
ParenthesizedExpression(BinaryExpression(
VariableName,
CompareOp,
Integer)),
Block(EchoStatement(echo,String)),
elseif, ParenthesizedExpression(BinaryExpression(VariableName,CompareOp,Integer)),
Block(EchoStatement(echo,String)),
else, Block(EchoStatement(echo,String))))
# Alternative if statements
<?php
if ($a) echo 1; else echo 0;
if ($a):
echo 1;
echo 2;
else:
echo 0;
endif;
==>
Template(
TextInterpolation(PhpOpen),
IfStatement(if,
ParenthesizedExpression(VariableName),
EchoStatement(echo,Integer),
else, EchoStatement(echo,Integer)),
IfStatement(if,
ParenthesizedExpression(VariableName),
ColonBlock(
EchoStatement(echo,Integer),
EchoStatement(echo,Integer)),
else, ColonBlock(EchoStatement(echo,Integer)),
endif))
# While statements
<?php
while ($a < 10) {
echo $a;
$a++;
}
==>
Template(
TextInterpolation(PhpOpen),
WhileStatement(while,
ParenthesizedExpression(BinaryExpression(VariableName,CompareOp,Integer)),
Block(
EchoStatement(echo,VariableName),
ExpressionStatement(UpdateExpression(VariableName, ArithOp)))))
# Alternative while statements
<?php
while ($a<5) echo $a++;
while ($a<9):
echo ++$a;
echo $b;
endwhile;
==>
Template(
TextInterpolation(PhpOpen),
WhileStatement(while,
ParenthesizedExpression(BinaryExpression(VariableName, CompareOp, Integer)),
EchoStatement(echo,UpdateExpression(VariableName, ArithOp))),
WhileStatement(while,
ParenthesizedExpression(BinaryExpression(VariableName, CompareOp, Integer)),
ColonBlock(
EchoStatement(echo,UpdateExpression(ArithOp, VariableName)),
EchoStatement(echo,VariableName)),
endwhile))
# For statements
<?php
for($a=0;$a<5;$a++) echo $a;
for($a=0;$a<5;$a++):
echo $a;
endfor;
==>
Template(
TextInterpolation(PhpOpen),
ForStatement(for,
ForSpec(
AssignmentExpression(VariableName, AssignOp, Integer),
BinaryExpression(VariableName, CompareOp, Integer),
UpdateExpression(VariableName, ArithOp)),
EchoStatement(echo,VariableName)),
ForStatement(for,
ForSpec(
AssignmentExpression(VariableName, AssignOp, Integer),
BinaryExpression(VariableName, CompareOp, Integer),
UpdateExpression(VariableName, ArithOp)),
ColonBlock(EchoStatement(echo,VariableName)),
endfor))
# Switch statements
<?php
switch ($a) {
case 0:
echo "bad";
break;
case 1:
echo "good";
break;
default:
echo "bad";
break;
}
?>
==>
Template(
TextInterpolation(PhpOpen),
SwitchStatement(switch,
ParenthesizedExpression(VariableName),
Block(
CaseStatement(case,
Integer,
EchoStatement(echo,String), BreakStatement(break)),
CaseStatement(case,
Integer,
EchoStatement(echo,String), BreakStatement(break)),
DefaultStatement(default,
EchoStatement(echo,String), BreakStatement(break)))),
TextInterpolation(PhpClose))
# Alternative switch statements
<?php
switch ($a):
case 0;
echo 0;
break;
case 5:
echo 1;
break;
default;
echo 0;
break;
endswitch;
==>
Template(
TextInterpolation(PhpOpen),
SwitchStatement(switch,
ParenthesizedExpression(VariableName),
ColonBlock(
CaseStatement(case,
Integer,
EchoStatement(echo,Integer),
BreakStatement(break)),
CaseStatement(case,
Integer,
EchoStatement(echo,Integer),
BreakStatement(break)),
DefaultStatement(default,
EchoStatement(echo,Integer),
BreakStatement(break)))
endswitch))
# Include statement
<?php
include "015.inc";
==>
Template(
TextInterpolation(PhpOpen),
ExpressionStatement(IncludeExpression(include, String)))
# Do-while statements
<?php
do {
echo $i;
$i--;
} while($i>0);
==>
Template(
TextInterpolation(PhpOpen),
DoStatement(do,
Block(
EchoStatement(echo,VariableName),
ExpressionStatement(UpdateExpression(VariableName, ArithOp))),
while, ParenthesizedExpression(BinaryExpression(VariableName, CompareOp, Integer))))
# Try statements
<?php
try {
} catch (MyException) {
} catch (OtherException|YetAnotherException $e) {
} finally {
}
try {
ThrowException();
} catch (MyException $exception) {
print "There was an exception: " . $exception->getException();
print "\n";
}
==>
Template(
TextInterpolation(PhpOpen),
TryStatement(
try, Block,
catch, CatchDeclarator(NamedType(Name)), Block,
catch, CatchDeclarator(UnionType(NamedType(Name), LogicOp, NamedType(Name)), VariableName), Block,
finally, Block),
TryStatement(
try, Block(ExpressionStatement(CallExpression(Name,ArgList))),
catch, CatchDeclarator(NamedType(Name), VariableName), Block(
ExpressionStatement(PrintIntrinsic(print, BinaryExpression(
String,
ConcatOp,
CallExpression(MemberExpression(VariableName,Name),ArgList)))),
ExpressionStatement(PrintIntrinsic(print, String(EscapeSequence))))))
# Foreach statements
<?php
foreach ($a as $b[0]) {
echo $b[0]."\n";
}
foreach($arr as $key => $value);
foreach($a as $b):
echo $a;
echo $b;
endforeach;
==>
Template(
TextInterpolation(PhpOpen),
ForeachStatement(foreach,
ForSpec(VariableName, as, SubscriptExpression(VariableName, Integer)),
Block(
EchoStatement(echo,BinaryExpression(
SubscriptExpression(VariableName, Integer),
ConcatOp,
String(EscapeSequence))))),
ForeachStatement(foreach,
ForSpec(VariableName, as, Pair(VariableName, VariableName)), EmptyStatement),
ForeachStatement(foreach,
ForSpec(VariableName, as, VariableName),
ColonBlock(
EchoStatement(echo,VariableName),
EchoStatement(echo,VariableName)),
endforeach))
# Case insensitive keywords
<?php
FOREACH ($a AS $b) {
DO {
if ($c) {
d();
} else {
e();
}
} while ($f);
}
==>
Template(
TextInterpolation(PhpOpen),
ForeachStatement(foreach,
ForSpec(VariableName, as, VariableName),
Block(
DoStatement(do,
Block(
IfStatement(if,
ParenthesizedExpression(VariableName),
Block(ExpressionStatement(CallExpression(Name, ArgList))),
else, Block(ExpressionStatement(CallExpression(Name, ArgList))))),
while, ParenthesizedExpression(VariableName)))))
# Accessing Constants
<?php
echo ANOTHER_CONST;
echo ANIMALS[1];
==>
Template(
TextInterpolation(PhpOpen),
EchoStatement(echo,
Name
),
EchoStatement(echo,
SubscriptExpression(
Name,
Integer
)
)
)
+411
View File
@@ -0,0 +1,411 @@
# Complex: Variable access
<?php
"{$test}";
==>
Template(
TextInterpolation(PhpOpen),
ExpressionStatement(
String(Interpolation(VariableName))
)
)
# Complex: Disallow space between { and $
<?php
"{ $test}";
==>
Template(
TextInterpolation(PhpOpen),
ExpressionStatement(
String(VariableName)
)
)
# Complex: PHP documentation tests
<?php
"This is {$great}";
"This square is {$square->width}00 centimeters broad.";
// Works, quoted keys only work using the curly brace syntax
"This works: {$arr['key']}";
"This works: {$arr[4][3]}";
// Works. When using multi-dimensional arrays, always use braces around arrays
// when inside of strings
"This works: {$arr['foo'][3]}";
"This works: " . $arr['foo'][3];
"This works too: {$obj->values[3]->name}";
"This is the value of the var named $name: {${$name}}";
"This is the value of the var named by the return value of getName(): {${getName()}}";
"This is the value of the var named by the return value of \$object->getName(): {${$object->getName()}}";
// Won't work, outputs: This is the return value of getName(): {getName()}
"This is the return value of getName(): {getName()}";
"{$foo->$bar}\n";
"{$foo->{$baz[1]}}\n";
"I'd like an {${beers::softdrink}}\n";
"I'd like an {${beers::$ale}}\n";
==>
Template(
TextInterpolation(PhpOpen),
ExpressionStatement(
String(Interpolation(VariableName))
),
ExpressionStatement(
String(Interpolation(MemberExpression(VariableName, Name)))
),
LineComment,
ExpressionStatement(
String(Interpolation(SubscriptExpression(VariableName, String)))),
ExpressionStatement(
String(Interpolation(SubscriptExpression(SubscriptExpression(VariableName,Integer),Integer)))
),
LineComment,
LineComment,
ExpressionStatement(
String(Interpolation(SubscriptExpression(SubscriptExpression(VariableName,String),Integer)))
),
ExpressionStatement(
BinaryExpression(
String,
ConcatOp,
SubscriptExpression(SubscriptExpression(VariableName,String),Integer))
),
ExpressionStatement(
String(
Interpolation(MemberExpression(
SubscriptExpression(
MemberExpression(
VariableName,
Name
),
Integer
),
Name
))
)
),
ExpressionStatement(
String(
VariableName,
Interpolation(DynamicVariable(VariableName))
)
),
ExpressionStatement(
String(
Interpolation(DynamicVariable(CallExpression(Name,ArgList)))
)
),
ExpressionStatement(
String(
EscapeSequence,
Interpolation(DynamicVariable(
CallExpression(MemberExpression(VariableName, Name), ArgList)
))
)
),
LineComment,
ExpressionStatement(String),
ExpressionStatement(
String(
Interpolation(MemberExpression(VariableName,VariableName)),
EscapeSequence
)
),
ExpressionStatement(
String(
Interpolation(MemberExpression(
VariableName,
SubscriptExpression(
VariableName,
Integer
)
)),
EscapeSequence
)
),
ExpressionStatement(
String(
Interpolation(DynamicVariable(
ScopedExpression(
Name,
ClassMemberName(Name)
)
)),
EscapeSequence
)
),
ExpressionStatement(
String(
Interpolation(DynamicVariable(
ScopedExpression(
Name,
ClassMemberName(VariableName)
)
)),
EscapeSequence
)
)
)
# Simple: Variable access
<?php
"Hello $people, you're awesome!";
"hello ${a} world";
==>
Template(
TextInterpolation(PhpOpen),
ExpressionStatement(
String(VariableName)
),
ExpressionStatement(
String(Interpolation(Name))
)
)
# Simple: Member and array access
<?php
"$people->john drank some $juices[0] juice.".PHP_EOL;
"$people->john then said hello to $people?->jane.".PHP_EOL;
"$people->john's wife greeted $people->robert.";
"The character at index -2 is $string[-2].";
==>
Template(
TextInterpolation(PhpOpen),
ExpressionStatement(
BinaryExpression(
String(
MemberExpression(VariableName,Name),
SubscriptExpression(VariableName,Integer),
),
ConcatOp,
Name
)
),
ExpressionStatement(
BinaryExpression(
String(
MemberExpression(VariableName,Name),
MemberExpression(VariableName,Name),
),
ConcatOp,
Name
)
),
ExpressionStatement(
String(
MemberExpression(VariableName,Name),
MemberExpression(VariableName,Name),
)
),
ExpressionStatement(
String(
SubscriptExpression(VariableName,UnaryExpression(ArithOp,Integer)),
)
)
)
# Corner cases
<?php
"{";
"{\$";
"{ $";
"/a";
"#";
"//";
"/*";
"/* text *#//";
"/**/";
"// # /**/";
"\\";
"\{";
"";
"\$notavar";
"\\\\\$notavar";
"\\\{$embedexp}";
"#x$var";
" # x $var#x";
"sometext$var";
"{$var::get()}";
"Test $var->tester- Hello";
" # x {$var->prop["key:"."key: {$var->func("arg")}"]}# x";
"hello \0 world";
"hello ${"a"."b"} world";
"$$$$$$$$$$$$$a";
"{$$$$$$$$b}";
"\{$";
"\u{$a}";
==>
Template(
TextInterpolation(PhpOpen),
ExpressionStatement(
String
),
ExpressionStatement(
String(EscapeSequence)
),
ExpressionStatement(
String
),
ExpressionStatement(
String
),
ExpressionStatement(
String
),
ExpressionStatement(
String
),
ExpressionStatement(
String
),
ExpressionStatement(
String
),
ExpressionStatement(
String
),
ExpressionStatement(
String
),
ExpressionStatement(
String(EscapeSequence)
),
ExpressionStatement(
String(EscapeSequence)
),
ExpressionStatement(
String
),
ExpressionStatement(
String(EscapeSequence)
),
ExpressionStatement(
String(EscapeSequence,EscapeSequence,EscapeSequence)
),
ExpressionStatement(
String(EscapeSequence,EscapeSequence,VariableName)
),
ExpressionStatement(
String(VariableName)
),
ExpressionStatement(
String(VariableName)
),
ExpressionStatement(
String(VariableName)
),
ExpressionStatement(
String(
Interpolation(CallExpression(ScopedExpression(VariableName,ClassMemberName(Name)), ArgList))
)
),
ExpressionStatement(
String(MemberExpression(VariableName,Name))
),
ExpressionStatement(
String(
Interpolation(SubscriptExpression(
MemberExpression(VariableName,Name),
BinaryExpression(
String,
ConcatOp,
String(Interpolation(CallExpression(MemberExpression(VariableName,Name),ArgList(String))))
)
))
)
),
ExpressionStatement(
String(EscapeSequence)
),
ExpressionStatement(
String(Interpolation(BinaryExpression(String,ConcatOp,String)))
),
ExpressionStatement(
String(VariableName)
),
ExpressionStatement(
String(
Interpolation(DynamicVariable(
DynamicVariable(
DynamicVariable(
DynamicVariable(
DynamicVariable(
DynamicVariable(
DynamicVariable(
VariableName
)
)
)
)
)
)
))
)
),
ExpressionStatement(
String(EscapeSequence)
),
ExpressionStatement(
String(Interpolation(VariableName))
)
)
# Single quoted
<?php
'this is a simple string';
'You can also have embedded newlines in
strings this way as it is
okay to do';
'Arnold once said: "I\'ll be back"';
'You deleted C:\\*.*?';
'You deleted C:\*.*?';
'This will not expand: \n a newline';
'Variables do not $expand $either';
==>
Template(
TextInterpolation(PhpOpen),
ExpressionStatement(String),
ExpressionStatement(String),
ExpressionStatement(String),
ExpressionStatement(String),
ExpressionStatement(String),
ExpressionStatement(String),
ExpressionStatement(String)
)
+17
View File
@@ -0,0 +1,17 @@
import {parser} from "../dist/index.js"
import {fileTests} from "@lezer/generator/dist/test"
import * as fs from "fs"
import * as path from "path"
import {fileURLToPath} from "url"
let caseDir = path.dirname(fileURLToPath(import.meta.url))
for (let file of fs.readdirSync(caseDir)) {
if (!/\.txt$/.test(file)) continue
let name = /^[^\.]*/.exec(file)[0]
describe(name, () => {
for (let {name, run} of fileTests(fs.readFileSync(path.join(caseDir, file), "utf8"), file))
it(name, () => run(parser))
})
}
+124
View File
@@ -0,0 +1,124 @@
# Type names
<?php
function a(): A {}
function b(): A\B {}
==>
Template(
TextInterpolation(PhpOpen),
FunctionDefinition(function,
Name, ParamList,
NamedType(Name),
Block),
FunctionDefinition(function,
Name, ParamList,
NamedType(QualifiedName(NamespaceName, Name)),
Block))
# Primitive types
<?php
function a(): int {}
function b(): callable {}
function c(): iterable {}
==>
Template(
TextInterpolation(PhpOpen),
FunctionDefinition(function,
Name, ParamList,
NamedType(Name),
Block),
FunctionDefinition(function,
Name, ParamList,
NamedType(Name),
Block),
FunctionDefinition(function,
Name, ParamList,
NamedType(Name),
Block))
# Optional types
<?php
function a(): ?array {}
function b(): ?Something {}
==>
Template(
TextInterpolation(PhpOpen),
FunctionDefinition(function,
Name, ParamList,
OptionalType(LogicOp, NamedType(array)),
Block),
FunctionDefinition(function,
Name, ParamList,
OptionalType(LogicOp, NamedType(Name)),
Block))
# Union types
<?php
function a(int|string|null $var) : ?int|MyClass {}
==>
Template(
TextInterpolation(PhpOpen),
FunctionDefinition(function,
Name,
ParamList(
Parameter(
UnionType(NamedType(Name),LogicOp,NamedType(Name),LogicOp,NamedType(null)),
VariableName)),
UnionType(OptionalType(LogicOp, NamedType(Name)),LogicOp,NamedType(Name)),
Block))
# Mixed type
<?php
function a(mixed|string $var) : mixed {
}
==>
Template(
TextInterpolation(PhpOpen),
FunctionDefinition(function,
Name,
ParamList(
Parameter(
UnionType(NamedType(Name),LogicOp,NamedType(Name)),
VariableName
)
),
NamedType(Name),
Block
)
)
# Static type
<?php
function a(string $var) : static {
}
==>
Template(
TextInterpolation(PhpOpen),
FunctionDefinition(function,
Name,
ParamList(
Parameter(NamedType(Name),VariableName)),
NamedType(Name),
Block))