Repository navigation
Build/QA: Retire parameterByRef.unusedType baseline - #14025
huzaifaalmesbah wants to merge 3 commits into
Conversation
…tf8_codepoint_span
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. Core Committers: Use this line as a base for the props when committing in SVN: To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. Props Bot commandsYou can trigger Props Bot actions by commenting on this PR:
|
Test using WordPress PlaygroundThe 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
For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation. |
There was a problem hiding this comment.
🟢 Approval recommended
There are no active review issues for the UTF-8 output-type clarifications and related PHPStan suppression cleanup.
No open issues 🎉
What changed in this PR
This PR clarifies by-reference output types in WordPress’s UTF-8 compatibility helpers and removes the PHPStan suppressions those changes resolve.
Changes:
- Adds output-type annotations and keeps noncharacter detection strictly boolean.
- Deletes the
parameterByRef.unusedTypebaseline and removes two resolvedparameterByRef.typeerrors. - Adds UTF-8 scanner tests covering ASCII, noncharacters, and ordinary multibyte text.
| File | Description |
|---|---|
tests/phpunit/tests/compat/wpScanUtf8.php |
Adds scanner tests asserting boolean noncharacter results. |
tests/phpstan/baselines/parameterByRef.unusedType.neon |
Deletes the resolved baseline. |
tests/phpstan/baselines/parameterByRef.type.neon |
Removes two resolved boolean-type suppressions. |
src/wp-includes/compat-utf8.php |
Documents output types and replaces bitwise accumulation with boolean logic. |
phpstan.neon.dist |
Removes the deleted baseline’s include. |
Review effort: Balanced
|
@dmsnell could you review the AI review · |
…sts. `assertTrue()` and `assertFalse()` already check the boolean type.
|
@dmsnell following up on my Oct 31 request: could you review the AI review · |
| * @param int|null $max_bytes Stop scanning after this many bytes have been seen. | ||
| * @param int|null $max_code_points Stop scanning after this many code points have been seen. | ||
| * @param bool|null $has_noncharacters Set to indicate if scanned string contained noncharacters. | ||
| * @param-out bool $has_noncharacters |
There was a problem hiding this comment.
please verify that this doesn’t break the docs-generation. before we start changing @param declarations, we should ensure that the published docs page isn’t broken.
you can hopefully lean on dmsnell#29 to figure out how to preview the generation.
I see that this is an additional annotation beyond the @param, but it would be ideal to double-check first.
There was a problem hiding this comment.
Thanks for flagging this. I couldn't build the full Playground preview locally, so I checked the parser and theme versions pinned in your preview branch instead. The docblock tag regex allows -, so @param-out comes through as its own param-out tag rather than a @param. The reference templates only read tags named param for the signature and the Parameters section, so the published page should stay the same. I also reverted the @param wording change on _wp_utf8_codepoint_span() in 9b682d6, so now the docblock only gains the @param-out lines.
| * | ||
| * @ticket 65817 | ||
| */ | ||
| public function test_scan_string_without_noncharacters() { |
There was a problem hiding this comment.
this is a misleading title. it would be clearer to show variant cases of multi-byte UTF-8 code points and extended grapheme clusters, which would clarify the behavior of the function.
let’s use a data provider and show interesting cases, and then use mb_strlen( $text, 'UTF-8' ) inside an assertSame() to verify the counts.
this way we can cover two-, three-, and four-byte sequences, spans of invalid bytes (covering the maximal subpart behavior), ZWJ sequences, and grapheme clusters.
There was a problem hiding this comment.
Good call, thank you. Done in 9b682d6. data_valid_utf8() now covers two-, three- and four-byte sequences, combining marks, conjoining jamo, flags, skin tone and keycap sequences, and ZWJ sequences, with the count checked against mb_strlen( $text, 'UTF-8' ). Invalid spans have their own provider, which walks the string and checks the maximal subpart length of each span. The expected values are written out in the data there, so they don't depend on how mbstring handles invalid bytes.
Replaces the ASCII and "without noncharacters" tests with data providers covering two-, three- and four-byte sequences, combining characters, ZWJ sequences and grapheme clusters, with the code point count verified against `mb_strlen()`. Adds cases for invalid byte spans that check the maximal subpart reported for each one. Also restores the original `@param` line for `$found_code_points` in `_wp_utf8_codepoint_span()`, so the only docblock additions are the `@param-out` tags, which the developer reference does not render. See #65817.
| // Covers the range U+FDD0–U+FDEF, U+FFFE, U+FFFF. | ||
| if ( 0xEF === $b1 ) { | ||
| $has_noncharacters |= ( | ||
| $has_noncharacters = $has_noncharacters || ( |
There was a problem hiding this comment.
this might result in a performance degradation inside a hot path, but I have not measured the change. it takes a branchless instruction and replaces it with a branching one.
in any case, this compat function is mostly here for edge cases where the built-in UTF-8 support is lacking, so if it does introduce a performance regression, that may be tolerable if the ultimate goal is ensuring that nothing expected appears for the types.
There was a problem hiding this comment.
Thanks, good point. I ran a quick benchmark to check. I compared the original |=, the || in this PR, and a third option that keeps a branchless |= on a local int and casts to bool before each return. Each ran on about 1 MB of text, 15 runs, taking the median, two separate runs each:
| Text | PHP 8.5 (native) | PHP 8.3 (Docker) |
|---|---|---|
| all 4-byte emoji | +0.3% / +3.0% | +0.1% / −3.4% |
all fullwidth 0xEF |
+1.3% / −2.1% | +2.8% / +0.3% |
CJK, 3-byte without 0xEF |
−1.1% / +0.3% | +6.7% / +2.9% |
| mostly Latin with some emoji | +1.0% / +1.1% | −0.2% / −3.2% |
These are || vs |=. The differences change direction between runs, and the largest one is on CJK text, where the changed line never runs, so it looks like noise rather than a regression. The local cast version wasn't consistently faster either. I'd lean toward keeping || for simplicity, but I'm happy to switch to the local cast version if you prefer to keep the hot path branchless.
Description
In
src/wp-includes/compat-utf8.php, by-reference parameters in_wp_scan_utf8()(&$has_noncharacters) and_wp_utf8_codepoint_span()(&$found_code_points) accept nullable input defaults, but are always assigned non-null values on exit (boolandintrespectively).Additionally, in
_wp_scan_utf8(),$has_noncharacterswas previously accumulated using bitwise OR assignment (|=), which coerced the boolean variable into an integer (0or1). Switching to boolean accumulating assignment ($has_noncharacters = $has_noncharacters || ( ... )) ensures it remains strictly a boolean.This PR:
@param-out bool $has_noncharactersto_wp_scan_utf8().@param-out int $found_code_pointsto_wp_utf8_codepoint_span(). The existing@paramlines are unchanged; the developer reference only renders tags namedparam, so the published docs pages are unaffected.tests/phpstan/baselines/parameterByRef.unusedType.neonand updatesphpstan.neon.dist.tests/phpstan/baselines/parameterByRef.type.neon._wp_scan_utf8(): code point counts for two-, three- and four-byte sequences, combining characters, ZWJ sequences and grapheme clusters (verified againstmb_strlen()), maximal subparts of invalid byte spans, and boolean noncharacter detection.Testing Instructions
composer phpstanlocally to confirm analysis passes with 0 errors.Trac ticket: https://core.trac.wordpress.org/ticket/65817
Use of AI Tools
AI assistance: Yes
Tool(s): Google Antigravity, Claude Code
Model(s): Gemini 3.8 Flash, Claude Opus 5.5
Used for: Assisting with static analysis archaeology, PHPStan baseline synchronization, and diff preparation; all code and tests were manually reviewed, verified, and locally run by me.