Skip to content

Commit c6c5c98

Browse files
committed
Support for PHP 8.4 Asymetric Visiblity
1 parent 6419de2 commit c6c5c98

File tree

7 files changed

+239
-2
lines changed

7 files changed

+239
-2
lines changed

src/Node/Parameter.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ class Parameter extends Node {
1515
public $attributes;
1616
/** @var Token|null */
1717
public $visibilityToken;
18+
/** @var Token|null */
19+
public $setVisibilityToken;
1820
/** @var Token[]|null */
1921
public $modifiers;
2022
/** @var Token|null */
@@ -37,6 +39,7 @@ class Parameter extends Node {
3739
const CHILD_NAMES = [
3840
'attributes',
3941
'visibilityToken',
42+
'setVisibilityToken',
4043
'modifiers',
4144
'questionToken',
4245
'typeDeclarationList',

src/Parser.php

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -643,7 +643,6 @@ private function parseClassElementFn() {
643643
$modifiers = $this->parseModifiers();
644644

645645
$token = $this->getCurrentToken();
646-
//dump(Token::getTokenKindNameFromValue($token->kind));
647646

648647
switch ($token->kind) {
649648
case TokenKind::ConstKeyword:
@@ -854,7 +853,15 @@ private function parseParameterFn() {
854853
// Note that parameter modifiers are allowed to be repeated by the parser in php 8.1 (it is a compiler error)
855854
//
856855
// TODO: Remove the visibilityToken in a future backwards incompatible release
857-
$parameter->visibilityToken = $this->eatOptional([TokenKind::PublicKeyword, TokenKind::ProtectedKeyword, TokenKind::PrivateKeyword]);
856+
$parameter->visibilityToken = $this->eatOptional([
857+
TokenKind::PublicKeyword,
858+
TokenKind::ProtectedKeyword,
859+
TokenKind::PrivateKeyword,
860+
]);
861+
$parameter->setVisibilityToken = $this->eatOptional([
862+
TokenKind::ProtectedSetKeyword,
863+
TokenKind::PrivateSetKeyword,
864+
]);
858865
$parameter->modifiers = $this->parseParameterModifiers() ?: null;
859866

860867
$parameter->questionToken = $this->eatOptional1(TokenKind::QuestionToken);

src/PhpTokenizer.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,8 @@ protected static function tokenGetAll(string $content, $parseContext): array
289289
T_LOGICAL_OR => TokenKind::OrKeyword,
290290
T_PRINT => TokenKind::PrintKeyword,
291291
T_PRIVATE => TokenKind::PrivateKeyword,
292+
T_PRIVATE_SET => TokenKind::PrivateSetKeyword,
293+
T_PROTECTED_SET => TokenKind::ProtectedSetKeyword,
292294
T_PROTECTED => TokenKind::ProtectedKeyword,
293295
T_PUBLIC => TokenKind::PublicKeyword,
294296
T_READONLY => TokenKind::ReadonlyKeyword,

src/TokenKind.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ class TokenKind {
9292
const EnumKeyword = 171;
9393
const ReadonlyKeyword = 172;
9494
const HaltCompilerKeyword = 173;
95+
const PrivateSetKeyword = 174;
96+
const ProtectedSetKeyword = 175;
9597

9698
const OpenBracketToken = 201;
9799
const CloseBracketToken = 202;
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
class Book
4+
{
5+
public function __construct(
6+
public private(set) string $title,
7+
public protected(set) string $author,
8+
public string $bar,
9+
) {}
10+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[]
Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
{
2+
"SourceFileNode": {
3+
"statementList": [
4+
{
5+
"InlineHtml": {
6+
"scriptSectionEndTag": null,
7+
"text": null,
8+
"scriptSectionStartTag": {
9+
"kind": "ScriptSectionStartTag",
10+
"textLength": 6
11+
}
12+
}
13+
},
14+
{
15+
"ClassDeclaration": {
16+
"attributes": null,
17+
"abstractOrFinalModifier": null,
18+
"modifiers": [],
19+
"classKeyword": {
20+
"kind": "ClassKeyword",
21+
"textLength": 5
22+
},
23+
"name": {
24+
"kind": "Name",
25+
"textLength": 4
26+
},
27+
"classBaseClause": null,
28+
"classInterfaceClause": null,
29+
"classMembers": {
30+
"ClassMembersNode": {
31+
"openBrace": {
32+
"kind": "OpenBraceToken",
33+
"textLength": 1
34+
},
35+
"classMemberDeclarations": [
36+
{
37+
"MethodDeclaration": {
38+
"attributes": null,
39+
"modifiers": [
40+
{
41+
"kind": "PublicKeyword",
42+
"textLength": 6
43+
}
44+
],
45+
"functionKeyword": {
46+
"kind": "FunctionKeyword",
47+
"textLength": 8
48+
},
49+
"byRefToken": null,
50+
"name": {
51+
"kind": "Name",
52+
"textLength": 11
53+
},
54+
"openParen": {
55+
"kind": "OpenParenToken",
56+
"textLength": 1
57+
},
58+
"parameters": {
59+
"ParameterDeclarationList": {
60+
"children": [
61+
{
62+
"Parameter": {
63+
"attributes": null,
64+
"visibilityToken": {
65+
"kind": "PublicKeyword",
66+
"textLength": 6
67+
},
68+
"setVisibilityToken": {
69+
"kind": "PrivateSetKeyword",
70+
"textLength": 12
71+
},
72+
"modifiers": null,
73+
"questionToken": null,
74+
"typeDeclarationList": {
75+
"QualifiedNameList": {
76+
"children": [
77+
{
78+
"kind": "StringReservedWord",
79+
"textLength": 6
80+
}
81+
]
82+
}
83+
},
84+
"byRefToken": null,
85+
"dotDotDotToken": null,
86+
"variableName": {
87+
"kind": "VariableName",
88+
"textLength": 6
89+
},
90+
"equalsToken": null,
91+
"default": null,
92+
"propertyHooks": null
93+
}
94+
},
95+
{
96+
"kind": "CommaToken",
97+
"textLength": 1
98+
},
99+
{
100+
"Parameter": {
101+
"attributes": null,
102+
"visibilityToken": {
103+
"kind": "PublicKeyword",
104+
"textLength": 6
105+
},
106+
"setVisibilityToken": {
107+
"kind": "ProtectedSetKeyword",
108+
"textLength": 14
109+
},
110+
"modifiers": null,
111+
"questionToken": null,
112+
"typeDeclarationList": {
113+
"QualifiedNameList": {
114+
"children": [
115+
{
116+
"kind": "StringReservedWord",
117+
"textLength": 6
118+
}
119+
]
120+
}
121+
},
122+
"byRefToken": null,
123+
"dotDotDotToken": null,
124+
"variableName": {
125+
"kind": "VariableName",
126+
"textLength": 7
127+
},
128+
"equalsToken": null,
129+
"default": null,
130+
"propertyHooks": null
131+
}
132+
},
133+
{
134+
"kind": "CommaToken",
135+
"textLength": 1
136+
},
137+
{
138+
"Parameter": {
139+
"attributes": null,
140+
"visibilityToken": {
141+
"kind": "PublicKeyword",
142+
"textLength": 6
143+
},
144+
"setVisibilityToken": null,
145+
"modifiers": null,
146+
"questionToken": null,
147+
"typeDeclarationList": {
148+
"QualifiedNameList": {
149+
"children": [
150+
{
151+
"kind": "StringReservedWord",
152+
"textLength": 6
153+
}
154+
]
155+
}
156+
},
157+
"byRefToken": null,
158+
"dotDotDotToken": null,
159+
"variableName": {
160+
"kind": "VariableName",
161+
"textLength": 4
162+
},
163+
"equalsToken": null,
164+
"default": null,
165+
"propertyHooks": null
166+
}
167+
},
168+
{
169+
"kind": "CommaToken",
170+
"textLength": 1
171+
}
172+
]
173+
}
174+
},
175+
"closeParen": {
176+
"kind": "CloseParenToken",
177+
"textLength": 1
178+
},
179+
"colonToken": null,
180+
"questionToken": null,
181+
"returnTypeList": null,
182+
"compoundStatementOrSemicolon": {
183+
"CompoundStatementNode": {
184+
"openBrace": {
185+
"kind": "OpenBraceToken",
186+
"textLength": 1
187+
},
188+
"statements": [],
189+
"closeBrace": {
190+
"kind": "CloseBraceToken",
191+
"textLength": 1
192+
}
193+
}
194+
}
195+
}
196+
}
197+
],
198+
"closeBrace": {
199+
"kind": "CloseBraceToken",
200+
"textLength": 1
201+
}
202+
}
203+
}
204+
}
205+
}
206+
],
207+
"endOfFileToken": {
208+
"kind": "EndOfFileToken",
209+
"textLength": 0
210+
}
211+
}
212+
}

0 commit comments

Comments
 (0)