From 83562b2f4a90ffe7d9ae7e271c9d072f914a0a0b Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Sun, 25 Oct 2026 13:52:14 -0700 Subject: [PATCH 01/11] Register the shadow attributes only when they are missing `wp_register_shadow_support()` checked `array_key_exists()` without negating it, which inverted both conditions: a block type with shadow support but no `style` or `shadow` attribute never had them registered, while one that already defined them had its definitions replaced, dropping any `default`. Negate the checks so the attributes are added when absent and left alone when present, as the other block supports do and as Gutenberg's `gutenberg_register_shadow_support()` already does. Add tests covering the attribute registration. Co-Authored-By: Claude Opus 5.5 --- src/wp-includes/block-supports/shadow.php | 4 +- tests/phpunit/tests/block-supports/shadow.php | 88 +++++++++++++++++++ 2 files changed, 90 insertions(+), 2 deletions(-) diff --git a/src/wp-includes/block-supports/shadow.php b/src/wp-includes/block-supports/shadow.php index 4c09ce9d08f0f..272eb87407099 100644 --- a/src/wp-includes/block-supports/shadow.php +++ b/src/wp-includes/block-supports/shadow.php @@ -25,13 +25,13 @@ function wp_register_shadow_support( $block_type ) { $block_type->attributes = array(); } - if ( array_key_exists( 'style', $block_type->attributes ) ) { + if ( ! array_key_exists( 'style', $block_type->attributes ) ) { $block_type->attributes['style'] = array( 'type' => 'object', ); } - if ( array_key_exists( 'shadow', $block_type->attributes ) ) { + if ( ! array_key_exists( 'shadow', $block_type->attributes ) ) { $block_type->attributes['shadow'] = array( 'type' => 'string', ); diff --git a/tests/phpunit/tests/block-supports/shadow.php b/tests/phpunit/tests/block-supports/shadow.php index bc2bb53b10ea4..43b00601f7c7b 100644 --- a/tests/phpunit/tests/block-supports/shadow.php +++ b/tests/phpunit/tests/block-supports/shadow.php @@ -47,6 +47,94 @@ private function register_shadow_block_with_support( $block_name, $supports = ar return $registry->get_registered( $this->test_block_name ); } + /** + * Tests that shadow block support attribute registration works as expected. + * + * @ticket 65817 + * + * @covers ::wp_register_shadow_support + * + * @dataProvider data_wp_register_shadow_support + * + * @param bool $support Shadow block support configuration. + * @param array>|null $value Attributes array for the block. + * @param array> $expected Expected attributes for the block. + */ + public function test_wp_register_shadow_support( bool $support, ?array $value, array $expected ) { + $this->test_block_name = 'test/shadow-attributes'; + register_block_type( + $this->test_block_name, + array( + 'api_version' => 3, + 'supports' => array( 'shadow' => $support ), + 'attributes' => $value, + ) + ); + $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $this->test_block_name ); + $this->assertInstanceOf( WP_Block_Type::class, $block_type ); + + wp_register_shadow_support( $block_type ); + + $actual = $block_type->attributes; + $this->assertIsArray( $actual ); + $expected = array_merge( WP_Block_Type::GLOBAL_ATTRIBUTES, $expected ); + $this->assertSameSetsWithIndex( $expected, $actual ); + } + + /** + * Data provider for test_wp_register_shadow_support(). + * + * @return array> + */ + public static function data_wp_register_shadow_support(): array { + return array( + 'style and shadow attributes are registered when block supports shadow' => array( + 'support' => true, + 'value' => null, + 'expected' => array( + 'style' => array( + 'type' => 'object', + ), + 'shadow' => array( + 'type' => 'string', + ), + ), + ), + 'no attributes are registered when block does not support shadow' => array( + 'support' => false, + 'value' => null, + 'expected' => array(), + ), + 'existing style and shadow attributes are not overwritten' => array( + 'support' => true, + 'value' => array( + 'style' => array( + 'type' => 'object', + 'default' => array( + 'shadow' => 'var:preset|shadow|natural', + ), + ), + 'shadow' => array( + 'type' => 'string', + 'default' => 'natural', + ), + ), + 'expected' => array( + 'style' => array( + 'type' => 'object', + 'default' => array( + 'shadow' => 'var:preset|shadow|natural', + ), + ), + 'shadow' => array( + 'type' => 'string', + 'default' => 'natural', + ), + ), + ), + ); + } + /** * Tests the generation of shadow block support styles. * From 76daa56db329dddbca44096ef4ac3cae5907a131 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Sun, 25 Oct 2026 13:52:58 -0700 Subject: [PATCH 02/11] Cast the column width value to a string for explode() `wp_get_child_layout_style_rules()` passed the float from `floatval()` as the separator to `explode()`, which expects a string. Cast it explicitly, which yields the same separator that PHP's implicit conversion did, and remove the corresponding PHPStan baseline entry. Co-Authored-By: Claude Opus 5.5 --- src/wp-includes/block-supports/layout.php | 2 +- tests/phpstan/baselines/argument.type.neon | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/wp-includes/block-supports/layout.php b/src/wp-includes/block-supports/layout.php index dc3b56c0171c5..3036c581fd67b 100644 --- a/src/wp-includes/block-supports/layout.php +++ b/src/wp-includes/block-supports/layout.php @@ -237,7 +237,7 @@ function wp_get_child_layout_style_rules( $selector, $child_layout, $parent_layo $column_start_number = floatval( $column_start ); $parent_column_width = $minimum_column_width ? $minimum_column_width : '12rem'; $parent_column_value = floatval( $parent_column_width ); - $parent_column_unit = explode( $parent_column_value, $parent_column_width ); + $parent_column_unit = explode( (string) $parent_column_value, $parent_column_width ); $num_cols_to_break_at = 2; if ( $column_span_number && $column_start_number ) { diff --git a/tests/phpstan/baselines/argument.type.neon b/tests/phpstan/baselines/argument.type.neon index 5438195438f19..3cecc6f4c2da0 100644 --- a/tests/phpstan/baselines/argument.type.neon +++ b/tests/phpstan/baselines/argument.type.neon @@ -653,11 +653,6 @@ parameters: identifier: argument.type count: 1 path: ../../../src/wp-includes/author-template.php - - - message: '#^Parameter \#1 \$separator of function explode expects string, float given\.$#' - identifier: argument.type - count: 1 - path: ../../../src/wp-includes/block-supports/layout.php - message: '#^Parameter \#1 \$block of function filter_block_kses expects WP_Block_Parser_Block, array given\.$#' identifier: argument.type From bbd54c6d9a2299346e36d1eb8bae4e2ccc9431c9 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Sun, 25 Oct 2026 13:53:26 -0700 Subject: [PATCH 03/11] Cast the parsed hue to a float in the duotone HSLA parser `WP_Duotone::colord_parse_hsla_string()` passed the matched hue string straight to `colord_parse_hue()`, which expects a float, while the saturation, lightness, and alpha matches beside it were already cast. Cast the hue too, and remove the corresponding PHPStan baseline entry. Co-Authored-By: Claude Opus 5.5 --- src/wp-includes/class-wp-duotone.php | 2 +- tests/phpstan/baselines/argument.type.neon | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/wp-includes/class-wp-duotone.php b/src/wp-includes/class-wp-duotone.php index 08beac3cd4923..b254e3c95b0a0 100644 --- a/src/wp-includes/class-wp-duotone.php +++ b/src/wp-includes/class-wp-duotone.php @@ -496,7 +496,7 @@ private static function colord_parse_hsla_string( $input ) { $hsla = self::colord_clamp_hsla( array( - 'h' => self::colord_parse_hue( $match[1], $match[2] ), + 'h' => self::colord_parse_hue( (float) $match[1], $match[2] ), 's' => (float) $match[3], 'l' => (float) $match[4], 'a' => '' === $match[5] ? 1 : (float) $match[5] / ( $match[6] ? 100 : 1 ), diff --git a/tests/phpstan/baselines/argument.type.neon b/tests/phpstan/baselines/argument.type.neon index 3cecc6f4c2da0..a8beb0366a515 100644 --- a/tests/phpstan/baselines/argument.type.neon +++ b/tests/phpstan/baselines/argument.type.neon @@ -728,11 +728,6 @@ parameters: identifier: argument.type count: 3 path: ../../../src/wp-includes/class-wp-date-query.php - - - message: '#^Parameter \#1 \$value of static method WP_Duotone\:\:colord_parse_hue\(\) expects float, string given\.$#' - identifier: argument.type - count: 1 - path: ../../../src/wp-includes/class-wp-duotone.php - message: '#^Parameter \#1 \$postarr of function wp_insert_post expects array\{ID\?\: int, post_author\?\: int, post_date\?\: string, post_date_gmt\?\: string, post_content\?\: string, post_content_filtered\?\: string, post_title\?\: string, post_excerpt\?\: string, \.\.\., \.\.\.\}, array\ given\.$#' identifier: argument.type From 1b0c1534c24b5addfb0d30dbdfeca92289d56c79 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Sun, 25 Oct 2026 13:53:58 -0700 Subject: [PATCH 04/11] Narrow the types for get_feature_declarations_for_node() Describe the shapes `WP_Theme_JSON::get_feature_declarations_for_node()` works with: the block metadata and the node are string-keyed arrays, the `selectors` the method reads map each feature to a selector string or to a map of subfeature selectors, and the returned declarations are keyed by selector. Each declaration list uses the same shape that `get_state_declarations_with_text_clip_escapes()` already documents. This resolves the PHPStan errors on mixed offsets and iteration inside the method at the higher rule levels. Co-Authored-By: Claude Opus 5.5 --- src/wp-includes/class-wp-theme-json.php | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/wp-includes/class-wp-theme-json.php b/src/wp-includes/class-wp-theme-json.php index 34c737bb0d1a7..1026b9223fa8b 100644 --- a/src/wp-includes/class-wp-theme-json.php +++ b/src/wp-includes/class-wp-theme-json.php @@ -6052,11 +6052,14 @@ protected static function get_block_element_selectors( $root_selector ) { * * @since 6.3.0 * - * @param array $metadata The related block metadata containing selectors. - * @param array $node A merged theme.json node for block or variation. Features - * promoted to their own selector are removed from it. - * @return array The style declarations for the node's features with custom - * selectors. + * @param array $metadata The related block metadata containing selectors. + * @param array $node A merged theme.json node for block or variation. Features + * promoted to their own selector are removed from it. + * @return array The style declarations for the node's features with custom + * selectors, keyed by selector. + * + * @phpstan-param array{ selectors?: array> } $metadata + * @phpstan-return array> */ protected function get_feature_declarations_for_node( $metadata, &$node ) { $declarations = array(); From d4dbb9598641a6a4025c01de8396116dbbd92680 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Sun, 25 Oct 2026 14:23:50 -0700 Subject: [PATCH 05/11] Check that a node feature is an array before reading its subfeatures `get_feature_declarations_for_node()` only checked that the feature's selectors were an array before reading `$node[ $feature ][ $subfeature ]`, but the node comes from theme.json data, where the feature value may be a string or another non-array value. Such a value has no subfeatures, and `empty()` already treated every lookup on it as empty, so skipping the subfeature loop for it keeps the behavior the same while making the check explicit. This resolves the PHPStan error for accessing an offset on `mixed`. Co-Authored-By: Claude Opus 5.5 --- src/wp-includes/class-wp-theme-json.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/class-wp-theme-json.php b/src/wp-includes/class-wp-theme-json.php index 1026b9223fa8b..8f043a842dc8d 100644 --- a/src/wp-includes/class-wp-theme-json.php +++ b/src/wp-includes/class-wp-theme-json.php @@ -6079,7 +6079,7 @@ protected function get_feature_declarations_for_node( $metadata, &$node ) { continue; } - if ( is_array( $feature_selectors ) ) { + if ( is_array( $feature_selectors ) && is_array( $node[ $feature ] ) ) { foreach ( $feature_selectors as $subfeature => $subfeature_selector ) { if ( 'root' === $subfeature || empty( $node[ $feature ][ $subfeature ] ) ) { continue; From d55d3052f6d93e82256994669aa39d9e6d14194b Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Sun, 25 Oct 2026 15:07:29 -0700 Subject: [PATCH 06/11] Read the subfeatures from a local copy of the feature styles Checking `is_array( $node[ $feature ] )` was not enough for PHPStan, since unsetting `$node[ $feature ][ $subfeature ]` inside the loop made it forget the narrowed type on the next iteration. Copy the feature styles to a local variable, read and unset the subfeatures there, and write the copy back to the node after the loop, which leaves the node exactly as before. This resolves the PHPStan error for accessing an offset on `mixed`. Co-Authored-By: Claude Opus 5.5 --- src/wp-includes/class-wp-theme-json.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/wp-includes/class-wp-theme-json.php b/src/wp-includes/class-wp-theme-json.php index 8f043a842dc8d..cd26e6173253a 100644 --- a/src/wp-includes/class-wp-theme-json.php +++ b/src/wp-includes/class-wp-theme-json.php @@ -6080,8 +6080,9 @@ protected function get_feature_declarations_for_node( $metadata, &$node ) { } if ( is_array( $feature_selectors ) && is_array( $node[ $feature ] ) ) { + $feature_styles = $node[ $feature ]; foreach ( $feature_selectors as $subfeature => $subfeature_selector ) { - if ( 'root' === $subfeature || empty( $node[ $feature ][ $subfeature ] ) ) { + if ( 'root' === $subfeature || empty( $feature_styles[ $subfeature ] ) ) { continue; } @@ -6091,7 +6092,7 @@ protected function get_feature_declarations_for_node( $metadata, &$node ) { */ $subfeature_node = array( $feature => array( - $subfeature => $node[ $feature ][ $subfeature ], + $subfeature => $feature_styles[ $subfeature ], ), ); @@ -6112,8 +6113,9 @@ protected function get_feature_declarations_for_node( $metadata, &$node ) { * styles will be included under its own selector not the * block's. */ - unset( $node[ $feature ][ $subfeature ] ); + unset( $feature_styles[ $subfeature ] ); } + $node[ $feature ] = $feature_styles; } /* From f61ef902a41fc0e1cab17550fa7681954f49e2dd Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Sun, 25 Oct 2026 15:07:46 -0700 Subject: [PATCH 07/11] Describe the shape of the theme.json data property Give the `$theme_json` property a `@phpstan-var` shape for its top-level `version`, `settings`, and `styles` keys, leaving it open to the others. Reading `$this->theme_json['settings']` or `['styles']` then yields an array rather than `mixed`, which resolves the PHPStan errors at the higher rule levels where these are passed to `compute_style_properties()` and the other style helpers, or have offsets read from them. The methods that build the data still return a plain `array`, so the assignments to the property are now reported instead, until those return types are narrowed as well. Co-Authored-By: Claude Opus 5.5 --- src/wp-includes/class-wp-theme-json.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/wp-includes/class-wp-theme-json.php b/src/wp-includes/class-wp-theme-json.php index cd26e6173253a..e9d4d0c5481fd 100644 --- a/src/wp-includes/class-wp-theme-json.php +++ b/src/wp-includes/class-wp-theme-json.php @@ -24,6 +24,7 @@ class WP_Theme_JSON { * * @since 5.8.0 * @var array + * @phpstan-var array{ version?: int, settings?: array, styles?: array, ... } */ protected $theme_json = null; From cca58677273bfa839e78bce82bf131acd9283d68 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Sun, 25 Oct 2026 15:08:16 -0700 Subject: [PATCH 08/11] Describe the declarations returned by compute_style_properties() Give `compute_style_properties()` a `@phpstan-return` with the same declaration shape that `get_state_declarations_with_text_clip_escapes()` documents. Its callers, including `get_feature_declarations_for_node()`, then see a list of declarations rather than a plain array, which resolves their PHPStan errors at the higher rule levels. This moves some errors elsewhere at those levels: to the method's own body, whose property names come from the untyped `$properties` parameter and whose font size value may be `null` as far as PHPStan can tell, and to the callers that pass a declaration value to `is_safe_css_declaration()`, which expects a string. Co-Authored-By: Claude Opus 5.5 --- src/wp-includes/class-wp-theme-json.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/wp-includes/class-wp-theme-json.php b/src/wp-includes/class-wp-theme-json.php index e9d4d0c5481fd..e3f0721343205 100644 --- a/src/wp-includes/class-wp-theme-json.php +++ b/src/wp-includes/class-wp-theme-json.php @@ -3188,6 +3188,8 @@ protected static function flatten_tree( $tree, $prefix = '', $token = '--' ) { * @param string $selector The style block selector. * @param bool $use_root_padding Whether to add custom properties at root level. * @return array Returns the modified $declarations. + * + * @phpstan-return list */ protected static function compute_style_properties( $styles, $settings = array(), $properties = null, $theme_json = null, $selector = null, $use_root_padding = null ) { if ( empty( $styles ) ) { From 8b67af19724df2f75a82bdae7a2147fdb6c9435b Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Sun, 25 Oct 2026 17:20:32 -0700 Subject: [PATCH 09/11] Describe the attribute shapes in the shadow registration test Add a `Shadow_Attributes` type alias for the `style` and `shadow` attribute definitions, and use it to narrow the `$value` and `$expected` parameters of `test_wp_register_shadow_support()` and the rows of its data provider. The data provider's keys are also narrowed to non-falsy strings, and its description references the test method with `{@see}`. Co-Authored-By: Claude Opus 5.5 --- tests/phpunit/tests/block-supports/shadow.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/tests/phpunit/tests/block-supports/shadow.php b/tests/phpunit/tests/block-supports/shadow.php index 43b00601f7c7b..7ab547b68b537 100644 --- a/tests/phpunit/tests/block-supports/shadow.php +++ b/tests/phpunit/tests/block-supports/shadow.php @@ -3,6 +3,11 @@ * @group block-supports * * @covers ::wp_apply_shadow_support + * + * @phpstan-type Shadow_Attributes array{ + * style?: array{ type: 'object', default?: array{ shadow: non-empty-string } }, + * shadow?: array{ type: 'string', default?: non-empty-string }, + * } */ class Tests_Block_Supports_Shadow extends WP_UnitTestCase { /** @@ -59,6 +64,9 @@ private function register_shadow_block_with_support( $block_name, $supports = ar * @param bool $support Shadow block support configuration. * @param array>|null $value Attributes array for the block. * @param array> $expected Expected attributes for the block. + * + * @phpstan-param Shadow_Attributes|null $value + * @phpstan-param Shadow_Attributes $expected */ public function test_wp_register_shadow_support( bool $support, ?array $value, array $expected ) { $this->test_block_name = 'test/shadow-attributes'; @@ -82,9 +90,11 @@ public function test_wp_register_shadow_support( bool $support, ?array $value, a } /** - * Data provider for test_wp_register_shadow_support(). + * Data provider for {@see self::test_wp_register_shadow_support()}. + * + * @return array> * - * @return array> + * @phpstan-return array */ public static function data_wp_register_shadow_support(): array { return array( From 23f45f4641df4db3fb117ab03432f9973094649c Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Sun, 25 Oct 2026 17:21:52 -0700 Subject: [PATCH 10/11] Use plain tags for the shadow registration test shapes Tests are not published in the developer docs, so the shapes can go in the regular `@param` and `@return` tags directly, without a type alias or `@phpstan-` prefixed tags. Co-Authored-By: Claude Opus 5.5 --- tests/phpunit/tests/block-supports/shadow.php | 34 +++++++++++-------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/tests/phpunit/tests/block-supports/shadow.php b/tests/phpunit/tests/block-supports/shadow.php index 7ab547b68b537..6553c1888a826 100644 --- a/tests/phpunit/tests/block-supports/shadow.php +++ b/tests/phpunit/tests/block-supports/shadow.php @@ -3,11 +3,6 @@ * @group block-supports * * @covers ::wp_apply_shadow_support - * - * @phpstan-type Shadow_Attributes array{ - * style?: array{ type: 'object', default?: array{ shadow: non-empty-string } }, - * shadow?: array{ type: 'string', default?: non-empty-string }, - * } */ class Tests_Block_Supports_Shadow extends WP_UnitTestCase { /** @@ -61,12 +56,15 @@ private function register_shadow_block_with_support( $block_name, $supports = ar * * @dataProvider data_wp_register_shadow_support * - * @param bool $support Shadow block support configuration. - * @param array>|null $value Attributes array for the block. - * @param array> $expected Expected attributes for the block. - * - * @phpstan-param Shadow_Attributes|null $value - * @phpstan-param Shadow_Attributes $expected + * @param bool $support Shadow block support configuration. + * @param array{ + * style?: array{ type: 'object', default?: array{ shadow: non-empty-string } }, + * shadow?: array{ type: 'string', default?: non-empty-string }, + * }|null $value Attributes array for the block. + * @param array{ + * style?: array{ type: 'object', default?: array{ shadow: non-empty-string } }, + * shadow?: array{ type: 'string', default?: non-empty-string }, + * } $expected Expected attributes for the block. */ public function test_wp_register_shadow_support( bool $support, ?array $value, array $expected ) { $this->test_block_name = 'test/shadow-attributes'; @@ -92,9 +90,17 @@ public function test_wp_register_shadow_support( bool $support, ?array $value, a /** * Data provider for {@see self::test_wp_register_shadow_support()}. * - * @return array> - * - * @phpstan-return array + * @return array */ public static function data_wp_register_shadow_support(): array { return array( From 0dcc7b4a5e23df400c79b99576933957263a8351 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Sun, 25 Oct 2026 17:23:11 -0700 Subject: [PATCH 11/11] Use a type alias for the shadow registration test shapes Define the attribute shape once as a `Shadow_Attributes` type alias and reference it from the plain `@param` and `@return` tags, rather than repeating the shape for the test method's parameters and the data provider's rows. Co-Authored-By: Claude Opus 5.5 --- tests/phpunit/tests/block-supports/shadow.php | 29 ++++++------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/tests/phpunit/tests/block-supports/shadow.php b/tests/phpunit/tests/block-supports/shadow.php index 6553c1888a826..5376d3f6be78a 100644 --- a/tests/phpunit/tests/block-supports/shadow.php +++ b/tests/phpunit/tests/block-supports/shadow.php @@ -3,6 +3,11 @@ * @group block-supports * * @covers ::wp_apply_shadow_support + * + * @phpstan-type Shadow_Attributes array{ + * style?: array{ type: 'object', default?: array{ shadow: non-empty-string } }, + * shadow?: array{ type: 'string', default?: non-empty-string }, + * } */ class Tests_Block_Supports_Shadow extends WP_UnitTestCase { /** @@ -56,15 +61,9 @@ private function register_shadow_block_with_support( $block_name, $supports = ar * * @dataProvider data_wp_register_shadow_support * - * @param bool $support Shadow block support configuration. - * @param array{ - * style?: array{ type: 'object', default?: array{ shadow: non-empty-string } }, - * shadow?: array{ type: 'string', default?: non-empty-string }, - * }|null $value Attributes array for the block. - * @param array{ - * style?: array{ type: 'object', default?: array{ shadow: non-empty-string } }, - * shadow?: array{ type: 'string', default?: non-empty-string }, - * } $expected Expected attributes for the block. + * @param bool $support Shadow block support configuration. + * @param Shadow_Attributes|null $value Attributes array for the block. + * @param Shadow_Attributes $expected Expected attributes for the block. */ public function test_wp_register_shadow_support( bool $support, ?array $value, array $expected ) { $this->test_block_name = 'test/shadow-attributes'; @@ -90,17 +89,7 @@ public function test_wp_register_shadow_support( bool $support, ?array $value, a /** * Data provider for {@see self::test_wp_register_shadow_support()}. * - * @return array + * @return array */ public static function data_wp_register_shadow_support(): array { return array(