rouge-ruby / rouge

A pure Ruby code highlighter that is compatible with Pygments
https://rouge.jneen.net/
Other
3.32k stars 731 forks source link

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

Closed nsfisis closed 2 years ago

nsfisis commented 2 years ago

Summary

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:

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

tancnle commented 2 years ago

Thank you for your contribution @nsfisis πŸ‘πŸΌ Looks great to me πŸš€