Skip to content

feat: support asymmetric visibility in constructor promotion#297

Merged
calebdw merged 2 commits into
tree-sitter:masterfrom
hbtweb:fix/asymmetric-visibility-constructor-promotion
Mar 19, 2026
Merged

feat: support asymmetric visibility in constructor promotion#297
calebdw merged 2 commits into
tree-sitter:masterfrom
hbtweb:fix/asymmetric-visibility-constructor-promotion

Conversation

@hbtweb

@hbtweb hbtweb commented Mar 19, 2026

Copy link
Copy Markdown
Contributor

Summary

PHP 8.4 added asymmetric visibility which allows separate read/write visibility on properties. PR #258 added support for this on property declarations, but missed the case where two visibility modifiers are used in constructor promotion parameters.

This PR adds an optional set_visibility field to property_promotion_parameter so that constructs like this parse correctly:

class User {
    public function __construct(
        public private(set) string $name,
        public protected(set) int $age,
    ) {}
}

Before: private(set) / protected(set) in constructor promotion with a preceding visibility modifier produces a parse error.

After: Parsed correctly as two visibility_modifier nodes — one for read, one for write.

Changes

  • common/define-grammar.js: Added optional set_visibility field to property_promotion_parameter
  • test/corpus/class.txt: Added test case for asymmetric visibility in constructor promotion
  • php/src/parser.c: Regenerated

Test plan

  • All 144 existing tests pass (0 failures)
  • New test case "Asymmetric Visibility in Constructor Promotion" passes
  • Existing "Asymmetric Property Visibility" test still passes
  • Single visibility modifier in constructor promotion still works (private(set) string $title)

@calebdw calebdw force-pushed the fix/asymmetric-visibility-constructor-promotion branch from fd722b5 to 539f721 Compare March 19, 2026 14:42
hbtweb added 2 commits March 19, 2026 09:51
PHP 8.4 allows asymmetric visibility on constructor promoted
properties (e.g. `public private(set) string $name`), but the
grammar only accepted a single visibility modifier in
`property_promotion_parameter`. This adds an optional
`set_visibility` field for the second modifier.
@calebdw calebdw force-pushed the fix/asymmetric-visibility-constructor-promotion branch from 539f721 to 55bf24f Compare March 19, 2026 14:53
@calebdw

calebdw commented Mar 19, 2026

Copy link
Copy Markdown
Collaborator

Thanks! I changed it from set_visibility to just repeating the visibility field---if you only have private(set) then it would be parsed as the visibility field and not the set_visibility field which is not correct.

I also regenerated the grammar (make generate)

@calebdw calebdw merged commit 3f2465c into tree-sitter:master Mar 19, 2026
4 checks passed
@hbtweb hbtweb deleted the fix/asymmetric-visibility-constructor-promotion branch April 1, 2026 00:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants