Skip to content

Block Parser: Restore count() stack access and type $stack as a list - #13487

Closed
mukeshpanchal27 wants to merge 5 commits into
WordPress:trunkfrom
mukeshpanchal27:use/array-last
Closed

mukeshpanchal27 wants to merge 5 commits into
WordPress:trunkfrom
mukeshpanchal27:use/array-last

Conversation

@mukeshpanchal27

@mukeshpanchal27 mukeshpanchal27 commented Sep 11, 2026 •

Copy link
Copy Markdown
Member

✅ Committed in:


Trac ticket: https://core.trac.wordpress.org/ticket/65818

Follow-up to r63624. Syncs WP_Block_Parser with WordPress/gutenberg#82695.

Changes

  • Restores $this->stack[ count( $this->stack ) - 1 ] in WP_Block_Parser::add_inner_block(), replacing array_key_last().
  • Removes the inline comment added in r63624 that explained why array_last() is not used.
  • Adds @phpstan-var list<WP_Block_Parser_Frame> to the $stack property.

Why

As raised by @dmsnell in WordPress/gutenberg#82695 (review), using array_key_last() suggests that $this->stack could be an associative array, which it never is. The original count()-based access was already correct. Both callers ensure the stack is not empty.

Typing $stack as a list, as suggested by @westonruter in WordPress/gutenberg#82695 (comment), tells static analysis that the stack is always sequentially indexed. That makes it clear there is no need for array_key_last() or array_last(), so the explanatory comment is no longer needed. PHPStan reports no errors for the file.

Use of AI Tools

AI assistance: Yes
Tool(s): Claude Code
Model(s): Claude Opus 5.5
Used for: Applying the review feedback and drafting this description. Reviewed and verified by me.


This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.

@mukeshpanchal27 mukeshpanchal27 self-assigned this Sep 11, 2026
@mukeshpanchal27
mukeshpanchal27 marked this pull request as ready for review September 11, 2026 09:19
@github-actions

github-actions Bot commented Sep 11, 2026 •

Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

Core Committers: Use this line as a base for the props when committing in SVN:

Props mukesh27, westonruter, soean.

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@Soean

Soean commented Sep 14, 2026

Copy link
Copy Markdown
Member

We tried to change this line and reverted it in 3dba2c6 of #12417 (comment)
Maybe we should add a comment?

CC: @westonruter

@westonruter westonruter left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, this change causes a PHPStan error to be introduced (above rule level 5):

image

So we reverted the change with this reasoning:

Replace the array_last() call and its accompanying LogicException guard with $this->stack[ array_key_last( $this->stack ) ].

Both internal call sites are already guarded against an empty stack, so the exception was unreachable from core. Since add_inner_block() is a public method of a class that can be replaced via the block_parser_class filter, throwing a new exception type would have changed behavior for third-party callers, which is out of scope for a coding standards change.

Indexing by array_key_last() keeps the readability improvement without introducing a nullable into the expression.

This error does not occur when using $this->stack[ array_key_last( $this->stack ) ].

So yes, to prevent this issue from being raised again, it probably makes sense to add a comment explaining why array_last() is not being used.

If we did throw an exception, then we would be obliged to add a @throws tag, but then any caller of the function could be flagged for not having a try/catch block when in practice an exception will never be thrown.

Updated the method to access the last element of the stack using array_key_last() instead of array_last() for better static analysis compatibility.
@mukeshpanchal27 mukeshpanchal27 changed the title Code Modernization: Use array_last() in WP_Block_Parser::add_inner_block() Docs: Explain why array_last() is not used in WP_Block_Parser::add_inner_block() Sep 15, 2026
@github-actions

Copy link
Copy Markdown

Test using WordPress Playground

The changes in this pull request can previewed and tested using a WordPress Playground instance.

WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser.

Some things to be aware of

  • All changes will be lost when closing a tab with a Playground instance.
  • All changes will be lost when refreshing the page.
  • A fresh instance is created each time the link below is clicked.
  • Every time this pull request is updated, a new ZIP file containing all changes is created. If changes are not reflected in the Playground instance,
    it's possible that the most recent build failed, or has not completed. Check the list of workflow runs to be sure.

For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation.

Test this pull request with WordPress Playground.

wporg-sync pushed a commit that referenced this pull request Sep 15, 2026
Add an inline comment to `WP_Block_Parser::add_inner_block()` recording why the last stack entry is read as `$this->stack[ array_key_last( $this->stack ) ]` rather than with `array_last()`. The latter was tried while preparing r62956 and reverted before it landed, and has since been proposed again.

