summaryrefslogtreecommitdiffstats
path: root/php86.patch
blob: 99bf7677f651d5091eaf9d804d7dccd4cd2d5ebc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
From 64ea7276bcd9cf8e503b719aafbec4d802c9eacc Mon Sep 17 00:00:00 2001
From: Rasmus Lerdorf <rasmus@lerdorf.com>
Date: Sat, 27 Jun 2026 15:34:01 -0400
Subject: [PATCH] Support PHP 8.6 (#259)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

# Support PHP 8.6

Add compatibility shims in php_ast.h for the internal Zend API changes
in PHP 8.6:

- `ZEND_AST_METHOD_REFERENCE` was renamed to
`ZEND_AST_TRAIT_METHOD_REFERENCE`
- The `_throw()` ZPP variants were removed; plain ZPP now always throws,
so `zend_parse_parameters_throw` maps to `zend_parse_parameters` and the
removed `ZEND_PARSE_PARAMS_THROW` flag is defined to `0` (the throwing
default).

All guarded on `PHP_VERSION_ID >= 80600`, so older versions are
unaffected and the userland `ast\AST_METHOD_REFERENCE` constant is
unchanged.

## New 8.6 feature: doc comments on parameters

Of the implemented PHP 8.6 RFCs, only [Add DocComments for function
parameters](https://wiki.php.net/rfc/parameter-doccomments) is a parser
change that affects the AST; the rest are library functions, new
built-in enums, and reflection/runtime/ini/stream changes that don't
touch the parse tree.

`AST_PARAM` already has a `docComment` child (index 4), which was always
`null` before 8.6. It is now populated by the parser for parameters
carrying a doc comment, with no extension changes required. The output
matches the engine's own `ReflectionParameter::getDocComment()`
(including the before-vs-after-parameter comment behavior), and older
AST versions are unaffected.

`tests/php86_param_doc_comments.phpt` is added as a version-gated
regression test (skips on PHP < 8.6), covering doc comments on both
function parameters and property-hook parameters.

## CI

There is no published `php:8.6` docker image yet, so 8.6 could not be
added to the previous docker-based test matrix. CI now uses
`shivammathur/setup-php` for all PHP versions (7.2–8.6) in a single
matrix, replacing the docker-based setup. 8.6 is built from php-src
master and marked `continue-on-error` since it is still in development
and is a moving target. The `package.xml` validation previously run in
`ci/test_inner.sh` is preserved as a `pecl package` step, and the
now-unused `ci/` docker scripts are removed.

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
---
 .github/workflows/main.yml          |  36 ++++++----
 ci/Dockerfile                       |  13 ----
 ci/test_dockerized.sh               |  16 -----
 ci/test_inner.sh                    |   9 ---
 php_ast.h                           |   9 +++
 tests/php86_param_doc_comments.phpt | 105 ++++++++++++++++++++++++++++
 6 files changed, 135 insertions(+), 53 deletions(-)
 delete mode 100644 ci/Dockerfile
 delete mode 100755 ci/test_dockerized.sh
 delete mode 100755 ci/test_inner.sh
 create mode 100644 tests/php86_param_doc_comments.phpt

diff --git a/php_ast.h b/php_ast.h
index efecc21..06756ed 100644
--- a/php_ast.h
+++ b/php_ast.h
@@ -99,6 +99,15 @@ extern ast_str_globals str_globals;
 # define ZEND_AST_CLONE 0x1fc
 #endif
 
+#if PHP_VERSION_ID >= 80600
+/* ZEND_AST_METHOD_REFERENCE was renamed to ZEND_AST_TRAIT_METHOD_REFERENCE. */
+# define ZEND_AST_METHOD_REFERENCE ZEND_AST_TRAIT_METHOD_REFERENCE
+/* The _throw() ZPP variants were removed; plain ZPP now always throws.
+ * ZEND_PARSE_PARAMS_THROW is gone, so a flag of 0 yields the throwing default. */
+# define ZEND_PARSE_PARAMS_THROW 0
+# define zend_parse_parameters_throw zend_parse_parameters
+#endif
+
 /* Pretend it still exists */
 # define ZEND_AST_LIST ((1 << (ZEND_AST_IS_LIST_SHIFT + 1)) - 1)
 
diff --git a/tests/php86_param_doc_comments.phpt b/tests/php86_param_doc_comments.phpt
new file mode 100644
index 0000000..ae11fd1
--- /dev/null
+++ b/tests/php86_param_doc_comments.phpt
@@ -0,0 +1,105 @@
+--TEST--
+Doc comments on function/method parameters (PHP 8.6+)
+--SKIPIF--
+<?php if (PHP_VERSION_ID < 80600) die('skip PHP >=8.6 only'); ?>
+--FILE--
+<?php
+
+require __DIR__ . '/../util.php';
+
+$code = <<<'PHP'
+<?php
+function f(
+    /** doc for $a */
+    int $a,
+    $b,
+    /** doc for $c */
+    string $c = "x",
+) {}
+
+class C {
+    public string $p {
+        set(
+            /** doc for $value */
+            string $value
+        ) { $this->p = $value; }
+    }
+}
+PHP;
+
+echo ast_dump(ast\parse_code($code, $version=120)), "\n";
+--EXPECT--
+AST_STMT_LIST
+    0: AST_FUNC_DECL
+        name: "f"
+        docComment: null
+        params: AST_PARAM_LIST
+            0: AST_PARAM
+                type: AST_TYPE
+                    flags: TYPE_LONG (4)
+                name: "a"
+                default: null
+                attributes: null
+                docComment: "/** doc for $a */"
+                hooks: null
+            1: AST_PARAM
+                type: null
+                name: "b"
+                default: null
+                attributes: null
+                docComment: null
+                hooks: null
+            2: AST_PARAM
+                type: AST_TYPE
+                    flags: TYPE_STRING (6)
+                name: "c"
+                default: "x"
+                attributes: null
+                docComment: "/** doc for $c */"
+                hooks: null
+        stmts: AST_STMT_LIST
+        returnType: null
+        attributes: null
+        __declId: 0
+    1: AST_CLASS
+        name: "C"
+        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: "p"
+                        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: "value"
+                                        default: null
+                                        attributes: null
+                                        docComment: "/** doc for $value */"
+                                        hooks: null
+                                stmts: AST_STMT_LIST
+                                    0: AST_ASSIGN
+                                        var: AST_PROP
+                                            expr: AST_VAR
+                                                name: "this"
+                                            prop: "p"
+                                        expr: AST_VAR
+                                            name: "value"
+                                attributes: null
+                                __declId: 1
+                attributes: null
+        attributes: null
+        type: null
+        __declId: 2