Skip to content
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

PHP: support new syntax (constructor property promotion, readonly modifier, etc.) #1829

Merged
merged 5 commits into from
Jun 21, 2022

Conversation

nsfisis
Copy link
Contributor

@nsfisis nsfisis commented Jun 6, 2022

Summary

  • Add missing keywords
    • empty
    • match
    • readonly
    • unset
  • Fix parsing of static properties
  • Support readonly modifiers
  • Support constructor property promotion

Details

Add missing keywords

empty and unset are function-like keywords. Previously they are parsed as built-in functions like this:

cf. https://www.php.net/manual/en/reserved.keywords.php

image

They should be parsed as keywords as isset() and die().

image

Also, match expression is introduced since PHP 8.0.

cf. https://www.php.net/manual/en/control-structures.match.php

image

image

Fix parsing of static properties

Previously, static property declaration with type hint like public static int $x; was parsed as the following:

  • Keyword (public)
  • Keyword (static)
  • Unknown token (int)
  • Variable ($x)

int should be parsed as a type.

The previous parser state :in_visibility defines these rules:

state :in_visibility do
  rule %r/(?=(abstract|const|function|static)\b)/i, Keyword, :pop!
  rule %r/\??#{id}/, Keyword::Type, :pop!
  # ...
end

Because a parser pops the current state once it find static, it cannot recognize a type hint following the static keyword.

I split the rule into two, static and other. If a parser encounters static, it stays in the current state and then parses a type hints.

image

image

Support readonly modifiers

readonly is a new property modifier, available in PHP 8.1 or later.

cf. https://www.php.net/manual/en/language.oop5.properties.php#language.oop5.properties.readonly-properties

Support constructor property promotion

Since PHP 8.0, you can prepend visibility modifiers to parameters of constructors. These parameters are "promoted" to class properties.
Since 8.1, you can specify readonly modifier as class properties.

cf. https://www.php.net/manual/en/language.oop5.decon.php#language.oop5.decon.constructor.promotion

Previously, static property declaration with type hint like
`public static int $x;` was parsed as the following:

* Keyword (`public`)
* Keyword (`static`)
* Unknown token (`int`)
* Variable (`$x`)

`int` should be parsed as a type.

The previous parser state `:in_visibility` defines these rules:

```ruby
state :in_visibility do
  rule %r/(?=(abstract|const|function|static)\b)/i, Keyword, :pop!
  rule %r/\??#{id}/, Keyword::Type, :pop!
  # ...
end
```

Because a parser pops the current state once it find `static`,
it cannot recognize a type hint following the `static` keyword.

I split the rule into two, `static` and other. If a parser encounters
`static`, it stays in the current state and then parses a type hints.
Since PHP 8.0, you can prepend visibility modifiers to parameters of
constructors. These parameters are "promoted" to class properties.
Since 8.1, you can specify `readonly` modifier as class properties.

cf. https://www.php.net/manual/en/language.oop5.decon.php#language.oop5.decon.constructor.promotion
@tancnle tancnle added the needs-review The PR needs to be reviewed label Jun 20, 2022
@tancnle
Copy link
Collaborator

tancnle commented Jun 21, 2022

Thank you for your contribution @nsfisis 👍🏼 Looks great to me 🚀

@tancnle tancnle merged commit ee4ff0a into rouge-ruby:master Jun 21, 2022
@nsfisis nsfisis deleted the feature.php-new-syntax branch June 21, 2022 06:44
razetime pushed a commit to razetime/rouge that referenced this pull request Jun 30, 2022
…ifier, etc.) (rouge-ruby#1829)

* PHP: add missing keywords

* `empty`
* `match`
* `readonly`
* `unset`

cf. https://www.php.net/manual/en/reserved.keywords.php

* PHP: fix parsing of static properties

Previously, static property declaration with type hint like
`public static int $x;` was parsed as the following:

* Keyword (`public`)
* Keyword (`static`)
* Unknown token (`int`)
* Variable (`$x`)

`int` should be parsed as a type.

The previous parser state `:in_visibility` defines these rules:

```ruby
state :in_visibility do
  rule %r/(?=(abstract|const|function|static)\b)/i, Keyword, :pop!
  rule %r/\??#{id}/, Keyword::Type, :pop!
  # ...
end
```

Because a parser pops the current state once it find `static`,
it cannot recognize a type hint following the `static` keyword.

I split the rule into two, `static` and other. If a parser encounters
`static`, it stays in the current state and then parses a type hints.

* PHP: support `readonly` modifier

* PHP: support constructor property promotion

Since PHP 8.0, you can prepend visibility modifiers to parameters of
constructors. These parameters are "promoted" to class properties.
Since 8.1, you can specify `readonly` modifier as class properties.

cf. https://www.php.net/manual/en/language.oop5.decon.php#language.oop5.decon.constructor.promotion

* PHP: add some visual tests
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs-review The PR needs to be reviewed
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants