Skip to content

Read tag types with phpstan/phpdoc-parser and export hash notation - #305

Draft
sirreal wants to merge 3 commits into
masterfrom
adopt-phpstan-phpdoc-parser
Draft

sirreal wants to merge 3 commits into
masterfrom
adopt-phpstan-phpdoc-parser

Conversation

@sirreal

@sirreal sirreal commented Oct 7, 2026

Copy link
Copy Markdown
Member

Read a tag's type with phpstan/phpdoc-parser instead of phpDocumentor's whitespace split, and export WordPress hash notation as structured data.

reflection-docblock 2.x splits a tag's content on the first whitespace and its type on every |. Today @param array<string, mixed> $l10n The data itself. (from wp_localize_script()) exports:

{ "types": ["\\array<string,"], "variable": "", "content": "mixed&gt; $l10n The data itself." }

With this PR:

{ "types": ["array<string, mixed>"], "variable": "$l10n", "content": "The data itself." }

Types

phpDocumentor still splits the DocBlock into descriptions and tags. For @param, @var, @property*, @return and @throws, TypeParser reads the type at the start of the tag content, followed by the variable and description. @method is unchanged.

The types contract is unchanged: one string per top-level union member (UnionTypeNode->types). Each member keeps its source spelling, with class names resolved against the DocBlock's namespace and use aliases as phpDocumentor resolves them. Resolution now also applies inside generics, shapes, callables, intersections and Foo::CONST_* patterns. Keywords, PHPStan pseudo-types (list, class-string, non-empty-string, int<0, max>, …), shape keys and the DocBlock's own @template names are not prefixed. Members are printed from the original tokens, with resolved class names substituted, not from the AST's string form. A multi-line array shape is printed on one line.

wp_ai_client_prompt()'s $prompt (#268) now exports:

string
\WordPress\AiClient\Messages\DTO\MessagePart
\WordPress\AiClient\Messages\DTO\Message
array
list<string|\WordPress\AiClient\Messages\DTO\MessagePart|array>
list<\WordPress\AiClient\Messages\DTO\Message>
null

If TypeParser throws, or the parsed type is not followed by whitespace or the end of the content ((bool): true, string|null.), the tag is exported as it is today. The same applies when whitespace at the top level separates a type from a following bracket (string <code>, array <int>).

Hash notation

When a typed tag's description is a { … } hash, the tag gets a hash key beside content. content is unchanged byte for byte, so the theme's text parsing keeps working until it reads hash. A @type line ending in { opens a nested hash, closed by a line holding only }.

'hash' => array(
	'content' => 'Text before the first @type line.',
	'items'   => array(
		array(
			'types'    => array( 'array<string, mixed>' ), // Read like a tag's types.
			'variable' => '$meta',                         // As written: `$label`, `$0`, `...$0`, or ''.
			'content'  => 'Description.',
			'hash'     => array( /* Nested, same shape. */ ),
		),
	),
),

@return array $results { is also read. Hashes with unbalanced braces get no hash key. In 7.1.2, the only case is the wp_privacy_personal_data_email_content docblock, which lacks its closing }. Part of #119; rendering from hash is theme work.

Import