Because `array_last()` returns `null` for an empty array, using it here reintroduces a static analysis error on the property accesses that follow. Guarding the return value is not an option: both call sites already return early when the stack is empty, so the guard would be unreachable from core, and `add_inner_block()` is a public method on a class that can be replaced via the `block_parser_class` filter, so throwing a new exception type would change behavior for third-party callers. A `@throws` tag for an exception that can never be thrown would in turn flag every caller for not wrapping the call in `try`/`catch`.

Developed in #13487.
Follow-up to r62956.

Props mukesh27, soean, westonruter.
See #65818.


git-svn-id: https://develop.svn.wordpress.org/trunk@63624 602fd350-edb4-49c9-b593-d223f7449a82
wporg-sync pushed a commit to WordPress/WordPress that referenced this pull request Sep 15, 2026
Add an inline comment to `WP_Block_Parser::add_inner_block()` recording why the last stack entry is read as `$this->stack[ array_key_last( $this->stack ) ]` rather than with `array_last()`. The latter was tried while preparing r62956 and reverted before it landed, and has since been proposed again.

Because `array_last()` returns `null` for an empty array, using it here reintroduces a static analysis error on the property accesses that follow. Guarding the return value is not an option: both call sites already return early when the stack is empty, so the guard would be unreachable from core, and `add_inner_block()` is a public method on a class that can be replaced via the `block_parser_class` filter, so throwing a new exception type would change behavior for third-party callers. A `@throws` tag for an exception that can never be thrown would in turn flag every caller for not wrapping the call in `try`/`catch`.

Developed in WordPress/wordpress-develop#13487.
Follow-up to r62956.

Props mukesh27, soean, westonruter.
See #65818.

Built from https://develop.svn.wordpress.org/trunk@63624


git-svn-id: http://core.svn.wordpress.org/trunk@62800 1a063a9b-81f0-0310-95a4-ce76da25c4cd
@westonruter

Copy link
Copy Markdown
Member

@mukeshpanchal27 mukeshpanchal27 changed the title Docs: Explain why array_last() is not used in WP_Block_Parser::add_inner_block() Block Parser: Restore count() stack access and type $stack as a list Sep 25, 2026
wporg-sync pushed a commit that referenced this pull request Sep 25, 2026
In `WP_Block_Parser::add_inner_block()` the last stack frame is once again read as `$this->stack[ count( $this->stack ) - 1 ]`, undoing the switch to `array_key_last()` made in r62956 and removing the inline comment added in r63624 that explained why `array_last()` is not used. Indexing by `array_key_last()` gives the misleading impression that `$this->stack` could be an associative array, when it is only ever a sequentially indexed list. The original code was already correct, and both callers ensure the stack is not empty.

The `$stack` property is now also documented with `@phpstan-var list<WP_Block_Parser_Frame>`, which tells static analysis that the stack is always sequentially indexed. With that in place, there is nothing prompting a switch to `array_key_last()` or `array_last()`, so the explanatory comment is no longer needed. This mirrors the change made to the parser in Gutenberg via WordPress/gutenberg#82695.

Developed in #13487.
Follow-up to r62956, r63624.

Props mukesh27, westonruter, dmsnell, soean.
See #65818, #65817.


git-svn-id: https://develop.svn.wordpress.org/trunk@63937 602fd350-edb4-49c9-b593-d223f7449a82
wporg-sync pushed a commit to WordPress/WordPress that referenced this pull request Sep 25, 2026
In `WP_Block_Parser::add_inner_block()` the last stack frame is once again read as `$this->stack[ count( $this->stack ) - 1 ]`, undoing the switch to `array_key_last()` made in r62956 and removing the inline comment added in r63624 that explained why `array_last()` is not used. Indexing by `array_key_last()` gives the misleading impression that `$this->stack` could be an associative array, when it is only ever a sequentially indexed list. The original code was already correct, and both callers ensure the stack is not empty.

The `$stack` property is now also documented with `@phpstan-var list<WP_Block_Parser_Frame>`, which tells static analysis that the stack is always sequentially indexed. With that in place, there is nothing prompting a switch to `array_key_last()` or `array_last()`, so the explanatory comment is no longer needed. This mirrors the change made to the parser in Gutenberg via WordPress/gutenberg#82695.

Developed in WordPress/wordpress-develop#13487.
Follow-up to r62956, r63624.

Props mukesh27, westonruter, dmsnell, soean.
See #65818, #65817.

Built from https://develop.svn.wordpress.org/trunk@63937


git-svn-id: http://core.svn.wordpress.org/trunk@63103 1a063a9b-81f0-0310-95a4-ce76da25c4cd
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.

3 participants