package.xml 0000664 0001750 0001750 00000067347 14655731747 012353 0 ustar tyson tyson
ast
pecl.php.net
Extension exposing PHP 7 abstract syntax tree
php-ast exports the AST internally used by PHP 7.
php-ast is significantly faster than PHP-Parser, because the AST construction is implemented in C.
However, php-ast may only parse code that is syntactically valid on the version of PHP it runs on.
Nikita Popov
nikic
nikic@php.net
yes
Tyson Andre
tandre
tandre@php.net
yes
2024-08-10
1.1.2
1.1.2
stable
stable
BSD-3-Clause
- Fix compilation errors in PHP 8.4.
- In version 110, `AST_PARAM` and `AST_PROP_ELEM` nodes have a `hooks` node for property hooks (https://wiki.php.net/rfc/property-hooks)
- In version 110, `AST_CLOSURE` and `AST_ARROW_FUNC` nodes have no `name`.
7.2.0
1.10.0
ast
1.1.1
1.1.1
stable
stable
BSD-3-Clause
- Added support for PHP 8.3
- In version 100, `AST_CLASS_CONST_GROUP` nodes have a `type` child node to represent typed class constants.
2022-08-09
1.1.0
1.1.0
stable
stable
BSD-3-Clause
- Change documentation files to properly namespace attributes as `#[\AllowDynamicProperties]`. The reflection attributes are already correct.
- Deprecated AST versions 50 and 60.
- Drop support for php <= 7.1
- Fix test failures seen in php 8.2.0beta2 due to change to var_export's output format.
- Add support for php 8.2 readonly classes. Add `ast\flags\CLASS_READONLY` constant.
- Add support for php 8.2 `true` type. Add `ast\flags\TYPE_TRUE` constant.
- Fix bug in php 8.2 where ZEND_AST_ARROW_FUNC output did not include the stub `AST_RETURN` node that was included in php 8.1 and below.
2021-11-27
1.0.16
1.0.16
stable
stable
BSD-3-Clause
- Optimize instantiating properties of ast\Node and ast\Metadata.
- Document that ast\Node implements `#[AllowDynamicProperties]` in php 8.2
- Allow ast\Node to have dynamic properties without emitting a notice in PHP 8.2.
2021-11-27
1.0.15
1.0.15
stable
stable
BSD-3-Clause
- Allow ast\Node to have dynamic properties without emitting a notice in PHP 8.2.
2021-07-24
1.0.14
1.0.14
stable
stable
BSD-3-Clause
- Support php 8.1 readonly properties with the flag 'MODIFIER_READONLY'
- Support php 8.1 first-class callable syntax, add the node kind 'AST_CALLABLE_CONVERT'
- Change the current AST version from 80 to the new version 90. AST version 85 is no longer experimental.
2021-07-08
1.0.13
1.0.13
stable
stable
BSD-3-Clause
- Indicate in metadata that 'AST_CLASS_CONST_GROUP' and 'AST_CLASS_CONST_DECL' can have 'MODIFIER_FINAL'
(and any modifier a class element can have, to reflect what the parser can actually parse)
- Support php 8.1 intersection types, add the node kind 'AST_TYPE_INTERSECTION'
2021-05-16
1.0.12
1.0.12
stable
stable
BSD-3-Clause
- Support parsing 'docComment' on php 8.1 enum cases
- Indicate in metadata that 'AST_CLASS_CONST_GROUP' and 'AST_CLASS_CONST_DECL' can have MODIFIER_FINAL
2021-04-20
1.0.11
1.0.11
stable
stable
BSD-3-Clause
- Add the experimental AST version 85.
- Support php 8.1 enums, add 'type' (for enum type) to AST_CLASS nodes in AST version 85+.
- Support php 8.1 'never' return type.
2020-09-12
1.0.10
1.0.10
stable
stable
BSD-3-Clause
- Support attributes syntax change (`#[...]`) in php 8.0.0RC1.
- Change the current AST version from 70 to 80. AST version 80 is no longer experimental.
- Add `ReflectionParameter` defaults for `ast\parse_code` and `ast\get_supported_versions` in php 8.
- Add parameter types and return types to reflection for various global functions.
php-ast was already throwing a `TypeError` when invalid parameter types were received.
- Always throw instead of warning when invalid parameters are passed to the ast\Node constructor.
2020-09-02
1.0.9
1.0.9
stable
stable
BSD-3-Clause
- Support API change in php 8.0.0beta3.
2020-08-04
1.0.8
1.0.8
stable
stable
BSD-3-Clause
- Recommend using the new constant `ast\flags\PARAM_MODIFIER_*` when checking if parameters use constructor property promotion.
The values of `ast\flags\MODIFIER_*` and `ast\flags\PARAM_VARIADIC` had some overlap in some php 7 versions.
The new constants will have the same values as `ast\flags\MODIFIER_*` in PHP 8.0+, but different values in PHP 7
(and these flags will never be set in php 7).
- Support PHP 8.0's named arguments.
- Support PHP 8.0's nullsafe operator (`?->`).
2020-07-11
1.0.7
1.0.7
stable
stable
BSD-3-Clause
- Add the experimental AST version 80
- In AST version 80, support returning `mixed` types as an `AST_TYPE` with type `TYPE_MIXED` instead of an `AST_NAME`.
- In AST version 80, support PHP 8.0 attributes for declarations.
- Support PHP 8.0's Match expressions.
- Support PHP 8.0 constructor property promotion, and allow indicating visibility on AST nodes.
Note that `MODIFIER_PUBLIC` and `ast\AST_PARAM` modifiers had overlap in php 7.4,
so the `MODIFIER_*` modifiers are only included in the provided metadata for php 8.0+
2020-02-22
1.0.6
1.0.6
stable
stable
BSD-3-Clause
- Support TYPE_STATIC for the php 8.0 static return type.
2019-11-23
1.0.5
1.0.5
stable
stable
BSD-3-Clause
- Add ast\flags\TYPE_FALSE to support PHP 8.0 Union Types.
2019-11-10
1.0.4
1.0.4
stable
stable
BSD-3-Clause
- Add AST_TYPE_UNION to support PHP 8.0 Union Types.
2019-07-27
1.0.3
1.0.3
stable
stable
BSD-3-Clause
- Fix build error in php 7.4.0alpha3.
- Add `DIM_ALTERNATIVE_SYNTAX` as a flag of `AST_DIM` for `$x{'offset'}` (for php 7.4+)
- Add `PARENTHESIZED_CONDITIONAL` as a flag of `AST_CONDITIONAL` for `($a ? $b : $c)` (for php 7.4+)
- Bugfix: Make `ast\kind_uses_flags(ast\AST_ARROW_FUNC)` true in php 7.3 and lower.
2019-06-30
1.0.2
1.0.2
stable
stable
BSD-3-Clause
- Fix compatibility with (currently) PHP 7.4 and PHP 8.0.
- Support AST_ARROW_FUNC for PHP 7.4.
- Make $version a required parameter for `ast\parse_*`. Previously, the absence would throw a LogicException.
- Make AST version 70 the current version.
2019-02-11
1.0.1
1.0.1
stable
stable
BSD-3-Clause
- Fix compatibility with (currently) PHP 7.4 and PHP 8.0.
- Support BINARY_COALESCE as a flag of AST_ASSIGN_OP for the `??=` operator added in PHP 7.4.
- Add AST version 70 (experimental):
- Version 70 adds AST_PROP_GROUP with type information for property groups.
- Version 70 adds AST_CLASS_NAME for `Foo::class`. Previously this used AST_CLASS_CONST
2018-10-21
1.0.0
1.0.0
stable
stable
BSD-3-Clause
This release is the same as version 0.1.7 with obsolete and deprecated functionality removed.
- Removed AST versions prior to version 50.
- Removed ast\Node\Decl class, which is no longer used.
- Removed AST kinds AST_AND, AST_COALESCE, AST_GREATER, AST_GREATER_EQUAL, AST_OR, AST_SILENCE,
AST_UNARY_MINUS, and AST_UNARY_PLUS, which are no longer used.
- Removed ASSIGN_* AST flags, which are no longer used.
2018-10-06
0.1.7
0.1.7
stable
stable
BSD-3-Clause
- Added AST version 60 with the following changes:
- `AST_FUNC_DECL` and `AST_METHOD` no longer generate a `uses` child. Previously this child was
always `null`.
- `AST_CONST_ELEM` now always has a `docComment` child. Previously it was absent on PHP 7.0.
On PHP 7.0 the value is always `null`.
- Added `ARRAY_ELEM_REF` flag, which is used by `AST_ARRAY_ELEM` for by-reference array elements
and (since PHP 7.3) for by-reference destructuring. Previously this flag was represented simply
by the value `1`.
- Deprecated AST versions 40 and 45.
- Fix build against PHP 7.4-dev.
2017-10-08
0.1.6
0.1.6
stable
stable
BSD-3-Clause
- Added ast\get_metadata() function, which returns an array of ast\Metadata objects, one for each
AST kind. The metadata contains information such as the supported flags for the kind.
- Added ast\get_supported_versions() function, which provides an array of currently supported AST
versions.
2017-07-19
0.1.5
0.1.5
stable
stable
BSD-3-Clause
- Fix issue #51: Make nullable array/callable have a flag of 0 in inner element, in version 40.
- Added a constructor for the ast\Node class.
- Added ast\flags\FUNC_GENERATOR constant, which is used since PHP 7.1.
- Added ast\flags\FUNC_RETURNS_REF constant, intended to supersede ast\flags\RETURNS_REF.
- Added ast\flags\CLOSURE_USE_REF constant, used by AST_CLOSURE_VAR nodes. Previously "1" was used.
- Added version 45 with the following changes (PHP 7.2 support):
- An `object` type annotation now returns an `AST_TYPE` with `TYPE_OBJECT` flag, rather than
treating `object` as a class name.
- Added version 50 with the following changes:
- `ast\Node\Decl` nodes are no longer generated. AST kinds `AST_FUNCTION`, `AST_METHOD`,
`AST_CLOSURE` and `AST_CLASS` now also use the normal `ast\Node` class. The `name` and
`docComment` properties are now represented as children. The `endLineno` is still represented as
an (undeclared) property.
- An integer `__declId` has been added to declaration nodes of kind `AST_FUNCTION`, `AST_METHOD`,
`AST_CLOSURE` and `AST_CLASS`. The `__declId` uniquely identifies a declaration within the
parsed code and will remain the same if the code is parsed again. This is useful to distinguish
closures declared on the same line, or multiple conditional declarations using the same name.
The ID is not unique across different codes/files.
- `\ast\parse_file` will now consistently return an empty statement list (similar to
`\ast\parse_code`) if it is was passed a zero-byte file. Previously, it would return `null`.
2017-01-25
0.1.4
0.1.4
BSD-3-Clause
0.1.4 release
2017-01-18
0.1.3
0.1.3
BSD-3-Clause
0.1.3 release
2017-08-04
0.1.2
0.1.2
BSD-3-Clause
0.1.2 release
2017-12-04
0.1.1
0.1.1
BSD-3-Clause
0.1.1 release
2017-12-04
0.1.0
0.1.0
BSD-3-Clause
0.1.0 release
ast-1.1.2/tests/001.phpt 0000664 0001750 0001750 00000004150 14655731747 014000 0 ustar tyson tyson --TEST--
ast_dump() test
--SKIPIF--
--FILE--
foo);
} else {
return $arg->bar;
}
}
PHP;
echo ast_dump(ast\parse_code($code, $version=70));
--EXPECT--
AST_STMT_LIST
0: AST_FUNC_DECL
name: "test"
docComment: "/** Test function */"
params: AST_PARAM_LIST
0: AST_PARAM
type: AST_NAME
flags: NAME_NOT_FQ (1)
name: "Type"
name: "arg"
default: AST_CONST
name: AST_NAME
flags: NAME_NOT_FQ (1)
name: "XYZ"
stmts: AST_STMT_LIST
0: AST_IF
0: AST_IF_ELEM
cond: AST_INSTANCEOF
expr: AST_VAR
name: "arg"
class: AST_NAME
flags: NAME_NOT_FQ (1)
name: "Foo\Bar"
stmts: AST_STMT_LIST
0: AST_RETURN
expr: AST_CALL
expr: AST_NAME
flags: NAME_NOT_FQ (1)
name: "test"
args: AST_ARG_LIST
0: AST_PROP
expr: AST_VAR
name: "arg"
prop: "foo"
1: AST_IF_ELEM
cond: null
stmts: AST_STMT_LIST
0: AST_RETURN
expr: AST_PROP
expr: AST_VAR
name: "arg"
prop: "bar"
returnType: AST_NAME
flags: NAME_NOT_FQ (1)
name: "Ret"
__declId: 0 ast-1.1.2/tests/array_destructuring_old.phpt 0000664 0001750 0001750 00000001664 14655731747 020445 0 ustar tyson tyson --TEST--
Array destructuring (using unkeyed list())
--FILE--
--EXPECTF--
AST_STMT_LIST
0: AST_ASSIGN
var: AST_ARRAY
flags: ARRAY_SYNTAX_LIST (%d)
0: AST_ARRAY_ELEM
flags: 0
value: AST_VAR
name: "a"
key: null
1: AST_ARRAY_ELEM
flags: 0
value: AST_VAR
name: "b"
key: null
expr: AST_VAR
name: "x"
1: AST_ASSIGN
var: AST_ARRAY
flags: ARRAY_SYNTAX_LIST (%d)
0: null
1: AST_ARRAY_ELEM
flags: 0
value: AST_VAR
name: "b"
key: null
expr: AST_VAR
name: "x" ast-1.1.2/tests/array_destructuring.phpt 0000664 0001750 0001750 00000003741 14655731747 017605 0 ustar tyson tyson --TEST--
Array destructuring
--FILE--
$a, 'bar' => $b) = $x;
[$a, $b] = $x;
['foo' => $a, 'bar' => $b] = $x;
[, [$a]] = $x;
PHP;
echo ast_dump(ast\parse_code($code, $version=70));
?>
--EXPECT--
AST_STMT_LIST
0: AST_ASSIGN
var: AST_ARRAY
flags: ARRAY_SYNTAX_LIST (1)
0: AST_ARRAY_ELEM
flags: 0
value: AST_VAR
name: "a"
key: "foo"
1: AST_ARRAY_ELEM
flags: 0
value: AST_VAR
name: "b"
key: "bar"
expr: AST_VAR
name: "x"
1: AST_ASSIGN
var: AST_ARRAY
flags: ARRAY_SYNTAX_SHORT (3)
0: AST_ARRAY_ELEM
flags: 0
value: AST_VAR
name: "a"
key: null
1: AST_ARRAY_ELEM
flags: 0
value: AST_VAR
name: "b"
key: null
expr: AST_VAR
name: "x"
2: AST_ASSIGN
var: AST_ARRAY
flags: ARRAY_SYNTAX_SHORT (3)
0: AST_ARRAY_ELEM
flags: 0
value: AST_VAR
name: "a"
key: "foo"
1: AST_ARRAY_ELEM
flags: 0
value: AST_VAR
name: "b"
key: "bar"
expr: AST_VAR
name: "x"
3: AST_ASSIGN
var: AST_ARRAY
flags: ARRAY_SYNTAX_SHORT (3)
0: null
1: AST_ARRAY_ELEM
flags: 0
value: AST_ARRAY
flags: ARRAY_SYNTAX_SHORT (3)
0: AST_ARRAY_ELEM
flags: 0
value: AST_VAR
name: "a"
key: null
key: null
expr: AST_VAR
name: "x" ast-1.1.2/tests/assign_ops.phpt 0000664 0001750 0001750 00000003751 14655731747 015653 0 ustar tyson tyson --TEST--
Assign op flags
--FILE--
>= $b;
PHP;
echo ast_dump(ast\parse_code($code, $version=70)), "\n";
?>
--EXPECTF--
AST_STMT_LIST
0: AST_ASSIGN_OP
flags: BINARY_BITWISE_OR (%d)
var: AST_VAR
name: "a"
expr: AST_VAR
name: "b"
1: AST_ASSIGN_OP
flags: BINARY_BITWISE_AND (%d)
var: AST_VAR
name: "a"
expr: AST_VAR
name: "b"
2: AST_ASSIGN_OP
flags: BINARY_BITWISE_XOR (%d)
var: AST_VAR
name: "a"
expr: AST_VAR
name: "b"
3: AST_ASSIGN_OP
flags: BINARY_CONCAT (%d)
var: AST_VAR
name: "a"
expr: AST_VAR
name: "b"
4: AST_ASSIGN_OP
flags: BINARY_ADD (%d)
var: AST_VAR
name: "a"
expr: AST_VAR
name: "b"
5: AST_ASSIGN_OP
flags: BINARY_SUB (%d)
var: AST_VAR
name: "a"
expr: AST_VAR
name: "b"
6: AST_ASSIGN_OP
flags: BINARY_MUL (%d)
var: AST_VAR
name: "a"
expr: AST_VAR
name: "b"
7: AST_ASSIGN_OP
flags: BINARY_DIV (%d)
var: AST_VAR
name: "a"
expr: AST_VAR
name: "b"
8: AST_ASSIGN_OP
flags: BINARY_MOD (%d)
var: AST_VAR
name: "a"
expr: AST_VAR
name: "b"
9: AST_ASSIGN_OP
flags: BINARY_POW (%d)
var: AST_VAR
name: "a"
expr: AST_VAR
name: "b"
10: AST_ASSIGN_OP
flags: BINARY_SHIFT_LEFT (%d)
var: AST_VAR
name: "a"
expr: AST_VAR
name: "b"
11: AST_ASSIGN_OP
flags: BINARY_SHIFT_RIGHT (%d)
var: AST_VAR
name: "a"
expr: AST_VAR
name: "b" ast-1.1.2/tests/ast_dump_with_exclude_doc.phpt 0000664 0001750 0001750 00000001211 14655731747 020700 0 ustar tyson tyson --TEST--
ast_dump() with AST_DUMP_EXCLUDE_DOC_COMMENT
--FILE--
--EXPECT--
AST_STMT_LIST
0: AST_FUNC_DECL
name: "test"
params: AST_PARAM_LIST
0: AST_PARAM
type: null
name: "foo"
default: null
attributes: null
stmts: AST_STMT_LIST
returnType: null
attributes: null
__declId: 0
ast-1.1.2/tests/ast_dump_with_linenos.phpt 0000664 0001750 0001750 00000001434 14655731747 020100 0 ustar tyson tyson --TEST--
ast_dump() with AST_DUMP_LINENOS
--SKIPIF--
--FILE--
--EXPECTF--
AST_STMT_LIST @ 1
0: AST_FUNC_DECL @ 2-9
name: "test"
docComment: null
params: AST_PARAM_LIST @ 4
stmts: AST_STMT_LIST @ 5
0: AST_CALL @ 6
expr: AST_NAME @ 6
flags: NAME_NOT_FQ (%d)
name: "var_dump"
args: AST_ARG_LIST @ 7
0: AST_VAR @ 7
name: "foo"
returnType: null
__declId: 0 ast-1.1.2/tests/attributes_01.phpt 0000664 0001750 0001750 00000003133 14655731747 016166 0 ustar tyson tyson --TEST--
Attributes in PHP 8.0 on globals
--SKIPIF--
= 8.0 only'); ?>
--FILE--
$x;
PHP;
echo ast_dump(ast\parse_code($code, $version=70));
--EXPECTF--
AST_STMT_LIST
0: AST_NAMESPACE
name: "NS"
stmts: null
1: AST_FUNC_DECL
name: "test"
docComment: null
params: AST_PARAM_LIST
0: AST_PARAM
type: AST_NAME
flags: NAME_NOT_FQ (%d)
name: "Type"
name: "arg"
default: null
stmts: AST_STMT_LIST
returnType: null
__declId: 0
2: AST_ASSIGN
var: AST_VAR
name: "x"
expr: AST_CLOSURE
name: "{closure}"
docComment: null
params: AST_PARAM_LIST
uses: null
stmts: AST_STMT_LIST
returnType: null
__declId: 1
3: AST_ASSIGN
var: AST_VAR
name: "y"
expr: AST_ARROW_FUNC
name: "{closure}"
docComment: null
params: AST_PARAM_LIST
0: AST_PARAM
type: null
name: "a"
default: null
stmts: AST_RETURN
expr: AST_VAR
name: "x"
returnType: null
__declId: 2 ast-1.1.2/tests/attributes_02.phpt 0000664 0001750 0001750 00000014553 14655731747 016177 0 ustar tyson tyson --TEST--
Attributes in PHP 8.0 on classes
--SKIPIF--
= 8.0 only'); ?>
--FILE--
$b;
$a >= $b;
$a and $b;
$a or $b;
PHP;
echo ast_dump(ast\parse_code($code, $version=70)), "\n";
?>
--EXPECT--
AST_STMT_LIST
0: AST_BINARY_OP
flags: BINARY_IS_GREATER (256)
left: AST_VAR
name: "a"
right: AST_VAR
name: "b"
1: AST_BINARY_OP
flags: BINARY_IS_GREATER_OR_EQUAL (257)
left: AST_VAR
name: "a"
right: AST_VAR
name: "b"
2: AST_BINARY_OP
flags: BINARY_BOOL_AND (259)
left: AST_VAR
name: "a"
right: AST_VAR
name: "b"
3: AST_BINARY_OP
flags: BINARY_BOOL_OR (258)
left: AST_VAR
name: "a"
right: AST_VAR
name: "b"
ast-1.1.2/tests/by_ref_destructuring.phpt 0000664 0001750 0001750 00000003134 14655731747 017731 0 ustar tyson tyson --TEST--
By-reference array destructuring (PHP 7.3)
--SKIPIF--
= 7.3 only'); ?>
--FILE--
--EXPECT--
AST_STMT_LIST
0: AST_ASSIGN
var: AST_ARRAY
flags: ARRAY_SYNTAX_LIST (1)
0: AST_ARRAY_ELEM
flags: 0
value: AST_VAR
name: "a"
key: null
1: AST_ARRAY_ELEM
flags: ARRAY_ELEM_REF (1)
value: AST_VAR
name: "b"
key: null
expr: AST_VAR
name: "c"
1: AST_ASSIGN
var: AST_ARRAY
flags: ARRAY_SYNTAX_SHORT (3)
0: AST_ARRAY_ELEM
flags: 0
value: AST_VAR
name: "a"
key: null
1: AST_ARRAY_ELEM
flags: ARRAY_ELEM_REF (1)
value: AST_VAR
name: "b"
key: null
expr: AST_VAR
name: "c"
2: AST_ASSIGN
var: AST_VAR
name: "c"
expr: AST_ARRAY
flags: ARRAY_SYNTAX_SHORT (3)
0: AST_ARRAY_ELEM
flags: 0
value: AST_VAR
name: "a"
key: null
1: AST_ARRAY_ELEM
flags: ARRAY_ELEM_REF (1)
value: AST_VAR
name: "b"
key: null ast-1.1.2/tests/class_consts.phpt 0000664 0001750 0001750 00000003346 14655731747 016204 0 ustar tyson tyson --TEST--
Class constants
--FILE--
--EXPECTF--
AST_STMT_LIST
0: AST_CLASS
name: "Test"
docComment: null
extends: null
implements: null
stmts: AST_STMT_LIST
0: AST_CLASS_CONST_DECL
flags: MODIFIER_PUBLIC (%d)
0: AST_CONST_ELEM
name: "A"
value: 1
docComment: "/** Doc A */"
1: AST_CLASS_CONST_DECL
flags: MODIFIER_PUBLIC (%d)
0: AST_CONST_ELEM
name: "B"
value: 2
docComment: null
2: AST_CLASS_CONST_DECL
flags: MODIFIER_PROTECTED (%d)
0: AST_CONST_ELEM
name: "C"
value: 3
docComment: null
3: AST_CLASS_CONST_DECL
flags: MODIFIER_PRIVATE (%d)
0: AST_CONST_ELEM
name: "D"
value: 4
docComment: null
4: AST_CLASS_CONST_DECL
flags: MODIFIER_PUBLIC (%d)
0: AST_CONST_ELEM
name: "E"
value: 5
docComment: "/** Doc E */"
1: AST_CONST_ELEM
name: "F"
value: 6
docComment: "/** Doc F */"
__declId: 0
ast-1.1.2/tests/class_consts_80.phpt 0000664 0001750 0001750 00000002444 14655731747 016511 0 ustar tyson tyson --TEST--
Class constants in AST version 80
--FILE--
--EXPECTF--
AST_STMT_LIST
0: AST_CLASS
name: "Test"
docComment: null
extends: null
implements: null
stmts: AST_STMT_LIST
0: AST_CLASS_CONST_GROUP
flags: MODIFIER_PUBLIC (%d)
const: AST_CLASS_CONST_DECL
0: AST_CONST_ELEM
name: "A"
value: 1
docComment: "/** Doc A */"
attributes: null
1: AST_CLASS_CONST_GROUP
flags: MODIFIER_PROTECTED (%d)
const: AST_CLASS_CONST_DECL
0: AST_CONST_ELEM
name: "E"
value: 5
docComment: "/** Doc E */"
1: AST_CONST_ELEM
name: "F"
value: 6
docComment: "/** Doc F */"
attributes: null
attributes: null
__declId: 0
ast-1.1.2/tests/class_const_types.phpt 0000664 0001750 0001750 00000005526 14655731747 017247 0 ustar tyson tyson --TEST--
PHP 8.3 class constant types
--SKIPIF--
= 8.3 only'); ?>
--FILE--
--EXPECTF--
Deprecated: ast\parse_code(): Version 50 is deprecated in %s.php on line 13
AST_STMT_LIST
0: AST_NAMESPACE
name: "Foo"
stmts: null
1: AST_ECHO
expr: AST_CLASS_CONST
class: AST_NAME
flags: NAME_NOT_FQ (1)
name: "Bar"
const: "class"
2: AST_ECHO
expr: AST_CLASS_CONST
class: AST_NAME
flags: NAME_RELATIVE (2)
name: "Bat"
const: "class"
3: AST_ECHO
expr: AST_CLASS_CONST
class: AST_NAME
flags: NAME_FQ (0)
name: "Baz"
const: "class"
ast-1.1.2/tests/class_name_version_70.phpt 0000664 0001750 0001750 00000003143 14655731747 017661 0 ustar tyson tyson --TEST--
Class properties in AST version 70
--FILE--
--EXPECTF--
AST_STMT_LIST
0: AST_NAMESPACE
name: "Foo"
stmts: null
1: AST_ECHO
expr: AST_CLASS_NAME
class: AST_NAME
flags: NAME_NOT_FQ (%d)
name: "Bar"
2: AST_ECHO
expr: AST_CLASS_NAME
class: AST_NAME
flags: NAME_RELATIVE (%d)
name: "Bat"
3: AST_ECHO
expr: AST_CLASS_CONST
class: AST_NAME
flags: NAME_NOT_FQ (%d)
name: "Bat"
const: "class_"
4: AST_ECHO
expr: AST_CLASS_NAME
class: AST_NAME
flags: NAME_FQ (%d)
name: "Baz"
5: AST_ECHO
expr: AST_CLASS_NAME
class: AST_ARRAY
flags: %s
6: AST_ECHO
expr: AST_CLASS_NAME
class: AST_NAME
flags: NAME_FQ (%d)
name: "foo"
7: AST_ECHO
expr: AST_CLASS_NAME
class: AST_NEW
class: AST_NAME
flags: NAME_FQ (0)
name: "stdClass"
args: AST_ARG_LIST
ast-1.1.2/tests/class_on_objects.phpt 0000664 0001750 0001750 00000000501 14655731747 017006 0 ustar tyson tyson --TEST--
$x::class in PHP 8.0
--FILE--
--EXPECTF--
Deprecated: ast\parse_code(): Version 60 is deprecated in %sclass.php on line 15
AST_STMT_LIST
0: AST_CLASS
name: "A"
docComment: null
extends: AST_NAME
flags: NAME_NOT_FQ (%d)
name: "B"
implements: AST_NAME_LIST
0: AST_NAME
flags: NAME_NOT_FQ (%d)
name: "D"
1: AST_NAME
flags: NAME_NOT_FQ (%d)
name: "E"
stmts: AST_STMT_LIST
0: AST_USE_TRAIT
traits: AST_NAME_LIST
0: AST_NAME
flags: NAME_NOT_FQ (%d)
name: "T"
1: AST_NAME
flags: NAME_NOT_FQ (%d)
name: "S"
adaptations: null
1: AST_CLASS_CONST_DECL
flags: MODIFIER_PUBLIC (%d)
0: AST_CONST_ELEM
name: "X"
value: "Y"
docComment: null
1: AST_CONST_ELEM
name: "Y"
value: "X"
docComment: null
2: AST_PROP_DECL
flags: MODIFIER_PUBLIC (%d)
0: AST_PROP_ELEM
name: "foo"
default: null
docComment: null
1: AST_PROP_ELEM
name: "bar"
default: null
docComment: null
3: AST_METHOD
flags: MODIFIER_PUBLIC | MODIFIER_ABSTRACT (%d)
name: "test"
docComment: null
params: AST_PARAM_LIST
stmts: null
returnType: null
__declId: 0
__declId: 1
AST_STMT_LIST
0: AST_CLASS
name: "A"
docComment: null
extends: AST_NAME
flags: NAME_NOT_FQ (%d)
name: "B"
implements: AST_NAME_LIST
0: AST_NAME
flags: NAME_NOT_FQ (%d)
name: "D"
1: AST_NAME
flags: NAME_NOT_FQ (%d)
name: "E"
stmts: AST_STMT_LIST
0: AST_USE_TRAIT
traits: AST_NAME_LIST
0: AST_NAME
flags: NAME_NOT_FQ (%d)
name: "T"
1: AST_NAME
flags: NAME_NOT_FQ (%d)
name: "S"
adaptations: null
1: AST_CLASS_CONST_DECL
flags: MODIFIER_PUBLIC (%d)
0: AST_CONST_ELEM
name: "X"
value: "Y"
docComment: null
1: AST_CONST_ELEM
name: "Y"
value: "X"
docComment: null
2: AST_PROP_GROUP
flags: MODIFIER_PUBLIC (%d)
type: null
props: AST_PROP_DECL
0: AST_PROP_ELEM
name: "foo"
default: null
docComment: null
1: AST_PROP_ELEM
name: "bar"
default: null
docComment: null
3: AST_METHOD
flags: MODIFIER_PUBLIC | MODIFIER_ABSTRACT (%d)
name: "test"
docComment: null
params: AST_PARAM_LIST
stmts: null
returnType: null
__declId: 0
__declId: 1 ast-1.1.2/tests/class_type_85.phpt 0000664 0001750 0001750 00000001343 14655731747 016163 0 ustar tyson tyson --TEST--
Class types only used for enums in AST version 85
--FILE--
--EXPECTF--
AST_STMT_LIST
0: AST_CLASS
name: "A"
docComment: null
extends: null
implements: null
stmts: AST_STMT_LIST
__declId: 0
1: AST_CLASS
flags: CLASS_ABSTRACT (%d)
name: "B"
docComment: null
extends: null
implements: null
stmts: AST_STMT_LIST
__declId: 1
2: AST_CLASS
flags: CLASS_FINAL (%d)
name: "C"
docComment: null
extends: null
implements: null
stmts: AST_STMT_LIST
__declId: 2
3: AST_CLASS
flags: CLASS_TRAIT (%d)
name: "D"
docComment: null
extends: null
implements: null
stmts: AST_STMT_LIST
__declId: 3
4: AST_CLASS
flags: CLASS_INTERFACE (%d)
name: "E"
docComment: null
extends: null
implements: null
stmts: AST_STMT_LIST
__declId: 4
5: AST_NEW
class: AST_CLASS
flags: CLASS_ANONYMOUS (%d)
name: null
docComment: null
extends: null
implements: null
stmts: AST_STMT_LIST
__declId: 5
args: AST_ARG_LIST
ast-1.1.2/tests/closure_use_vars.phpt 0000664 0001750 0001750 00000002152 14655731747 017063 0 ustar tyson tyson --TEST--
Closure uses should parse to CLOSURE_USE_VAR nodes
--FILE--
--EXPECTF--
AST_STMT_LIST
0: AST_ASSIGN
var: AST_VAR
name: "fn"
expr: AST_CLOSURE
flags: MODIFIER_STATIC | FUNC_RETURNS_REF (%d)
name: "{closure}"
docComment: null
params: AST_PARAM_LIST
0: AST_PARAM
type: null
name: "a"
default: null
1: AST_PARAM
flags: PARAM_REF (%d)
type: null
name: "b"
default: null
uses: AST_CLOSURE_USES
0: AST_CLOSURE_VAR
flags: 0
name: "c"
1: AST_CLOSURE_VAR
flags: CLOSURE_USE_REF (%d)
name: "d"
stmts: AST_STMT_LIST
returnType: null
__declId: 0 ast-1.1.2/tests/coalesce.phpt 0000664 0001750 0001750 00000000542 14655731747 015257 0 ustar tyson tyson --TEST--
Null-coalesce operator
--FILE--
--EXPECTF--
AST_STMT_LIST
0: AST_BINARY_OP
flags: BINARY_COALESCE (%d)
left: AST_VAR
name: "a"
right: AST_VAR
name: "b" ast-1.1.2/tests/concat.phpt 0000664 0001750 0001750 00000001674 14655731747 014757 0 ustar tyson tyson --TEST--
AST_CONCAT with/without parenthesis
--FILE--
--EXPECTF--
AST_STMT_LIST
0: AST_INCLUDE_OR_EVAL
flags: EXEC_REQUIRE_ONCE (%d)
expr: AST_BINARY_OP
flags: BINARY_CONCAT (%d)
left: AST_MAGIC_CONST
flags: MAGIC_DIR (%d)
right: "/first.php"
1: AST_INCLUDE_OR_EVAL
flags: EXEC_REQUIRE_ONCE (%d)
expr: AST_BINARY_OP
flags: BINARY_CONCAT (%d)
left: AST_MAGIC_CONST
flags: MAGIC_DIR (%d)
right: "/second.php"
ast-1.1.2/tests/constructor.phpt 0000664 0001750 0001750 00000001414 14655731747 016065 0 ustar tyson tyson --TEST--
ast\Node has a __construct method
--FILE--
'FOO'], 2), AST_DUMP_LINENOS) . "\n";
?>
===DONE===
--EXPECT--
object(ast\Node)#1 (4) {
["kind"]=>
NULL
["flags"]=>
NULL
["lineno"]=>
NULL
["children"]=>
NULL
}
object(ast\Node)#1 (4) {
["kind"]=>
NULL
["flags"]=>
NULL
["lineno"]=>
NULL
["children"]=>
NULL
}
AST_NAME @ 2
flags: NAME_NOT_FQ (1)
name: "FOO"
===DONE===
ast-1.1.2/tests/decl_ids.phpt 0000664 0001750 0001750 00000005336 14655731747 015255 0 ustar tyson tyson --TEST--
Closures should have unique identifiers within parsed code in version 50
--FILE--
--EXPECTF--
Deprecated: ast\parse_code(): Version 50 is deprecated in %s.php on line 11
AST_STMT_LIST
0: AST_CLOSURE
name: "{closure}"
docComment: null
params: AST_PARAM_LIST
uses: null
stmts: AST_STMT_LIST
returnType: null
__declId: 0
1: AST_CLOSURE
name: "{closure}"
docComment: null
params: AST_PARAM_LIST
uses: null
stmts: AST_STMT_LIST
returnType: null
__declId: 1
2: AST_FUNC_DECL
name: "test"
docComment: null
params: AST_PARAM_LIST
uses: null
stmts: AST_STMT_LIST
returnType: null
__declId: 2
3: AST_FUNC_DECL
name: "test"
docComment: null
params: AST_PARAM_LIST
uses: null
stmts: AST_STMT_LIST
returnType: null
__declId: 3
4: AST_CLASS
name: "Test"
docComment: null
extends: null
implements: null
stmts: AST_STMT_LIST
__declId: 4
5: AST_CLASS
name: "Test"
docComment: null
extends: null
implements: null
stmts: AST_STMT_LIST
__declId: 5
AST_STMT_LIST
0: AST_CLOSURE
name: "{closure}"
docComment: null
params: AST_PARAM_LIST
uses: null
stmts: AST_STMT_LIST
returnType: null
attributes: null
__declId: 0
1: AST_CLOSURE
name: "{closure}"
docComment: null
params: AST_PARAM_LIST
uses: null
stmts: AST_STMT_LIST
returnType: null
attributes: null
__declId: 1
2: AST_FUNC_DECL
name: "test"
docComment: null
params: AST_PARAM_LIST
stmts: AST_STMT_LIST
returnType: null
attributes: null
__declId: 2
3: AST_FUNC_DECL
name: "test"
docComment: null
params: AST_PARAM_LIST
stmts: AST_STMT_LIST
returnType: null
attributes: null
__declId: 3
4: AST_CLASS
name: "Test"
docComment: null
extends: null
implements: null
stmts: AST_STMT_LIST
attributes: null
__declId: 4
5: AST_CLASS
name: "Test"
docComment: null
extends: null
implements: null
stmts: AST_STMT_LIST
attributes: null
__declId: 5
ast-1.1.2/tests/decl_normalization.phpt 0000664 0001750 0001750 00000007065 14655731747 017365 0 ustar tyson tyson --TEST--
The class ast\Node\Decl no longer exists
--FILE--
children));
echo ast_dump($ast) . "\n";
$ast = ast\parse_code($code, $version=50);
echo ast_dump($ast) . "\n";
?>
--EXPECTF--
array(4) {
[0]=>
string(8) "ast\Node"
[1]=>
string(8) "ast\Node"
[2]=>
string(8) "ast\Node"
[3]=>
string(8) "ast\Node"
}
AST_STMT_LIST
0: AST_CLASS
name: "A"
docComment: "/** A */"
extends: null
implements: null
stmts: AST_STMT_LIST
0: AST_CLASS_CONST_DECL
flags: MODIFIER_PUBLIC (%d)
0: AST_CONST_ELEM
name: "B"
value: 0
docComment: "/** B */"
1: AST_PROP_GROUP
flags: MODIFIER_PUBLIC (%d)
type: null
props: AST_PROP_DECL
0: AST_PROP_ELEM
name: "c"
default: null
docComment: "/** c */"
2: AST_METHOD
flags: MODIFIER_PUBLIC (%d)
name: "d"
docComment: "/** d */"
params: AST_PARAM_LIST
stmts: AST_STMT_LIST
returnType: null
__declId: 0
__declId: 1
1: AST_CONST_DECL
0: AST_CONST_ELEM
name: "E"
value: 0
docComment: "/** E */"
2: AST_FUNC_DECL
name: "f"
docComment: "/** f */"
params: AST_PARAM_LIST
stmts: AST_STMT_LIST
returnType: null
__declId: 2
3: AST_CLOSURE
name: "{closure}"
docComment: "/** g */"
params: AST_PARAM_LIST
uses: null
stmts: AST_STMT_LIST
returnType: null
__declId: 3
Deprecated: ast\parse_code(): Version 50 is deprecated in %sdecl_normalization.php on line 29
AST_STMT_LIST
0: AST_CLASS
name: "A"
docComment: "/** A */"
extends: null
implements: null
stmts: AST_STMT_LIST
0: AST_CLASS_CONST_DECL
flags: MODIFIER_PUBLIC (%d)
0: AST_CONST_ELEM
name: "B"
value: 0
docComment: "/** B */"
1: AST_PROP_DECL
flags: MODIFIER_PUBLIC (%d)
0: AST_PROP_ELEM
name: "c"
default: null
docComment: "/** c */"
2: AST_METHOD
flags: MODIFIER_PUBLIC (%d)
name: "d"
docComment: "/** d */"
params: AST_PARAM_LIST
uses: null
stmts: AST_STMT_LIST
returnType: null
__declId: 0
__declId: 1
1: AST_CONST_DECL
0: AST_CONST_ELEM
name: "E"
value: 0
docComment: "/** E */"
2: AST_FUNC_DECL
name: "f"
docComment: "/** f */"
params: AST_PARAM_LIST
uses: null
stmts: AST_STMT_LIST
returnType: null
__declId: 2
3: AST_CLOSURE
name: "{closure}"
docComment: "/** g */"
params: AST_PARAM_LIST
uses: null
stmts: AST_STMT_LIST
returnType: null
__declId: 3 ast-1.1.2/tests/empty_file.php 0000664 0001750 0001750 00000000000 14655731747 015437 0 ustar tyson tyson ast-1.1.2/tests/empty_file_parse.phpt 0000664 0001750 0001750 00000000613 14655731747 017027 0 ustar tyson tyson --TEST--
ast\parse_file() with empty file
--FILE--
--EXPECT--
bool(true)
AST_STMT_LIST
bool(true)
AST_STMT_LIST
ast-1.1.2/tests/eval_include.phpt 0000664 0001750 0001750 00000001337 14655731747 016136 0 ustar tyson tyson --TEST--
eval() and include parsing
--FILE--
--EXPECT--
AST_STMT_LIST
0: AST_INCLUDE_OR_EVAL
flags: EXEC_EVAL (1)
expr: "echo "hello";"
1: AST_INCLUDE_OR_EVAL
flags: EXEC_INCLUDE (2)
expr: "foo.php"
2: AST_INCLUDE_OR_EVAL
flags: EXEC_INCLUDE_ONCE (4)
expr: "foo.php"
3: AST_INCLUDE_OR_EVAL
flags: EXEC_REQUIRE (8)
expr: "foo.php"
4: AST_INCLUDE_OR_EVAL
flags: EXEC_REQUIRE_ONCE (16)
expr: "foo.php"
ast-1.1.2/tests/functions_dont_use.phpt 0000664 0001750 0001750 00000002303 14655731747 017406 0 ustar tyson tyson --TEST--
Uses only make sense on closures
--FILE--
--EXPECTF--
Deprecated: ast\parse_code(): Version 50 is deprecated in %s.php on line 11
AST_STMT_LIST
0: AST_CLOSURE
name: "{closure}"
docComment: null
params: AST_PARAM_LIST
uses: null
stmts: AST_STMT_LIST
returnType: null
__declId: 0
1: AST_FUNC_DECL
name: "test"
docComment: null
params: AST_PARAM_LIST
uses: null
stmts: AST_STMT_LIST
returnType: null
__declId: 1
Deprecated: ast\parse_code(): Version 60 is deprecated in %s.php on line 12
AST_STMT_LIST
0: AST_CLOSURE
name: "{closure}"
docComment: null
params: AST_PARAM_LIST
uses: null
stmts: AST_STMT_LIST
returnType: null
__declId: 0
1: AST_FUNC_DECL
name: "test"
docComment: null
params: AST_PARAM_LIST
stmts: AST_STMT_LIST
returnType: null
__declId: 1
ast-1.1.2/tests/generator_flag.phpt 0000664 0001750 0001750 00000001007 14655731747 016455 0 ustar tyson tyson --TEST--
Flag on generator functions
--FILE--
--EXPECTF--
AST_STMT_LIST
0: AST_FUNC_DECL
flags: FUNC_GENERATOR (%d)
name: "gen"
docComment: null
params: AST_PARAM_LIST
stmts: AST_STMT_LIST
0: AST_YIELD
value: null
key: null
returnType: null
__declId: 0
ast-1.1.2/tests/get_kind_name.phpt 0000664 0001750 0001750 00000000621 14655731747 016263 0 ustar tyson tyson --TEST--
Test ast\get_kind_name()
--FILE--
getMessage(), "\n";
}
?>
--EXPECT--
string(7) "AST_VAR"
string(8) "AST_NAME"
string(15) "AST_CLOSURE_VAR"
Unknown kind 12345
ast-1.1.2/tests/get_supported_versions.phpt 0000664 0001750 0001750 00000000674 14655731747 020323 0 ustar tyson tyson --TEST--
ast\get_supported_versions() function
--FILE--
--EXPECT--
array(8) {
[0]=>
int(50)
[1]=>
int(60)
[2]=>
int(70)
[3]=>
int(80)
[4]=>
int(85)
[5]=>
int(90)
[6]=>
int(100)
[7]=>
int(110)
}
array(6) {
[0]=>
int(70)
[1]=>
int(80)
[2]=>
int(85)
[3]=>
int(90)
[4]=>
int(100)
[5]=>
int(110)
}
ast-1.1.2/tests/invalid_file.php 0000664 0001750 0001750 00000000026 14655731747 015737 0 ustar tyson tyson
--EXPECTF--
AST_STMT_LIST
0: AST_MAGIC_CONST
flags: MAGIC_LINE (%d)
1: AST_MAGIC_CONST
flags: MAGIC_FILE (%d)
2: AST_MAGIC_CONST
flags: MAGIC_DIR (%d)
3: AST_MAGIC_CONST
flags: MAGIC_NAMESPACE (%d)
4: AST_MAGIC_CONST
flags: MAGIC_FUNCTION (%d)
5: AST_MAGIC_CONST
flags: MAGIC_METHOD (%d)
6: AST_MAGIC_CONST
flags: MAGIC_CLASS (%d)
7: AST_MAGIC_CONST
flags: MAGIC_TRAIT (%d)
ast-1.1.2/tests/match_expression.phpt 0000664 0001750 0001750 00000002650 14655731747 017056 0 ustar tyson tyson --TEST--
Match expression in PHP 8.0
--SKIPIF--
= 8.0 only'); ?>
--FILE--
3, default => 5 };
match(1) {};
match(my_const) {
1, \other_const => $x,
default, => 123,
};
PHP;
$node = ast\parse_code($code, $version=70);
echo ast_dump($node), "\n";
--EXPECTF--
AST_STMT_LIST
0: AST_ASSIGN
var: AST_VAR
name: "x"
expr: AST_MATCH
cond: AST_VAR
name: "y"
stmts: AST_MATCH_ARM_LIST
0: AST_MATCH_ARM
cond: AST_EXPR_LIST
0: 2
expr: 3
1: AST_MATCH_ARM
cond: null
expr: 5
1: AST_MATCH
cond: 1
stmts: AST_MATCH_ARM_LIST
2: AST_MATCH
cond: AST_CONST
name: AST_NAME
flags: NAME_NOT_FQ (%d)
name: "my_const"
stmts: AST_MATCH_ARM_LIST
0: AST_MATCH_ARM
cond: AST_EXPR_LIST
0: 1
1: AST_CONST
name: AST_NAME
flags: NAME_FQ (%d)
name: "other_const"
expr: AST_VAR
name: "x"
1: AST_MATCH_ARM
cond: null
expr: 123 ast-1.1.2/tests/metadata.phpt 0000664 0001750 0001750 00000014037 14655731747 015265 0 ustar tyson tyson --TEST--
AST metadata
--FILE--
flags as $flag) {
$flags[] = substr($flag, strrpos($flag, '\\') + 1);
}
$metadataHasFlags = count($flags) > 0;
$kindUsesFlags = ast\kind_uses_flags($data->kind);
if ($metadataHasFlags != $kindUsesFlags) {
echo "kind_uses_flags for $data->name is unexpectedly " . var_export($kindUsesFlags, true) . "\n";
}
echo "$data->name: ";
if ($data->flagsCombinable) {
echo "(combinable) ";
}
echo "[", implode(", ", $flags), "]\n";
}
// NOTE: AST_PARAM has overlapping flag values for MODIFIER_PUBLIC and PARAM_REF in php 7.4.
// To work around this, MODIFIER_* were omitted from get_metadata in 7.4 and older.
?>
--EXPECT--
AST_ARG_LIST: []
AST_LIST: []
AST_ARRAY: [ARRAY_SYNTAX_LIST, ARRAY_SYNTAX_LONG, ARRAY_SYNTAX_SHORT]
AST_ENCAPS_LIST: []
AST_EXPR_LIST: []
AST_STMT_LIST: []
AST_IF: []
AST_SWITCH_LIST: []
AST_CATCH_LIST: []
AST_PARAM_LIST: []
AST_CLOSURE_USES: []
AST_PROP_DECL: (combinable) [MODIFIER_PUBLIC, MODIFIER_PROTECTED, MODIFIER_PRIVATE, MODIFIER_STATIC, MODIFIER_ABSTRACT, MODIFIER_FINAL, MODIFIER_READONLY]
AST_CONST_DECL: []
AST_CLASS_CONST_DECL: (combinable) [MODIFIER_PUBLIC, MODIFIER_PROTECTED, MODIFIER_PRIVATE, MODIFIER_STATIC, MODIFIER_ABSTRACT, MODIFIER_FINAL, MODIFIER_READONLY]
AST_NAME_LIST: []
AST_TRAIT_ADAPTATIONS: []
AST_USE: [USE_NORMAL, USE_FUNCTION, USE_CONST]
AST_TYPE_UNION: []
AST_TYPE_INTERSECTION: []
AST_ATTRIBUTE_LIST: []
AST_ATTRIBUTE_GROUP: []
AST_MATCH_ARM_LIST: []
AST_NAME: [NAME_FQ, NAME_NOT_FQ, NAME_RELATIVE]
AST_CLOSURE_VAR: [CLOSURE_USE_REF]
AST_NULLABLE_TYPE: []
AST_FUNC_DECL: (combinable) [MODIFIER_PUBLIC, MODIFIER_PROTECTED, MODIFIER_PRIVATE, MODIFIER_STATIC, MODIFIER_ABSTRACT, MODIFIER_FINAL, MODIFIER_READONLY, FUNC_RETURNS_REF, FUNC_GENERATOR]
AST_CLOSURE: (combinable) [MODIFIER_PUBLIC, MODIFIER_PROTECTED, MODIFIER_PRIVATE, MODIFIER_STATIC, MODIFIER_ABSTRACT, MODIFIER_FINAL, MODIFIER_READONLY, FUNC_RETURNS_REF, FUNC_GENERATOR]
AST_METHOD: (combinable) [MODIFIER_PUBLIC, MODIFIER_PROTECTED, MODIFIER_PRIVATE, MODIFIER_STATIC, MODIFIER_ABSTRACT, MODIFIER_FINAL, MODIFIER_READONLY, FUNC_RETURNS_REF, FUNC_GENERATOR]
AST_ARROW_FUNC: (combinable) [MODIFIER_PUBLIC, MODIFIER_PROTECTED, MODIFIER_PRIVATE, MODIFIER_STATIC, MODIFIER_ABSTRACT, MODIFIER_FINAL, MODIFIER_READONLY, FUNC_RETURNS_REF, FUNC_GENERATOR]
AST_CLASS: (combinable) [CLASS_ABSTRACT, CLASS_FINAL, CLASS_TRAIT, CLASS_INTERFACE, CLASS_ANONYMOUS, CLASS_ENUM, CLASS_READONLY]
AST_PROPERTY_HOOK: (combinable) [MODIFIER_PUBLIC, MODIFIER_PROTECTED, MODIFIER_PRIVATE, MODIFIER_STATIC, MODIFIER_ABSTRACT, MODIFIER_FINAL, MODIFIER_READONLY, FUNC_RETURNS_REF, FUNC_GENERATOR]
AST_MAGIC_CONST: [MAGIC_LINE, MAGIC_FILE, MAGIC_DIR, MAGIC_NAMESPACE, MAGIC_FUNCTION, MAGIC_METHOD, MAGIC_CLASS, MAGIC_TRAIT]
AST_TYPE: [TYPE_NULL, TYPE_FALSE, TYPE_TRUE, TYPE_BOOL, TYPE_LONG, TYPE_DOUBLE, TYPE_STRING, TYPE_ARRAY, TYPE_OBJECT, TYPE_CALLABLE, TYPE_VOID, TYPE_ITERABLE, TYPE_STATIC, TYPE_MIXED, TYPE_NEVER]
AST_CALLABLE_CONVERT: []
AST_VAR: (combinable) [ENCAPS_VAR_DOLLAR_CURLY_VAR_VAR, ENCAPS_VAR_DOLLAR_CURLY]
AST_CONST: []
AST_UNPACK: []
AST_CAST: [TYPE_NULL, TYPE_FALSE, TYPE_TRUE, TYPE_BOOL, TYPE_LONG, TYPE_DOUBLE, TYPE_STRING, TYPE_ARRAY, TYPE_OBJECT, TYPE_CALLABLE, TYPE_VOID, TYPE_ITERABLE, TYPE_STATIC, TYPE_MIXED, TYPE_NEVER]
AST_EMPTY: []
AST_ISSET: []
AST_SHELL_EXEC: []
AST_CLONE: []
AST_EXIT: []
AST_PRINT: []
AST_INCLUDE_OR_EVAL: [EXEC_EVAL, EXEC_INCLUDE, EXEC_INCLUDE_ONCE, EXEC_REQUIRE, EXEC_REQUIRE_ONCE]
AST_UNARY_OP: [UNARY_BOOL_NOT, UNARY_BITWISE_NOT, UNARY_MINUS, UNARY_PLUS, UNARY_SILENCE]
AST_PRE_INC: []
AST_PRE_DEC: []
AST_POST_INC: []
AST_POST_DEC: []
AST_YIELD_FROM: []
AST_GLOBAL: []
AST_UNSET: []
AST_RETURN: []
AST_LABEL: []
AST_REF: []
AST_HALT_COMPILER: []
AST_ECHO: []
AST_THROW: []
AST_GOTO: []
AST_BREAK: []
AST_CONTINUE: []
AST_CLASS_NAME: []
AST_PROPERTY_HOOK_SHORT_BODY: []
AST_CLASS_CONST_GROUP: (combinable) [MODIFIER_PUBLIC, MODIFIER_PROTECTED, MODIFIER_PRIVATE, MODIFIER_STATIC, MODIFIER_ABSTRACT, MODIFIER_FINAL, MODIFIER_READONLY]
AST_DIM: (combinable) [DIM_ALTERNATIVE_SYNTAX, ENCAPS_VAR_DOLLAR_CURLY]
AST_PROP: []
AST_NULLSAFE_PROP: []
AST_STATIC_PROP: []
AST_CALL: []
AST_CLASS_CONST: []
AST_ASSIGN: []
AST_ASSIGN_REF: []
AST_ASSIGN_OP: [BINARY_BITWISE_OR, BINARY_BITWISE_AND, BINARY_BITWISE_XOR, BINARY_CONCAT, BINARY_ADD, BINARY_SUB, BINARY_MUL, BINARY_DIV, BINARY_MOD, BINARY_POW, BINARY_SHIFT_LEFT, BINARY_SHIFT_RIGHT, BINARY_COALESCE]
AST_BINARY_OP: [BINARY_BITWISE_OR, BINARY_BITWISE_AND, BINARY_BITWISE_XOR, BINARY_CONCAT, BINARY_ADD, BINARY_SUB, BINARY_MUL, BINARY_DIV, BINARY_MOD, BINARY_POW, BINARY_SHIFT_LEFT, BINARY_SHIFT_RIGHT, BINARY_COALESCE, BINARY_BOOL_AND, BINARY_BOOL_OR, BINARY_BOOL_XOR, BINARY_IS_IDENTICAL, BINARY_IS_NOT_IDENTICAL, BINARY_IS_EQUAL, BINARY_IS_NOT_EQUAL, BINARY_IS_SMALLER, BINARY_IS_SMALLER_OR_EQUAL, BINARY_IS_GREATER, BINARY_IS_GREATER_OR_EQUAL, BINARY_SPACESHIP]
AST_ARRAY_ELEM: [ARRAY_ELEM_REF]
AST_NEW: []
AST_INSTANCEOF: []
AST_YIELD: []
AST_STATIC: []
AST_WHILE: []
AST_DO_WHILE: []
AST_IF_ELEM: []
AST_SWITCH: []
AST_SWITCH_CASE: []
AST_DECLARE: []
AST_PROP_ELEM: []
AST_PROP_GROUP: (combinable) [MODIFIER_PUBLIC, MODIFIER_PROTECTED, MODIFIER_PRIVATE, MODIFIER_STATIC, MODIFIER_ABSTRACT, MODIFIER_FINAL, MODIFIER_READONLY]
AST_CONST_ELEM: []
AST_USE_TRAIT: []
AST_TRAIT_PRECEDENCE: []
AST_METHOD_REFERENCE: []
AST_NAMESPACE: []
AST_USE_ELEM: [USE_NORMAL, USE_FUNCTION, USE_CONST]
AST_TRAIT_ALIAS: (combinable) [MODIFIER_PUBLIC, MODIFIER_PROTECTED, MODIFIER_PRIVATE, MODIFIER_STATIC, MODIFIER_ABSTRACT, MODIFIER_FINAL, MODIFIER_READONLY]
AST_GROUP_USE: [USE_NORMAL, USE_FUNCTION, USE_CONST]
AST_ATTRIBUTE: []
AST_MATCH: []
AST_MATCH_ARM: []
AST_NAMED_ARG: []
AST_METHOD_CALL: []
AST_NULLSAFE_METHOD_CALL: []
AST_STATIC_CALL: []
AST_CONDITIONAL: (combinable) [PARENTHESIZED_CONDITIONAL]
AST_TRY: []
AST_CATCH: []
AST_FOR: []
AST_FOREACH: []
AST_ENUM_CASE: []
AST_PARAM: (combinable) [PARAM_REF, PARAM_VARIADIC, PARAM_MODIFIER_PUBLIC, PARAM_MODIFIER_PROTECTED, PARAM_MODIFIER_PRIVATE]
ast-1.1.2/tests/mixed_type.phpt 0000664 0001750 0001750 00000004164 14655731747 015654 0 ustar tyson tyson --TEST--
Mixed types in PHP 8.0
--FILE--
--EXPECT--
AST_STMT_LIST
0: AST_TRY
try: AST_STMT_LIST
catches: AST_CATCH_LIST
0: AST_CATCH
class: AST_NAME_LIST
0: AST_NAME
flags: NAME_NOT_FQ (1)
name: "A"
1: AST_NAME
flags: NAME_NOT_FQ (1)
name: "B"
var: AST_VAR
name: "b"
stmts: AST_STMT_LIST
finally: null ast-1.1.2/tests/multiple_final_modifiers.phpt 0000664 0001750 0001750 00000000646 14655731747 020553 0 ustar tyson tyson --TEST--
Multiple final multipliers should generate CompileError, not a fatal error
--SKIPIF--
--FILE--
getMessage(), "\n";
}
?>
--EXPECT--
Multiple final modifiers are not allowed
ast-1.1.2/tests/named_children.phpt 0000664 0001750 0001750 00000001762 14655731747 016442 0 ustar tyson tyson --TEST--
Named child nodes
--FILE--
--EXPECT--
AST_STMT_LIST
0: AST_ASSIGN
var: AST_VAR
name: "fn"
expr: AST_CLOSURE
name: "{closure}"
docComment: null
params: AST_PARAM_LIST
uses: AST_CLOSURE_USES
0: AST_CLOSURE_VAR
flags: CLOSURE_USE_REF (1)
name: "var"
stmts: AST_STMT_LIST
0: AST_ASSIGN_OP
flags: BINARY_ADD (1)
var: AST_VAR
name: "var"
expr: AST_CALL
expr: AST_NAME
flags: NAME_NOT_FQ (1)
name: "func"
args: AST_ARG_LIST
returnType: null
__declId: 0 ast-1.1.2/tests/name_node.phpt 0000664 0001750 0001750 00000001310 14655731747 015420 0 ustar tyson tyson --TEST--
Name nodes
--FILE--
--EXPECT--
AST_STMT_LIST
0: AST_CALL
expr: AST_NAME
flags: NAME_NOT_FQ (1)
name: "foo"
args: AST_ARG_LIST
1: AST_CALL
expr: AST_NAME
flags: NAME_FQ (0)
name: "foo"
args: AST_ARG_LIST
2: AST_CALL
expr: AST_NAME
flags: NAME_FQ (0)
name: "foo"
args: AST_ARG_LIST
3: AST_CALL
expr: AST_NAME
flags: NAME_FQ (0)
name: "foo"
args: AST_ARG_LIST
ast-1.1.2/tests/nested_stmt_lists.phpt 0000664 0001750 0001750 00000001020 14655731747 017240 0 ustar tyson tyson --TEST--
Nested statement lists
--FILE--
--EXPECT--
AST_STMT_LIST
0: AST_VAR
name: "a"
1: AST_VAR
name: "b"
2: AST_VAR
name: "c"
3: AST_VAR
name: "d"
4: AST_VAR
name: "e"
5: AST_VAR
name: "f"
6: AST_VAR
name: "g" ast-1.1.2/tests/never_return_type.phpt 0000664 0001750 0001750 00000000732 14655731747 017261 0 ustar tyson tyson --TEST--
'never' return type parsing
--FILE--
--FILE--
getMessage()}\n";
}
--EXPECTF--
Caught %s, string given
ast-1.1.2/tests/nop_statements.phpt 0000664 0001750 0001750 00000000412 14655731747 016540 0 ustar tyson tyson --TEST--
Nop statements
--FILE--
--EXPECT--
AST_STMT_LIST
0: AST_VAR
name: "a"
1: AST_VAR
name: "b"
ast-1.1.2/tests/nullable_types.phpt 0000664 0001750 0001750 00000003272 14655731747 016526 0 ustar tyson tyson --TEST--
Nullable types
--FILE--
--EXPECT--
AST_STMT_LIST
0: AST_FUNC_DECL
name: "test"
docComment: null
params: AST_PARAM_LIST
0: AST_PARAM
type: AST_NULLABLE_TYPE
type: AST_NAME
flags: NAME_NOT_FQ (1)
name: "Foo"
name: "foo"
default: null
stmts: AST_STMT_LIST
returnType: AST_NULLABLE_TYPE
type: AST_NAME
flags: NAME_NOT_FQ (1)
name: "Bar"
__declId: 0
1: AST_FUNC_DECL
name: "test"
docComment: null
params: AST_PARAM_LIST
0: AST_PARAM
type: AST_NULLABLE_TYPE
type: AST_TYPE
flags: TYPE_LONG (4)
name: "foo"
default: null
stmts: AST_STMT_LIST
returnType: AST_NULLABLE_TYPE
type: AST_TYPE
flags: TYPE_LONG (4)
__declId: 1
2: AST_FUNC_DECL
name: "test"
docComment: null
params: AST_PARAM_LIST
0: AST_PARAM
type: AST_NULLABLE_TYPE
type: AST_TYPE
flags: TYPE_ARRAY (7)
name: "foo"
default: null
stmts: AST_STMT_LIST
returnType: AST_NULLABLE_TYPE
type: AST_TYPE
flags: TYPE_ARRAY (7)
__declId: 2
ast-1.1.2/tests/object_type.phpt 0000664 0001750 0001750 00000001141 14655731747 016004 0 ustar tyson tyson --TEST--
The object type is recognized
--FILE--
--EXPECTF--
AST_STMT_LIST
0: AST_FUNC_DECL
name: "test"
docComment: null
params: AST_PARAM_LIST
0: AST_PARAM
type: AST_TYPE
flags: TYPE_OBJECT (%d)
name: "obj"
default: null
stmts: AST_STMT_LIST
returnType: AST_TYPE
flags: TYPE_OBJECT (%d)
__declId: 0
ast-1.1.2/tests/params.phpt 0000664 0001750 0001750 00000007351 14655731747 014771 0 ustar tyson tyson --TEST--
Function parameters
--FILE--
--EXPECTF--
AST_STMT_LIST
0: AST_FUNC_DECL
name: "test"
docComment: null
params: AST_PARAM_LIST
0: AST_PARAM
type: null
name: "a"
default: null
1: AST_PARAM
flags: PARAM_VARIADIC (%d)
type: null
name: "b"
default: null
stmts: AST_STMT_LIST
returnType: null
__declId: 0
1: AST_FUNC_DECL
name: "test2"
docComment: null
params: AST_PARAM_LIST
0: AST_PARAM
flags: PARAM_REF (%d)
type: null
name: "a"
default: null
1: AST_PARAM
flags: PARAM_REF | PARAM_VARIADIC (%d)
type: null
name: "b"
default: null
stmts: AST_STMT_LIST
returnType: null
__declId: 1
2: AST_FUNC_DECL
name: "test3"
docComment: null
params: AST_PARAM_LIST
0: AST_PARAM
flags: PARAM_REF (%d)
type: AST_TYPE
flags: TYPE_ARRAY (%d)
name: "a"
default: null
1: AST_PARAM
flags: PARAM_REF | PARAM_VARIADIC (%d)
type: AST_TYPE
flags: TYPE_ARRAY (%d)
name: "b"
default: null
stmts: AST_STMT_LIST
returnType: null
__declId: 2
AST_STMT_LIST
0: AST_FUNC_DECL
name: "test"
docComment: null
params: AST_PARAM_LIST
0: AST_PARAM
type: null
name: "a"
default: null
attributes: null
docComment: null
1: AST_PARAM
flags: PARAM_VARIADIC (%d)
type: null
name: "b"
default: null
attributes: null
docComment: null
stmts: AST_STMT_LIST
returnType: null
attributes: null
__declId: 0
1: AST_FUNC_DECL
name: "test2"
docComment: null
params: AST_PARAM_LIST
0: AST_PARAM
flags: PARAM_REF (%d)
type: null
name: "a"
default: null
attributes: null
docComment: null
1: AST_PARAM
flags: PARAM_REF | PARAM_VARIADIC (%d)
type: null
name: "b"
default: null
attributes: null
docComment: null
stmts: AST_STMT_LIST
returnType: null
attributes: null
__declId: 1
2: AST_FUNC_DECL
name: "test3"
docComment: null
params: AST_PARAM_LIST
0: AST_PARAM
flags: PARAM_REF (%d)
type: AST_TYPE
flags: TYPE_ARRAY (%d)
name: "a"
default: null
attributes: null
docComment: null
1: AST_PARAM
flags: PARAM_REF | PARAM_VARIADIC (%d)
type: AST_TYPE
flags: TYPE_ARRAY (%d)
name: "b"
default: null
attributes: null
docComment: null
stmts: AST_STMT_LIST
returnType: null
attributes: null
__declId: 2 ast-1.1.2/tests/parse_code_parse_error.phpt 0000664 0001750 0001750 00000001104 14655731747 020203 0 ustar tyson tyson --TEST--
ast\parse_code() throwing a ParseError
--FILE--
--EXPECTF--
ParseError: syntax error, unexpected %s&%s expecting end of file in string code:1
Stack trace:
#0 %s(%d): ast\parse_code('%s', %d)
#1 {main}
ParseError: syntax error, unexpected %s&%s expecting end of file in file.php:1
Stack trace:
#0 %s(%d): ast\parse_code('%s', %d, 'file.php')
#1 {main}
ast-1.1.2/tests/parse_file_not_existing.phpt 0000664 0001750 0001750 00000000615 14655731747 020405 0 ustar tyson tyson --TEST--
ast\parse_file() on file that does not exist
--FILE--
--EXPECTF--
RuntimeException: ast\parse_file(%stests/non_existing_file.php): %sailed to open stream: No such file or directory in %s:%d
Stack trace:
#0 %s(%d): ast\parse_file('%s', %d)
#1 {main}
ast-1.1.2/tests/parse_file_parse_error.phpt 0000664 0001750 0001750 00000000514 14655731747 020214 0 ustar tyson tyson --TEST--
ast\parse_file() on file with parse error
--FILE--
--EXPECTF--
ParseError: syntax error, unexpected %s)%s in %stests/invalid_file.php:3
Stack trace:
#0 %s(%d): ast\parse_file('%s', %d)
#1 {main}
ast-1.1.2/tests/parse_file.phpt 0000664 0001750 0001750 00000000362 14655731747 015612 0 ustar tyson tyson --TEST--
ast\parse_file() on valid file
--FILE--
--EXPECT--
AST_STMT_LIST
0: AST_RETURN
expr: 123
ast-1.1.2/tests/php74_ast_assign_coalesce.phpt 0000664 0001750 0001750 00000001567 14655731747 020524 0 ustar tyson tyson --TEST--
'??=' operator in PHP 7.4
--SKIPIF--
= 7.4 only'); ?>
--FILE--
--EXPECTF--
AST_STMT_LIST
0: AST_ASSIGN_OP
flags: BINARY_COALESCE (%d)
var: AST_VAR
name: "x"
expr: 2
1: AST_ASSIGN_OP
flags: BINARY_COALESCE (%d)
var: AST_DIM
expr: AST_STATIC_PROP
class: AST_NAME
flags: NAME_NOT_FQ (%d)
name: "Foo"
prop: "prop"
dim: "offset"
expr: AST_ASSIGN_OP
flags: BINARY_COALESCE (%d)
var: AST_VAR
name: "other"
expr: "value" ast-1.1.2/tests/php74_dim_alternative_syntax.phpt 0000664 0001750 0001750 00000001211 14655731747 021272 0 ustar tyson tyson --TEST--
'$x{"offset"}' flag in PHP 7.4
--SKIPIF--
= 80400) die('skip PHP 7.4-8.3 only'); ?>
--FILE--
--EXPECTF--
AST_STMT_LIST
0: AST_CALL
expr: AST_NAME
flags: NAME_NOT_FQ (%d)
name: "var_export"
args: AST_ARG_LIST
0: AST_DIM
flags: DIM_ALTERNATIVE_SYNTAX (%d)
expr: AST_VAR
name: "x"
dim: "offset"
ast-1.1.2/tests/php74_ordinary_class.phpt 0000664 0001750 0001750 00000004004 14655731747 017534 0 ustar tyson tyson --TEST--
Class properties in AST version 70 (php 7.0+)
--FILE--
--EXPECTF--
AST_STMT_LIST
0: AST_NAMESPACE
name: "Foo"
stmts: null
1: AST_CLASS
name: "test"
docComment: null
extends: null
implements: null
stmts: AST_STMT_LIST
0: AST_PROP_GROUP
flags: MODIFIER_PUBLIC (%d)
type: null
props: AST_PROP_DECL
0: AST_PROP_ELEM
name: "i"
default: 2
docComment: null
1: AST_PROP_ELEM
name: "j"
default: null
docComment: null
1: AST_PROP_GROUP
flags: MODIFIER_PROTECTED (%d)
type: null
props: AST_PROP_DECL
0: AST_PROP_ELEM
name: "row"
default: null
docComment: null
2: AST_PROP_GROUP
flags: MODIFIER_PUBLIC (%d)
type: null
props: AST_PROP_DECL
0: AST_PROP_ELEM
name: "o"
default: null
docComment: null
3: AST_PROP_GROUP
flags: MODIFIER_PRIVATE | MODIFIER_STATIC (%d)
type: null
props: AST_PROP_DECL
0: AST_PROP_ELEM
name: "normal"
default: AST_CONST
name: AST_NAME
flags: NAME_NOT_FQ (1)
name: "null"
docComment: null
__declId: 0
ast-1.1.2/tests/php74_parenthesized_conditional.phpt 0000664 0001750 0001750 00000002204 14655731747 021750 0 ustar tyson tyson --TEST--
parenthesized conditionals in PHP 7.4
--SKIPIF--
= 7.4 only'); ?>
--FILE--
--EXPECT--
AST_STMT_LIST
0: AST_RETURN
expr: AST_CONDITIONAL
cond: AST_CONDITIONAL
cond: AST_VAR
name: "a"
true: AST_VAR
name: "b"
false: AST_VAR
name: "c"
true: AST_VAR
name: "d"
false: AST_VAR
name: "e"
1: AST_RETURN
expr: AST_CONDITIONAL
cond: AST_VAR
name: "a"
true: AST_VAR
name: "b"
false: AST_CONDITIONAL
flags: PARENTHESIZED_CONDITIONAL (1)
cond: AST_VAR
name: "c"
true: AST_VAR
name: "d"
false: AST_VAR
name: "e" ast-1.1.2/tests/php74_type_hints.phpt 0000664 0001750 0001750 00000012314 14655731747 016711 0 ustar tyson tyson --TEST--
Property type hints in PHP 7.4
--SKIPIF--
= 7.4 only'); ?>
--FILE--
--EXPECTF--
Deprecated: ast\parse_code(): Version 60 is deprecated in %s.php on line 18
The type property should not be set in version 60
AST_STMT_LIST
0: AST_NAMESPACE
name: "Foo"
stmts: null
1: AST_CLASS
name: "test"
docComment: null
extends: null
implements: null
stmts: AST_STMT_LIST
0: AST_PROP_DECL
flags: MODIFIER_PUBLIC (%d)
0: AST_PROP_ELEM
name: "i"
default: 2
docComment: null
1: AST_PROP_ELEM
name: "j"
default: null
docComment: null
1: AST_PROP_DECL
flags: MODIFIER_PUBLIC | MODIFIER_STATIC (%d)
0: AST_PROP_ELEM
name: "s"
default: null
docComment: null
2: AST_PROP_DECL
flags: MODIFIER_PRIVATE (%d)
0: AST_PROP_ELEM
name: "it"
default: null
docComment: null
3: AST_PROP_DECL
flags: MODIFIER_PROTECTED (%d)
0: AST_PROP_ELEM
name: "row"
default: null
docComment: null
4: AST_PROP_DECL
flags: MODIFIER_PUBLIC (%d)
0: AST_PROP_ELEM
name: "o"
default: null
docComment: null
5: AST_PROP_DECL
flags: MODIFIER_PRIVATE | MODIFIER_STATIC (%d)
0: AST_PROP_ELEM
name: "normal"
default: AST_CONST
name: AST_NAME
flags: NAME_NOT_FQ (1)
name: "null"
docComment: null
__declId: 0
But the type property should be set in version 70
AST_STMT_LIST
0: AST_NAMESPACE
name: "Foo"
stmts: null
1: AST_CLASS
name: "test"
docComment: null
extends: null
implements: null
stmts: AST_STMT_LIST
0: AST_PROP_GROUP
flags: MODIFIER_PUBLIC (%d)
type: AST_TYPE
flags: TYPE_LONG (4)
props: AST_PROP_DECL
0: AST_PROP_ELEM
name: "i"
default: 2
docComment: null
1: AST_PROP_ELEM
name: "j"
default: null
docComment: null
1: AST_PROP_GROUP
flags: MODIFIER_PUBLIC | MODIFIER_STATIC (%d)
type: AST_NULLABLE_TYPE
type: AST_TYPE
flags: TYPE_STRING (6)
props: AST_PROP_DECL
0: AST_PROP_ELEM
name: "s"
default: null
docComment: null
2: AST_PROP_GROUP
flags: MODIFIER_PRIVATE (%d)
type: AST_NULLABLE_TYPE
type: AST_TYPE
flags: TYPE_ITERABLE (%d)
props: AST_PROP_DECL
0: AST_PROP_ELEM
name: "it"
default: null
docComment: null
3: AST_PROP_GROUP
flags: MODIFIER_PROTECTED (%d)
type: AST_NAME
flags: NAME_NOT_FQ (1)
name: "Row"
props: AST_PROP_DECL
0: AST_PROP_ELEM
name: "row"
default: null
docComment: null
4: AST_PROP_GROUP
flags: MODIFIER_PUBLIC (%d)
type: AST_NAME
flags: NAME_FQ (0)
name: "stdClass"
props: AST_PROP_DECL
0: AST_PROP_ELEM
name: "o"
default: null
docComment: null
5: AST_PROP_GROUP
flags: MODIFIER_PRIVATE | MODIFIER_STATIC (%d)
type: null
props: AST_PROP_DECL
0: AST_PROP_ELEM
name: "normal"
default: AST_CONST
name: AST_NAME
flags: NAME_NOT_FQ (1)
name: "null"
docComment: null
__declId: 0
ast-1.1.2/tests/php80_named_params.phpt 0000664 0001750 0001750 00000002323 14655731747 017146 0 ustar tyson tyson --TEST--
Named parameters in PHP 8.0
--SKIPIF--
= 8.0 only'); ?>
--FILE--
count(1, myVar:$foo, myVar: 1); // error
PHP;
$node = ast\parse_code($code, $version=70);
echo ast_dump($node), "\n";
--EXPECTF--
AST_STMT_LIST
0: AST_CALL
expr: AST_VAR
name: "foo"
args: AST_ARG_LIST
0: AST_NAMED_ARG
name: "first"
expr: 1
1: AST_NAMED_ARG
name: "second"
expr: 2
1: AST_CALL
expr: AST_NAME
flags: NAME_NOT_FQ (%d)
name: "count"
args: AST_ARG_LIST
0: AST_NAMED_ARG
name: "var"
expr: AST_VAR
name: "argv"
2: AST_METHOD_CALL
expr: AST_VAR
name: "other"
method: "count"
args: AST_ARG_LIST
0: 1
1: AST_NAMED_ARG
name: "myVar"
expr: AST_VAR
name: "foo"
2: AST_NAMED_ARG
name: "myVar"
expr: 1
ast-1.1.2/tests/php80_noncapturing_catch.phpt 0000664 0001750 0001750 00000001645 14655731747 020376 0 ustar tyson tyson --TEST--
Non-capturing catches in PHP 8.0
--SKIPIF--
= 8.0 only'); ?>
--FILE--
= 8.0 only'); ?>
--FILE--
bar(2);
$a = $b?->c;
$a = new $b?->c;
PHP;
$node = ast\parse_code($code, $version=70);
echo ast_dump($node), "\n";
--EXPECTF--
AST_STMT_LIST
0: AST_NULLSAFE_METHOD_CALL
expr: AST_VAR
name: "foo"
method: "bar"
args: AST_ARG_LIST
0: 2
1: AST_ASSIGN
var: AST_VAR
name: "a"
expr: AST_NULLSAFE_PROP
expr: AST_VAR
name: "b"
prop: "c"
2: AST_ASSIGN
var: AST_VAR
name: "a"
expr: AST_NEW
class: AST_NULLSAFE_PROP
expr: AST_VAR
name: "b"
prop: "c"
args: AST_ARG_LIST ast-1.1.2/tests/php80_promotion.phpt 0000664 0001750 0001750 00000003731 14655731747 016551 0 ustar tyson tyson --TEST--
Constructor property promotion in PHP 8.0
--SKIPIF--
= 8.0 only'); ?>
--FILE--
= 8.0 only'); ?>
--FILE--
= 8.0 only'); ?>
--FILE--
$a;
$g = function (false $arg) : false|null { return false; };
PHP;
$node = ast\parse_code($code, $version=70);
echo ast_dump($node), "\n";
--EXPECTF--
AST_STMT_LIST
0: AST_CLASS
name: "Example"
docComment: null
extends: null
implements: null
stmts: AST_STMT_LIST
0: AST_PROP_GROUP
flags: MODIFIER_PUBLIC (%d)
type: AST_TYPE_UNION
0: AST_TYPE
flags: TYPE_ITERABLE (%d)
1: AST_TYPE
flags: TYPE_NULL (%d)
2: AST_TYPE
flags: TYPE_FALSE (%d)
props: AST_PROP_DECL
0: AST_PROP_ELEM
name: "value"
default: null
docComment: null
__declId: 0
1: AST_ASSIGN
var: AST_VAR
name: "f"
expr: AST_ARROW_FUNC
name: "{closure}"
docComment: null
params: AST_PARAM_LIST
0: AST_PARAM
type: AST_TYPE_UNION
0: AST_TYPE
flags: TYPE_OBJECT (%d)
1: AST_TYPE
flags: TYPE_FALSE (%d)
name: "a"
default: null
stmts: AST_RETURN
expr: AST_VAR
name: "a"
returnType: AST_TYPE
flags: TYPE_FALSE (%d)
__declId: 1
2: AST_ASSIGN
var: AST_VAR
name: "g"
expr: AST_CLOSURE
name: "{closure}"
docComment: null
params: AST_PARAM_LIST
0: AST_PARAM
type: AST_TYPE
flags: TYPE_FALSE (%d)
name: "arg"
default: null
uses: null
stmts: AST_STMT_LIST
0: AST_RETURN
expr: AST_CONST
name: AST_NAME
flags: NAME_NOT_FQ (%d)
name: "false"
returnType: AST_TYPE_UNION
0: AST_TYPE
flags: TYPE_FALSE (%d)
1: AST_TYPE
flags: TYPE_NULL (%d)
__declId: 2
ast-1.1.2/tests/php80_union_types_nullable.phpt 0000664 0001750 0001750 00000007444 14655731747 020762 0 ustar tyson tyson --TEST--
Union types in PHP 8.0 (nullable)
--SKIPIF--
= 8.0 only'); ?>
--FILE--
= 8.0 only'); ?>
--FILE--
= 8.1 only'); ?>
--FILE--
= 8.1 only'); ?>
--FILE--
foo(...);
PHP;
$node = ast\parse_code($code, $version=80);
echo ast_dump($node), "\n";
?>
--EXPECTF--
AST_STMT_LIST
0: AST_ASSIGN
var: AST_VAR
name: "c1"
expr: AST_CALL
expr: AST_NAME
flags: NAME_NOT_FQ (%d)
name: "foo"
args: AST_CALLABLE_CONVERT
1: AST_ASSIGN
var: AST_VAR
name: "c2"
expr: AST_STATIC_CALL
class: AST_NAME
flags: NAME_NOT_FQ (%d)
name: "C"
method: "foo"
args: AST_CALLABLE_CONVERT
2: AST_ASSIGN
var: AST_VAR
name: "c2"
expr: AST_METHOD_CALL
expr: AST_VAR
name: "x"
method: "foo"
args: AST_CALLABLE_CONVERT ast-1.1.2/tests/php81_intersection_types.phpt 0000664 0001750 0001750 00000006247 14655731747 020463 0 ustar tyson tyson --TEST--
Intersection types in php 8.1
--SKIPIF--
= 8.1 only'); ?>
--FILE--
= 8.1 only'); ?>
--FILE--
=8.2 only'); ?>
--FILE--
getAttributes() as $attribute) {
echo "- " . $attribute->getName() . "\n";
}
}
$node = new ast\Node();
$node->undeclaredDynamic = 123;
dump($node);
$metadata = new ast\Metadata();
$metadata->undeclaredDynamic = 123;
dump($metadata);
dump_attributes(ast\Node::class);
dump_attributes(ast\Metadata::class);
--EXPECTF--
%Sast\Node::__set_state(array(
'kind' => NULL,
'flags' => NULL,
'lineno' => NULL,
'children' => NULL,
'undeclaredDynamic' => 123,
))
Deprecated: Creation of dynamic property ast\Metadata::$undeclaredDynamic is deprecated in %sphp82_dynamic_property_attribute.php on line 21
%Sast\Metadata::__set_state(array(
'kind' => NULL,
'name' => NULL,
'flags' => NULL,
'flagsCombinable' => NULL,
'undeclaredDynamic' => 123,
))
Attributes of ast\Node:
- AllowDynamicProperties
Attributes of ast\Metadata:
ast-1.1.2/tests/php82_encaps_list2.phpt 0000664 0001750 0001750 00000002246 14655731747 017113 0 ustar tyson tyson --TEST--
Encapsulated variable flags in PHP 8.2
--SKIPIF--
= 8.2 only'); ?>
--FILE--
c}{$d}${$e["f"]}${g[\'h\']}{$i[\'j\']}";';
$node = ast\parse_code($code, $version=85);
echo ast_dump($node), "\n";
--EXPECTF--
AST_STMT_LIST
0: AST_ENCAPS_LIST
0: AST_VAR
flags: ENCAPS_VAR_DOLLAR_CURLY (%d)
name: "a"
1: AST_VAR
flags: ENCAPS_VAR_DOLLAR_CURLY_VAR_VAR (%d)
name: AST_PROP
expr: AST_CONST
name: AST_NAME
flags: NAME_NOT_FQ (%d)
name: "b"
prop: "c"
2: AST_VAR
name: "d"
3: AST_VAR
flags: ENCAPS_VAR_DOLLAR_CURLY_VAR_VAR (%d)
name: AST_DIM
expr: AST_VAR
name: "e"
dim: "f"
4: AST_DIM
flags: ENCAPS_VAR_DOLLAR_CURLY (%d)
expr: AST_VAR
name: "g"
dim: "h"
5: AST_DIM
expr: AST_VAR
name: "i"
dim: "j"
ast-1.1.2/tests/php82_encaps_list.phpt 0000664 0001750 0001750 00000002372 14655731747 017031 0 ustar tyson tyson --TEST--
Encapsulated variable flags in PHP 8.2-8.3
--SKIPIF--
= 80400) die('skip PHP >= 8.2 < 8.4 only'); ?>
--FILE--
c}{$d}${$e["f"]}${g[\'h\']}{$i{\'j\'}}";';
$node = ast\parse_code($code, $version=85);
echo ast_dump($node), "\n";
--EXPECTF--
AST_STMT_LIST
0: AST_ENCAPS_LIST
0: AST_VAR
flags: ENCAPS_VAR_DOLLAR_CURLY (%d)
name: "a"
1: AST_VAR
flags: ENCAPS_VAR_DOLLAR_CURLY_VAR_VAR (%d)
name: AST_PROP
expr: AST_CONST
name: AST_NAME
flags: NAME_NOT_FQ (%d)
name: "b"
prop: "c"
2: AST_VAR
name: "d"
3: AST_VAR
flags: ENCAPS_VAR_DOLLAR_CURLY_VAR_VAR (%d)
name: AST_DIM
expr: AST_VAR
name: "e"
dim: "f"
4: AST_DIM
flags: ENCAPS_VAR_DOLLAR_CURLY (%d)
expr: AST_VAR
name: "g"
dim: "h"
5: AST_DIM
flags: DIM_ALTERNATIVE_SYNTAX (%d)
expr: AST_VAR
name: "i"
dim: "j"
ast-1.1.2/tests/php82_readonly_class.phpt 0000664 0001750 0001750 00000001050 14655731747 017517 0 ustar tyson tyson --TEST--
readonly class support in php 8.2+
--SKIPIF--
=8.2 only'); ?>
--FILE--
= 8.4 only'); ?>
--FILE--
getMessage(), "\n";
}
?>
--EXPECT--
Caught: syntax error, unexpected token "{", expecting ")"
ast-1.1.2/tests/php84_property_hook2.phpt 0000664 0001750 0001750 00000007140 14655731747 017513 0 ustar tyson tyson --TEST--
Property hooks in php 8.4 bodies
--SKIPIF--
=8.4 only'); ?>
--FILE--
name = $newName;
}
}
}
PHP;
$node = ast\parse_code($code, $version=90);
echo ast_dump($node), "\n";
$node = ast\parse_code($code, $version=110);
echo ast_dump($node), "\n";
--EXPECTF--
AST_STMT_LIST
0: AST_CLASS
name: "A"
docComment: null
extends: null
implements: null
stmts: AST_STMT_LIST
0: AST_PROP_GROUP
flags: MODIFIER_PUBLIC (1)
type: AST_TYPE
flags: TYPE_STRING (6)
props: AST_PROP_DECL
0: AST_PROP_ELEM
name: "normal"
default: null
docComment: null
attributes: null
1: AST_PROP_GROUP
flags: MODIFIER_PUBLIC (1)
type: AST_TYPE
flags: TYPE_STRING (6)
props: AST_PROP_DECL
0: AST_PROP_ELEM
name: "name"
default: null
docComment: null
attributes: null
attributes: null
type: null
__declId: 0
AST_STMT_LIST
0: AST_CLASS
name: "A"
docComment: null
extends: null
implements: null
stmts: AST_STMT_LIST
0: AST_PROP_GROUP
flags: MODIFIER_PUBLIC (1)
type: AST_TYPE
flags: TYPE_STRING (6)
props: AST_PROP_DECL
0: AST_PROP_ELEM
name: "normal"
default: null
docComment: null
hooks: null
attributes: null
1: AST_PROP_GROUP
flags: MODIFIER_PUBLIC (1)
type: AST_TYPE
flags: TYPE_STRING (6)
props: AST_PROP_DECL
0: AST_PROP_ELEM
name: "name"
default: null
docComment: null
hooks: AST_STMT_LIST
0: AST_PROPERTY_HOOK
name: "set"
docComment: null
params: AST_PARAM_LIST
0: AST_PARAM
type: AST_TYPE
flags: TYPE_STRING (6)
name: "newName"
default: null
attributes: null
docComment: null
hooks: null
stmts: AST_STMT_LIST
0: AST_ASSIGN
var: AST_PROP
expr: AST_VAR
name: "this"
prop: "name"
expr: AST_VAR
name: "newName"
attributes: null
__declId: 0
attributes: null
attributes: null
type: null
__declId: 1
ast-1.1.2/tests/php84_property_hook3.phpt 0000664 0001750 0001750 00000003723 14655731747 017517 0 ustar tyson tyson --TEST--
Property hooks in php 8.4 bodies flags
--SKIPIF--
=8.4 only'); ?>
--FILE--
=8.4 only'); ?>
--FILE--
strtolower($value); }
) {}
}
PHP;
$node = ast\parse_code($code, $version=110);
echo ast_dump($node), "\n";
--EXPECTF--
AST_STMT_LIST
0: AST_CLASS
name: "User"
docComment: null
extends: null
implements: null
stmts: AST_STMT_LIST
0: AST_METHOD
flags: MODIFIER_PUBLIC (%d)
name: "__construct"
docComment: null
params: AST_PARAM_LIST
0: AST_PARAM
flags: PARAM_MODIFIER_PUBLIC (%d)
type: AST_TYPE
flags: TYPE_STRING (%d)
name: "username"
default: null
attributes: null
docComment: null
hooks: AST_STMT_LIST
0: AST_PROPERTY_HOOK
name: "set"
docComment: null
params: null
stmts: AST_PROPERTY_HOOK_SHORT_BODY
expr: AST_CALL
expr: AST_NAME
flags: NAME_NOT_FQ (%d)
name: "strtolower"
args: AST_ARG_LIST
0: AST_VAR
name: "value"
attributes: null
__declId: 0
stmts: AST_STMT_LIST
returnType: null
attributes: null
__declId: 1
attributes: null
type: null
__declId: 2
ast-1.1.2/tests/php84_property_hook.phpt 0000664 0001750 0001750 00000003127 14655731747 017432 0 ustar tyson tyson --TEST--
Property hooks in php 8.4
--SKIPIF--
=8.4 only'); ?>
--FILE--
--EXPECTF--
Deprecated: ast\parse_code(): Version 50 is deprecated in %s.php on line 20
AST_STMT_LIST
0: AST_CLASS
name: "A"
docComment: null
extends: null
implements: null
stmts: AST_STMT_LIST
0: AST_PROP_DECL
flags: MODIFIER_PUBLIC (%d)
0: AST_PROP_ELEM
name: "a"
default: null
docComment: "/** docComment $a */"
1: AST_PROP_DECL
flags: MODIFIER_PUBLIC (%d)
0: AST_PROP_ELEM
name: "b"
default: null
docComment: "/** docComment $b */"
1: AST_PROP_ELEM
name: "c"
default: null
docComment: "/** docComment $c */"
__declId: 0
AST_STMT_LIST
0: AST_CLASS
name: "A"
docComment: null
extends: null
implements: null
stmts: AST_STMT_LIST
0: AST_PROP_GROUP
flags: MODIFIER_PUBLIC (%d)
type: null
props: AST_PROP_DECL
0: AST_PROP_ELEM
name: "a"
default: null
docComment: "/** docComment $a */"
attributes: null
1: AST_PROP_GROUP
flags: MODIFIER_PUBLIC (%d)
type: null
props: AST_PROP_DECL
0: AST_PROP_ELEM
name: "b"
default: null
docComment: "/** docComment $b */"
1: AST_PROP_ELEM
name: "c"
default: null
docComment: "/** docComment $c */"
attributes: null
attributes: null
__declId: 0
AST_STMT_LIST
0: AST_CLASS
name: "A"
docComment: null
extends: null
implements: null
stmts: AST_STMT_LIST
0: AST_PROP_GROUP
flags: MODIFIER_PUBLIC (%d)
type: null
props: AST_PROP_DECL
0: AST_PROP_ELEM
name: "a"
default: null
docComment: "/** docComment $a */"
hooks: null
attributes: null
1: AST_PROP_GROUP
flags: MODIFIER_PUBLIC (%d)
type: null
props: AST_PROP_DECL
0: AST_PROP_ELEM
name: "b"
default: null
docComment: "/** docComment $b */"
hooks: null
1: AST_PROP_ELEM
name: "c"
default: null
docComment: "/** docComment $c */"
hooks: null
attributes: null
attributes: null
type: null
__declId: 0
ast-1.1.2/tests/short_arrow_function.phpt 0000664 0001750 0001750 00000005556 14655731747 017771 0 ustar tyson tyson --TEST--
Arrow functions ('fn($x) => $x') in PHP 7.4
--SKIPIF--
= 7.4 only'); ?>
--FILE--
$x * $y;
$b = static fn() => 1;
$c = /** doc comment */ static fn(?int... $args): array => $args;
$fn = fn() => yield 123;
PHP;
$node = ast\parse_code($code, $version=70);
$version_70_repr = ast_dump($node);
echo $version_70_repr . "\n";
$node50 = ast\parse_code($code, $version=50);
$version_50_repr = ast_dump($node50);
echo "Same representation in version 50/70: ";
var_export($version_50_repr == $version_70_repr);
echo "\n";
?>
--EXPECTF--
AST_STMT_LIST
0: AST_ASSIGN
var: AST_VAR
name: "y"
expr: 1
1: AST_ASSIGN
var: AST_VAR
name: "a"
expr: AST_ARROW_FUNC
name: "{closure}"
docComment: null
params: AST_PARAM_LIST
0: AST_PARAM
type: null
name: "x"
default: null
stmts: AST_RETURN
expr: AST_BINARY_OP
flags: BINARY_MUL (%d)
left: AST_VAR
name: "x"
right: AST_VAR
name: "y"
returnType: null
__declId: 0
2: AST_ASSIGN
var: AST_VAR
name: "b"
expr: AST_ARROW_FUNC
flags: MODIFIER_STATIC (%d)
name: "{closure}"
docComment: null
params: AST_PARAM_LIST
stmts: AST_RETURN
expr: 1
returnType: null
__declId: 1
3: AST_ASSIGN
var: AST_VAR
name: "c"
expr: AST_ARROW_FUNC
flags: MODIFIER_STATIC (%d)
name: "{closure}"
docComment: "/** doc comment */"
params: AST_PARAM_LIST
0: AST_PARAM
flags: PARAM_VARIADIC (%d)
type: AST_NULLABLE_TYPE
type: AST_TYPE
flags: TYPE_LONG (%d)
name: "args"
default: null
stmts: AST_RETURN
expr: AST_VAR
name: "args"
returnType: AST_TYPE
flags: TYPE_ARRAY (%d)
__declId: 2
4: AST_ASSIGN
var: AST_VAR
name: "fn"
expr: AST_ARROW_FUNC
flags: FUNC_GENERATOR (%d)
name: "{closure}"
docComment: null
params: AST_PARAM_LIST
stmts: AST_RETURN
expr: AST_YIELD
value: 123
key: null
returnType: null
__declId: 3
Deprecated: ast\parse_code(): Version 50 is deprecated in %s.php on line 17
Same representation in version 50/70: true ast-1.1.2/tests/short_arrow_function_decl_id.phpt 0000664 0001750 0001750 00000001756 14655731747 021432 0 ustar tyson tyson --TEST--
Nested arrow functions in PHP 7.4
--SKIPIF--
= 7.4 only'); ?>
--FILE--
fn() => $undef;
PHP;
$node = ast\parse_code($code, $version=85);
echo ast_dump($node) . "\n";
?>
--EXPECT--
AST_STMT_LIST
0: AST_ASSIGN
var: AST_VAR
name: "cb"
expr: AST_ARROW_FUNC
name: "{closure}"
docComment: null
params: AST_PARAM_LIST
stmts: AST_RETURN
expr: AST_ARROW_FUNC
name: "{closure}"
docComment: null
params: AST_PARAM_LIST
stmts: AST_RETURN
expr: AST_VAR
name: "undef"
returnType: null
attributes: null
__declId: 0
returnType: null
attributes: null
__declId: 1 ast-1.1.2/tests/short_arrow_function_return.phpt 0000664 0001750 0001750 00000005220 14655731747 021354 0 ustar tyson tyson --TEST--
Arrow functions and types ('fn($x) => $x') in PHP 7.4
--SKIPIF--
= 7.4 only'); ?>
--FILE--
1;
fn(iterable $i) : array => [$i];
fn(stdClass $param) : \stdClass => $param;
fn(\stdClass $param) : stdClass => $param;
PHP;
$node = ast\parse_code($code, $version=70);
$version_70_repr = ast_dump($node);
echo $version_70_repr . "\n";
$node50 = ast\parse_code($code, $version=50);
$version_50_repr = ast_dump($node50);
echo "Same representation in version 50/70: ";
var_export($version_50_repr == $version_70_repr);
echo "\n";
?>
--EXPECTF--
AST_STMT_LIST
0: AST_ARROW_FUNC
flags: MODIFIER_STATIC (%d)
name: "{closure}"
docComment: null
params: AST_PARAM_LIST
stmts: AST_RETURN
expr: 1
returnType: AST_TYPE
flags: TYPE_LONG (%d)
__declId: 0
1: AST_ARROW_FUNC
name: "{closure}"
docComment: null
params: AST_PARAM_LIST
0: AST_PARAM
type: AST_TYPE
flags: TYPE_ITERABLE (%d)
name: "i"
default: null
stmts: AST_RETURN
expr: AST_ARRAY
flags: ARRAY_SYNTAX_SHORT (%d)
0: AST_ARRAY_ELEM
flags: 0
value: AST_VAR
name: "i"
key: null
returnType: AST_TYPE
flags: TYPE_ARRAY (%d)
__declId: 1
2: AST_ARROW_FUNC
name: "{closure}"
docComment: null
params: AST_PARAM_LIST
0: AST_PARAM
type: AST_NAME
flags: NAME_NOT_FQ (%d)
name: "stdClass"
name: "param"
default: null
stmts: AST_RETURN
expr: AST_VAR
name: "param"
returnType: AST_NAME
flags: NAME_FQ (%d)
name: "stdClass"
__declId: 2
3: AST_ARROW_FUNC
name: "{closure}"
docComment: null
params: AST_PARAM_LIST
0: AST_PARAM
type: AST_NAME
flags: NAME_FQ (%d)
name: "stdClass"
name: "param"
default: null
stmts: AST_RETURN
expr: AST_VAR
name: "param"
returnType: AST_NAME
flags: NAME_NOT_FQ (%d)
name: "stdClass"
__declId: 3
Deprecated: ast\parse_code(): Version 50 is deprecated in %sshort_arrow_function_return.php on line 16
Same representation in version 50/70: true ast-1.1.2/tests/stmt_list.phpt 0000664 0001750 0001750 00000002025 14655731747 015521 0 ustar tyson tyson --TEST--
Statement list normalization
--FILE--
--EXPECT--
AST_STMT_LIST
0: AST_WHILE
cond: AST_VAR
name: "a"
stmts: AST_STMT_LIST
1: AST_WHILE
cond: AST_VAR
name: "a"
stmts: AST_STMT_LIST
0: AST_VAR
name: "b"
2: AST_WHILE
cond: AST_VAR
name: "a"
stmts: AST_STMT_LIST
0: AST_VAR
name: "b"
3: AST_DECLARE
declares: AST_CONST_DECL
0: AST_CONST_ELEM
name: "ticks"
value: 1
docComment: null
stmts: null
4: AST_DECLARE
declares: AST_CONST_DECL
0: AST_CONST_ELEM
name: "ticks"
value: 1
docComment: null
stmts: AST_STMT_LIST ast-1.1.2/tests/true_type.phpt 0000664 0001750 0001750 00000001434 14655731747 015522 0 ustar tyson tyson --TEST--
'true' type parsing
--FILE--
--EXPECT--
AST_STMT_LIST
0: AST_TRY
try: AST_STMT_LIST
0: AST_ECHO
expr: "try"
catches: AST_CATCH_LIST
0: AST_CATCH
class: AST_NAME_LIST
0: AST_NAME
flags: NAME_NOT_FQ (1)
name: "Exception"
var: AST_VAR
name: "e"
stmts: AST_STMT_LIST
0: AST_ECHO
expr: "catch 1"
1: AST_CATCH
class: AST_NAME_LIST
0: AST_NAME
flags: NAME_NOT_FQ (1)
name: "bar\FooException"
var: AST_VAR
name: "e2"
stmts: AST_STMT_LIST
0: AST_ECHO
expr: "catch 2"
finally: AST_STMT_LIST
0: AST_ECHO
expr: "finally" ast-1.1.2/tests/type_hints.phpt 0000664 0001750 0001750 00000003364 14655731747 015674 0 ustar tyson tyson --TEST--
Type hints
--FILE--
--EXPECTF--
AST_STMT_LIST
0: AST_FUNC_DECL
name: "test"
docComment: null
params: AST_PARAM_LIST
0: AST_PARAM
type: AST_NAME
flags: NAME_NOT_FQ (1)
name: "A"
name: "a"
default: null
1: AST_PARAM
type: AST_TYPE
flags: TYPE_ARRAY (7)
name: "b"
default: null
2: AST_PARAM
type: AST_TYPE
flags: TYPE_CALLABLE (%d)
name: "c"
default: null
3: AST_PARAM
type: AST_TYPE
flags: TYPE_LONG (4)
name: "d"
default: null
4: AST_PARAM
type: AST_TYPE
flags: TYPE_DOUBLE (5)
name: "e"
default: null
5: AST_PARAM
type: AST_TYPE
flags: TYPE_STRING (6)
name: "f"
default: null
6: AST_PARAM
type: AST_TYPE
flags: TYPE_BOOL (%d)
name: "g"
default: null
7: AST_PARAM
type: AST_TYPE
flags: TYPE_ITERABLE (%d)
name: "h"
default: null
stmts: AST_STMT_LIST
returnType: AST_TYPE
flags: TYPE_VOID (%d)
__declId: 0
ast-1.1.2/tests/unary_ops.phpt 0000664 0001750 0001750 00000000770 14655731747 015523 0 ustar tyson tyson --TEST--
Convert unary ops AST_(SILENCE|UNARY_(PLUS|MINUS)) to flags of ZEND_AST_UNARY_OP
--FILE--
--EXPECT--
AST_STMT_LIST
0: AST_UNARY_OP
flags: UNARY_SILENCE (260)
expr: AST_VAR
name: "a"
1: AST_UNARY_OP
flags: UNARY_PLUS (261)
expr: 1
2: AST_UNARY_OP
flags: UNARY_MINUS (262)
expr: 1 ast-1.1.2/tests/use_declarations.phpt 0000664 0001750 0001750 00000002416 14655731747 017027 0 ustar tyson tyson --TEST--
Test parse and dump of use declarations
--FILE--
--EXPECTF--
AST_STMT_LIST
0: AST_USE
flags: USE_NORMAL (%d)
0: AST_USE_ELEM
flags: 0
name: "Foo\Bar"
alias: "Baz"
1: AST_USE
flags: USE_FUNCTION (%d)
0: AST_USE_ELEM
flags: 0
name: "foo\bar"
alias: "baz"
2: AST_GROUP_USE
flags: 0
prefix: "Foo"
uses: AST_USE
flags: 0
0: AST_USE_ELEM
flags: USE_NORMAL (%d)
name: "Bar"
alias: null
1: AST_USE_ELEM
flags: USE_FUNCTION (%d)
name: "bar"
alias: null
3: AST_GROUP_USE
flags: USE_FUNCTION (%d)
prefix: "foo"
uses: AST_USE
flags: 0
0: AST_USE_ELEM
flags: 0
name: "bar"
alias: null
1: AST_USE_ELEM
flags: 0
name: "baz"
alias: null ast-1.1.2/tests/valid_file.php 0000664 0001750 0001750 00000000023 14655731747 015405 0 ustar tyson tyson getMessage(), "\n";
}
try {
ast\parse_code('getMessage(), "\n";
}
?>
--EXPECTF--
No version specified. Current version is %d. All versions (including experimental): {%d, %s}
Unknown version 10000. Current version is %d. All versions (including experimental): {%d, %s}
ast-1.1.2/tests/zpp_errors.phpt 0000664 0001750 0001750 00000001124 14655731747 015703 0 ustar tyson tyson --TEST--
zpp failures throw TypeError
--FILE--
getMessage(), "\n"; }
try { ast\parse_file(); }
catch (TypeError $e) { echo $e->getMessage(), "\n"; }
try { ast\get_kind_name(); }
catch (TypeError $e) { echo $e->getMessage(), "\n"; }
try { ast\kind_uses_flags(); }
catch (TypeError $e) { echo $e->getMessage(), "\n"; }
?>
--EXPECTF--
ast\parse_code() expects at least 1 %s, 0 given
ast\parse_file() expects at least 1 %s, 0 given
ast\get_kind_name() expects exactly 1 %s, 0 given
ast\kind_uses_flags() expects exactly 1 %s, 0 given
ast-1.1.2/config.m4 0000664 0001750 0001750 00000000341 14655731747 013146 0 ustar tyson tyson dnl config.m4 for extension ast
PHP_ARG_ENABLE(ast, whether to enable ast support,
[ --enable-ast Enable ast support])
if test "$PHP_AST" != "no"; then
PHP_NEW_EXTENSION(ast, ast.c ast_data.c, $ext_shared)
fi
ast-1.1.2/config.w32 0000664 0001750 0001750 00000000207 14655731747 013242 0 ustar tyson tyson // vim:ft=javascript
ARG_ENABLE("ast", "enable ast support", "no");
if (PHP_AST != "no") {
EXTENSION("ast", "ast.c ast_data.c");
}
ast-1.1.2/util.php 0000664 0001750 0001750 00000004610 14655731747 013130 0 ustar tyson tyson flags)) {
continue;
}
$flagMap = [];
foreach ($data->flags as $fullName) {
$shortName = substr($fullName, strrpos($fullName, '\\') + 1);
$flagMap[constant($fullName)] = $shortName;
}
$info[(int) $data->flagsCombinable][$data->kind] = $flagMap;
}
return $info;
}
function is_combinable_flag(int $kind) : bool {
return isset(get_flag_info()[1][$kind]);
}
function format_flags(int $kind, int $flags) : string {
list($exclusive, $combinable) = get_flag_info();
if (isset($exclusive[$kind])) {
$flagInfo = $exclusive[$kind];
if (isset($flagInfo[$flags])) {
return "{$flagInfo[$flags]} ($flags)";
}
} else if (isset($combinable[$kind])) {
$flagInfo = $combinable[$kind];
$names = [];
foreach ($flagInfo as $flag => $name) {
if ($flags & $flag) {
$names[] = $name;
}
}
if (!empty($names)) {
return implode(" | ", $names) . " ($flags)";
}
}
return (string) $flags;
}
/** Dumps abstract syntax tree */
function ast_dump($ast, int $options = 0) : string {
if ($ast instanceof ast\Node) {
$result = ast\get_kind_name($ast->kind);
if ($options & AST_DUMP_LINENOS) {
$result .= " @ $ast->lineno";
if (isset($ast->endLineno)) {
$result .= "-$ast->endLineno";
}
}
if ((ast\kind_uses_flags($ast->kind) && !is_combinable_flag($ast->kind)) || $ast->flags != 0) {
$result .= "\n flags: " . format_flags($ast->kind, $ast->flags);
}
foreach ($ast->children as $i => $child) {
if (($options & AST_DUMP_EXCLUDE_DOC_COMMENT) && $i === 'docComment') {
continue;
}
$result .= "\n $i: " . str_replace("\n", "\n ", ast_dump($child, $options));
}
return $result;
} else if ($ast === null) {
return 'null';
} else if (is_string($ast)) {
return "\"$ast\"";
} else {
return (string) $ast;
}
}
ast-1.1.2/ast.c 0000664 0001750 0001750 00000135743 14655731747 012411 0 ustar tyson tyson #ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
#include "php_ast.h"
#include "ext/spl/spl_exceptions.h"
#include "zend_language_scanner.h"
#include "zend_language_scanner_defs.h"
#include "zend_language_parser.h"
#include "zend_exceptions.h"
#include "zend_hash.h"
#include "zend_smart_str.h"
#if PHP_VERSION_ID >= 80200
/* Used for AllowDynamicProperties */
#include "zend_attributes.h"
#endif
#if PHP_VERSION_ID < 70200
#error "The php-ast 1.1 release dropped support for php 7.0-7.1. Use php-ast 1.0.16 instead."
#endif
#ifndef ZEND_THIS
#define ZEND_THIS getThis()
#endif
#ifndef ZEND_ARG_INFO_WITH_DEFAULT_VALUE
#define ZEND_ARG_INFO_WITH_DEFAULT_VALUE(pass_by_ref, name, default_value) \
ZEND_ARG_INFO(pass_by_ref, name)
#endif
#ifndef ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX
#define ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(name, return_reference, required_num_args, class_name, allow_null) \
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(name, return_reference, required_num_args, class_name, allow_null)
#endif
#ifndef ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE
#define ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(pass_by_ref, name, type_hint, allow_null, default_value) \
ZEND_ARG_TYPE_INFO(pass_by_ref, name, type_hint, allow_null)
#endif
#include "ast_arginfo.h"
#define ast_throw_exception(exception_ce, ...) \
zend_throw_exception_ex(exception_ce, 0, __VA_ARGS__)
#define ast_declare_property(ce, name, value) \
zend_declare_property_ex((ce), (name), (value), ZEND_ACC_PUBLIC, NULL)
#define ast_register_flag_constant(name, value) \
REGISTER_NS_LONG_CONSTANT("ast\\flags", name, value, CONST_CS | CONST_PERSISTENT)
// These are in the order the properties were declared with ast_declare_property.
#define AST_NODE_PROP_KIND(object) OBJ_PROP_NUM((object), 0)
#define AST_NODE_PROP_FLAGS(object) OBJ_PROP_NUM((object), 1)
#define AST_NODE_PROP_LINENO(object) OBJ_PROP_NUM((object), 2)
#define AST_NODE_PROP_CHILDREN(object) OBJ_PROP_NUM((object), 3)
#define AST_NODE_SET_PROP_KIND(object, num) ZVAL_LONG(AST_NODE_PROP_KIND((object)), (num))
#define AST_NODE_SET_PROP_FLAGS(object, num) ZVAL_LONG(AST_NODE_PROP_FLAGS((object)), (num))
#define AST_NODE_SET_PROP_LINENO(object, num) ZVAL_LONG(AST_NODE_PROP_LINENO((object)), (num))
// Set the ast\Node->children array to the given reference-counted array without incrementing the reference count of the array.
// Do not use this macro with immutable arrays.
#define AST_NODE_SET_PROP_CHILDREN_ARRAY(object, array) ZVAL_ARR(AST_NODE_PROP_CHILDREN((object)), (array))
#define AST_METADATA_PROP_KIND(object) OBJ_PROP_NUM((object), 0)
#define AST_METADATA_PROP_NAME(object) OBJ_PROP_NUM((object), 1)
#define AST_METADATA_PROP_FLAGS(object) OBJ_PROP_NUM((object), 2)
#define AST_METADATA_PROP_FLAGS_COMBINABLE(object) OBJ_PROP_NUM((object), 3)
#define AST_CURRENT_VERSION 110
/* Additional flags for BINARY_OP */
#define AST_BINARY_IS_GREATER 256
#define AST_BINARY_IS_GREATER_OR_EQUAL 257
#define AST_BINARY_BOOL_OR 258
#define AST_BINARY_BOOL_AND 259
#define AST_BINARY_COALESCE 260
/* Flags for UNARY_OP to use instead of AST_SILENCE, AST_UNARY_PLUS, AST_UNARY_MINUS */
#define AST_SILENCE 260
#define AST_PLUS 261
#define AST_MINUS 262
#if PHP_VERSION_ID < 70300
# define ZEND_BIND_REF 1
#endif
#if PHP_VERSION_ID < 70400
# define ZEND_DIM_ALTERNATIVE_SYNTAX (1<<1)
# define ZEND_PARENTHESIZED_CONDITIONAL 1
#endif
/* Make IS_STATIC follow IS_ITERABLE in php 7.0 */
#if PHP_VERSION_ID < 80000
# define IS_STATIC 20
# define IS_MIXED 21
/* In PHP 7.0-7.4, PARAM_REF and PARAM_VARIADIC were 1 and 2. */
# define PARAM_MODIFIER_PUBLIC (1 << 2)
# define PARAM_MODIFIER_PROTECTED (1 << 3)
# define PARAM_MODIFIER_PRIVATE (1 << 4)
#else
# define PARAM_MODIFIER_PUBLIC ZEND_ACC_PUBLIC
# define PARAM_MODIFIER_PROTECTED ZEND_ACC_PROTECTED
# define PARAM_MODIFIER_PRIVATE ZEND_ACC_PRIVATE
#endif
#if PHP_VERSION_ID < 80100
# define IS_NEVER 22
#endif
#if PHP_VERSION_ID < 80200
# define ZEND_ENCAPS_VAR_DOLLAR_CURLY (1<<0)
# define ZEND_ENCAPS_VAR_DOLLAR_CURLY_VAR_VAR (1<<1)
#endif
#if PHP_VERSION_ID >= 80400
# define ZEND_DIM_ALTERNATIVE_SYNTAX (1<<1)
#endif
/* This contains state of the ast Node creator. */
typedef struct ast_state_info {
zend_long version;
zend_long declIdCounter;
} ast_state_info_t;
typedef struct _ast_flag_info {
uint16_t ast_kind;
zend_bool combinable;
const char **flags;
} ast_flag_info;
ZEND_DECLARE_MODULE_GLOBALS(ast)
ast_str_globals str_globals;
static zend_class_entry *ast_node_ce;
static zend_class_entry *ast_metadata_ce;
#define AST_FLAG(name) "ast\\flags\\" #name
static const char *name_flags[] = {
AST_FLAG(NAME_FQ),
AST_FLAG(NAME_NOT_FQ),
AST_FLAG(NAME_RELATIVE),
NULL
};
static const char *class_flags[] = {
AST_FLAG(CLASS_ABSTRACT),
AST_FLAG(CLASS_FINAL),
AST_FLAG(CLASS_TRAIT),
AST_FLAG(CLASS_INTERFACE),
AST_FLAG(CLASS_ANONYMOUS),
AST_FLAG(CLASS_ENUM),
AST_FLAG(CLASS_READONLY),
NULL
};
static const char *param_flags[] = {
AST_FLAG(PARAM_REF),
AST_FLAG(PARAM_VARIADIC),
AST_FLAG(PARAM_MODIFIER_PUBLIC),
AST_FLAG(PARAM_MODIFIER_PROTECTED),
AST_FLAG(PARAM_MODIFIER_PRIVATE),
NULL
};
static const char *type_flags[] = {
AST_FLAG(TYPE_NULL),
AST_FLAG(TYPE_FALSE),
AST_FLAG(TYPE_TRUE),
AST_FLAG(TYPE_BOOL),
AST_FLAG(TYPE_LONG),
AST_FLAG(TYPE_DOUBLE),
AST_FLAG(TYPE_STRING),
AST_FLAG(TYPE_ARRAY),
AST_FLAG(TYPE_OBJECT),
AST_FLAG(TYPE_CALLABLE),
AST_FLAG(TYPE_VOID),
AST_FLAG(TYPE_ITERABLE),
AST_FLAG(TYPE_STATIC),
AST_FLAG(TYPE_MIXED),
AST_FLAG(TYPE_NEVER),
NULL
};
static const char *unary_op_flags[] = {
AST_FLAG(UNARY_BOOL_NOT),
AST_FLAG(UNARY_BITWISE_NOT),
AST_FLAG(UNARY_MINUS),
AST_FLAG(UNARY_PLUS),
AST_FLAG(UNARY_SILENCE),
NULL
};
#define AST_SHARED_BINARY_OP_FLAGS \
AST_FLAG(BINARY_BITWISE_OR), \
AST_FLAG(BINARY_BITWISE_AND), \
AST_FLAG(BINARY_BITWISE_XOR), \
AST_FLAG(BINARY_CONCAT), \
AST_FLAG(BINARY_ADD), \
AST_FLAG(BINARY_SUB), \
AST_FLAG(BINARY_MUL), \
AST_FLAG(BINARY_DIV), \
AST_FLAG(BINARY_MOD), \
AST_FLAG(BINARY_POW), \
AST_FLAG(BINARY_SHIFT_LEFT), \
AST_FLAG(BINARY_SHIFT_RIGHT), \
AST_FLAG(BINARY_COALESCE) \
static const char *binary_op_flags[] = {
AST_SHARED_BINARY_OP_FLAGS,
AST_FLAG(BINARY_BOOL_AND),
AST_FLAG(BINARY_BOOL_OR),
AST_FLAG(BINARY_BOOL_XOR),
AST_FLAG(BINARY_IS_IDENTICAL),
AST_FLAG(BINARY_IS_NOT_IDENTICAL),
AST_FLAG(BINARY_IS_EQUAL),
AST_FLAG(BINARY_IS_NOT_EQUAL),
AST_FLAG(BINARY_IS_SMALLER),
AST_FLAG(BINARY_IS_SMALLER_OR_EQUAL),
AST_FLAG(BINARY_IS_GREATER),
AST_FLAG(BINARY_IS_GREATER_OR_EQUAL),
AST_FLAG(BINARY_SPACESHIP),
NULL
};
static const char *assign_op_flags[] = {
AST_SHARED_BINARY_OP_FLAGS,
NULL
};
static const char *magic_const_flags[] = {
AST_FLAG(MAGIC_LINE),
AST_FLAG(MAGIC_FILE),
AST_FLAG(MAGIC_DIR),
AST_FLAG(MAGIC_NAMESPACE),
AST_FLAG(MAGIC_FUNCTION),
AST_FLAG(MAGIC_METHOD),
AST_FLAG(MAGIC_CLASS),
AST_FLAG(MAGIC_TRAIT),
NULL
};
static const char *use_flags[] = {
AST_FLAG(USE_NORMAL),
AST_FLAG(USE_FUNCTION),
AST_FLAG(USE_CONST),
NULL
};
static const char *include_flags[] = {
AST_FLAG(EXEC_EVAL),
AST_FLAG(EXEC_INCLUDE),
AST_FLAG(EXEC_INCLUDE_ONCE),
AST_FLAG(EXEC_REQUIRE),
AST_FLAG(EXEC_REQUIRE_ONCE),
NULL
};
static const char *array_flags[] = {
AST_FLAG(ARRAY_SYNTAX_LIST),
AST_FLAG(ARRAY_SYNTAX_LONG),
AST_FLAG(ARRAY_SYNTAX_SHORT),
NULL
};
static const char *array_elem_flags[] = {
AST_FLAG(ARRAY_ELEM_REF),
NULL
};
static const char *closure_use_flags[] = {
AST_FLAG(CLOSURE_USE_REF),
NULL
};
#define AST_MODIFIER_FLAGS \
AST_FLAG(MODIFIER_PUBLIC), \
AST_FLAG(MODIFIER_PROTECTED), \
AST_FLAG(MODIFIER_PRIVATE), \
AST_FLAG(MODIFIER_STATIC), \
AST_FLAG(MODIFIER_ABSTRACT), \
AST_FLAG(MODIFIER_FINAL), \
AST_FLAG(MODIFIER_READONLY)
static const char *modifier_flags[] = {
AST_MODIFIER_FLAGS,
NULL
};
static const char *func_flags[] = {
AST_MODIFIER_FLAGS,
AST_FLAG(FUNC_RETURNS_REF),
AST_FLAG(FUNC_GENERATOR),
NULL
};
static const char *dim_flags[] = {
AST_FLAG(DIM_ALTERNATIVE_SYNTAX),
AST_FLAG(ENCAPS_VAR_DOLLAR_CURLY),
NULL
};
// Flags of AST_CONDITIONAL are marked as combinable in case any other flags get added in the future.
static const char *conditional_flags[] = {
AST_FLAG(PARENTHESIZED_CONDITIONAL),
NULL
};
static const char *var_flags[] = {
AST_FLAG(ENCAPS_VAR_DOLLAR_CURLY_VAR_VAR),
AST_FLAG(ENCAPS_VAR_DOLLAR_CURLY),
NULL
};
static const ast_flag_info flag_info[] = {
{ AST_NAME, 0, name_flags },
{ ZEND_AST_CLASS, 1, class_flags },
{ ZEND_AST_PARAM, 1, param_flags },
{ ZEND_AST_TYPE, 0, type_flags },
{ ZEND_AST_CAST, 0, type_flags },
{ ZEND_AST_UNARY_OP, 0, unary_op_flags },
{ ZEND_AST_BINARY_OP, 0, binary_op_flags },
{ ZEND_AST_ASSIGN_OP, 0, assign_op_flags },
{ ZEND_AST_MAGIC_CONST, 0, magic_const_flags },
{ ZEND_AST_USE, 0, use_flags },
{ ZEND_AST_GROUP_USE, 0, use_flags },
{ ZEND_AST_USE_ELEM, 0, use_flags },
{ ZEND_AST_INCLUDE_OR_EVAL, 0, include_flags },
{ ZEND_AST_ARRAY, 0, array_flags },
{ ZEND_AST_ARRAY_ELEM, 0, array_elem_flags },
{ AST_CLOSURE_VAR, 0, closure_use_flags },
{ ZEND_AST_METHOD, 1, func_flags },
{ ZEND_AST_FUNC_DECL, 1, func_flags },
{ ZEND_AST_CLOSURE, 1, func_flags },
{ ZEND_AST_ARROW_FUNC, 1, func_flags },
{ ZEND_AST_PROPERTY_HOOK, 1, func_flags },
{ ZEND_AST_PROP_DECL, 1, modifier_flags },
{ ZEND_AST_PROP_GROUP, 1, modifier_flags },
{ ZEND_AST_CLASS_CONST_DECL, 1, modifier_flags },
{ ZEND_AST_CLASS_CONST_GROUP, 1, modifier_flags },
{ ZEND_AST_TRAIT_ALIAS, 1, modifier_flags },
{ ZEND_AST_DIM, 1, dim_flags },
{ ZEND_AST_CONDITIONAL, 1, conditional_flags },
{ ZEND_AST_VAR, 1, var_flags },
};
static inline void ast_update_property(zval *object, zend_string *name, zval *value) {
#if PHP_VERSION_ID < 80000
zval name_zv;
ZVAL_STR(&name_zv, name);
Z_OBJ_HT_P(object)->write_property(object, &name_zv, value, NULL);
#else
Z_OBJ_HT_P(object)->write_property(Z_OBJ_P(object), name, value, NULL);
#endif
}
static inline void ast_update_property_long(zval *object, zend_string *name, zend_long value_raw) {
zval value_zv;
ZVAL_LONG(&value_zv, value_raw);
ast_update_property(object, name, &value_zv);
}
static zend_ast *get_ast(zend_string *code, zend_arena **ast_arena, zend_string *filename) {
#if PHP_VERSION_ID >= 80100
if (filename) {
return zend_compile_string_to_ast(code, ast_arena, filename);
} else {
zend_ast *ast;
filename = zend_string_init("string code", sizeof("string code") - 1, 0);
ast = zend_compile_string_to_ast(code, ast_arena, filename);
zend_string_release_ex(filename, 0);
return ast;
}
#else
zval code_zv;
zend_bool original_in_compilation;
zend_lex_state original_lex_state;
zend_ast *ast;
ZVAL_STR_COPY(&code_zv, code);
original_in_compilation = CG(in_compilation);
CG(in_compilation) = 1;
zend_save_lexical_state(&original_lex_state);
zend_prepare_string_for_scanning(&code_zv, filename ? filename->val : "string code");
CG(ast) = NULL;
CG(ast_arena) = zend_arena_create(1024 * 32);
LANG_SCNG(yy_state) = yycINITIAL;
if (zendparse() != 0) {
zend_ast_destroy(CG(ast));
zend_arena_destroy(CG(ast_arena));
CG(ast) = NULL;
}
/* restore_lexical_state changes CG(ast) and CG(ast_arena) */
ast = CG(ast);
*ast_arena = CG(ast_arena);
zend_restore_lexical_state(&original_lex_state);
CG(in_compilation) = original_in_compilation;
zval_dtor(&code_zv);
return ast;
#endif
}
/* Returns whether node->attr (i.e. flags) is used by this node kind. Not to be confused with php 8.0's attributes. */
static inline zend_bool ast_kind_uses_attr(zend_ast_kind kind) {
return kind == ZEND_AST_PARAM || kind == ZEND_AST_TYPE || kind == ZEND_AST_TRAIT_ALIAS
|| kind == ZEND_AST_UNARY_OP || kind == ZEND_AST_BINARY_OP || kind == ZEND_AST_ASSIGN_OP
|| kind == ZEND_AST_CAST || kind == ZEND_AST_MAGIC_CONST || kind == ZEND_AST_ARRAY_ELEM
|| kind == ZEND_AST_INCLUDE_OR_EVAL || kind == ZEND_AST_USE || kind == ZEND_AST_PROP_DECL
|| kind == ZEND_AST_PROP_GROUP
|| kind == ZEND_AST_GROUP_USE || kind == ZEND_AST_USE_ELEM
|| kind == AST_NAME || kind == AST_CLOSURE_VAR || kind == ZEND_AST_CLASS_CONST_DECL
|| kind == ZEND_AST_CLASS_CONST_GROUP
|| kind == ZEND_AST_ARRAY || kind == ZEND_AST_DIM || kind == ZEND_AST_CONDITIONAL
|| kind == ZEND_AST_VAR;
}
/* Returns true if nodes of this kind are represented with the C struct zend_ast_decl. */
static inline zend_bool ast_kind_is_decl(zend_ast_kind kind) {
return kind == ZEND_AST_FUNC_DECL || kind == ZEND_AST_CLOSURE
|| kind == ZEND_AST_ARROW_FUNC
|| kind == ZEND_AST_PROPERTY_HOOK
|| kind == ZEND_AST_METHOD || kind == ZEND_AST_CLASS;
}
static inline zend_bool ast_is_name(zend_ast *ast, zend_ast *parent, uint32_t i) {
if (!ast) {
return 0;
}
if (ast->kind != ZEND_AST_ZVAL || Z_TYPE_P(zend_ast_get_zval(ast)) != IS_STRING) {
return 0;
}
if (parent->kind == ZEND_AST_NAME_LIST) {
return 1;
}
#if PHP_VERSION_ID >= 80100
if (parent->kind == ZEND_AST_TYPE_INTERSECTION) {
return 1;
}
#endif
#if PHP_VERSION_ID >= 80000
if (parent->kind == ZEND_AST_TYPE_UNION) {
return 1;
}
#endif
if (i == 0) {
return parent->kind == ZEND_AST_CATCH || parent->kind == ZEND_AST_CLASS
|| parent->kind == ZEND_AST_PARAM || parent->kind == ZEND_AST_METHOD_REFERENCE
|| parent->kind == ZEND_AST_CALL || parent->kind == ZEND_AST_CONST
|| parent->kind == ZEND_AST_NEW || parent->kind == ZEND_AST_STATIC_CALL
|| parent->kind == ZEND_AST_CLASS_CONST || parent->kind == ZEND_AST_STATIC_PROP
|| parent->kind == ZEND_AST_PROP_GROUP || parent->kind == ZEND_AST_CLASS_NAME
#if PHP_VERSION_ID >= 80000
|| parent->kind == ZEND_AST_ATTRIBUTE
#endif
;
}
#if PHP_VERSION_ID >= 80300
if (i == 2) {
return parent->kind == ZEND_AST_CLASS_CONST_GROUP;
}
#endif
if (i == 1) {
return parent->kind == ZEND_AST_INSTANCEOF;
}
if (i == 3) {
return parent->kind == ZEND_AST_FUNC_DECL || parent->kind == ZEND_AST_CLOSURE
#if PHP_VERSION_ID >= 70400
|| parent->kind == ZEND_AST_ARROW_FUNC
#endif
|| parent->kind == ZEND_AST_METHOD;
}
#if PHP_VERSION_ID >= 80100
if (i == 4) {
return parent->kind == ZEND_AST_CLASS;
}
#endif
return 0;
}
/* Assumes that ast_is_name is already true */
static inline zend_bool ast_is_type(zend_ast *ast, zend_ast *parent, uint32_t i) {
#if PHP_VERSION_ID >= 80100
if (parent->kind == ZEND_AST_TYPE_INTERSECTION) {
return 1;
}
#endif
#if PHP_VERSION_ID >= 80000
if (parent->kind == ZEND_AST_TYPE_UNION) {
return 1;
}
#endif
if (i == 0) {
return parent->kind == ZEND_AST_PARAM
#if PHP_VERSION_ID >= 70400
|| parent->kind == ZEND_AST_PROP_GROUP
#endif
;
}
#if PHP_VERSION_ID >= 80300
if (i == 2) {
return parent->kind == ZEND_AST_CLASS_CONST_GROUP;
}
#endif
if (i == 3) {
return parent->kind == ZEND_AST_CLOSURE || parent->kind == ZEND_AST_FUNC_DECL
#if PHP_VERSION_ID >= 70400
|| parent->kind == ZEND_AST_ARROW_FUNC
#endif
|| parent->kind == ZEND_AST_METHOD;
}
#if PHP_VERSION_ID >= 80100
if (i == 4) {
return parent->kind == ZEND_AST_CLASS;
}
#endif
return 0;
}
static inline zend_bool ast_is_var_name(zend_ast *ast, zend_ast *parent, uint32_t i) {
return (parent->kind == ZEND_AST_STATIC && i == 0)
|| (parent->kind == ZEND_AST_CATCH && i == 1 && ast != NULL);
}
/* Whether this node may need statement list normalization */
static inline zend_bool ast_should_normalize_list(zend_ast *ast, zend_ast *parent, uint32_t i) {
if (ast && ast->kind == ZEND_AST_STMT_LIST) {
return 0;
}
if (i == 0) {
return parent->kind == ZEND_AST_DO_WHILE;
}
if (i == 1) {
if (parent->kind == ZEND_AST_DECLARE) {
/* declare(); and declare() {} are not the same */
return ast != NULL;
}
return parent->kind == ZEND_AST_IF_ELEM || parent->kind == ZEND_AST_WHILE;
}
if (i == 2) {
return parent->kind == ZEND_AST_CATCH;
}
if (i == 3) {
return parent->kind == ZEND_AST_FOR || parent->kind == ZEND_AST_FOREACH;
}
return 0;
}
/* Adopted from zend_compile.c */
typedef struct _builtin_type_info {
const char* name;
const size_t name_len;
const zend_uchar type;
} builtin_type_info;
static const builtin_type_info builtin_types[] = {
{ZEND_STRL("int"), IS_LONG},
{ZEND_STRL("float"), IS_DOUBLE},
{ZEND_STRL("string"), IS_STRING},
{ZEND_STRL("bool"), _IS_BOOL},
{ZEND_STRL("void"), IS_VOID},
{ZEND_STRL("iterable"), IS_ITERABLE},
{ZEND_STRL("object"), IS_OBJECT},
{ZEND_STRL("null"), IS_NULL}, /* Null and false for php 8.0 union types */
{ZEND_STRL("false"), IS_FALSE},
// {ZEND_STRL("static"), IS_STATIC}, /* Impossible to be parsed before php 8 */
{ZEND_STRL("mixed"), IS_MIXED},
{ZEND_STRL("never"), IS_NEVER},
{ZEND_STRL("true"), IS_TRUE}, /* PHP 8.2 added the true type */
{NULL, 0, IS_UNDEF}
};
static inline zend_uchar lookup_builtin_type(const zend_string *name) {
const builtin_type_info *info = &builtin_types[0];
for (; info->name; ++info) {
if (ZSTR_LEN(name) == info->name_len
&& !zend_binary_strcasecmp(ZSTR_VAL(name), ZSTR_LEN(name), info->name, info->name_len)
) {
return info->type;
}
}
return 0;
}
#if PHP_VERSION_ID < 70400
static inline zend_ast_attr ast_assign_op_to_binary_op(zend_ast_attr attr) {
switch (attr) {
case ZEND_ASSIGN_BW_OR: return ZEND_BW_OR;
case ZEND_ASSIGN_BW_AND: return ZEND_BW_AND;
case ZEND_ASSIGN_BW_XOR: return ZEND_BW_XOR;
case ZEND_ASSIGN_CONCAT: return ZEND_CONCAT;
case ZEND_ASSIGN_ADD: return ZEND_ADD;
case ZEND_ASSIGN_SUB: return ZEND_SUB;
case ZEND_ASSIGN_MUL: return ZEND_MUL;
case ZEND_ASSIGN_DIV: return ZEND_DIV;
case ZEND_ASSIGN_MOD: return ZEND_MOD;
case ZEND_ASSIGN_POW: return ZEND_POW;
case ZEND_ASSIGN_SL: return ZEND_SL;
case ZEND_ASSIGN_SR: return ZEND_SR;
EMPTY_SWITCH_DEFAULT_CASE()
}
}
#endif
static inline zend_ast **ast_get_children(zend_ast *ast, ast_state_info_t *state, uint32_t *count) {
if (ast_kind_is_decl(ast->kind)) {
zend_ast_decl *decl = (zend_ast_decl *) ast;
#if PHP_VERSION_ID >= 80100
*count = decl->kind == ZEND_AST_CLASS ? (state->version >= 85 ? 5 : 4) : 5;
#elif PHP_VERSION_ID >= 80000
*count = decl->kind == ZEND_AST_CLASS ? 4 : 5;
#else
*count = decl->kind == ZEND_AST_CLASS ? 3 : 4;
#endif
return decl->child;
} else if (zend_ast_is_list(ast)) {
zend_ast_list *list = zend_ast_get_list(ast);
*count = list->children;
return list->child;
} else {
*count = zend_ast_get_num_children(ast);
return ast->child;
}
}
static void ast_to_zval(zval *zv, zend_ast *ast, ast_state_info_t *state);
static void ast_create_virtual_node_ex(
zval *zv, zend_ast_kind kind, zend_ast_attr attr, uint32_t lineno,
ast_state_info_t *state, uint32_t num_children, ...) {
va_list va;
uint32_t i;
object_init_ex(zv, ast_node_ce);
zend_object *obj = Z_OBJ_P(zv);
AST_NODE_SET_PROP_KIND(obj, kind);
AST_NODE_SET_PROP_FLAGS(obj, attr);
AST_NODE_SET_PROP_LINENO(obj, lineno);
array_init_size(AST_NODE_PROP_CHILDREN(obj), num_children);
HashTable *children = Z_ARRVAL_P(AST_NODE_PROP_CHILDREN(obj));
va_start(va, num_children);
for (i = 0; i < num_children; i++) {
zval *child_zv = va_arg(va, zval *);
zend_string *child_name = ast_kind_child_name(kind, i);
if (child_name) {
zend_hash_add_new(children, child_name, child_zv);
} else {
zend_hash_next_index_insert(children, child_zv);
}
}
va_end(va);
}
static void ast_create_virtual_node(
zval *zv, zend_ast_kind kind, zend_ast_attr attr, zend_ast *child, ast_state_info_t *state) {
zval child_zv;
ast_to_zval(&child_zv, child, state);
ast_create_virtual_node_ex(
zv, kind, attr, zend_ast_get_lineno(child), state, 1, &child_zv);
}
static inline void ast_name_to_zval(zend_ast *child, zend_ast *ast, zval *child_zv, int i, ast_state_info_t *state) {
zend_uchar type;
zend_bool is_nullable = 0;
if (child->attr & ZEND_TYPE_NULLABLE) {
is_nullable = 1;
child->attr &= ~ZEND_TYPE_NULLABLE;
}
if (child->attr == ZEND_NAME_FQ) {
/* Ensure there is no leading \ for fully-qualified names. This can happen if
* something like ('\bar')() is used. */
zval *name = zend_ast_get_zval(child);
if (Z_STRVAL_P(name)[0] == '\\') {
zend_string *new_name = zend_string_init(
Z_STRVAL_P(name) + 1, Z_STRLEN_P(name) - 1, 0);
zend_string_release(Z_STR_P(name));
Z_STR_P(name) = new_name;
}
}
if (child->attr == ZEND_NAME_NOT_FQ
&& ast_is_type(child, ast, i)
&& (type = lookup_builtin_type(zend_ast_get_str(child)))
&& (type != IS_MIXED || state->version >= 80)
) {
/* Convert "int" etc typehints to TYPE nodes */
ast_create_virtual_node_ex(
child_zv, ZEND_AST_TYPE, type, zend_ast_get_lineno(child), state, 0);
} else {
ast_create_virtual_node(child_zv, AST_NAME, child->attr, child, state);
}
if (is_nullable) {
/* Create explicit AST_NULLABLE_TYPE node */
zval tmp;
ZVAL_COPY_VALUE(&tmp, child_zv);
ast_create_virtual_node_ex(
child_zv, AST_NULLABLE_TYPE, 0, zend_ast_get_lineno(child), state, 1, &tmp);
}
}
static void ast_fill_children_ht(HashTable *ht, zend_ast *ast, ast_state_info_t *state) {
uint32_t i, count;
zend_bool is_list = zend_ast_is_list(ast);
zend_ast **children = ast_get_children(ast, state, &count);
const zend_ast_kind ast_kind = ast->kind;
for (i = 0; i < count; ++i) {
zend_ast *child = children[i];
zend_string *child_name = !is_list ? ast_kind_child_name(ast_kind, i) : NULL;
zval child_zv;
if (ast_kind == ZEND_AST_STMT_LIST) {
if (child != NULL && child->kind == ZEND_AST_STMT_LIST) {
ast_fill_children_ht(ht, child, state);
continue;
}
if (child == NULL) {
continue;
}
}
#if PHP_VERSION_ID >= 80000
if (state->version < 80) {
switch (ast_kind) {
case ZEND_AST_PARAM:
if (i >= 3) {
/* Skip attributes and doc comment and hooks. */
continue;
}
break;
case ZEND_AST_METHOD:
case ZEND_AST_FUNC_DECL:
case ZEND_AST_CLOSURE:
case ZEND_AST_ARROW_FUNC:
if (i == 4) {
continue;
}
break;
case ZEND_AST_CLASS:
if (i >= 3) {
continue;
}
break;
case ZEND_AST_PROP_GROUP:
if (i == 2) {
continue;
}
break;
}
}
#if PHP_VERSION_ID >= 80100
if (ast_kind == ZEND_AST_CLASS && i == 4) {
if (state->version < 85) {
continue;
}
}
#endif
#if PHP_VERSION_ID >= 80300
if (ast_kind == ZEND_AST_CLASS_CONST_GROUP && i == 2) {
if (state->version < 100) {
continue;
}
}
#endif
#if PHP_VERSION_ID >= 80400
if (ast_kind == ZEND_AST_PROP_ELEM && i == 3) {
if (state->version < 110) {
continue;
}
}
if (ast_kind == ZEND_AST_PROPERTY_HOOK && (i == 1 || i == 3)) {
/* Property hooks don't have uses/returnType but they do have params/stmts/attributes. */
continue;
}
/* Constructor property promotion shorthand can have property hooks. */
if (ast_kind == ZEND_AST_PARAM && i == 5) {
if (state->version < 110) {
continue;
}
}
#endif
#endif
if (ast_is_name(child, ast, i)) {
ast_name_to_zval(child, ast, &child_zv, i, state);
} else if (child && child->kind == ZEND_AST_TYPE && (child->attr & ZEND_TYPE_NULLABLE)) {
child->attr &= ~ZEND_TYPE_NULLABLE;
ast_create_virtual_node(&child_zv, AST_NULLABLE_TYPE, 0, child, state);
} else if (ast_kind == ZEND_AST_CLOSURE_USES) {
ast_create_virtual_node(&child_zv, AST_CLOSURE_VAR, child->attr, child, state);
} else if (ast_is_var_name(child, ast, i)) {
ast_create_virtual_node(&child_zv, ZEND_AST_VAR, 0, child, state);
} else if (ast_should_normalize_list(child, ast, i)) {
if (child) {
zval tmp;
ast_to_zval(&tmp, child, state);
ast_create_virtual_node_ex(
&child_zv, ZEND_AST_STMT_LIST, 0, zend_ast_get_lineno(child), state, 1, &tmp);
} else {
ast_create_virtual_node_ex(
&child_zv, ZEND_AST_STMT_LIST, 0, zend_ast_get_lineno(ast), state, 0);
}
} else if (state->version >= 60 && i == 1
&& (ast_kind == ZEND_AST_FUNC_DECL || ast_kind == ZEND_AST_METHOD)) {
/* Skip "uses" child, it is only relevant for closures */
continue;
#if PHP_VERSION_ID >= 70400
} else if (i == 1 && ast_kind == ZEND_AST_ARROW_FUNC) {
/* Skip "uses" child since it is always empty */
continue;
#endif
} else if (ast_kind == ZEND_AST_LIST && child != NULL) {
/* Emulate simple variable list */
ast_to_zval(&child_zv, child->child[0], state);
} else {
ast_to_zval(&child_zv, child, state);
}
if (child_name) {
#if PHP_VERSION_ID >= 80200
if (ast_kind == ZEND_AST_ARROW_FUNC && i == 2) {
/* Imitate the native arrow function ast structure used in php 7.4-8.1 for stmts */
/* (This is still different from regular functions, which have AST_STMT_LIST) */
/* TODO: In a new node type, remove the ZEND_AST_RETURN node instead. */
zval tmp;
ZVAL_COPY_VALUE(&tmp, &child_zv);
ast_create_virtual_node_ex(
&child_zv, ZEND_AST_RETURN, 0, zend_ast_get_lineno(child), state, 1, &tmp);
}
#endif
zend_hash_add_new(ht, child_name, &child_zv);
} else {
zend_hash_next_index_insert(ht, &child_zv);
}
}
#if PHP_VERSION_ID < 80000
if (state->version >= 80) {
if (ast_kind == ZEND_AST_PARAM) {
zval tmp;
ZVAL_NULL(&tmp);
zend_hash_add_new(ht, AST_STR(str_attributes), &tmp);
zend_hash_add_new(ht, AST_STR(str_docComment), &tmp);
return;
} else if (ast_kind == ZEND_AST_PROP_GROUP) {
zval tmp;
ZVAL_NULL(&tmp);
zend_hash_add_new(ht, AST_STR(str_attributes), &tmp);
return;
}
}
#endif
#if PHP_VERSION_ID < 80400
if (state->version >= 110) {
if (ast_kind == ZEND_AST_PARAM || ast_kind == ZEND_AST_PROP_ELEM) {
zval tmp;
ZVAL_NULL(&tmp);
zend_hash_add_new(ht, AST_STR(str_hooks), &tmp);
return;
}
}
#endif
if (ast_kind_is_decl(ast_kind)) {
zval id_zval;
#if PHP_VERSION_ID < 80000
if (state->version >= 80) {
zval tmp;
ZVAL_NULL(&tmp);
zend_hash_add_new(ht, AST_STR(str_attributes), &tmp);
}
#endif
#if PHP_VERSION_ID < 80100
if (ast_kind == ZEND_AST_CLASS) {
if (state->version >= 85) {
zval tmp;
ZVAL_NULL(&tmp);
zend_hash_add_new(ht, AST_STR(str_type), &tmp);
}
}
#endif
#if PHP_VERSION_ID < 80300
if (ast_kind == ZEND_AST_CLASS_CONST_GROUP) {
if (state->version >= 100) {
zval tmp;
ZVAL_NULL(&tmp);
zend_hash_add_new(ht, AST_STR(str_type), &tmp);
}
}
#endif
ZVAL_LONG(&id_zval, state->declIdCounter);
state->declIdCounter++;
zend_hash_add_new(ht, AST_STR(str___declId), &id_zval);
}
}
static void ast_to_zval(zval *zv, zend_ast *ast, ast_state_info_t *state) {
zval tmp_zv;
if (ast == NULL) {
ZVAL_NULL(zv);
return;
}
if (ast->kind == ZEND_AST_ZVAL) {
ZVAL_COPY(zv, zend_ast_get_zval(ast));
return;
}
switch (ast->kind) {
#if PHP_VERSION_ID < 70400
case ZEND_AST_ASSIGN_OP:
ast->attr = ast_assign_op_to_binary_op(ast->attr);
break;
#endif
case ZEND_AST_GREATER:
ast->kind = ZEND_AST_BINARY_OP;
ast->attr = AST_BINARY_IS_GREATER;
break;
case ZEND_AST_GREATER_EQUAL:
ast->kind = ZEND_AST_BINARY_OP;
ast->attr = AST_BINARY_IS_GREATER_OR_EQUAL;
break;
case ZEND_AST_OR:
ast->kind = ZEND_AST_BINARY_OP;
ast->attr = AST_BINARY_BOOL_OR;
break;
case ZEND_AST_AND:
ast->kind = ZEND_AST_BINARY_OP;
ast->attr = AST_BINARY_BOOL_AND;
break;
case ZEND_AST_COALESCE:
ast->kind = ZEND_AST_BINARY_OP;
ast->attr = AST_BINARY_COALESCE;
break;
case ZEND_AST_SILENCE:
ast->kind = ZEND_AST_UNARY_OP;
ast->attr = AST_SILENCE;
break;
case ZEND_AST_UNARY_PLUS:
ast->kind = ZEND_AST_UNARY_OP;
ast->attr = AST_PLUS;
break;
case ZEND_AST_UNARY_MINUS:
ast->kind = ZEND_AST_UNARY_OP;
ast->attr = AST_MINUS;
break;
#if PHP_VERSION_ID >= 80000
case ZEND_AST_CLASS_CONST_GROUP:
// ast->child is [AST_CLASS_CONST_DECL, optional attributes_list]
if (state->version < 80) {
// Keep class constants as a list of numerically indexed values in php 8
ast->child[0]->attr = ast->attr;
ast_to_zval(zv, ast->child[0], state);
return;
}
break;
#endif
#if PHP_VERSION_ID >= 70400
case ZEND_AST_PROP_GROUP:
if (state->version < 70) {
// In versions less than 70, just omit property type information entirely.
// ast->child is [type_ast, prop_ast]
ast_to_zval(zv, ast->child[1], state);
// The property visibility is on the AST_PROP_GROUP node.
// Add it to the AST_PROP_DECL node for old
AST_NODE_SET_PROP_FLAGS(Z_OBJ_P(zv), ast->attr);
return;
}
break;
case ZEND_AST_ASSIGN_COALESCE:
ast->kind = ZEND_AST_ASSIGN_OP;
ast->attr = AST_BINARY_COALESCE;
break;
case ZEND_AST_CLASS_NAME:
if (state->version < 70) {
zval name_zval;
ast_to_zval(&name_zval, ast->child[0], state);
zval class_name_zval;
ast_create_virtual_node_ex(
&class_name_zval, AST_NAME, ast->child[0]->attr, zend_ast_get_lineno(ast), state, 1, &name_zval);
zval const_zval;
ZVAL_STR_COPY(&const_zval, AST_STR(str_class));
ast_create_virtual_node_ex(
zv, ZEND_AST_CLASS_CONST, 0, zend_ast_get_lineno(ast), state, 2, &class_name_zval, &const_zval);
return;
}
break;
#ifdef ZEND_PARENTHESIZED_CONCAT
case ZEND_AST_BINARY_OP:
if (ast->attr == ZEND_PARENTHESIZED_CONCAT) {
ast->attr = ZEND_CONCAT;
}
break;
#endif
#else
case ZEND_AST_CLASS_CONST:
if (state->version >= 70) {
// Convert to an AST_CLASS_NAME instead. This is the opposite of the work done in the ZEND_AST_CLASS_NAME case.
zend_ast *const_name_ast = ast->child[1];
zend_string *str = zend_ast_get_str(const_name_ast);
if (zend_string_equals_ci(AST_STR(str_class), str)) {
zend_ast *class_name_ast = ast->child[0];
zval class_name_zval;
if (class_name_ast->kind == ZEND_AST_ZVAL) {
// e.g. Foo::class
zval class_name_raw_zval;
ZVAL_COPY(&class_name_raw_zval, zend_ast_get_zval(class_name_ast));
ast_create_virtual_node_ex(
&class_name_zval, AST_NAME, class_name_ast->attr, zend_ast_get_lineno(class_name_ast), state, 1, &class_name_raw_zval);
} else {
// e.g. []::class (not a parse error, but a runtime error)
ast_to_zval(&class_name_zval, class_name_ast, state);
}
ast_create_virtual_node_ex(
zv, ZEND_AST_CLASS_NAME, 0, zend_ast_get_lineno(ast), state, 1, &class_name_zval);
return;
}
}
break;
#endif
}
object_init_ex(zv, ast_node_ce);
zend_object *obj = Z_OBJ_P(zv);
zend_ast_kind kind = ast->kind;
AST_NODE_SET_PROP_KIND(obj, kind);
AST_NODE_SET_PROP_LINENO(obj, zend_ast_get_lineno(ast));
array_init(AST_NODE_PROP_CHILDREN(obj));
HashTable *children = Z_ARRVAL_P(AST_NODE_PROP_CHILDREN(obj));
if (ast_kind_is_decl(kind)) {
zend_ast_decl *decl = (zend_ast_decl *) ast;
uint32_t flags = decl->flags;
#if PHP_VERSION_ID >= 80200
if (kind == ZEND_AST_CLASS) {
flags &= ~ZEND_ACC_NO_DYNAMIC_PROPERTIES;
}
#endif
AST_NODE_SET_PROP_FLAGS(obj, flags);
// This is an undeclared dynamic property and has no cache slot.
ast_update_property_long(zv, AST_STR(str_endLineno), decl->end_lineno);
if (kind == ZEND_AST_CLOSURE || kind == ZEND_AST_ARROW_FUNC) {
if (state->version < 110) {
ZVAL_STR(&tmp_zv, AST_STR(str_bracketed_closure));
} else {
/* These never have names. */
ZVAL_UNDEF(&tmp_zv);
}
} else if (decl->name) {
ZVAL_STR(&tmp_zv, decl->name);
Z_TRY_ADDREF(tmp_zv);
} else {
ZVAL_NULL(&tmp_zv);
}
if (!Z_ISUNDEF(tmp_zv)) {
zend_hash_add_new(children, AST_STR(str_name), &tmp_zv);
}
if (decl->doc_comment) {
ZVAL_STR(&tmp_zv, decl->doc_comment);
Z_TRY_ADDREF(tmp_zv);
} else {
ZVAL_NULL(&tmp_zv);
}
zend_hash_add_new(children, AST_STR(str_docComment), &tmp_zv);
} else {
AST_NODE_SET_PROP_FLAGS(obj, ast->attr);
}
ast_fill_children_ht(children, ast, state);
#if PHP_VERSION_ID < 70400
if (ast->kind == ZEND_AST_PROP_DECL && state->version >= 70) {
zval type_zval;
zval prop_group_zval;
ZVAL_COPY_VALUE(&prop_group_zval, zv);
ZVAL_NULL(&type_zval);
// For version 70, create an AST_PROP_GROUP wrapping the created AST_PROP_DECL.
if (state->version >= 80) {
// For version 80, add a null attributes node.
ast_create_virtual_node_ex(
zv, ZEND_AST_PROP_GROUP, ast->attr, zend_ast_get_lineno(ast), state, 3, &type_zval, &prop_group_zval, &type_zval);
} else {
ast_create_virtual_node_ex(
zv, ZEND_AST_PROP_GROUP, ast->attr, zend_ast_get_lineno(ast), state, 2, &type_zval, &prop_group_zval);
}
AST_NODE_SET_PROP_FLAGS(obj, 0);
}
#endif
#if PHP_VERSION_ID < 80000
if (ast->kind == ZEND_AST_CLASS_CONST_DECL && state->version >= 80) {
zval const_decl_zval;
zval attributes_zval;
ZVAL_COPY_VALUE(&const_decl_zval, zv);
ZVAL_NULL(&attributes_zval);
AST_NODE_SET_PROP_FLAGS(obj, 0);
// For version 80, create an AST_CLASS_CONST_GROUP wrapping the created AST_CLASS_CONST_DECL
ast_create_virtual_node_ex(
zv, ZEND_AST_CLASS_CONST_GROUP, ast->attr, zend_ast_get_lineno(ast), state, 2, &const_decl_zval, &attributes_zval);
}
#endif
}
static const zend_long versions[] = {50, 60, 70, 80, 85, 90, 100, 110};
static const size_t versions_count = sizeof(versions)/sizeof(versions[0]);
static inline zend_bool ast_version_deprecated(zend_long version) {
return version < 70;
}
static zend_string *ast_version_info(void) {
smart_str str = {0};
size_t i;
smart_str_appends(&str, "Current version is ");
smart_str_append_long(&str, AST_CURRENT_VERSION);
smart_str_appends(&str, ". All versions (including experimental): {");
for (i = 0; i < versions_count; ++i) {
if (i != 0) smart_str_appends(&str, ", ");
smart_str_append_long(&str, versions[i]);
}
smart_str_appends(&str, "}");
smart_str_0(&str);
return str.s;
}
static inline zend_bool ast_version_known(zend_long version) {
size_t i;
for (i = 0; i < versions_count; ++i) {
if (version == versions[i]) {
return 1;
}
}
return 0;
}
static int ast_check_version(zend_long version) {
zend_string *version_info;
if (ast_version_known(version)) {
if (ast_version_deprecated(version)) {
php_error_docref(NULL, E_DEPRECATED,
"Version " ZEND_LONG_FMT " is deprecated", version);
}
return SUCCESS;
}
version_info = ast_version_info();
if (version != -1) {
ast_throw_exception(spl_ce_LogicException,
"Unknown version " ZEND_LONG_FMT ". %s", version, ZSTR_VAL(version_info));
} else {
ast_throw_exception(spl_ce_LogicException,
"No version specified. %s", ZSTR_VAL(version_info));
}
zend_string_release(version_info);
return FAILURE;
}
PHP_FUNCTION(parse_file) {
zend_string *filename, *code;
zend_long version = -1;
ast_state_info_t state;
zend_ast *ast;
zend_arena *arena;
php_stream *stream;
zend_error_handling error_handling;
if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "P|l", &filename, &version) == FAILURE) {
return;
}
if (ast_check_version(version) == FAILURE) {
return;
}
zend_replace_error_handling(EH_THROW, spl_ce_RuntimeException, &error_handling);
stream = php_stream_open_wrapper_ex(filename->val, "rb", REPORT_ERRORS, NULL, NULL);
if (!stream) {
zend_restore_error_handling(&error_handling);
return;
}
code = php_stream_copy_to_mem(stream, PHP_STREAM_COPY_ALL, 0);
php_stream_close(stream);
zend_restore_error_handling(&error_handling);
if (!code) {
/* php_stream_copy_to_mem will return NULL if the file is empty, strangely. */
code = ZSTR_EMPTY_ALLOC();
}
ast = get_ast(code, &arena, filename);
if (!ast) {
zend_string_free(code);
return;
}
state.version = version;
state.declIdCounter = 0;
ast_to_zval(return_value, ast, &state);
zend_string_free(code);
zend_ast_destroy(ast);
zend_arena_destroy(arena);
}
PHP_FUNCTION(parse_code) {
zend_string *code, *filename = NULL;
zend_long version = -1;
ast_state_info_t state;
zend_ast *ast;
zend_arena *arena;
if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "S|lP", &code, &version, &filename) == FAILURE) {
return;
}
if (ast_check_version(version) == FAILURE) {
return;
}
ast = get_ast(code, &arena, filename);
if (!ast) {
return;
}
state.version = version;
state.declIdCounter = 0;
ast_to_zval(return_value, ast, &state);
zend_ast_destroy(ast);
zend_arena_destroy(arena);
}
PHP_FUNCTION(get_kind_name) {
zend_long kind;
const char *name;
if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "l", &kind) == FAILURE) {
return;
}
name = ast_kind_to_name(kind);
if (!name) {
ast_throw_exception(spl_ce_LogicException, "Unknown kind " ZEND_LONG_FMT, kind);
return;
}
RETURN_STRING(name);
}
PHP_FUNCTION(kind_uses_flags) {
zend_long kind;
if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "l", &kind) == FAILURE) {
return;
}
RETURN_BOOL(ast_kind_uses_attr(kind) || ast_kind_is_decl(kind));
}
static inline const ast_flag_info *ast_get_flag_info(uint16_t ast_kind) {
size_t i, flag_info_count = sizeof(flag_info)/sizeof(ast_flag_info);
for (i = 0; i < flag_info_count; i++) {
const ast_flag_info *info = &flag_info[i];
if (info->ast_kind == ast_kind) {
return info;
}
}
return NULL;
}
static void ast_build_metadata(zval *result) {
size_t i;
array_init_size(result, ast_kinds_count);
for (i = 0; i < ast_kinds_count; i++) {
zend_ast_kind kind = ast_kinds[i];
const ast_flag_info *flag_info = ast_get_flag_info(kind);
zval info_zv, tmp_zv;
zend_object *obj;
object_init_ex(&info_zv, ast_metadata_ce);
obj = Z_OBJ(info_zv);
/* kind */
ZVAL_LONG(AST_METADATA_PROP_KIND(obj), kind);
/* name */
ZVAL_STRING(AST_METADATA_PROP_NAME(obj), ast_kind_to_name(kind));
/* flags */
array_init(&tmp_zv);
if (flag_info) {
const char **flag;
for (flag = flag_info->flags; *flag; flag++) {
add_next_index_string(&tmp_zv, *flag);
}
}
ZVAL_ARR(AST_METADATA_PROP_FLAGS(obj), Z_ARRVAL(tmp_zv));
/* flagsCombinable */
ZVAL_BOOL(AST_METADATA_PROP_FLAGS_COMBINABLE(obj), flag_info && flag_info->combinable);
add_index_zval(result, kind, &info_zv);
}
}
PHP_FUNCTION(get_metadata) {
if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "") == FAILURE) {
return;
}
if (Z_ISUNDEF(AST_G(metadata))) {
ast_build_metadata(&AST_G(metadata));
}
ZVAL_COPY(return_value, &AST_G(metadata));
}
PHP_FUNCTION(get_supported_versions) {
zend_bool exclude_deprecated = 0;
size_t i;
if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "|b", &exclude_deprecated) == FAILURE) {
return;
}
array_init(return_value);
for (i = 0; i < versions_count; i++) {
zend_long version = versions[i];
if (!exclude_deprecated || !ast_version_deprecated(version)) {
add_next_index_long(return_value, version);
}
}
}
PHP_METHOD(ast_Node, __construct) {
int num_args = ZEND_NUM_ARGS();
if (num_args == 0) {
/* If arguments aren't passed, leave them as their default values. */
return;
}
zend_long kind;
zend_long flags;
zval *children;
zend_long lineno;
zend_bool kindNull, flagsNull, linenoNull;
ZEND_PARSE_PARAMETERS_START_EX(ZEND_PARSE_PARAMS_THROW, 0, 4)
Z_PARAM_OPTIONAL
Z_PARAM_LONG_EX(kind, kindNull, 1, 0)
Z_PARAM_LONG_EX(flags, flagsNull, 1, 0)
Z_PARAM_ARRAY_EX(children, 1, 0)
Z_PARAM_LONG_EX(lineno, linenoNull, 1, 0)
ZEND_PARSE_PARAMETERS_END();
zend_object *obj = Z_OBJ_P(ZEND_THIS);
switch (num_args) {
case 4:
if (!linenoNull) {
AST_NODE_SET_PROP_LINENO(obj, lineno);
}
/* Falls through - break missing intentionally */
case 3:
if (children != NULL) {
ZVAL_COPY(AST_NODE_PROP_CHILDREN(obj), children);
}
/* Falls through - break missing intentionally */
case 2:
if (!flagsNull) {
AST_NODE_SET_PROP_FLAGS(obj, flags);
}
/* Falls through - break missing intentionally */
case 1:
if (!kindNull) {
AST_NODE_SET_PROP_KIND(obj, kind);
}
/* Falls through - break missing intentionally */
case 0:
break;
}
}
PHP_MINFO_FUNCTION(ast) {
zend_string *info = ast_version_info();
php_info_print_table_start();
php_info_print_table_row(2, "ast support", "enabled");
php_info_print_table_row(2, "extension version", PHP_AST_VERSION);
php_info_print_table_row(2, "AST version", ZSTR_VAL(info));
php_info_print_table_end();
zend_string_release(info);
}
PHP_RINIT_FUNCTION(ast) {
ZVAL_UNDEF(&AST_G(metadata));
return SUCCESS;
}
PHP_RSHUTDOWN_FUNCTION(ast) {
zval_ptr_dtor(&AST_G(metadata));
return SUCCESS;
}
PHP_MINIT_FUNCTION(ast) {
zend_class_entry tmp_ce;
zval zv_null;
ZVAL_NULL(&zv_null);
#define X(str, value) \
AST_STR(str_ ## str) = zend_new_interned_string( \
zend_string_init(value, sizeof(value) - 1, 1));
AST_STR_DEFS
#undef X
ast_register_kind_constants(INIT_FUNC_ARGS_PASSTHRU);
ast_register_flag_constant("NAME_FQ", ZEND_NAME_FQ);
ast_register_flag_constant("NAME_NOT_FQ", ZEND_NAME_NOT_FQ);
ast_register_flag_constant("NAME_RELATIVE", ZEND_NAME_RELATIVE);
ast_register_flag_constant("MODIFIER_PUBLIC", ZEND_ACC_PUBLIC);
ast_register_flag_constant("MODIFIER_PROTECTED", ZEND_ACC_PROTECTED);
ast_register_flag_constant("MODIFIER_PRIVATE", ZEND_ACC_PRIVATE);
ast_register_flag_constant("MODIFIER_STATIC", ZEND_ACC_STATIC);
ast_register_flag_constant("MODIFIER_ABSTRACT", ZEND_ACC_ABSTRACT);
ast_register_flag_constant("MODIFIER_FINAL", ZEND_ACC_FINAL);
ast_register_flag_constant("MODIFIER_READONLY", ZEND_ACC_READONLY);
ast_register_flag_constant("PARAM_MODIFIER_PUBLIC", PARAM_MODIFIER_PUBLIC);
ast_register_flag_constant("PARAM_MODIFIER_PROTECTED", PARAM_MODIFIER_PROTECTED);
ast_register_flag_constant("PARAM_MODIFIER_PRIVATE", PARAM_MODIFIER_PRIVATE);
ast_register_flag_constant("RETURNS_REF", ZEND_ACC_RETURN_REFERENCE);
ast_register_flag_constant("FUNC_RETURNS_REF", ZEND_ACC_RETURN_REFERENCE);
ast_register_flag_constant("FUNC_GENERATOR", ZEND_ACC_GENERATOR);
ast_register_flag_constant("ARRAY_ELEM_REF", 1);
ast_register_flag_constant("CLOSURE_USE_REF", ZEND_BIND_REF);
ast_register_flag_constant("CLASS_ABSTRACT", ZEND_ACC_EXPLICIT_ABSTRACT_CLASS);
ast_register_flag_constant("CLASS_FINAL", ZEND_ACC_FINAL);
ast_register_flag_constant("CLASS_TRAIT", ZEND_ACC_TRAIT);
ast_register_flag_constant("CLASS_INTERFACE", ZEND_ACC_INTERFACE);
ast_register_flag_constant("CLASS_ANONYMOUS", ZEND_ACC_ANON_CLASS);
ast_register_flag_constant("CLASS_ENUM", ZEND_ACC_ENUM);
ast_register_flag_constant("CLASS_READONLY", ZEND_ACC_READONLY_CLASS);
ast_register_flag_constant("PARAM_REF", ZEND_PARAM_REF);
ast_register_flag_constant("PARAM_VARIADIC", ZEND_PARAM_VARIADIC);
ast_register_flag_constant("TYPE_NULL", IS_NULL);
ast_register_flag_constant("TYPE_FALSE", IS_FALSE);
ast_register_flag_constant("TYPE_TRUE", IS_TRUE);
ast_register_flag_constant("TYPE_BOOL", _IS_BOOL);
ast_register_flag_constant("TYPE_LONG", IS_LONG);
ast_register_flag_constant("TYPE_DOUBLE", IS_DOUBLE);
ast_register_flag_constant("TYPE_STRING", IS_STRING);
ast_register_flag_constant("TYPE_ARRAY", IS_ARRAY);
ast_register_flag_constant("TYPE_OBJECT", IS_OBJECT);
ast_register_flag_constant("TYPE_CALLABLE", IS_CALLABLE);
ast_register_flag_constant("TYPE_VOID", IS_VOID);
ast_register_flag_constant("TYPE_ITERABLE", IS_ITERABLE);
ast_register_flag_constant("TYPE_STATIC", IS_STATIC);
ast_register_flag_constant("TYPE_MIXED", IS_MIXED);
ast_register_flag_constant("TYPE_NEVER", IS_NEVER);
ast_register_flag_constant("UNARY_BOOL_NOT", ZEND_BOOL_NOT);
ast_register_flag_constant("UNARY_BITWISE_NOT", ZEND_BW_NOT);
ast_register_flag_constant("UNARY_SILENCE", AST_SILENCE);
ast_register_flag_constant("UNARY_PLUS", AST_PLUS);
ast_register_flag_constant("UNARY_MINUS", AST_MINUS);
ast_register_flag_constant("BINARY_BOOL_AND", AST_BINARY_BOOL_AND);
ast_register_flag_constant("BINARY_BOOL_OR", AST_BINARY_BOOL_OR);
ast_register_flag_constant("BINARY_BOOL_XOR", ZEND_BOOL_XOR);
ast_register_flag_constant("BINARY_BITWISE_OR", ZEND_BW_OR);
ast_register_flag_constant("BINARY_BITWISE_AND", ZEND_BW_AND);
ast_register_flag_constant("BINARY_BITWISE_XOR", ZEND_BW_XOR);
ast_register_flag_constant("BINARY_CONCAT", ZEND_CONCAT);
ast_register_flag_constant("BINARY_ADD", ZEND_ADD);
ast_register_flag_constant("BINARY_SUB", ZEND_SUB);
ast_register_flag_constant("BINARY_MUL", ZEND_MUL);
ast_register_flag_constant("BINARY_DIV", ZEND_DIV);
ast_register_flag_constant("BINARY_MOD", ZEND_MOD);
ast_register_flag_constant("BINARY_POW", ZEND_POW);
ast_register_flag_constant("BINARY_SHIFT_LEFT", ZEND_SL);
ast_register_flag_constant("BINARY_SHIFT_RIGHT", ZEND_SR);
ast_register_flag_constant("BINARY_IS_IDENTICAL", ZEND_IS_IDENTICAL);
ast_register_flag_constant("BINARY_IS_NOT_IDENTICAL", ZEND_IS_NOT_IDENTICAL);
ast_register_flag_constant("BINARY_IS_EQUAL", ZEND_IS_EQUAL);
ast_register_flag_constant("BINARY_IS_NOT_EQUAL", ZEND_IS_NOT_EQUAL);
ast_register_flag_constant("BINARY_IS_SMALLER", ZEND_IS_SMALLER);
ast_register_flag_constant("BINARY_IS_SMALLER_OR_EQUAL", ZEND_IS_SMALLER_OR_EQUAL);
ast_register_flag_constant("BINARY_IS_GREATER", AST_BINARY_IS_GREATER);
ast_register_flag_constant("BINARY_IS_GREATER_OR_EQUAL", AST_BINARY_IS_GREATER_OR_EQUAL);
ast_register_flag_constant("BINARY_SPACESHIP", ZEND_SPACESHIP);
ast_register_flag_constant("BINARY_COALESCE", AST_BINARY_COALESCE);
ast_register_flag_constant("EXEC_EVAL", ZEND_EVAL);
ast_register_flag_constant("EXEC_INCLUDE", ZEND_INCLUDE);
ast_register_flag_constant("EXEC_INCLUDE_ONCE", ZEND_INCLUDE_ONCE);
ast_register_flag_constant("EXEC_REQUIRE", ZEND_REQUIRE);
ast_register_flag_constant("EXEC_REQUIRE_ONCE", ZEND_REQUIRE_ONCE);
ast_register_flag_constant("USE_NORMAL", ZEND_SYMBOL_CLASS);
ast_register_flag_constant("USE_FUNCTION", ZEND_SYMBOL_FUNCTION);
ast_register_flag_constant("USE_CONST", ZEND_SYMBOL_CONST);
ast_register_flag_constant("MAGIC_LINE", T_LINE);
ast_register_flag_constant("MAGIC_FILE", T_FILE);
ast_register_flag_constant("MAGIC_DIR", T_DIR);
ast_register_flag_constant("MAGIC_NAMESPACE", T_NS_C);
ast_register_flag_constant("MAGIC_FUNCTION", T_FUNC_C);
ast_register_flag_constant("MAGIC_METHOD", T_METHOD_C);
ast_register_flag_constant("MAGIC_CLASS", T_CLASS_C);
ast_register_flag_constant("MAGIC_TRAIT", T_TRAIT_C);
ast_register_flag_constant("ARRAY_SYNTAX_LIST", ZEND_ARRAY_SYNTAX_LIST);
ast_register_flag_constant("ARRAY_SYNTAX_LONG", ZEND_ARRAY_SYNTAX_LONG);
ast_register_flag_constant("ARRAY_SYNTAX_SHORT", ZEND_ARRAY_SYNTAX_SHORT);
ast_register_flag_constant("DIM_ALTERNATIVE_SYNTAX", ZEND_DIM_ALTERNATIVE_SYNTAX);
ast_register_flag_constant("PARENTHESIZED_CONDITIONAL", ZEND_PARENTHESIZED_CONDITIONAL);
ast_register_flag_constant("ENCAPS_VAR_DOLLAR_CURLY", ZEND_ENCAPS_VAR_DOLLAR_CURLY);
ast_register_flag_constant("ENCAPS_VAR_DOLLAR_CURLY_VAR_VAR", ZEND_ENCAPS_VAR_DOLLAR_CURLY_VAR_VAR);
INIT_CLASS_ENTRY(tmp_ce, "ast\\Node", class_ast_Node_methods);
ast_node_ce = zend_register_internal_class(&tmp_ce);
ast_declare_property(ast_node_ce, AST_STR(str_kind), &zv_null);
ast_declare_property(ast_node_ce, AST_STR(str_flags), &zv_null);
ast_declare_property(ast_node_ce, AST_STR(str_lineno), &zv_null);
ast_declare_property(ast_node_ce, AST_STR(str_children), &zv_null);
#ifdef ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES
zend_add_class_attribute(ast_node_ce, zend_ce_allow_dynamic_properties->name, 0);
ast_node_ce->ce_flags |= ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES;
#endif
INIT_CLASS_ENTRY(tmp_ce, "ast\\Metadata", NULL);
ast_metadata_ce = zend_register_internal_class(&tmp_ce);
ast_declare_property(ast_metadata_ce, AST_STR(str_kind), &zv_null);
ast_declare_property(ast_metadata_ce, AST_STR(str_name), &zv_null);
ast_declare_property(ast_metadata_ce, AST_STR(str_flags), &zv_null);
ast_declare_property(ast_metadata_ce, AST_STR(str_flagsCombinable), &zv_null);
return SUCCESS;
}
PHP_MSHUTDOWN_FUNCTION(ast) {
#define X(str, value) zend_string_release(AST_STR(str_ ## str));
AST_STR_DEFS
#undef X
return SUCCESS;
}
zend_module_entry ast_module_entry = {
STANDARD_MODULE_HEADER,
"ast",
ext_functions,
PHP_MINIT(ast),
PHP_MSHUTDOWN(ast),
PHP_RINIT(ast),
PHP_RSHUTDOWN(ast),
PHP_MINFO(ast),
PHP_AST_VERSION,
PHP_MODULE_GLOBALS(ast),
NULL,
NULL,
NULL,
STANDARD_MODULE_PROPERTIES_EX
};
#ifdef COMPILE_DL_AST
ZEND_GET_MODULE(ast)
#endif
ast-1.1.2/ast_data.c 0000664 0001750 0001750 00000066027 14655731747 013400 0 ustar tyson tyson #include "php_ast.h"
const zend_ast_kind ast_kinds[] = {
ZEND_AST_ARG_LIST,
ZEND_AST_LIST,
ZEND_AST_ARRAY,
ZEND_AST_ENCAPS_LIST,
ZEND_AST_EXPR_LIST,
ZEND_AST_STMT_LIST,
ZEND_AST_IF,
ZEND_AST_SWITCH_LIST,
ZEND_AST_CATCH_LIST,
ZEND_AST_PARAM_LIST,
ZEND_AST_CLOSURE_USES,
ZEND_AST_PROP_DECL,
ZEND_AST_CONST_DECL,
ZEND_AST_CLASS_CONST_DECL,
ZEND_AST_NAME_LIST,
ZEND_AST_TRAIT_ADAPTATIONS,
ZEND_AST_USE,
ZEND_AST_TYPE_UNION,
ZEND_AST_TYPE_INTERSECTION,
ZEND_AST_ATTRIBUTE_LIST,
ZEND_AST_ATTRIBUTE_GROUP,
ZEND_AST_MATCH_ARM_LIST,
AST_NAME,
AST_CLOSURE_VAR,
AST_NULLABLE_TYPE,
ZEND_AST_FUNC_DECL,
ZEND_AST_CLOSURE,
ZEND_AST_METHOD,
ZEND_AST_ARROW_FUNC,
ZEND_AST_CLASS,
ZEND_AST_PROPERTY_HOOK,
ZEND_AST_MAGIC_CONST,
ZEND_AST_TYPE,
ZEND_AST_CALLABLE_CONVERT,
ZEND_AST_VAR,
ZEND_AST_CONST,
ZEND_AST_UNPACK,
ZEND_AST_CAST,
ZEND_AST_EMPTY,
ZEND_AST_ISSET,
ZEND_AST_SHELL_EXEC,
ZEND_AST_CLONE,
ZEND_AST_EXIT,
ZEND_AST_PRINT,
ZEND_AST_INCLUDE_OR_EVAL,
ZEND_AST_UNARY_OP,
ZEND_AST_PRE_INC,
ZEND_AST_PRE_DEC,
ZEND_AST_POST_INC,
ZEND_AST_POST_DEC,
ZEND_AST_YIELD_FROM,
ZEND_AST_GLOBAL,
ZEND_AST_UNSET,
ZEND_AST_RETURN,
ZEND_AST_LABEL,
ZEND_AST_REF,
ZEND_AST_HALT_COMPILER,
ZEND_AST_ECHO,
ZEND_AST_THROW,
ZEND_AST_GOTO,
ZEND_AST_BREAK,
ZEND_AST_CONTINUE,
ZEND_AST_CLASS_NAME,
ZEND_AST_PROPERTY_HOOK_SHORT_BODY,
ZEND_AST_CLASS_CONST_GROUP,
ZEND_AST_DIM,
ZEND_AST_PROP,
ZEND_AST_NULLSAFE_PROP,
ZEND_AST_STATIC_PROP,
ZEND_AST_CALL,
ZEND_AST_CLASS_CONST,
ZEND_AST_ASSIGN,
ZEND_AST_ASSIGN_REF,
ZEND_AST_ASSIGN_OP,
ZEND_AST_BINARY_OP,
ZEND_AST_ARRAY_ELEM,
ZEND_AST_NEW,
ZEND_AST_INSTANCEOF,
ZEND_AST_YIELD,
ZEND_AST_STATIC,
ZEND_AST_WHILE,
ZEND_AST_DO_WHILE,
ZEND_AST_IF_ELEM,
ZEND_AST_SWITCH,
ZEND_AST_SWITCH_CASE,
ZEND_AST_DECLARE,
ZEND_AST_PROP_ELEM,
ZEND_AST_PROP_GROUP,
ZEND_AST_CONST_ELEM,
ZEND_AST_USE_TRAIT,
ZEND_AST_TRAIT_PRECEDENCE,
ZEND_AST_METHOD_REFERENCE,
ZEND_AST_NAMESPACE,
ZEND_AST_USE_ELEM,
ZEND_AST_TRAIT_ALIAS,
ZEND_AST_GROUP_USE,
ZEND_AST_ATTRIBUTE,
ZEND_AST_MATCH,
ZEND_AST_MATCH_ARM,
ZEND_AST_NAMED_ARG,
ZEND_AST_METHOD_CALL,
ZEND_AST_NULLSAFE_METHOD_CALL,
ZEND_AST_STATIC_CALL,
ZEND_AST_CONDITIONAL,
ZEND_AST_TRY,
ZEND_AST_CATCH,
ZEND_AST_FOR,
ZEND_AST_FOREACH,
ZEND_AST_ENUM_CASE,
ZEND_AST_PARAM,
};
const size_t ast_kinds_count = sizeof(ast_kinds) / sizeof(ast_kinds[0]);
const char *ast_kind_to_name(zend_ast_kind kind) {
switch (kind) {
case ZEND_AST_ARG_LIST: return "AST_ARG_LIST";
case ZEND_AST_LIST: return "AST_LIST";
case ZEND_AST_ARRAY: return "AST_ARRAY";
case ZEND_AST_ENCAPS_LIST: return "AST_ENCAPS_LIST";
case ZEND_AST_EXPR_LIST: return "AST_EXPR_LIST";
case ZEND_AST_STMT_LIST: return "AST_STMT_LIST";
case ZEND_AST_IF: return "AST_IF";
case ZEND_AST_SWITCH_LIST: return "AST_SWITCH_LIST";
case ZEND_AST_CATCH_LIST: return "AST_CATCH_LIST";
case ZEND_AST_PARAM_LIST: return "AST_PARAM_LIST";
case ZEND_AST_CLOSURE_USES: return "AST_CLOSURE_USES";
case ZEND_AST_PROP_DECL: return "AST_PROP_DECL";
case ZEND_AST_CONST_DECL: return "AST_CONST_DECL";
case ZEND_AST_CLASS_CONST_DECL: return "AST_CLASS_CONST_DECL";
case ZEND_AST_NAME_LIST: return "AST_NAME_LIST";
case ZEND_AST_TRAIT_ADAPTATIONS: return "AST_TRAIT_ADAPTATIONS";
case ZEND_AST_USE: return "AST_USE";
case ZEND_AST_TYPE_UNION: return "AST_TYPE_UNION";
case ZEND_AST_TYPE_INTERSECTION: return "AST_TYPE_INTERSECTION";
case ZEND_AST_ATTRIBUTE_LIST: return "AST_ATTRIBUTE_LIST";
case ZEND_AST_ATTRIBUTE_GROUP: return "AST_ATTRIBUTE_GROUP";
case ZEND_AST_MATCH_ARM_LIST: return "AST_MATCH_ARM_LIST";
case AST_NAME: return "AST_NAME";
case AST_CLOSURE_VAR: return "AST_CLOSURE_VAR";
case AST_NULLABLE_TYPE: return "AST_NULLABLE_TYPE";
case ZEND_AST_FUNC_DECL: return "AST_FUNC_DECL";
case ZEND_AST_CLOSURE: return "AST_CLOSURE";
case ZEND_AST_METHOD: return "AST_METHOD";
case ZEND_AST_ARROW_FUNC: return "AST_ARROW_FUNC";
case ZEND_AST_CLASS: return "AST_CLASS";
case ZEND_AST_PROPERTY_HOOK: return "AST_PROPERTY_HOOK";
case ZEND_AST_MAGIC_CONST: return "AST_MAGIC_CONST";
case ZEND_AST_TYPE: return "AST_TYPE";
case ZEND_AST_CALLABLE_CONVERT: return "AST_CALLABLE_CONVERT";
case ZEND_AST_VAR: return "AST_VAR";
case ZEND_AST_CONST: return "AST_CONST";
case ZEND_AST_UNPACK: return "AST_UNPACK";
case ZEND_AST_CAST: return "AST_CAST";
case ZEND_AST_EMPTY: return "AST_EMPTY";
case ZEND_AST_ISSET: return "AST_ISSET";
case ZEND_AST_SHELL_EXEC: return "AST_SHELL_EXEC";
case ZEND_AST_CLONE: return "AST_CLONE";
case ZEND_AST_EXIT: return "AST_EXIT";
case ZEND_AST_PRINT: return "AST_PRINT";
case ZEND_AST_INCLUDE_OR_EVAL: return "AST_INCLUDE_OR_EVAL";
case ZEND_AST_UNARY_OP: return "AST_UNARY_OP";
case ZEND_AST_PRE_INC: return "AST_PRE_INC";
case ZEND_AST_PRE_DEC: return "AST_PRE_DEC";
case ZEND_AST_POST_INC: return "AST_POST_INC";
case ZEND_AST_POST_DEC: return "AST_POST_DEC";
case ZEND_AST_YIELD_FROM: return "AST_YIELD_FROM";
case ZEND_AST_GLOBAL: return "AST_GLOBAL";
case ZEND_AST_UNSET: return "AST_UNSET";
case ZEND_AST_RETURN: return "AST_RETURN";
case ZEND_AST_LABEL: return "AST_LABEL";
case ZEND_AST_REF: return "AST_REF";
case ZEND_AST_HALT_COMPILER: return "AST_HALT_COMPILER";
case ZEND_AST_ECHO: return "AST_ECHO";
case ZEND_AST_THROW: return "AST_THROW";
case ZEND_AST_GOTO: return "AST_GOTO";
case ZEND_AST_BREAK: return "AST_BREAK";
case ZEND_AST_CONTINUE: return "AST_CONTINUE";
case ZEND_AST_CLASS_NAME: return "AST_CLASS_NAME";
case ZEND_AST_PROPERTY_HOOK_SHORT_BODY: return "AST_PROPERTY_HOOK_SHORT_BODY";
case ZEND_AST_CLASS_CONST_GROUP: return "AST_CLASS_CONST_GROUP";
case ZEND_AST_DIM: return "AST_DIM";
case ZEND_AST_PROP: return "AST_PROP";
case ZEND_AST_NULLSAFE_PROP: return "AST_NULLSAFE_PROP";
case ZEND_AST_STATIC_PROP: return "AST_STATIC_PROP";
case ZEND_AST_CALL: return "AST_CALL";
case ZEND_AST_CLASS_CONST: return "AST_CLASS_CONST";
case ZEND_AST_ASSIGN: return "AST_ASSIGN";
case ZEND_AST_ASSIGN_REF: return "AST_ASSIGN_REF";
case ZEND_AST_ASSIGN_OP: return "AST_ASSIGN_OP";
case ZEND_AST_BINARY_OP: return "AST_BINARY_OP";
case ZEND_AST_ARRAY_ELEM: return "AST_ARRAY_ELEM";
case ZEND_AST_NEW: return "AST_NEW";
case ZEND_AST_INSTANCEOF: return "AST_INSTANCEOF";
case ZEND_AST_YIELD: return "AST_YIELD";
case ZEND_AST_STATIC: return "AST_STATIC";
case ZEND_AST_WHILE: return "AST_WHILE";
case ZEND_AST_DO_WHILE: return "AST_DO_WHILE";
case ZEND_AST_IF_ELEM: return "AST_IF_ELEM";
case ZEND_AST_SWITCH: return "AST_SWITCH";
case ZEND_AST_SWITCH_CASE: return "AST_SWITCH_CASE";
case ZEND_AST_DECLARE: return "AST_DECLARE";
case ZEND_AST_PROP_ELEM: return "AST_PROP_ELEM";
case ZEND_AST_PROP_GROUP: return "AST_PROP_GROUP";
case ZEND_AST_CONST_ELEM: return "AST_CONST_ELEM";
case ZEND_AST_USE_TRAIT: return "AST_USE_TRAIT";
case ZEND_AST_TRAIT_PRECEDENCE: return "AST_TRAIT_PRECEDENCE";
case ZEND_AST_METHOD_REFERENCE: return "AST_METHOD_REFERENCE";
case ZEND_AST_NAMESPACE: return "AST_NAMESPACE";
case ZEND_AST_USE_ELEM: return "AST_USE_ELEM";
case ZEND_AST_TRAIT_ALIAS: return "AST_TRAIT_ALIAS";
case ZEND_AST_GROUP_USE: return "AST_GROUP_USE";
case ZEND_AST_ATTRIBUTE: return "AST_ATTRIBUTE";
case ZEND_AST_MATCH: return "AST_MATCH";
case ZEND_AST_MATCH_ARM: return "AST_MATCH_ARM";
case ZEND_AST_NAMED_ARG: return "AST_NAMED_ARG";
case ZEND_AST_METHOD_CALL: return "AST_METHOD_CALL";
case ZEND_AST_NULLSAFE_METHOD_CALL: return "AST_NULLSAFE_METHOD_CALL";
case ZEND_AST_STATIC_CALL: return "AST_STATIC_CALL";
case ZEND_AST_CONDITIONAL: return "AST_CONDITIONAL";
case ZEND_AST_TRY: return "AST_TRY";
case ZEND_AST_CATCH: return "AST_CATCH";
case ZEND_AST_FOR: return "AST_FOR";
case ZEND_AST_FOREACH: return "AST_FOREACH";
case ZEND_AST_ENUM_CASE: return "AST_ENUM_CASE";
case ZEND_AST_PARAM: return "AST_PARAM";
}
return NULL;
}
zend_string *ast_kind_child_name(zend_ast_kind kind, uint32_t child) {
switch (kind) {
case AST_NAME:
case AST_CLOSURE_VAR:
case ZEND_AST_VAR:
case ZEND_AST_CONST:
case ZEND_AST_LABEL:
switch (child) {
case 0: return AST_STR(str_name);
}
return NULL;
case AST_NULLABLE_TYPE:
switch (child) {
case 0: return AST_STR(str_type);
}
return NULL;
case ZEND_AST_FUNC_DECL:
case ZEND_AST_CLOSURE:
case ZEND_AST_METHOD:
case ZEND_AST_ARROW_FUNC:
case ZEND_AST_PROPERTY_HOOK:
switch (child) {
case 0: return AST_STR(str_params);
case 1: return AST_STR(str_uses);
case 2: return AST_STR(str_stmts);
case 3: return AST_STR(str_returnType);
case 4: return AST_STR(str_attributes);
}
return NULL;
case ZEND_AST_CLASS:
switch (child) {
case 0: return AST_STR(str_extends);
case 1: return AST_STR(str_implements);
case 2: return AST_STR(str_stmts);
case 3: return AST_STR(str_attributes);
case 4: return AST_STR(str_type);
}
return NULL;
case ZEND_AST_MAGIC_CONST:
case ZEND_AST_TYPE:
case ZEND_AST_CALLABLE_CONVERT:
return NULL;
case ZEND_AST_UNPACK:
case ZEND_AST_CAST:
case ZEND_AST_EMPTY:
case ZEND_AST_SHELL_EXEC:
case ZEND_AST_CLONE:
case ZEND_AST_EXIT:
case ZEND_AST_PRINT:
case ZEND_AST_INCLUDE_OR_EVAL:
case ZEND_AST_UNARY_OP:
case ZEND_AST_YIELD_FROM:
case ZEND_AST_RETURN:
case ZEND_AST_ECHO:
case ZEND_AST_THROW:
case ZEND_AST_PROPERTY_HOOK_SHORT_BODY:
switch (child) {
case 0: return AST_STR(str_expr);
}
return NULL;
case ZEND_AST_ISSET:
case ZEND_AST_PRE_INC:
case ZEND_AST_PRE_DEC:
case ZEND_AST_POST_INC:
case ZEND_AST_POST_DEC:
case ZEND_AST_GLOBAL:
case ZEND_AST_UNSET:
case ZEND_AST_REF:
switch (child) {
case 0: return AST_STR(str_var);
}
return NULL;
case ZEND_AST_HALT_COMPILER:
switch (child) {
case 0: return AST_STR(str_offset);
}
return NULL;
case ZEND_AST_GOTO:
switch (child) {
case 0: return AST_STR(str_label);
}
return NULL;
case ZEND_AST_BREAK:
case ZEND_AST_CONTINUE:
switch (child) {
case 0: return AST_STR(str_depth);
}
return NULL;
case ZEND_AST_CLASS_NAME:
switch (child) {
case 0: return AST_STR(str_class);
}
return NULL;
case ZEND_AST_CLASS_CONST_GROUP:
switch (child) {
case 0: return AST_STR(str_const);
case 1: return AST_STR(str_attributes);
case 2: return AST_STR(str_type);
}
return NULL;
case ZEND_AST_DIM:
switch (child) {
case 0: return AST_STR(str_expr);
case 1: return AST_STR(str_dim);
}
return NULL;
case ZEND_AST_PROP:
case ZEND_AST_NULLSAFE_PROP:
switch (child) {
case 0: return AST_STR(str_expr);
case 1: return AST_STR(str_prop);
}
return NULL;
case ZEND_AST_STATIC_PROP:
switch (child) {
case 0: return AST_STR(str_class);
case 1: return AST_STR(str_prop);
}
return NULL;
case ZEND_AST_CALL:
switch (child) {
case 0: return AST_STR(str_expr);
case 1: return AST_STR(str_args);
}
return NULL;
case ZEND_AST_CLASS_CONST:
switch (child) {
case 0: return AST_STR(str_class);
case 1: return AST_STR(str_const);
}
return NULL;
case ZEND_AST_ASSIGN:
case ZEND_AST_ASSIGN_REF:
case ZEND_AST_ASSIGN_OP:
switch (child) {
case 0: return AST_STR(str_var);
case 1: return AST_STR(str_expr);
}
return NULL;
case ZEND_AST_BINARY_OP:
switch (child) {
case 0: return AST_STR(str_left);
case 1: return AST_STR(str_right);
}
return NULL;
case ZEND_AST_ARRAY_ELEM:
case ZEND_AST_YIELD:
switch (child) {
case 0: return AST_STR(str_value);
case 1: return AST_STR(str_key);
}
return NULL;
case ZEND_AST_NEW:
case ZEND_AST_ATTRIBUTE:
switch (child) {
case 0: return AST_STR(str_class);
case 1: return AST_STR(str_args);
}
return NULL;
case ZEND_AST_INSTANCEOF:
switch (child) {
case 0: return AST_STR(str_expr);
case 1: return AST_STR(str_class);
}
return NULL;
case ZEND_AST_STATIC:
switch (child) {
case 0: return AST_STR(str_var);
case 1: return AST_STR(str_default);
}
return NULL;
case ZEND_AST_WHILE:
case ZEND_AST_IF_ELEM:
case ZEND_AST_SWITCH:
case ZEND_AST_SWITCH_CASE:
case ZEND_AST_MATCH:
switch (child) {
case 0: return AST_STR(str_cond);
case 1: return AST_STR(str_stmts);
}
return NULL;
case ZEND_AST_DO_WHILE:
switch (child) {
case 0: return AST_STR(str_stmts);
case 1: return AST_STR(str_cond);
}
return NULL;
case ZEND_AST_DECLARE:
switch (child) {
case 0: return AST_STR(str_declares);
case 1: return AST_STR(str_stmts);
}
return NULL;
case ZEND_AST_PROP_ELEM:
switch (child) {
case 0: return AST_STR(str_name);
case 1: return AST_STR(str_default);
case 2: return AST_STR(str_docComment);
case 3: return AST_STR(str_hooks);
}
return NULL;
case ZEND_AST_PROP_GROUP:
switch (child) {
case 0: return AST_STR(str_type);
case 1: return AST_STR(str_props);
case 2: return AST_STR(str_attributes);
}
return NULL;
case ZEND_AST_CONST_ELEM:
switch (child) {
case 0: return AST_STR(str_name);
case 1: return AST_STR(str_value);
case 2: return AST_STR(str_docComment);
}
return NULL;
case ZEND_AST_USE_TRAIT:
switch (child) {
case 0: return AST_STR(str_traits);
case 1: return AST_STR(str_adaptations);
}
return NULL;
case ZEND_AST_TRAIT_PRECEDENCE:
switch (child) {
case 0: return AST_STR(str_method);
case 1: return AST_STR(str_insteadof);
}
return NULL;
case ZEND_AST_METHOD_REFERENCE:
switch (child) {
case 0: return AST_STR(str_class);
case 1: return AST_STR(str_method);
}
return NULL;
case ZEND_AST_NAMESPACE:
switch (child) {
case 0: return AST_STR(str_name);
case 1: return AST_STR(str_stmts);
}
return NULL;
case ZEND_AST_USE_ELEM:
switch (child) {
case 0: return AST_STR(str_name);
case 1: return AST_STR(str_alias);
}
return NULL;
case ZEND_AST_TRAIT_ALIAS:
switch (child) {
case 0: return AST_STR(str_method);
case 1: return AST_STR(str_alias);
}
return NULL;
case ZEND_AST_GROUP_USE:
switch (child) {
case 0: return AST_STR(str_prefix);
case 1: return AST_STR(str_uses);
}
return NULL;
case ZEND_AST_MATCH_ARM:
switch (child) {
case 0: return AST_STR(str_cond);
case 1: return AST_STR(str_expr);
}
return NULL;
case ZEND_AST_NAMED_ARG:
switch (child) {
case 0: return AST_STR(str_name);
case 1: return AST_STR(str_expr);
}
return NULL;
case ZEND_AST_METHOD_CALL:
case ZEND_AST_NULLSAFE_METHOD_CALL:
switch (child) {
case 0: return AST_STR(str_expr);
case 1: return AST_STR(str_method);
case 2: return AST_STR(str_args);
}
return NULL;
case ZEND_AST_STATIC_CALL:
switch (child) {
case 0: return AST_STR(str_class);
case 1: return AST_STR(str_method);
case 2: return AST_STR(str_args);
}
return NULL;
case ZEND_AST_CONDITIONAL:
switch (child) {
case 0: return AST_STR(str_cond);
case 1: return AST_STR(str_true);
case 2: return AST_STR(str_false);
}
return NULL;
case ZEND_AST_TRY:
switch (child) {
case 0: return AST_STR(str_try);
case 1: return AST_STR(str_catches);
case 2: return AST_STR(str_finally);
}
return NULL;
case ZEND_AST_CATCH:
switch (child) {
case 0: return AST_STR(str_class);
case 1: return AST_STR(str_var);
case 2: return AST_STR(str_stmts);
}
return NULL;
case ZEND_AST_FOR:
switch (child) {
case 0: return AST_STR(str_init);
case 1: return AST_STR(str_cond);
case 2: return AST_STR(str_loop);
case 3: return AST_STR(str_stmts);
}
return NULL;
case ZEND_AST_FOREACH:
switch (child) {
case 0: return AST_STR(str_expr);
case 1: return AST_STR(str_value);
case 2: return AST_STR(str_key);
case 3: return AST_STR(str_stmts);
}
return NULL;
case ZEND_AST_ENUM_CASE:
switch (child) {
case 0: return AST_STR(str_name);
case 1: return AST_STR(str_expr);
case 2: return AST_STR(str_docComment);
case 3: return AST_STR(str_attributes);
}
return NULL;
case ZEND_AST_PARAM:
switch (child) {
case 0: return AST_STR(str_type);
case 1: return AST_STR(str_name);
case 2: return AST_STR(str_default);
case 3: return AST_STR(str_attributes);
case 4: return AST_STR(str_docComment);
case 5: return AST_STR(str_hooks);
}
return NULL;
}
return NULL;
}
void ast_register_kind_constants(INIT_FUNC_ARGS) {
REGISTER_NS_LONG_CONSTANT("ast", "AST_ARG_LIST", ZEND_AST_ARG_LIST, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_LIST", ZEND_AST_LIST, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_ARRAY", ZEND_AST_ARRAY, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_ENCAPS_LIST", ZEND_AST_ENCAPS_LIST, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_EXPR_LIST", ZEND_AST_EXPR_LIST, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_STMT_LIST", ZEND_AST_STMT_LIST, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_IF", ZEND_AST_IF, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_SWITCH_LIST", ZEND_AST_SWITCH_LIST, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_CATCH_LIST", ZEND_AST_CATCH_LIST, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_PARAM_LIST", ZEND_AST_PARAM_LIST, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_CLOSURE_USES", ZEND_AST_CLOSURE_USES, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_PROP_DECL", ZEND_AST_PROP_DECL, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_CONST_DECL", ZEND_AST_CONST_DECL, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_CLASS_CONST_DECL", ZEND_AST_CLASS_CONST_DECL, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_NAME_LIST", ZEND_AST_NAME_LIST, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_TRAIT_ADAPTATIONS", ZEND_AST_TRAIT_ADAPTATIONS, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_USE", ZEND_AST_USE, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_TYPE_UNION", ZEND_AST_TYPE_UNION, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_TYPE_INTERSECTION", ZEND_AST_TYPE_INTERSECTION, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_ATTRIBUTE_LIST", ZEND_AST_ATTRIBUTE_LIST, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_ATTRIBUTE_GROUP", ZEND_AST_ATTRIBUTE_GROUP, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_MATCH_ARM_LIST", ZEND_AST_MATCH_ARM_LIST, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_NAME", AST_NAME, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_CLOSURE_VAR", AST_CLOSURE_VAR, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_NULLABLE_TYPE", AST_NULLABLE_TYPE, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_FUNC_DECL", ZEND_AST_FUNC_DECL, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_CLOSURE", ZEND_AST_CLOSURE, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_METHOD", ZEND_AST_METHOD, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_ARROW_FUNC", ZEND_AST_ARROW_FUNC, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_CLASS", ZEND_AST_CLASS, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_PROPERTY_HOOK", ZEND_AST_PROPERTY_HOOK, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_MAGIC_CONST", ZEND_AST_MAGIC_CONST, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_TYPE", ZEND_AST_TYPE, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_CALLABLE_CONVERT", ZEND_AST_CALLABLE_CONVERT, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_VAR", ZEND_AST_VAR, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_CONST", ZEND_AST_CONST, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_UNPACK", ZEND_AST_UNPACK, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_CAST", ZEND_AST_CAST, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_EMPTY", ZEND_AST_EMPTY, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_ISSET", ZEND_AST_ISSET, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_SHELL_EXEC", ZEND_AST_SHELL_EXEC, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_CLONE", ZEND_AST_CLONE, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_EXIT", ZEND_AST_EXIT, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_PRINT", ZEND_AST_PRINT, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_INCLUDE_OR_EVAL", ZEND_AST_INCLUDE_OR_EVAL, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_UNARY_OP", ZEND_AST_UNARY_OP, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_PRE_INC", ZEND_AST_PRE_INC, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_PRE_DEC", ZEND_AST_PRE_DEC, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_POST_INC", ZEND_AST_POST_INC, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_POST_DEC", ZEND_AST_POST_DEC, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_YIELD_FROM", ZEND_AST_YIELD_FROM, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_GLOBAL", ZEND_AST_GLOBAL, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_UNSET", ZEND_AST_UNSET, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_RETURN", ZEND_AST_RETURN, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_LABEL", ZEND_AST_LABEL, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_REF", ZEND_AST_REF, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_HALT_COMPILER", ZEND_AST_HALT_COMPILER, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_ECHO", ZEND_AST_ECHO, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_THROW", ZEND_AST_THROW, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_GOTO", ZEND_AST_GOTO, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_BREAK", ZEND_AST_BREAK, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_CONTINUE", ZEND_AST_CONTINUE, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_CLASS_NAME", ZEND_AST_CLASS_NAME, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_PROPERTY_HOOK_SHORT_BODY", ZEND_AST_PROPERTY_HOOK_SHORT_BODY, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_CLASS_CONST_GROUP", ZEND_AST_CLASS_CONST_GROUP, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_DIM", ZEND_AST_DIM, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_PROP", ZEND_AST_PROP, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_NULLSAFE_PROP", ZEND_AST_NULLSAFE_PROP, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_STATIC_PROP", ZEND_AST_STATIC_PROP, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_CALL", ZEND_AST_CALL, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_CLASS_CONST", ZEND_AST_CLASS_CONST, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_ASSIGN", ZEND_AST_ASSIGN, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_ASSIGN_REF", ZEND_AST_ASSIGN_REF, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_ASSIGN_OP", ZEND_AST_ASSIGN_OP, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_BINARY_OP", ZEND_AST_BINARY_OP, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_ARRAY_ELEM", ZEND_AST_ARRAY_ELEM, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_NEW", ZEND_AST_NEW, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_INSTANCEOF", ZEND_AST_INSTANCEOF, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_YIELD", ZEND_AST_YIELD, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_STATIC", ZEND_AST_STATIC, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_WHILE", ZEND_AST_WHILE, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_DO_WHILE", ZEND_AST_DO_WHILE, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_IF_ELEM", ZEND_AST_IF_ELEM, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_SWITCH", ZEND_AST_SWITCH, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_SWITCH_CASE", ZEND_AST_SWITCH_CASE, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_DECLARE", ZEND_AST_DECLARE, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_PROP_ELEM", ZEND_AST_PROP_ELEM, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_PROP_GROUP", ZEND_AST_PROP_GROUP, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_CONST_ELEM", ZEND_AST_CONST_ELEM, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_USE_TRAIT", ZEND_AST_USE_TRAIT, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_TRAIT_PRECEDENCE", ZEND_AST_TRAIT_PRECEDENCE, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_METHOD_REFERENCE", ZEND_AST_METHOD_REFERENCE, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_NAMESPACE", ZEND_AST_NAMESPACE, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_USE_ELEM", ZEND_AST_USE_ELEM, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_TRAIT_ALIAS", ZEND_AST_TRAIT_ALIAS, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_GROUP_USE", ZEND_AST_GROUP_USE, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_ATTRIBUTE", ZEND_AST_ATTRIBUTE, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_MATCH", ZEND_AST_MATCH, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_MATCH_ARM", ZEND_AST_MATCH_ARM, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_NAMED_ARG", ZEND_AST_NAMED_ARG, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_METHOD_CALL", ZEND_AST_METHOD_CALL, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_NULLSAFE_METHOD_CALL", ZEND_AST_NULLSAFE_METHOD_CALL, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_STATIC_CALL", ZEND_AST_STATIC_CALL, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_CONDITIONAL", ZEND_AST_CONDITIONAL, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_TRY", ZEND_AST_TRY, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_CATCH", ZEND_AST_CATCH, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_FOR", ZEND_AST_FOR, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_FOREACH", ZEND_AST_FOREACH, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_ENUM_CASE", ZEND_AST_ENUM_CASE, CONST_CS | CONST_PERSISTENT);
REGISTER_NS_LONG_CONSTANT("ast", "AST_PARAM", ZEND_AST_PARAM, CONST_CS | CONST_PERSISTENT);
}
ast-1.1.2/ast_arginfo.h 0000664 0001750 0001750 00000004535 14655731747 014115 0 ustar tyson tyson /* This is a generated file, edit the .stub.php file instead.
* Stub hash: bd6cdcf553c8e2d0fa06a42f9ff86e716544f817 */
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_ast_parse_code, 0, 2, ast\\Node, 0)
ZEND_ARG_TYPE_INFO(0, code, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, version, IS_LONG, 0)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, filename, IS_STRING, 0, "\'string code\'")
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_ast_parse_file, 0, 2, ast\\Node, 0)
ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, version, IS_LONG, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_ast_get_kind_name, 0, 1, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, kind, IS_LONG, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_ast_kind_uses_flags, 0, 1, _IS_BOOL, 0)
ZEND_ARG_TYPE_INFO(0, kind, IS_LONG, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_ast_get_metadata, 0, 0, IS_ARRAY, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_ast_get_supported_versions, 0, 0, IS_ARRAY, 0)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, exclude_deprecated, _IS_BOOL, 0, "false")
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ast_Node___construct, 0, 0, 0)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, kind, IS_LONG, 1, "null")
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 1, "null")
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, children, IS_ARRAY, 1, "null")
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, lineno, IS_LONG, 1, "null")
ZEND_END_ARG_INFO()
ZEND_FUNCTION(parse_code);
ZEND_FUNCTION(parse_file);
ZEND_FUNCTION(get_kind_name);
ZEND_FUNCTION(kind_uses_flags);
ZEND_FUNCTION(get_metadata);
ZEND_FUNCTION(get_supported_versions);
ZEND_METHOD(ast_Node, __construct);
static const zend_function_entry ext_functions[] = {
ZEND_NS_FE("ast", parse_code, arginfo_ast_parse_code)
ZEND_NS_FE("ast", parse_file, arginfo_ast_parse_file)
ZEND_NS_FE("ast", get_kind_name, arginfo_ast_get_kind_name)
ZEND_NS_FE("ast", kind_uses_flags, arginfo_ast_kind_uses_flags)
ZEND_NS_FE("ast", get_metadata, arginfo_ast_get_metadata)
ZEND_NS_FE("ast", get_supported_versions, arginfo_ast_get_supported_versions)
ZEND_FE_END
};
static const zend_function_entry class_ast_Node_methods[] = {
ZEND_ME(ast_Node, __construct, arginfo_class_ast_Node___construct, ZEND_ACC_PUBLIC)
ZEND_FE_END
};
ast-1.1.2/ast_str_defs.h 0000664 0001750 0001750 00000002326 14655731747 014275 0 ustar tyson tyson #ifndef AST_STR_DEFS_H
#define AST_STR_DEFS_H
#define AST_STR_DEFS \
X(kind, "kind") \
X(flags, "flags") \
X(lineno, "lineno") \
X(children, "children") \
X(name, "name") \
X(docComment, "docComment") \
X(endLineno, "endLineno") \
X(__declId, "__declId") \
X(flagsCombinable, "flagsCombinable") \
X(type, "type") \
X(params, "params") \
X(uses, "uses") \
X(stmts, "stmts") \
X(returnType, "returnType") \
X(attributes, "attributes") \
X(extends, "extends") \
X(implements, "implements") \
X(expr, "expr") \
X(var, "var") \
X(offset, "offset") \
X(label, "label") \
X(depth, "depth") \
X(class, "class") \
X(const, "const") \
X(dim, "dim") \
X(prop, "prop") \
X(args, "args") \
X(left, "left") \
X(right, "right") \
X(value, "value") \
X(key, "key") \
X(default, "default") \
X(cond, "cond") \
X(declares, "declares") \
X(hooks, "hooks") \
X(props, "props") \
X(traits, "traits") \
X(adaptations, "adaptations") \
X(method, "method") \
X(insteadof, "insteadof") \
X(alias, "alias") \
X(prefix, "prefix") \
X(true, "true") \
X(false, "false") \
X(try, "try") \
X(catches, "catches") \
X(finally, "finally") \
X(init, "init") \
X(loop, "loop") \
X(bracketed_closure, "{closure}") \
#endif
ast-1.1.2/ast_stub.php 0000664 0001750 0001750 00000021350 14655731747 013777 0 ustar tyson tyson
* @author Nikita Popov
*/
// AST KIND CONSTANTS
namespace ast;
const AST_ARG_LIST = 128;
const AST_LIST = 255;
const AST_ARRAY = 129;
const AST_ENCAPS_LIST = 130;
const AST_EXPR_LIST = 131;
const AST_STMT_LIST = 132;
const AST_IF = 133;
const AST_SWITCH_LIST = 134;
const AST_CATCH_LIST = 135;
const AST_PARAM_LIST = 136;
const AST_CLOSURE_USES = 137;
const AST_PROP_DECL = 138;
const AST_CONST_DECL = 139;
const AST_CLASS_CONST_DECL = 140;
const AST_NAME_LIST = 141;
const AST_TRAIT_ADAPTATIONS = 142;
const AST_USE = 143;
const AST_TYPE_UNION = 144;
const AST_TYPE_INTERSECTION = 145;
const AST_ATTRIBUTE_LIST = 146;
const AST_ATTRIBUTE_GROUP = 147;
const AST_MATCH_ARM_LIST = 148;
const AST_NAME = 2048;
const AST_CLOSURE_VAR = 2049;
const AST_NULLABLE_TYPE = 2050;
const AST_FUNC_DECL = 67;
const AST_CLOSURE = 68;
const AST_METHOD = 69;
const AST_ARROW_FUNC = 71;
const AST_CLASS = 70;
const AST_MAGIC_CONST = 0;
const AST_TYPE = 1;
const AST_CALLABLE_CONVERT = 3;
const AST_VAR = 256;
const AST_CONST = 257;
const AST_UNPACK = 258;
const AST_CAST = 261;
const AST_EMPTY = 262;
const AST_ISSET = 263;
const AST_SHELL_EXEC = 265;
const AST_CLONE = 266;
const AST_EXIT = 267;
const AST_PRINT = 268;
const AST_INCLUDE_OR_EVAL = 269;
const AST_UNARY_OP = 270;
const AST_PRE_INC = 271;
const AST_PRE_DEC = 272;
const AST_POST_INC = 273;
const AST_POST_DEC = 274;
const AST_YIELD_FROM = 275;
const AST_GLOBAL = 277;
const AST_UNSET = 278;
const AST_RETURN = 279;
const AST_LABEL = 280;
const AST_REF = 281;
const AST_HALT_COMPILER = 282;
const AST_ECHO = 283;
const AST_THROW = 284;
const AST_GOTO = 285;
const AST_BREAK = 286;
const AST_CONTINUE = 287;
const AST_CLASS_NAME = 276;
const AST_CLASS_CONST_GROUP = 777;
const AST_DIM = 512;
const AST_PROP = 513;
const AST_NULLSAFE_PROP = 514;
const AST_STATIC_PROP = 515;
const AST_CALL = 516;
const AST_CLASS_CONST = 517;
const AST_ASSIGN = 518;
const AST_ASSIGN_REF = 519;
const AST_ASSIGN_OP = 520;
const AST_BINARY_OP = 521;
const AST_ARRAY_ELEM = 526;
const AST_NEW = 527;
const AST_INSTANCEOF = 528;
const AST_YIELD = 529;
const AST_STATIC = 532;
const AST_WHILE = 533;
const AST_DO_WHILE = 534;
const AST_IF_ELEM = 535;
const AST_SWITCH = 536;
const AST_SWITCH_CASE = 537;
const AST_DECLARE = 538;
const AST_PROP_ELEM = 775;
const AST_PROP_GROUP = 774;
const AST_CONST_ELEM = 776;
const AST_USE_TRAIT = 539;
const AST_TRAIT_PRECEDENCE = 540;
const AST_METHOD_REFERENCE = 541;
const AST_NAMESPACE = 542;
const AST_USE_ELEM = 543;
const AST_TRAIT_ALIAS = 544;
const AST_GROUP_USE = 545;
const AST_ATTRIBUTE = 546;
const AST_MATCH = 547;
const AST_MATCH_ARM = 548;
const AST_NAMED_ARG = 549;
const AST_METHOD_CALL = 768;
const AST_NULLSAFE_METHOD_CALL = 769;
const AST_STATIC_CALL = 770;
const AST_CONDITIONAL = 771;
const AST_TRY = 772;
const AST_CATCH = 773;
const AST_FOR = 1024;
const AST_FOREACH = 1025;
const AST_ENUM_CASE = 1026;
const AST_PARAM = 1280;
// END AST KIND CONSTANTS
// AST FLAG CONSTANTS
namespace ast\flags;
const NAME_FQ = 0;
const NAME_NOT_FQ = 1;
const NAME_RELATIVE = 2;
const MODIFIER_PUBLIC = 1;
const MODIFIER_PROTECTED = 2;
const MODIFIER_PRIVATE = 4;
const MODIFIER_STATIC = 16;
const MODIFIER_ABSTRACT = 64;
const MODIFIER_FINAL = 32;
const MODIFIER_READONLY = 128;
const PARAM_MODIFIER_PUBLIC = 1;
const PARAM_MODIFIER_PROTECTED = 2;
const PARAM_MODIFIER_PRIVATE = 4;
const RETURNS_REF = 4096;
const FUNC_RETURNS_REF = 4096;
const FUNC_GENERATOR = 16777216;
const ARRAY_ELEM_REF = 1;
const CLOSURE_USE_REF = 1;
const CLASS_ABSTRACT = 64;
const CLASS_FINAL = 32;
const CLASS_TRAIT = 2;
const CLASS_INTERFACE = 1;
const CLASS_ANONYMOUS = 4;
const CLASS_ENUM = 268435456;
const CLASS_READONLY = 65536;
const PARAM_REF = 8;
const PARAM_VARIADIC = 16;
const TYPE_NULL = 1;
const TYPE_FALSE = 2;
const TYPE_TRUE = 3;
const TYPE_BOOL = 18;
const TYPE_LONG = 4;
const TYPE_DOUBLE = 5;
const TYPE_STRING = 6;
const TYPE_ARRAY = 7;
const TYPE_OBJECT = 8;
const TYPE_CALLABLE = 12;
const TYPE_VOID = 14;
const TYPE_ITERABLE = 13;
const TYPE_STATIC = 15;
const TYPE_MIXED = 16;
const TYPE_NEVER = 17;
const UNARY_BOOL_NOT = 14;
const UNARY_BITWISE_NOT = 13;
const UNARY_SILENCE = 260;
const UNARY_PLUS = 261;
const UNARY_MINUS = 262;
const BINARY_BOOL_AND = 259;
const BINARY_BOOL_OR = 258;
const BINARY_BOOL_XOR = 15;
const BINARY_BITWISE_OR = 9;
const BINARY_BITWISE_AND = 10;
const BINARY_BITWISE_XOR = 11;
const BINARY_CONCAT = 8;
const BINARY_ADD = 1;
const BINARY_SUB = 2;
const BINARY_MUL = 3;
const BINARY_DIV = 4;
const BINARY_MOD = 5;
const BINARY_POW = 12;
const BINARY_SHIFT_LEFT = 6;
const BINARY_SHIFT_RIGHT = 7;
const BINARY_IS_IDENTICAL = 16;
const BINARY_IS_NOT_IDENTICAL = 17;
const BINARY_IS_EQUAL = 18;
const BINARY_IS_NOT_EQUAL = 19;
const BINARY_IS_SMALLER = 20;
const BINARY_IS_SMALLER_OR_EQUAL = 21;
const BINARY_IS_GREATER = 256;
const BINARY_IS_GREATER_OR_EQUAL = 257;
const BINARY_SPACESHIP = 170;
const BINARY_COALESCE = 260;
const EXEC_EVAL = 1;
const EXEC_INCLUDE = 2;
const EXEC_INCLUDE_ONCE = 4;
const EXEC_REQUIRE = 8;
const EXEC_REQUIRE_ONCE = 16;
const USE_NORMAL = 1;
const USE_FUNCTION = 2;
const USE_CONST = 4;
const MAGIC_LINE = 379;
const MAGIC_FILE = 380;
const MAGIC_DIR = 381;
const MAGIC_NAMESPACE = 386;
const MAGIC_FUNCTION = 385;
const MAGIC_METHOD = 384;
const MAGIC_CLASS = 382;
const MAGIC_TRAIT = 383;
const ARRAY_SYNTAX_LIST = 1;
const ARRAY_SYNTAX_LONG = 2;
const ARRAY_SYNTAX_SHORT = 3;
const DIM_ALTERNATIVE_SYNTAX = 2;
const PARENTHESIZED_CONDITIONAL = 1;
const ENCAPS_VAR_DOLLAR_CURLY = 1;
const ENCAPS_VAR_DOLLAR_CURLY_VAR_VAR = 2;
// END AST FLAG CONSTANTS
namespace ast;
/**
* Parses code file and returns AST root node.
*
* @param string $filename Code file to parse
* @param int $version AST version
* @return Node Root node of AST
*
* @see https://github.com/nikic/php-ast for version information
*/
function parse_file(string $filename, int $version)
{
}
/**
* Parses code string and returns AST root node.
*
* @param string $code Code string to parse
* @param int $version AST version
* @param string $filename Optional filename for use in parse errors
* @return Node Root node of AST
*
* @see https://github.com/nikic/php-ast for version information
*/
function parse_code(string $code, int $version, string $filename = "string code")
{
}
/**
* @param int $kind AST_* constant value defining the kind of an AST node
* @return string String representation of AST kind value
*/
function get_kind_name(int $kind): string
{
}
/**
* @param int $kind AST_* constant value defining the kind of an AST node
* @return bool Returns true if AST kind uses flags
*/
function kind_uses_flags(int $kind): bool
{
}
/**
* Provides metadata for the AST kinds.
*
* The returned array is a map from AST kind to a Metadata object.
*
* @return Metadata[] Metadata about AST kinds
*/
function get_metadata(): array
{
}
/**
* Returns currently supported AST versions.
*
* @param bool $exclude_deprecated Whether to exclude deprecated versions
* @return int[] Array of supported AST versions
*/
function get_supported_versions($exclude_deprecated = false): array
{
}
// In php 8.2+, this class has the attribute AllowDynamicProperties
/**
* This class describes a single node in a PHP AST.
*/
#[AllowDynamicProperties]
class Node
{
/** @var int AST Node Kind. Values are one of ast\AST_* constants. */
public $kind;
/**
* @var int AST Flags.
* Certain node kinds have flags that can be set.
* These will be a bitfield of ast\flags\* constants.
*/
public $flags;
/** @var int Line the node starts in */
public $lineno;
/** @var array Child nodes (may be empty) */
public $children;
/**
* A constructor which validates data types but not the values themselves.
* For backwards compatibility reasons, all values are optional and properties default to null
*/
public function __construct(int $kind = null, int $flags = null, array $children = null, int $lineno = null) {
$this->kind = $kind;
$this->flags = $flags;
$this->children = $children;
$this->lineno = $lineno;
}
}
/**
* Metadata entry for a single AST kind, as returned by ast\get_metadata().
*/
class Metadata
{
/** @var int AST node kind (one of the ast\AST_* constants). */
public $kind;
/** @var string Name of the node kind (e.g. "AST_NAME"). */
public $name;
/**
* @var string[] Array of supported flags. The flags are given as names of constants, such as
* "ast\flags\TYPE_STRING".
*/
public $flags;
/**
* @var bool Whether the flags are exclusive or combinable. Exclusive flags should be checked
* using ===, while combinable flags should be checked using &. */
public $flagsCombinable;
}
ast-1.1.2/LICENSE 0000644 0001750 0001750 00000002723 14655731747 012450 0 ustar tyson tyson Copyright (c) 2014 by Nikita Popov.
Some rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* The names of the contributors may not be used to endorse or
promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
ast-1.1.2/php_ast.h 0000664 0001750 0001750 00000006354 14655731747 013260 0 ustar tyson tyson #ifndef PHP_AST_H
#define PHP_AST_H
#include "php.h"
#include "ast_str_defs.h"
extern zend_module_entry ast_module_entry;
#define phpext_ast_ptr &ast_module_entry
#define PHP_AST_VERSION "1.1.2"
#ifdef PHP_WIN32
# define PHP_AST_API __declspec(dllexport)
#elif defined(__GNUC__) && __GNUC__ >= 4
# define PHP_AST_API __attribute__ ((visibility("default")))
#else
# define PHP_AST_API
#endif
#ifdef ZTS
#include "TSRM.h"
#endif
ZEND_BEGIN_MODULE_GLOBALS(ast)
zval metadata;
ZEND_END_MODULE_GLOBALS(ast)
ZEND_EXTERN_MODULE_GLOBALS(ast)
#define AST_G(v) ZEND_MODULE_GLOBALS_ACCESSOR(ast, v)
typedef struct _ast_str_globals {
#define X(str, value) zend_string *str_ ## str;
AST_STR_DEFS
#undef X
} ast_str_globals;
extern ast_str_globals str_globals;
#define AST_STR(str) str_globals.str
/* Custom ast kind for names */
#define AST_NAME 2048
#define AST_CLOSURE_VAR 2049
#define AST_NULLABLE_TYPE 2050
// 544 is already taken by ZEND_AST_GROUP_USE
#if PHP_VERSION_ID < 70400
// NOTE: The first hex digit is the number of child nodes a given kind has
# define ZEND_AST_CLASS_NAME 0x1ff
# define ZEND_AST_PROP_GROUP 0x2ff
// ZEND_AST_ARROW_FUNC technically should have been in the ZEND_AST_SPECIAL_SHIFT group, but keeping this value for compatibility with older releases. (e.g. serialized ast Nodes)
# define ZEND_AST_ARROW_FUNC 0x5ff
#endif
#if PHP_VERSION_ID < 80000
/* NOTE: For list nodes, the first set bit is 0x80 */
# define ZEND_AST_TYPE_UNION ((1 << (ZEND_AST_IS_LIST_SHIFT + 1)) - 2)
# define ZEND_AST_ATTRIBUTE_LIST ((1 << (ZEND_AST_IS_LIST_SHIFT + 1)) - 3)
# define ZEND_AST_MATCH_ARM_LIST ((1 << (ZEND_AST_IS_LIST_SHIFT + 1)) - 4)
# define ZEND_AST_ATTRIBUTE_GROUP ((1 << (ZEND_AST_IS_LIST_SHIFT + 1)) - 5)
/* 2 child nodes */
# define ZEND_AST_CLASS_CONST_GROUP 0x2fe
# define ZEND_AST_ATTRIBUTE 0x2fd
# define ZEND_AST_MATCH 0x2fc
# define ZEND_AST_MATCH_ARM 0x2fb
# define ZEND_AST_NAMED_ARG 0x2fa
# define ZEND_AST_NULLSAFE_PROP 0x2f9
/* 3 child nodes */
# define ZEND_AST_NULLSAFE_METHOD_CALL 0x3ff
// NOTE: The first hex digit is the number of child nodes a given kind has
#endif
#if PHP_VERSION_ID < 80100
# define ZEND_ACC_ENUM (1 << 22)
# define ZEND_ACC_READONLY (1 << 7)
/* 0 child nodes */
# define ZEND_AST_CALLABLE_CONVERT 3
/* 3 child nodes - name, expr, attributes */
# define ZEND_AST_ENUM_CASE 0x3fe
# define ZEND_AST_TYPE_INTERSECTION ((1 << (ZEND_AST_IS_LIST_SHIFT + 1)) - 6)
#endif
#if PHP_VERSION_ID < 80200
# define ZEND_ACC_READONLY_CLASS (1 << 23)
#endif
#if PHP_VERSION_ID < 80400
# define ZEND_AST_PROPERTY_HOOK ((1 << (ZEND_AST_SPECIAL_SHIFT + 1)) - 1)
// NOTE: The first hex digit is the number of child nodes a given kind has
# define ZEND_AST_PROPERTY_HOOK_SHORT_BODY 0x1fe
# define ZEND_AST_PARENT_PROPERTY_HOOK_CALL 0x2f8
#endif
/* Pretend it still exists */
# define ZEND_AST_LIST ((1 << (ZEND_AST_IS_LIST_SHIFT + 1)) - 1)
extern const size_t ast_kinds_count;
extern const zend_ast_kind ast_kinds[];
const char *ast_kind_to_name(zend_ast_kind kind);
zend_string *ast_kind_child_name(zend_ast_kind kind, uint32_t child);
void ast_register_kind_constants(INIT_FUNC_ARGS);
#endif /* PHP_AST_H */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
ast-1.1.2/README.md 0000664 0001750 0001750 00000054302 14655731747 012724 0 ustar tyson tyson php-ast
=======
This extension exposes the abstract syntax tree generated by PHP 7 and 8.
**This is the documentation for version 1.x.y. See also [documentation for version 0.1.x][v0_1_x].**
Table of Contents
-----------------
* [Installation](#installation)
* [API overview](#api-overview)
* [Basic usage](#basic-usage)
* [Example](#example)
* [Metadata](#metadata)
* [Flags](#flags)
* [AST node kinds](#ast-node-kinds)
* [AST versioning](#ast-versioning)
* [Differences to PHP-Parser](#differences-to-php-parser)
Installation
------------
**Windows**: Download a [prebuilt Windows DLL](https://downloads.php.net/~windows/pecl/releases/ast/)
and move it into the `ext/` directory of your PHP installation. Furthermore, add
`extension=php_ast.dll` to your `php.ini` file.
(The [php-ast PECL page](https://downloads.php.net/~windows/pecl/releases/ast/) also links to the same DLLs for Windows.)
**Unix (PECL)**: Run `pecl install ast` and add `extension=ast.so` to your `php.ini`.
**Unix (Compile)**: Compile and install the extension as follows.
```sh
phpize
./configure
make
sudo make install
```
Additionally add `extension=ast.so` to your `php.ini` file.
API overview
------------
Defines:
* `ast\Node` class
* `ast\Metadata` class
* `ast\AST_*` kind constants
* `ast\flags\*` flag constants
* `ast\parse_file(string $filename, int $version)`
* `ast\parse_code(string $code, int $version [, string $filename = "string code"])`
* `ast\get_kind_name(int $kind)`
* `ast\kind_uses_flags(int $kind)`
* `ast\get_metadata()`
* `ast\get_supported_versions(bool $exclude_deprecated = false)`
Basic usage
-----------
Code can be parsed using either `ast\parse_code()`, which accepts a code string, or
`ast\parse_file()`, which accepts a file path. Additionally, both functions require a `$version`
argument to ensure forward-compatibility. The current version is 110.
```php
$ast = ast\parse_code('
int(132)
["flags"]=>
int(0)
["lineno"]=>
int(1)
["children"]=>
array(1) {
[0]=>
object(ast\Node)#2 (4) {
["kind"]=>
int(517)
["flags"]=>
int(0)
["lineno"]=>
int(2)
["children"]=>
array(2) {
["var"]=>
object(ast\Node)#3 (4) {
["kind"]=>
int(256)
["flags"]=>
int(0)
["lineno"]=>
int(2)
["children"]=>
array(1) {
["name"]=>
string(3) "var"
}
}
["expr"]=>
int(42)
}
}
}
}
```
The [`util.php`][util] file defines an `ast_dump()` function, which can be used to create a more
compact and human-readable dump of the AST structure:
```php
flags & ast\flags\FOO`. The
"exclusive" flags are used standalone and should be checked using `$ast->flags === ast\flags\BAR`.
```
// Used by ast\AST_NAME (exclusive)
ast\flags\NAME_FQ (= 0) // example: \Foo\Bar
ast\flags\NAME_NOT_FQ // example: Foo\Bar
ast\flags\NAME_RELATIVE // example: namespace\Foo\Bar
// Used by ast\AST_METHOD, ast\AST_PROP_DECL, ast\AST_PROP_GROUP,
// ast\AST_CLASS_CONST_DECL, ast\AST_CLASS_CONST_GROUP, and ast\AST_TRAIT_ALIAS (combinable)
ast\flags\MODIFIER_PUBLIC
ast\flags\MODIFIER_PROTECTED
ast\flags\MODIFIER_PRIVATE
ast\flags\MODIFIER_STATIC
ast\flags\MODIFIER_ABSTRACT
ast\flags\MODIFIER_FINAL
ast\flags\MODIFIER_READONLY
// Used by ast\AST_CLOSURE, ast\AST_ARROW_FUNC (combinable)
ast\flags\MODIFIER_STATIC
// Used by ast\AST_FUNC_DECL, ast\AST_METHOD, ast\AST_CLOSURE, ast\AST_ARROW_FUNC (combinable)
ast\flags\FUNC_RETURNS_REF // legacy alias: ast\flags\RETURNS_REF
ast\flags\FUNC_GENERATOR // used only in PHP >= 7.1
// Used by ast\AST_CLOSURE_VAR
ast\flags\CLOSURE_USE_REF
// Used by ast\AST_CLASS (combinable since PHP 8.1 enums)
ast\flags\CLASS_ABSTRACT
ast\flags\CLASS_FINAL
ast\flags\CLASS_TRAIT
ast\flags\CLASS_INTERFACE
ast\flags\CLASS_ANONYMOUS
ast\flags\CLASS_ENUM // php 8.1 enums
ast\flags\CLASS_READONLY // php 8.2 readonly classes
// Used by ast\AST_PARAM (combinable)
ast\flags\PARAM_REF
ast\flags\PARAM_VARIADIC
ast\flags\PARAM_MODIFIER_PUBLIC (available since 1.0.8, same as ast\flags\MODIFIER_* in PHP >= 8.0)
ast\flags\PARAM_MODIFIER_PROTECTED (available since 1.0.8)
ast\flags\PARAM_MODIFIER_PRIVATE (available since 1.0.8)
// Used by ast\AST_TYPE (exclusive)
ast\flags\TYPE_ARRAY
ast\flags\TYPE_CALLABLE
ast\flags\TYPE_VOID
ast\flags\TYPE_BOOL
ast\flags\TYPE_LONG
ast\flags\TYPE_DOUBLE
ast\flags\TYPE_STRING
ast\flags\TYPE_ITERABLE
ast\flags\TYPE_OBJECT
ast\flags\TYPE_NULL // php 8.0 union types
ast\flags\TYPE_FALSE // php 8.0 union types
ast\flags\TYPE_TRUE // php 8.2 true type
ast\flags\TYPE_STATIC // php 8.0 static return type
ast\flags\TYPE_MIXED // php 8.0 mixed type
ast\flags\TYPE_NEVER // php 8.1 never type
// Used by ast\AST_CAST (exclusive)
ast\flags\TYPE_NULL
ast\flags\TYPE_BOOL
ast\flags\TYPE_LONG
ast\flags\TYPE_DOUBLE
ast\flags\TYPE_STRING
ast\flags\TYPE_ARRAY
ast\flags\TYPE_OBJECT
// Used by ast\AST_UNARY_OP (exclusive)
ast\flags\UNARY_BOOL_NOT
ast\flags\UNARY_BITWISE_NOT
ast\flags\UNARY_MINUS
ast\flags\UNARY_PLUS
ast\flags\UNARY_SILENCE
// Used by ast\AST_BINARY_OP and ast\AST_ASSIGN_OP (exclusive)
ast\flags\BINARY_BITWISE_OR
ast\flags\BINARY_BITWISE_AND
ast\flags\BINARY_BITWISE_XOR
ast\flags\BINARY_CONCAT
ast\flags\BINARY_ADD
ast\flags\BINARY_SUB
ast\flags\BINARY_MUL
ast\flags\BINARY_DIV
ast\flags\BINARY_MOD
ast\flags\BINARY_POW
ast\flags\BINARY_SHIFT_LEFT
ast\flags\BINARY_SHIFT_RIGHT
ast\flags\BINARY_COALESCE
// Used by ast\AST_BINARY_OP (exclusive)
ast\flags\BINARY_BOOL_AND
ast\flags\BINARY_BOOL_OR
ast\flags\BINARY_BOOL_XOR
ast\flags\BINARY_IS_IDENTICAL
ast\flags\BINARY_IS_NOT_IDENTICAL
ast\flags\BINARY_IS_EQUAL
ast\flags\BINARY_IS_NOT_EQUAL
ast\flags\BINARY_IS_SMALLER
ast\flags\BINARY_IS_SMALLER_OR_EQUAL
ast\flags\BINARY_IS_GREATER
ast\flags\BINARY_IS_GREATER_OR_EQUAL
ast\flags\BINARY_SPACESHIP
// Used by ast\AST_MAGIC_CONST (exclusive)
ast\flags\MAGIC_LINE
ast\flags\MAGIC_FILE
ast\flags\MAGIC_DIR
ast\flags\MAGIC_NAMESPACE
ast\flags\MAGIC_FUNCTION
ast\flags\MAGIC_METHOD
ast\flags\MAGIC_CLASS
ast\flags\MAGIC_TRAIT
// Used by ast\AST_USE, ast\AST_GROUP_USE and ast\AST_USE_ELEM (exclusive)
ast\flags\USE_NORMAL
ast\flags\USE_FUNCTION
ast\flags\USE_CONST
// Used by ast\AST_INCLUDE_OR_EVAL (exclusive)
ast\flags\EXEC_EVAL
ast\flags\EXEC_INCLUDE
ast\flags\EXEC_INCLUDE_ONCE
ast\flags\EXEC_REQUIRE
ast\flags\EXEC_REQUIRE_ONCE
// Used by ast\AST_ARRAY (exclusive), since PHP 7.1
ast\flags\ARRAY_SYNTAX_SHORT
ast\flags\ARRAY_SYNTAX_LONG
ast\flags\ARRAY_SYNTAX_LIST
// Used by ast\AST_ARRAY_ELEM (exclusive)
ast\flags\ARRAY_ELEM_REF
// Used by ast\AST_DIM (combinable), since PHP 7.4
ast\flags\DIM_ALTERNATIVE_SYNTAX
ast\flags\ENCAPS_VAR_DOLLAR_CURLY // php 8.2 deprecation, only available in php 8.2+
// Used by ast\AST_VAR (combinable), since PHP 8.2
ast\flags\ENCAPS_VAR_DOLLAR_CURLY
ast\flags\ENCAPS_VAR_DOLLAR_CURLY_VAR_VAR
// Used by ast\AST_CONDITIONAL (combinable), since PHP 7.4
ast\flags\PARENTHESIZED_CONDITIONAL
```
AST node kinds
--------------
This section lists the AST node kinds that are supported and the names of their child nodes.
```
AST_ARRAY_ELEM: value, key
AST_ARROW_FUNC: name, docComment, params, stmts, returnType, attributes // name removed in version 110
AST_ASSIGN: var, expr
AST_ASSIGN_OP: var, expr
AST_ASSIGN_REF: var, expr
AST_ATTRIBUTE: class, args // php 8.0+ attributes (version 80+)
AST_BINARY_OP: left, right
AST_BREAK: depth
AST_CALL: expr, args
AST_CALLABLE_CONVERT: // php 8.1+ first-class callable syntax
AST_CAST: expr
AST_CATCH: class, var, stmts
AST_CLASS: name, docComment, extends, implements, stmts, (for enums) type
AST_CLASS_CONST: class, const
AST_CLASS_CONST_GROUP class, attributes, type // version 80+
AST_CLASS_NAME: class // version 70+
AST_CLONE: expr
AST_CLOSURE: name, docComment, params, uses, stmts, returnType, attributes // name removed in version 110
AST_CLOSURE_VAR: name
AST_CONDITIONAL: cond, true, false
AST_CONST: name
AST_CONST_ELEM: name, value, docComment
AST_CONTINUE: depth
AST_DECLARE: declares, stmts
AST_DIM: expr, dim
AST_DO_WHILE: stmts, cond
AST_ECHO: expr
AST_EMPTY: expr
AST_ENUM_CASE: name, expr, docComment, attributes // php 8.1+ enums
AST_EXIT: expr
AST_FOR: init, cond, loop, stmts
AST_FOREACH: expr, value, key, stmts
AST_FUNC_DECL: name, docComment, params, stmts, returnType, attributes
uses // prior to version 60
AST_GLOBAL: var
AST_GOTO: label
AST_GROUP_USE: prefix, uses
AST_HALT_COMPILER: offset
AST_IF_ELEM: cond, stmts
AST_INCLUDE_OR_EVAL: expr
AST_INSTANCEOF: expr, class
AST_ISSET: var
AST_LABEL: name
AST_MAGIC_CONST:
AST_MATCH: cond, stmts // php 8.0+ match
AST_MATCH_ARM: cond, expr // php 8.0+ match
AST_METHOD: name, docComment, params, stmts, returnType, attributes
uses // prior to version 60
AST_METHOD_CALL: expr, method, args
AST_METHOD_REFERENCE: class, method
AST_NAME: name
AST_NAMED_ARG: name, expr // php 8.0 named parameters
AST_NAMESPACE: name, stmts
AST_NEW: class, args
AST_NULLABLE_TYPE: type // Used only since PHP 7.1
AST_NULLSAFE_METHOD_CALL: expr, method, args // php 8.0 null safe operator
AST_NULLSAFE_PROP: expr, prop // php 8.0 null safe operator
AST_PARAM: type, name, default, attributes, docComment, hooks // 'hooks' field added in version 110
AST_POST_DEC: var
AST_POST_INC: var
AST_PRE_DEC: var
AST_PRE_INC: var
AST_PRINT: expr
AST_PROP: expr, prop
AST_PROP_ELEM: name, default, docComment, hooks // 'hooks' field added in version 110
AST_PROP_GROUP: type, props, attributes // version 70+
AST_PROPERTY_HOOK: name, docComment, params, stmts, attributes // version 110+
AST_PROPERTY_HOOK_SHORT_BODY: expr
AST_REF: var // only used in foreach ($a as &$v)
AST_RETURN: expr
AST_SHELL_EXEC: expr
AST_STATIC: var, default
AST_STATIC_CALL: class, method, args
AST_STATIC_PROP: class, prop
AST_SWITCH: cond, stmts
AST_SWITCH_CASE: cond, stmts
AST_THROW: expr
AST_TRAIT_ALIAS: method, alias
AST_TRAIT_PRECEDENCE: method, insteadof
AST_TRY: try, catches, finally
AST_TYPE:
AST_UNARY_OP: expr
AST_UNPACK: expr
AST_UNSET: var
AST_USE_ELEM: name, alias
AST_USE_TRAIT: traits, adaptations
AST_VAR: name
AST_WHILE: cond, stmts
AST_YIELD: value, key
AST_YIELD_FROM: expr
// List nodes (numerically indexed children):
AST_ARG_LIST
AST_ARRAY
AST_ATTRIBUTE_LIST // php 8.0+ attributes (version 80+)
AST_ATTRIBUTE_GROUP // php 8.0+ attributes (version 80+)
AST_CATCH_LIST
AST_CLASS_CONST_DECL
AST_CLOSURE_USES
AST_CONST_DECL
AST_ENCAPS_LIST // interpolated string: "foo$bar"
AST_EXPR_LIST
AST_IF
AST_LIST
AST_MATCH_ARM_LIST // php 8.0+ match
AST_NAME_LIST
AST_PARAM_LIST
AST_PROP_DECL
AST_STMT_LIST
AST_SWITCH_LIST
AST_TRAIT_ADAPTATIONS
AST_USE
AST_TYPE_UNION // php 8.0+ union types
AST_TYPE_INTERSECTION // php 8.1+ intersection types
```
AST Versioning
--------------
The `ast\parse_code()` and `ast\parse_file()` functions each accept a required AST `$version`
argument. The idea behind the AST version is that we may need to change the format of the AST to
account for new features in newer PHP versions, or to improve it in other ways. Such changes will
always be made under a new AST version, while previous formats continue to be supported for some
time.
Old AST versions may be deprecated in minor versions and removed in major versions of the AST extension.
A list of currently supported versions is available through `ast\get_supported_versions()`. The
function accepts a boolean argument that determines whether deprecated versions should be excluded.
In the following the changes in the respective AST versions, as well as their current support state,
are listed.
### 110 (current)
Supported since 1.1.2 (2024-08-10).
* Add a `hooks` child node for `AST_PROP_ELEM` (PHP 8.4 property hooks) and `AST_PARAM` (constructor property promotion can have property hooks)
* Add new node kinds `AST_PROPERTY_HOOK` and `AST_PROPERTY_HOOK_SHORT_BODY`.
* Remove the `name` child node from the `AST_ARROW_FUNC` and `AST_CLOSURE` nodes (previously `"{closure}"`)
### 100 (stable)
Supported since 1.1.1 (2023-11-12).
* Add a `type` child node for all `AST_CLASS_CONST_GROUP` nodes.
### 90 (stable)
Supported since 1.0.14 (2021-07-24)
* Same as AST version 85.
### 85 (stable)
Supported since 1.0.11 (2021-04-20)
* Add a `type` child node (for enum type) for all `AST_CLASS` nodes.
### 80 (stable)
Supported since 1.0.10 (2020-09-12).
* `mixed` type hints are now reported as an `AST_TYPE` with type `TYPE_MIXED` instead of an `AST_NAME`.
* `AST_CLASS_CONST_GROUP` nodes are emitted for class constant declarations wrapping the `AST_CLASS_CONST_DECL` and any attributes.
Previously, `AST_CLASS_CONST_DECL` would be emitted.
* `AST_PARAM`, `AST_CLASS_DECL`, `AST_METHOD`, `AST_PROP_DECL`, `AST_CLOSURE`, `AST_FUNC_DECL`, and `AST_ARROW_FUNC` nodes
now contain an attributes child.
### 70 (stable)
Supported since 1.0.1 (2019-02-11).
* `AST_PROP_GROUP` was added to support PHP 7.4's typed properties.
The property visibility modifiers are now part of `AST_PROP_GROUP` instead of `AST_PROP_DECL`.
Note that property group type information is only available with AST versions 70+.
* `AST_CLASS_NAME` is created instead of `AST_CLASS_CONST` for `SomeClass::class`.
### 60 (deprecated)
Supported since 0.1.7 (2018-10-06).
Deprecated in php-ast 1.1.0.
* `AST_FUNC_DECL` and `AST_METHOD` no longer generate a `uses` child. Previously this child was
always `null`.
* `AST_CONST_ELEM` now always has a `docComment` child. Previously it was absent on PHP 7.0.
On PHP 7.0 the value is always `null`.
### 50 (deprecated)
Supported since 0.1.5 (2017-07-19).
Deprecated in php-ast 1.1.0.
This is the oldest AST version available in 1.0.0. See the
[0.1.x AST version changelog][v0_1_x_versions] for information on changes prior to this version.
Differences to PHP-Parser
-------------------------
Next to php-ast I also maintain the [PHP-Parser][php-parser] library, which has some overlap with
this extension. This section summarizes the main differences between php-ast and PHP-Parser so you
may decide which is preferable for your use-case.
The primary difference is that php-ast is a PHP extension (written in C) which exports the AST
internally used by PHP 7 and 8. PHP-Parser on the other hand is library written in PHP. This has a number
of consequences:
* php-ast is significantly faster than PHP-Parser, because the AST construction is implemented in
C.
* php-ast needs to be installed as an extension, on Linux either by compiling it manually or
retrieving it from a package manager, on Windows by loading a DLL. PHP-Parser is installed as a
Composer dependency.
* php-ast only runs on PHP >= 7.0 (php-ast 1.0.16 was the last version supporting php <= 7.1), as prior versions did not use an internal AST. PHP-Parser
supports PHP >= 5.5.
* php-ast may only parse code that is syntactically valid on the version of PHP it runs on. This
means that it's not possible to parse code using features of newer versions (e.g. PHP 7.4 code
while running on PHP 7.2). Similarly, it is not possible to parse code that is no longer
syntactically valid on the used version (e.g. some PHP 5 code may no longer be parsed -- however
most code will work). PHP-Parser supports parsing both newer and older (up to PHP 5.2) versions.
* php-ast can only parse code which is syntactically valid, while PHP-Parser can provide a partial
AST for code that contains errors (e.g., because it is currently being edited).
* php-ast only provides the starting line number (and for declarations the ending line number) of
nodes, because this is the only part that PHP itself stores. PHP-Parser provides precise file
offsets.
There are a number of differences in the AST representation and available support code:
* The PHP-Parser library uses a separate class for every node type, with child nodes stored as
type-annotated properties. php-ast uses one class for everything, with children stored as
arrays. The former approach is friendlier to developers because it has very good IDE integration.
The php-ast extension does not use separate classes, because registering hundreds of classes was
judged a no-go for a bundled extension.
* The PHP-Parser library contains various support code for working with the AST, while php-ast only
handles AST construction. The reason for this is that implementing this support code in C is
extremely complicated and there is little other benefit to implementing it in C. The main
components that PHP-Parser offers that may be of interest are:
* Node dumper (human readable representation): While the php-ast extension does not directly
implement this, a `ast_dump` function is provided in the `util.php` file.
* Pretty printer (converting the AST back to PHP code): This is not provided natively, but the
[php-ast-reverter][php-ast-reverter] package implements this functionality.
* Name resolution (resolving namespace prefixes and aliases): There is currently no standalone
package for this.
* AST traversal / visitation: There is currently no standalone package for this either, but
implementing a recursive AST walk is easy.
The [tolerant-php-parser-to-php-ast][tolerant-php-parser-to-php-ast] project can convert the AST produced by
[tolerant-php-parser][tolerant-php-parser] (Another pure PHP parser library) into the format used by the php-ast extension.
This can be used as a slow fallback in
case the php-ast extension is not available. It may also be used to produce a partial php-ast output
for code with syntax errors.
[parser]: http://lxr.php.net/xref/PHP_TRUNK/Zend/zend_language_parser.y
[util]: https://github.com/nikic/php-ast/blob/master/util.php
[test_dump]: https://github.com/nikic/php-ast/blob/master/tests/001.phpt
[php-parser]: https://github.com/nikic/PHP-Parser
[php-ast-reverter]: https://github.com/tpunt/php-ast-reverter
[tolerant-php-parser]: https://github.com/Microsoft/tolerant-php-parser
[tolerant-php-parser-to-php-ast]: https://github.com/tysonandre/tolerant-php-parser-to-php-ast
[v0_1_x]: https://github.com/nikic/php-ast/tree/v0.1.x#php-ast
[v0_1_x_versions]: https://github.com/nikic/php-ast/tree/v0.1.x#ast-versioning
ast-1.1.2/php_ast.h 0000664 0001750 0001750 00000006354 14655731747 013260 0 ustar tyson tyson #ifndef PHP_AST_H
#define PHP_AST_H
#include "php.h"
#include "ast_str_defs.h"
extern zend_module_entry ast_module_entry;
#define phpext_ast_ptr &ast_module_entry
#define PHP_AST_VERSION "1.1.2"
#ifdef PHP_WIN32
# define PHP_AST_API __declspec(dllexport)
#elif defined(__GNUC__) && __GNUC__ >= 4
# define PHP_AST_API __attribute__ ((visibility("default")))
#else
# define PHP_AST_API
#endif
#ifdef ZTS
#include "TSRM.h"
#endif
ZEND_BEGIN_MODULE_GLOBALS(ast)
zval metadata;
ZEND_END_MODULE_GLOBALS(ast)
ZEND_EXTERN_MODULE_GLOBALS(ast)
#define AST_G(v) ZEND_MODULE_GLOBALS_ACCESSOR(ast, v)
typedef struct _ast_str_globals {
#define X(str, value) zend_string *str_ ## str;
AST_STR_DEFS
#undef X
} ast_str_globals;
extern ast_str_globals str_globals;
#define AST_STR(str) str_globals.str
/* Custom ast kind for names */
#define AST_NAME 2048
#define AST_CLOSURE_VAR 2049
#define AST_NULLABLE_TYPE 2050
// 544 is already taken by ZEND_AST_GROUP_USE
#if PHP_VERSION_ID < 70400
// NOTE: The first hex digit is the number of child nodes a given kind has
# define ZEND_AST_CLASS_NAME 0x1ff
# define ZEND_AST_PROP_GROUP 0x2ff
// ZEND_AST_ARROW_FUNC technically should have been in the ZEND_AST_SPECIAL_SHIFT group, but keeping this value for compatibility with older releases. (e.g. serialized ast Nodes)
# define ZEND_AST_ARROW_FUNC 0x5ff
#endif
#if PHP_VERSION_ID < 80000
/* NOTE: For list nodes, the first set bit is 0x80 */
# define ZEND_AST_TYPE_UNION ((1 << (ZEND_AST_IS_LIST_SHIFT + 1)) - 2)
# define ZEND_AST_ATTRIBUTE_LIST ((1 << (ZEND_AST_IS_LIST_SHIFT + 1)) - 3)
# define ZEND_AST_MATCH_ARM_LIST ((1 << (ZEND_AST_IS_LIST_SHIFT + 1)) - 4)
# define ZEND_AST_ATTRIBUTE_GROUP ((1 << (ZEND_AST_IS_LIST_SHIFT + 1)) - 5)
/* 2 child nodes */
# define ZEND_AST_CLASS_CONST_GROUP 0x2fe
# define ZEND_AST_ATTRIBUTE 0x2fd
# define ZEND_AST_MATCH 0x2fc
# define ZEND_AST_MATCH_ARM 0x2fb
# define ZEND_AST_NAMED_ARG 0x2fa
# define ZEND_AST_NULLSAFE_PROP 0x2f9
/* 3 child nodes */
# define ZEND_AST_NULLSAFE_METHOD_CALL 0x3ff
// NOTE: The first hex digit is the number of child nodes a given kind has
#endif
#if PHP_VERSION_ID < 80100
# define ZEND_ACC_ENUM (1 << 22)
# define ZEND_ACC_READONLY (1 << 7)
/* 0 child nodes */
# define ZEND_AST_CALLABLE_CONVERT 3
/* 3 child nodes - name, expr, attributes */
# define ZEND_AST_ENUM_CASE 0x3fe
# define ZEND_AST_TYPE_INTERSECTION ((1 << (ZEND_AST_IS_LIST_SHIFT + 1)) - 6)
#endif
#if PHP_VERSION_ID < 80200
# define ZEND_ACC_READONLY_CLASS (1 << 23)
#endif
#if PHP_VERSION_ID < 80400
# define ZEND_AST_PROPERTY_HOOK ((1 << (ZEND_AST_SPECIAL_SHIFT + 1)) - 1)
// NOTE: The first hex digit is the number of child nodes a given kind has
# define ZEND_AST_PROPERTY_HOOK_SHORT_BODY 0x1fe
# define ZEND_AST_PARENT_PROPERTY_HOOK_CALL 0x2f8
#endif
/* Pretend it still exists */
# define ZEND_AST_LIST ((1 << (ZEND_AST_IS_LIST_SHIFT + 1)) - 1)
extern const size_t ast_kinds_count;
extern const zend_ast_kind ast_kinds[];
const char *ast_kind_to_name(zend_ast_kind kind);
zend_string *ast_kind_child_name(zend_ast_kind kind, uint32_t child);
void ast_register_kind_constants(INIT_FUNC_ARGS);
#endif /* PHP_AST_H */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/