The importer stores tags with update_post_meta() and applies no KSES there, so generics and hash are stored as exported. A test covers this. make_args_safe() does run wp_filter_kses(), but only on the template-side wp_parser_get_arguments filter. Namespace separators are still unslashed on import (#287).

Corpus diff (WordPress 7.1.2)

Local run of tools/export-corpus.php on master and on this branch: 1,429 hunks. 822 tag entries change type, content or variable; 669 gain hash.

  • 467 types cut at whitespace inside brackets are now whole. Their descriptions lose the leaked tail, and 145 recover their variable.
  • 16 unions inside brackets (list<int|string>, (string|null)[][]) are no longer split.
  • 199 keywords and pseudo-types lose a namespace prefix: \array<string,string>, \SimplePie\?string, \WpOrg\Requests\iterable.
  • 133 change resolution, mostly class names inside generics: \WordPress\AiClient\Builders\list<Message> becomes list<\WordPress\AiClient\Messages\DTO\Message>. This also fixes wrong resolutions: \SimplePie\Cache\InvalidArgumentException&Throwable becomes \Psr\SimpleCache\InvalidArgumentException&\Throwable per the file's use, and \?WP_Error becomes ?\WP_Error.
  • 6 by-reference parameters (Type &$x) recover their variable.
  • 1 literal union, -1|0|1, was exported as \SimplePie\-1, \SimplePie\1, dropping 0; it is now three members.
  • The 669 hashes contain 3,826 items, nested up to 4 levels: 529 on @param, 137 on @return and 3 on @var.

No exported type in the corpus has unbalanced brackets after this change. No variable is lost, and every content change removes a leaked type fragment.

Known limitations:

  • @template names declared on a class are not visible from a method or property DocBlock. SimplePie's Psr7Compatible exports as \SimplePie\HTTP\Psr7Compatible inside a conditional type, as it is resolved on master.
  • The existing global-namespace cleanup in parse_files() strips the leading \ only from a whole bare name. WP_Post stays bare, while list<\WP_Post> and ?\WP_Post keep the backslash.

Relation to other PRs

Supersedes #270, which fixes the type split with a hand-written bracket scanner. This PR uses PHPStan's grammar instead, keeps the current export contract, and leaves theme rendering to wporg-developer.

Unlike #247, this PR does not move the parser onto php-parser 5 or replace reflection-docblock. It adds phpstan/phpdoc-parser ^2.3 (PHP ^7.4 || ^8.0, matching composer.json) and replaces only how a tag's type, variable and description are read.

Rendering generics on developer.wordpress.org also needs WordPress/wporg-developer#598, which escapes types in the theme.

Testing

npm test in wp-env passed on PHP 7.4.33 and 8.4.26 (193 tests, 452 assertions). New tests cover:

  • generics with whitespace, nested unions, array shapes (including multi-line), nullables, intersections, callables, pseudo-types, templates and class-constant patterns
  • class-name resolution inside generics against namespaces and aliases
  • @return generics, by-reference variables and untyped parameters
  • fallback for tags TypeParser rejects
  • the wp_localize_script(), wp_ai_client_prompt() and wp_register_ability() DocBlocks from core
  • nested hashes with $0, ...$0, unnamed entries, continuation lines, generics with whitespace and unbalanced braces
  • a direct data-provider test of the type reader
  • import of generic types and hash into _wp-parser_tags

Fixes #304
Fixes #268
Part of #119

phpDocumentor's reflection-docblock 2.x splits a tag's content on the
first whitespace and its type on every `|`, with no bracket awareness.
`@param array<string, mixed> $l10n Desc` exports the type
`array<string,`, no variable, and the description `mixed> $l10n Desc`;
`list<string|MessagePart|array>` becomes three types. Generic arguments
are never resolved, and PHPDoc keywords such as `list`, `?string` or
`class-string<...>` are prefixed with the namespace as if they were
class names.

Read the type at the start of `@param`, `@var`, `@property*`, `@return`
and `@throws` content with phpstan/phpdoc-parser's TypeParser, then the
variable and description after it. phpDocumentor still splits the
DocBlock into tags and descriptions; only how a tag's type, variable and
description are derived changes.

The exported `types` array keeps its contract: one string per top-level
union member, each printed as written, with class names resolved against
the DocBlock's namespace and `use` aliases as phpDocumentor resolved
them, now including names inside generics, shapes, callables and class
constant patterns. Keywords, PHPStan pseudo-types, shape keys and the
DocBlock's own `@template` names are not prefixed. A by-reference
`&$name` now yields the variable name.

When PHPStan's parser rejects a tag, or the type does not end at
whitespace, the tag is exported exactly as before.
WordPress documents array keys with its own hash notation: a tag
description of the form `{ intro @type Type $key Desc. ... }`, nested
when a `@type` line ends in `{`. The parser exports it only as flat text
in the tag's `content`, which the theme re-parses at render time by
splitting each `@type` line on spaces, so a generic such as
`array<string, mixed>` breaks there too.

When a typed tag's description is a hash, also export a `hash` key:
`content` holds the text before the first `@type` line, and `items` one
entry per `@type` line with `types` (read like a tag's, falling back to
phpDocumentor's reading when PHPStan's parser rejects it), `variable`
(as written: `$label`, `$0`, `...$0`, or empty), `content`, and a nested
`hash` when the line opens one. A `@return` that names the array before
the brace (`@return array $args {`) is read the same way. A hash whose
braces do not balance gets no `hash` key.

The tag's `content` string is unchanged, so the theme keeps working
until it reads `hash`.
Generic types now reach the export intact, and typed tags may carry a
`hash` key. The importer stores tags in `_wp-parser_tags` with
update_post_meta(), which applies no KSES, so `<...>` in types and the
nested `hash` structure are stored as exported and need no importer
change.

`make_args_safe()`, which does run wp_filter_kses(), is attached to the
`wp_parser_get_arguments` filter in the plugin's template functions, not
to import.

Namespace separators are a separate case: update_post_meta() unslashes
them, which #287 addresses.
@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

Corpus diff

1430 hunks, +33248 -2129 lines, over WordPress 7.1.2, parser at a1ba4bd (base) vs 80a5fc7 (PR head, merged into base). Every hunk must be intended and explained in the PR. Only 33 of 1430 hunks fit below; the download has them all. Download corpus.diff.

corpus.diff (33 of 1430 hunks)
--- base
+++ head
@@ -4596,7 +4596,33 @@
                             "types": [
                                 "array"
                             ],
-                            "variable": "$request"
+                            "variable": "$request",
+                            "hash": {
+                                "content": "The array of request data. All arguments are optional and may be empty.",
+                                "items": [
+                                    {
+                                        "types": [
+                                            "string"
+                                        ],
+                                        "variable": "$app_name",
+                                        "content": "The suggested name of the application."
+                                    },
+                                    {
+                                        "types": [
+                                            "string"
+                                        ],
+                                        "variable": "$success_url",
+                                        "content": "The URL the user will be redirected to after approving the application."
+                                    },
+                                    {
+                                        "types": [
+                                            "string"
+                                        ],
+                                        "variable": "$reject_url",
+                                        "content": "The URL the user will be redirected to after rejecting the application."
+                                    }
+                                ]
+                            }
                         },
                         {
                             "name": "param",
@@ -13307,7 +13333,62 @@
                             "types": [
                                 "array"
                             ],
-                            "variable": "$dropdown_args"
+                            "variable": "$dropdown_args",
+                            "hash": {
+                                "content": "An array of taxonomy parent drop-down arguments.",
+                                "items": [
+                                    {
+                                        "types": [
+                                            "int",
+                                            "bool"
+                                        ],
+                                        "variable": "$hide_empty",
+                                        "content": "Whether to hide terms not attached to any posts. Default 0."
+                                    },
+                                    {
+                                        "types": [
+                                            "bool"
+                                        ],
+                                        "variable": "$hide_if_empty",
+                                        "content": "Whether to hide the drop-down if no terms exist. Default false."
+                                    },
+                                    {
+                                        "types": [
+                                            "string"
+                                        ],
+                                        "variable": "$taxonomy",
+                                        "content": "The taxonomy slug."
+                                    },
+                                    {
+                                        "types": [
+                                            "string"
+                                        ],
+                                        "variable": "$name",
+                                        "content": "Value of the name attribute to use for the drop-down select element.<br>Default 'parent'."
+                                    },
+                                    {
+                                        "types": [
+                                            "string"
+                                        ],
+                                        "variable": "$orderby",
+                                        "content": "The field to order by. Default 'name'."
+                                    },
+                                    {
+                                        "types": [
+                                            "bool"
+                                        ],
+                                        "variable": "$hierarchical",
+                                        "content": "Whether the taxonomy is hierarchical. Default true."
+                                    },
+                                    {
+                                        "types": [
+                                            "string"
+                                        ],
+                                        "variable": "$show_option_none",
+                                        "content": "Label to display if there are no terms. Default 'None'."
+                                    }
+                                ]
+                            }
                         },
                         {
                             "name": "param",
@@ -28892,7 +28973,38 @@
                                     "types": [
                                         "array"
                                     ],
-                                    "variable": "$args"
+                                    "variable": "$args",
+                                    "hash": {
+                                        "content": "An array of callable exporters of personal data. Default empty array.",
+                                        "items": [
+                                            {
+                                                "types": [
+                                                    "array"
+                                                ],
+                                                "variable": "...$0",
+                                                "content": "",
+                                                "hash": {
+                                                    "content": "Array of personal data exporters.",
+                                                    "items": [
+                                                        {
+                                                            "types": [
+                                                                "callable"
+                                                            ],
+                                                            "variable": "$callback",
+                                                            "content": "Callable exporter function that accepts an email address and a page number and returns an array of name =&gt; value pairs of personal data."
+                                                        },
+                                                        {
+                                                            "types": [
+                                                                "string"
+                                                            ],
+                                                            "variable": "$exporter_friendly_name",
+                                                            "content": "Translated user facing friendly name for the exporter."
+                                                        }
+                                                    ]
+                                                }
+                                            }
+                                        ]
+                                    }
                                 }
                             ]
                         }
@@ -29404,7 +29516,38 @@
                                     "types": [
                                         "array"
                                     ],
-                                    "variable": "$args"
+                                    "variable": "$args",
+                                    "hash": {
+                                        "content": "An array of callable erasers of personal data. Default empty array.",
+                                        "items": [
+                                            {
+                                                "types": [
+                                                    "array"
+                                                ],
+                                                "variable": "...$0",
+                                                "content": "",
+                                                "hash": {
+                                                    "content": "Array of personal data exporters.",
+                                                    "items": [
+                                                        {
+                                                            "types": [
+                                                                "callable"
+                                                            ],
+                                                            "variable": "$callback",
+                                                            "content": "Callable eraser that accepts an email address and a page number, and returns an array with boolean values for whether items were removed or retained and any messages from the eraser, as well as if additional pages are available."
+                                                        },
+                                                        {
+                                                            "types": [
+                                                                "string"
+                                                            ],
+                                                            "variable": "$exporter_friendly_name",
+                                                            "content": "Translated user facing friendly name for the eraser."
+                                                        }
+                                                    ]
+                                                }
+                                            }
+                                        ]
+                                    }
                                 }
                             ]
                         }
@@ -29436,7 +29579,40 @@
                                     "types": [
                                         "array"
                                     ],
-                                    "variable": "$response"
+                                    "variable": "$response",
+                                    "hash": {
+                                        "content": "The personal data for the given exporter and page number.",
+                                        "items": [
+                                            {
+                                                "types": [
+                                                    "bool"
+                                                ],
+                                                "variable": "$items_removed",
+                                                "content": "Whether items were actually removed or not."
+                                            },
+                                            {
+                                                "types": [
+                                                    "bool"
+                                                ],
+                                                "variable": "$items_retained",
+                                                "content": "Whether items were retained or not."
+                                            },
+                                            {
+                                                "types": [
+                                                    "string[]"
+                                                ],
+                                                "variable": "$messages",
+                                                "content": "An array of messages to add to the personal data export file."
+                                            },
+                                            {
+                                                "types": [
+                                                    "bool"
+                                                ],
+                                                "variable": "$done",
+                                                "content": "Whether the eraser is finished or not."
+                                            }
+                                        ]
+                                    }
                                 },
                                 {
                                     "name": "param",
@@ -31122,7 +31298,103 @@
                             "types": [
                                 "array"
                             ],
-                            "variable": "$linkdata"
+                            "variable": "$linkdata",
+                            "hash": {
+                                "content": "Elements that make up the link to insert.",
+                                "items": [
+                                    {
+                                        "types": [
+                                            "int"
+                                        ],
+                                        "variable": "$link_id",
+                                        "content": "Optional. The ID of the existing link if updating."
+                                    },
+                                    {
+                                        "types": [
+                                            "string"
+                                        ],
+                                        "variable": "$link_url",
+                                        "content": "The URL the link points to."
+                                    },
+                                    {
+                                        "types": [
+                                            "string"
+                                        ],
+                                        "variable": "$link_name",
+                                        "content": "The title of the link."
+                                    },
+                                    {
+                                        "types": [
+                                            "string"
+                                        ],
+                                        "variable": "$link_image",
+                                        "content": "Optional. A URL of an image."
+                                    },
+                                    {
+                                        "types": [
+                                            "string"
+                                        ],
+                                        "variable": "$link_target",
+                                        "content": "Optional. The target element for the anchor tag."
+                                    },
+                                    {
+                                        "types": [
+                                            "string"
+                                        ],
+                                        "variable": "$link_description",
+                                        "content": "Optional. A short description of the link."
+                                    },
+                                    {
+                                        "types": [
+                                            "string"
+                                        ],
+                                        "variable": "$link_visible",
+                                        "content": "Optional. 'Y' means visible, anything else means not."
+                                    },
+                                    {
+                                        "types": [
+                                            "int"
+                                        ],
+                                        "variable": "$link_owner",
+                                        "content": "Optional. A user ID."
+                                    },
+                                    {
+                                        "types": [
+                                            "int"
+                                        ],
+                                        "variable": "$link_rating",
+                                        "content": "Optional. A rating for the link."
+                                    },
+                                    {
+                                        "types": [
+                                            "string"
+                                        ],
+                                        "variable": "$link_rel",
+                                        "content": "Optional. A relationship of the link to you."
+                                    },
+                                    {
+                                        "types": [
+                                            "string"
+                                        ],
+                                        "variable": "$link_notes",
+                                        "content": "Optional. An extended description of or notes on the link."
+                                    },
+                                    {
+                                        "types": [
+                                            "string"
+                                        ],
+                                        "variable": "$link_rss",
+                                        "content": "Optional. A URL of an associated RSS feed."
+                                    },
+                                    {
+                                        "types": [
+                                            "int"
+                                        ],
+                                        "variable": "$link_category",
+                                        "content": "Optional. The term ID of the link category.<br>If empty, uses default link category."
+                                    }
+                                ]
+                            }
                         },
                         {
                             "name": "param",
@@ -33649,7 +33921,33 @@
                                     "types": [
                                         "array"
                                     ],
-                                    "variable": "$args"
+                                    "variable": "$args",
+                                    "hash": {
+                                        "content": "Optional. Arguments for upgrading WordPress core. Default empty array.",
+                                        "items": [
+                                            {
+                                                "types": [
+                                                    "bool"
+                                                ],
+                                                "variable": "$pre_check_md5",
+                                                "content": "Whether to check the file checksums before attempting the upgrade. Default true."
+                                            },
+                                            {
+                                                "types": [
+                                                    "bool"
+                                                ],
+                                                "variable": "$attempt_rollback",
+                                                "content": "Whether to attempt to rollback the chances if there is a problem. Default false."
+                                            },
+                                            {
+                                                "types": [
+                                                    "bool"
+                                                ],
+                                                "variable": "$do_rollback",
+                                                "content": "Whether to perform this \"upgrade\" as a rollback.<br>Default false."
+                                            }
+                                        ]
+                                    }
                                 },
                                 {
                                     "name": "return",
@@ -46737,7 +47035,19 @@
                                     "types": [
                                         "array"
                                     ],
-                                    "variable": "$args"
+                                    "variable": "$args",
+                                    "hash": {
+                                        "content": "Other arguments for upgrading multiple language packs. Default empty array.",
+                                        "items": [
+                                            {
+                                                "types": [
+                                                    "bool"
+                                                ],
+                                                "variable": "$clear_update_cache",
+                                                "content": "Whether to clear the update cache when done.<br>Default true."
+                                            }
+                                        ]
+                                    }
                                 },
                                 {
                                     "name": "return",
@@ -56463,7 +56773,19 @@
                                     "types": [
                                         "array"
                                     ],
-                                    "variable": "$args"
+                                    "variable": "$args",
+                                    "hash": {
+                                        "content": "Optional. Other arguments for installing a plugin package. Default empty array.",
+                                        "items": [
+                                            {
+                                                "types": [
+                                                    "bool"
+                                                ],
+                                                "variable": "$clear_update_cache",
+                                                "content": "Whether to clear the plugin updates cache if successful.<br>Default true."
+                                            }
+                                        ]
+                                    }
                                 },
                                 {
                                     "name": "return",
@@ -56639,7 +56961,19 @@
                                     "types": [
                                         "array"
                                     ],
-                                    "variable": "$args"
+                                    "variable": "$args",
+                                    "hash": {
+                                        "content": "Optional. Other arguments for upgrading a plugin package. Default empty array.",
+                                        "items": [
+                                            {
+                                                "types": [
+                                                    "bool"
+                                                ],
+                                                "variable": "$clear_update_cache",
+                                                "content": "Whether to clear the plugin updates cache if successful.<br>Default true."
+                                            }
+                                        ]
+                                    }
                                 },
                                 {
                                     "name": "return",
@@ -56841,7 +57175,19 @@
                                     "types": [
                                         "array"
                                     ],
-                                    "variable": "$args"
+                                    "variable": "$args",
+                                    "hash": {
+                                        "content": "Optional. Other arguments for upgrading several plugins at once.",
+                                        "items": [
+                                            {
+                                                "types": [
+                                                    "bool"
+                                                ],
+                                                "variable": "$clear_update_cache",
+                                                "content": "Whether to clear the plugin updates cache if successful. Default true."
+                                            }
+                                        ]
+                                    }
                                 },
                                 {
                                     "name": "return",
@@ -59966,7 +60312,19 @@
                                     "types": [
                                         "array"
                                     ],
-                                    "variable": "$args"
+                                    "variable": "$args",
+                                    "hash": {
+                                        "content": "Optional. Other arguments for installing a theme package. Default empty array.",
+                                        "items": [
+                                            {
+                                                "types": [
+                                                    "bool"
+                                                ],
+                                                "variable": "$clear_update_cache",
+                                                "content": "Whether to clear the updates cache if successful.<br>Default true."
+                                            }
+                                        ]
+                                    }
                                 },
                                 {
                                     "name": "return",
@@ -60128,7 +60486,19 @@
                                     "types": [
                                         "array"
                                     ],
-                                    "variable": "$args"
+                                    "variable": "$args",
+                                    "hash": {
+                                        "content": "Optional. Other arguments for upgrading a theme. Default empty array.",
+                                        "items": [
+                                            {
+                                                "types": [
+                                                    "bool"
+                                                ],
+                                                "variable": "$clear_update_cache",
+                                                "content": "Whether to clear the update cache if successful.<br>Default true."
+                                            }
+                                        ]
+                                    }
                                 },
                                 {
                                     "name": "return",
@@ -60325,7 +60695,19 @@
                                     "types": [
                                         "array"
                                     ],
-                                    "variable": "$args"
+                                    "variable": "$args",
+                                    "hash": {
+                                        "content": "Optional. Other arguments for upgrading several themes at once. Default empty array.",
+                                        "items": [
+                                            {
+                                                "types": [
+                                                    "bool"
+                                                ],
+                                                "variable": "$clear_update_cache",
+                                                "content": "Whether to clear the update cache if successful.<br>Default true."
+                                            }
+                                        ]
+                                    }
                                 },
                                 {
                                     "name": "return",
@@ -66688,7 +67070,40 @@
                                             "types": [
                                                 "array"
                                             ],
-                                            "variable": "$email"
+                                            "variable": "$email",
+                                            "hash": {
+                                                "content": "Array of email arguments that will be passed to wp_mail().",
+                                                "items": [
+                                                    {
+                                                        "types": [
+                                                            "string"
+                                                        ],
+                                                        "variable": "$to",
+                                                        "content": "The email recipient. An array of emails can be returned, as handled by wp_mail()."
+                                                    },
+                                                    {
+                                                        "types": [
+                                                            "string"
+                                                        ],
+                                                        "variable": "$subject",
+                                                        "content": "The email's subject."
+                                                    },
+                                                    {
+                                                        "types": [
+                                                            "string"
+                                                        ],
+                                                        "variable": "$body",
+                                                        "content": "The email message body."
+                                                    },
+                                                    {
+                                                        "types": [
+                                                            "string"
+                                                        ],
+                                                        "variable": "$headers",
+                                                        "content": "Any email headers, defaults to no headers."
+                                                    }
+                                                ]
+                                            }
                                         },
                                         {
                                             "name": "param",
@@ -67402,7 +67817,40 @@
                                             "types": [
                                                 "array"
                                             ],
-                                            "variable": "$email"
+                                            "variable": "$email",
+                                            "hash": {
+                                                "content": "Array of email arguments that will be passed to wp_mail().",
+                                                "items": [
+                                                    {
+                                                        "types": [
+                                                            "string"
+                                                        ],
+                                                        "variable": "$to",
+                                                        "content": "The email recipient. An array of emails can be returned, as handled by wp_mail()."
+                                                    },
+                                                    {
+                                                        "types": [
+                                                            "string"
+                                                        ],
+                                                        "variable": "$subject",
+                                                        "content": "The email's subject."
+                                                    },
+                                                    {
+                                                        "types": [
+                                                            "string"
+                                                        ],
+                                                        "variable": "$body",
+                                                        "content": "The email message body."
+                                                    },
+                                                    {
+                                                        "types": [
+                                                            "string"
+                                                        ],
+                                                        "variable": "$headers",
+                                                        "content": "Any email headers, defaults to no headers."
+                                                    }
+                                                ]
+                                            }
                                         },
                                         {
                                             "name": "param",
@@ -67821,7 +68269,40 @@
                                             "types": [
                                                 "array"
                                             ],
-                                            "variable": "$email"
+                                            "variable": "$email",
+                                            "hash": {
+                                                "content": "Array of email arguments that will be passed to wp_mail().",
+                                                "items": [
+                                                    {
+                                                        "types": [
+                                                            "string"
+                                                        ],
+                                                        "variable": "$to",
+                                                        "content": "The email recipient. An array of emails can be returned, as handled by wp_mail()."
+                                                    },
+                                                    {
+                                                        "types": [
+                                                            "string"
+                                                        ],
+                                                        "variable": "$subject",
+                                                        "content": "Email subject."
+                                                    },
+                                                    {
+                                                        "types": [
+                                                            "string"
+                                                        ],
+                                                        "variable": "$body",
+                                                        "content": "Email message body."
+                                                    },
+                                                    {
+                                                        "types": [
+                                                            "string"
+                                                        ],
+                                                        "variable": "$headers",
+                                                        "content": "Any email headers. Default empty."
+                                                    }
+                                                ]
+                                            }
                                         },
                                         {
                                             "name": "param",
@@ -68673,9 +69154,9 @@
                                 },
                                 {
                                     "name": "return",
-                                    "content": "string&gt; Comment status HTML links keyed by view.",
+                                    "content": "Comment status HTML links keyed by view.",
                                     "types": [
-                                        "\\array<string,"
+                                        "array<string, string>"
                                     ]
                                 }
                             ]
