You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
PHP: single-line attributes are highlighted as one flat token, unlike multi-line ones
#2339
In the PHP lexer, a single-line PHP 8 attribute is emitted as one flat Name::Attribute token, while the same attribute split over several lines is tokenised normally (strings, names, punctuation, etc.). The two forms therefore render very differently, e.g. in GitLab diffs and file views (GitLab uses Rouge).
Follow-up to #1759, which added attribute support.
Cause
lib/rouge/lexers/php.rb, :php state:
rule%r/#\[.*\]$/,Name::Attribute
This matches #[ ... ] to the end of the line as a single token. Multi-line attributes do not match (no ] at the end of the first line), so they fall through to the generic rules and get proper highlighting.
Reproduction
<?phpclass FooController
{
// Rendered as a single flat Name::Attribute token:
#[Route(path: '/crews/members/remove', name: 'crews_members_remove')]
publicfunctionremove(): Response {}
// Rendered with normal tokens (strings, keywords, punctuation):
#[Route(
path: '/crews/{crew_id}/members/{user_id}',
name: 'crews_members_details',
requirements: ['crew_id' => '\d+'],
)]
publicfunctiondetails(): Response {}
}
Expected
Both forms highlight the same way: #[ and ] as attribute punctuation, the attribute class as Name::Attribute (or Name::Decorator), and the arguments tokenised as ordinary PHP (named-argument labels, strings, arrays, constants).
Possible fix
Replace the single-line rule with one that pushes an :attribute state on #[ and pops on the matching ], tracking bracket depth, so that the contents are lexed as PHP regardless of line count.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Summary
In the PHP lexer, a single-line PHP 8 attribute is emitted as one flat
Name::Attributetoken, while the same attribute split over several lines is tokenised normally (strings, names, punctuation, etc.). The two forms therefore render very differently, e.g. in GitLab diffs and file views (GitLab uses Rouge).Follow-up to #1759, which added attribute support.
Cause
lib/rouge/lexers/php.rb,:phpstate:This matches
#[ ... ]to the end of the line as a single token. Multi-line attributes do not match (no]at the end of the first line), so they fall through to the generic rules and get proper highlighting.Reproduction
Expected
Both forms highlight the same way:
#[and]as attribute punctuation, the attribute class asName::Attribute(orName::Decorator), and the arguments tokenised as ordinary PHP (named-argument labels, strings, arrays, constants).Possible fix
Replace the single-line rule with one that pushes an
:attributestate on#[and pops on the matching], tracking bracket depth, so that the contents are lexed as PHP regardless of line count.All reactions