-
-
Notifications
You must be signed in to change notification settings - Fork 73
PHP 8.4 | Add tokenization of asymmetric visibility #871
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
PHP 8.4 | Add tokenization of asymmetric visibility #871
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@DanielEScherzer Awesome work on this !
I have left a few comments and questions in-line, but generally speaking, this is looking great!
One additional question: how did you determine where in the (huge) PHP::tokenize()
method, the polyfill should go ?
It is currently between the tokenization blocks for T_ENUM_CASE
and PHP 8.0 namespaced names handling.
Is there a particular reason for that ?
T_PRIVATE_SET => T_PRIVATE_SET, | ||
T_PROTECTED => T_PROTECTED, | ||
T_PROTECTED_SET => T_PROTECTED_SET, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure this is correct... Should these "keywords" ever be changed into T_STRING
depending on their context.... ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure, but it looked like all of the other keywords were there, so I added them - should I remove?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Except, while these are tokens, these are not keywords.
This list is primarily for use with the PHP
Tokenizer correction of context sensitive keyword tokenization. What that means is as follows:
class Foreach {
function exit() {}
}
Foreach
and exit
in the above code sample should be (re-)tokenized to T_STRING
and should not be tokenized as T_FOREACH
or T_EXIT
(which is the PHP native tokenization in parse-error tolerant mode).
As the T_*_SET
tokens are combined tokens, they cannot be used in those places anyway - class Private(set)
would be a parse error -, so they are irrelevant for the context sensitive keyword list. Same as the cast tokens are not part of this list.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But when I remove the tokens from here, the ContextSensitiveKeywordsTest.php starts failing saying that things were T_STRING rather than the correct T_*_SET tokens
No idea, sorry |
@jrfnl my understanding is that this is waiting for re-review, just want to check that you aren't waiting for me to do something and have us both just wait |
Sorry, yes, been busy with some other things. Let me have a look now. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@DanielEScherzer Thanks for the updates you've made.
While looking at this PR again - and in particularly, looking at the changes made to the predefined Tokens::$*
properties, I realized more changes are needed. In particular related to the correct handling by the tokenizer of |
, &
and parenthesis in union, intersection and DNF types. See #907 as a loosely related example.
And while with the current changes, I believe the tokenization of ?
in nullable types in combination with asym visibility will be handled correctly, this will need to be safeguarded by tests. See #908 for another loosely related example.
I've also looked at the tests again.
I would prefer for the "valid" asym visibility tests and the "invalid" tests to be split into two test methods.
I believe the testAsymmetricVisibility()
method should, in that case, not need the $testContent
parameter.
As for the "invalid" tests method - I think it might be worth it to do a bit more strenuous testing on the other tokens after the visibility keyword not being retokenized incorrectly.
I.e. test a token sequence for those cases.
Also regarding the "invalid" tests - I still miss tests with (valid) PHP code, which is not asym visibility, like the below:
class Foo {
function protected() {}
function public(Set $setter) {}
}
Those tests can go either in the new test file or in the test file for ContextSensitiveKeywords, but safeguarding that this valid code is not negatively affected is important to me (and yes, your implementation should not cause any problem, but this is about making sure that potential future changes do not break this).
T_PRIVATE_SET => T_PRIVATE_SET, | ||
T_PROTECTED => T_PROTECTED, | ||
T_PROTECTED_SET => T_PROTECTED_SET, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Except, while these are tokens, these are not keywords.
This list is primarily for use with the PHP
Tokenizer correction of context sensitive keyword tokenization. What that means is as follows:
class Foreach {
function exit() {}
}
Foreach
and exit
in the above code sample should be (re-)tokenized to T_STRING
and should not be tokenized as T_FOREACH
or T_EXIT
(which is the PHP native tokenization in parse-error tolerant mode).
As the T_*_SET
tokens are combined tokens, they cannot be used in those places anyway - class Private(set)
would be a parse error -, so they are irrelevant for the context sensitive keyword list. Same as the cast tokens are not part of this list.
Done for matching 907, after 908 is merged I'll add test cases there
I split them, and kept
Done |
@DanielEScherzer I've merged both #907 as well as #908 now, so you should be able to make that update now. |
cd204d5
to
c817433
Compare
Failure is from HTTP 405 error when uploading code coverage, which I think is unrelated to the actual changes |
💯 Coveralls is doing some disruptive maintenance: https://status.coveralls.io/ (also the reason my own recent PRs are all marked as failing). I will retrigger the relevant builds once the maintenance has finished. |
This was done, but I can't remove the |
Thanks @DanielEScherzer. I'm hoping to take another look over the next few days, but what with the PRs for 4.0 being lined up (see #924), I may delay this PR until after next week (though it would still go into 3.x). Please bear with me. It is on my radar though. |
P.S.: I see there is another merge conflict. Sorry about that. PR #948 also touches that same sniff, so you may want to hold off resolving the conflict until that PR has been merged. |
309be53
to
51fddcc
Compare
Tests need to pass on PHP 5 where `string` wasn't reserved yet
51fddcc
to
387063d
Compare
Done the holding off, and done the subsequent resolving of the conflict |
Description
Set up tokenization of asymmetric visibility modifiers:
T_PUBLIC_SET
,T_PROTECTED_SET
, andT_PRIVATE_SET
if not already definedPHP_CodeSniffer\Util\Tokens::$scopeModifiers
)PHP_CodeSniffer\Util\Tokens::$contextSensitiveKeywords
)PHP_CodeSniffer\Tokenizers\PHP::$knownLengths
)Suggested changelog entry
PHP 8.4 | Support tokenization of asymmetric visibility modifiers
Related issues/external references
Related to #851
Types of changes
PR checklist