@@ -68864,9 +69345,9 @@
                                 },
                                 {
                                     "name": "return",
-                                    "content": "string&gt; Bulk action labels keyed by action name.",
+                                    "content": "Bulk action labels keyed by action name.",
                                     "types": [
-                                        "\\array<string,"
+                                        "array<string, string>"
                                     ]
                                 }
                             ]
@@ -69364,9 +69845,9 @@
                             "tags": [
                                 {
                                     "name": "return",
-                                    "content": "string|array&gt; The sortable columns.",
+                                    "content": "The sortable columns.",
                                     "types": [
-                                        "\\array<string,"
+                                        "array<string, string|array>"
                                     ]
                                 }
                             ]
@@ -70836,7 +71317,40 @@
                                         "false",
                                         "array"
                                     ],
-                                    "variable": "$user_location"
+                                    "variable": "$user_location",
+                                    "hash": {
+                                        "content": "Stored location data for the user. false to pass no location.",
+                                        "items": [
+                                            {
+                                                "types": [
+                                                    "string"
+                                                ],
+                                                "variable": "$description",
+                                                "content": "The name of the location"
+                                            },
+                                            {
+                                                "types": [
+                                                    "string"
+                                                ],
+                                                "variable": "$latitude",
+                                                "content": "The latitude in decimal degrees notation, without the degree symbol. e.g.: 47.615200."
+                                            },
+                                            {
+                                                "types": [
+                                                    "string"
+                                                ],
+                                                "variable": "$longitude",
+                                                "content": "The longitude in decimal degrees notation, without the degree symbol. e.g.: -122.341100."
+                                            },
+                                            {
+                                                "types": [
+                                                    "string"
+                                                ],
+                                                "variable": "$country",
+                                                "content": "The ISO 3166-1 alpha-2 country code. e.g.: BR"
+                                            }
+                                        ]
+                                    }
                                 }
                             ]
                         },
@@ -72070,7 +72584,104 @@
                                             "types": [
                                                 "array"
                                             ],
-                                            "variable": "$args"
+                                            "variable": "$args",
+                                            "hash": {
+                                                "content": "The debug information to be added to the core information page.<br>This is an associative multi-dimensional array, up to three levels deep.<br>The topmost array holds the sections, keyed by section ID.",
+                                                "items": [
+                                                    {
+                                                        "types": [
+                                                            "array"
+                                                        ],
+                                                        "variable": "...$0",
+                                                        "content": "",
+                                                        "hash": {
+                                                            "content": "Each section has a <code>$fields<\/code> associative array (see below), and each <code>$value<\/code> in <code>$fields<\/code> can be another associative array of name\/value pairs when there is more structured data to display.",
+                                                            "items": [
+                                                                {
+                                                                    "types": [
+                                                                        "string"
+                                                                    ],
+                                                                    "variable": "$label",
+                                                                    "content": "Required. The title for this section of the debug output."
+                                                                },
+                                                                {
+                                                                    "types": [
+                                                                        "string"
+                                                                    ],
+                                                                    "variable": "$description",
+                                                                    "content": "Optional. A description for your information section which may contain basic HTML markup, inline tags only as it is outputted in a paragraph."
+                                                                },
+                                                                {
+                                                                    "types": [
+                                                                        "bool"
+                                                                    ],
+                                                                    "variable": "$show_count",
+                                                                    "content": "Optional. If set to <code>true<\/code>, the amount of fields will be included in the title for this section. Default false."
+                                                                },
+                                                                {
+                                                                    "types": [
+                                                                        "bool"
+                                                                    ],
+                                                                    "variable": "$private",
+                                                                    "content": "Optional. If set to <code>true<\/code>, the section and all associated fields will be excluded from the copied data. Default false."
+                                                                },
+                                                                {
+                                                                    "types": [
+                                                                        "array"
+                                                                    ],
+                                                                    "variable": "$fields",
+                                                                    "content": "",
+                                                                    "hash": {
+                                                                        "content": "Required. An associative array containing the fields to be displayed in the section, keyed by field ID.",
+                                                                        "items": [
+                                                                            {
+                                                                                "types": [
+                                                                                    "array"
+                                                                                ],
+                                                                                "variable": "...$0",
+                                                                                "content": "",
+                                                                                "hash": {
+                                                                                    "content": "An associative array containing the data to be displayed for the field.",
+                                                                                    "items": [
+                                                                                        {
+                                                                                            "types": [
+                                                                                                "string"
+                                                                                            ],
+                                                                                            "variable": "$label",
+                                                                                            "content": "Required. The label for this piece of information."
+                                                                                        },
+                                                                                        {
+                                                                                            "types": [
+                                                                                                "mixed"
+                                                                                            ],
+                                                                                            "variable": "$value",
+                                                                                            "content": "Required. The output that is displayed for this field.<br>Text should be translated. Can be an associative array that is displayed as name\/value pairs.<br>Accepted types: <code>string|int|float|(string|int|float)[]<\/code>."
+                                                                                        },
+                                                                                        {
+                                                                                            "types": [
+                                                                                                "string"
+                                                                                            ],
+                                                                                            "variable": "$debug",
+                                                                                            "content": "Optional. The output that is used for this field when the user copies the data. It should be more concise and not translated. If not set, the content of <code>$value<\/code> is used. Note that the array keys are used as labels for the copied data."
+                                                                                        },
+                                                                                        {
+                                                                                            "types": [
+                                                                                                "bool"
+                                                                                            ],
+                                                                                            "variable": "$private",
+                                                                                            "content": "Optional. If set to <code>true<\/code>, the field will be excluded from the copied data, allowing you to show, for example, API keys here. Default false."
+                                                                                        }
+                                                                                    ]
+                                                                                }
+                                                                            }
+                                                                        ]
+                                                                    }
+                                                                }
+                                                            ]
+                                                        }
+                                                    }
+                                                ]
+                                            }
                                         }
                                     ]
                                 }
@@ -72098,9 +72709,9 @@
                                 },
                                 {
                                     "name": "return",
-                                    "content": "string|array&gt; The debug data for the Info screen.",
+                                    "content": "The debug data for the Info screen.",
                                     "types": [
-                                        "\\array<string,"
+                                        "array<string, string|array>"
                                     ]
                                 }
                             ]
@@ -72456,9 +73067,9 @@
                                 },
                                 {
                                     "name": "return",
-                                    "content": "string|bool|array&gt; The drop-ins debug data.",
+                                    "content": "The drop-ins debug data.",
                                     "types": [
-                                        "\\array<string,"
+                                        "array<string, string|bool|array>"
                                     ]
                                 }
                             ]
@@ -72524,9 +73135,9 @@
                                 },
                                 {
                                     "name": "return",
-                                    "content": "string|array&gt; The server-related debug data.",
+                                    "content": "The server-related debug data.",
                                     "types": [
-                                        "\\array<string,"
+                                        "array<string, string|array>"
                                     ]
                                 }
                             ]
@@ -73153,9 +73764,9 @@
                                 },
                                 {
                                     "name": "return",
-                                    "content": "string|array&gt; The media handling debug data.",
+                                    "content": "The media handling debug data.",
                                     "types": [
-                                        "\\array<string,"
+                                        "array<string, string|array>"
                                     ]
                                 }
                             ]
@@ -73662,9 +74273,9 @@
                                 },
                                 {
                                     "name": "return",
-                                    "content": "string|bool|array&gt; The must-use plugins debug data.",
+                                    "content": "The must-use plugins debug data.",
                                     "types": [
-                                        "\\array<string,"
+                                        "array<string, string|bool|array>"
                                     ]
                                 }
                             ]
@@ -73889,9 +74500,9 @@
                                 },
                                 {
                                     "name": "return",
-                                    "content": "string|bool|array&gt; The active plugins debug data.",
+                                    "content": "The active plugins debug data.",
                                     "types": [
-                                        "\\array<string,"
+                                        "array<string, string|bool|array>"
                                     ]
                                 }
                             ]
@@ -73936,9 +74547,9 @@
                                 },
                                 {
                                     "name": "return",
-                                    "content": "string|bool|array&gt; The inactive plugins debug data.",
+                                    "content": "The inactive plugins debug data.",
                                     "types": [
-                                        "\\array<string,"
+                                        "array<string, string|bool|array>"
                                     ]
                                 }
                             ]
@@ -73983,9 +74594,9 @@
                                 },
                                 {
                                     "name": "return",
-                                    "content": "array&lt;string, array&lt;string, string&gt;&gt;&gt; The raw plugin debug data for active and inactive plugins.",
+                                    "content": "The raw plugin debug data for active and inactive plugins.",
                                     "types": [
-                                        "\\array<string,"
+                                        "array<string, array<string, array<string, string>>>"
                                     ]
                                 }
                             ]
@@ -74225,9 +74836,9 @@
                                 },
                                 {
                                     "name": "return",
-                                    "content": "string|array&gt; The active theme debug data.",
+                                    "content": "The active theme debug data.",
                                     "types": [
-                                        "\\array<string,"
+                                        "array<string, string|array>"
                                     ]
                                 }
                             ]
@@ -74455,9 +75066,9 @@
                                 },
                                 {
                                     "name": "return",
-                                    "content": "string|array&gt; The parent theme debug data.",
+                                    "content": "The parent theme debug data.",
                                     "types": [
-                                        "\\array<string,"
+                                        "array<string, string|array>"
                                     ]
                                 }
                             ]
@@ -74657,9 +75268,9 @@
                                 },
                                 {
                                     "name": "return",
-                                    "content": "string|bool|array&gt; The inactive themes debug data.",
+                                    "content": "The inactive themes debug data.",
                                     "types": [
-                                        "\\array<string,"
+                                        "array<string, string|bool|array>"
                                     ]
                                 }
                             ]

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.

Adopt PHPStan for types Nested union types inside generics are split incorrectly

1 participant