Changeset 62939
- Timestamp:
- 07/30/2026 04:45:34 AM (less than one hour ago)
- Location:
- trunk/tests/phpstan
- Files:
-
- 6 added
- 2 edited
-
ApplyFiltersDynamicFunctionReturnTypeExtension.php (added)
-
HookDocBlock.php (added)
-
HookDocsResultCacheMetaExtension.php (added)
-
HookDocsVisitor.php (added)
-
HookDocumentationRule.php (added)
-
HookParamCountRule.php (added)
-
README.md (modified) (1 diff)
-
base.neon (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/tests/phpstan/README.md
r61699 r62939 50 50 For more information about configuring PHPStan, see the [PHPStan documentation's Config reference](https://phpstan.org/config-reference). 51 51 52 ## WordPress-specific extensions 53 54 This directory also contains extensions that teach PHPStan conventions specific to WordPress. They are registered in [`base.neon`](base.neon), so they apply to the default configuration and to any local override of it. 55 56 ### Global variables in function docblocks 57 58 Core documents the globals a function uses with `@global Type $varname`. `GlobalDocBlockVisitor` bridges that convention to PHPStan's variable type resolution, so those globals are typed rather than `mixed` inside the function. 59 60 ### Hook documentation 61 62 The remaining extensions read the docblock documenting a hook where the hook is fired, which is where WordPress documents its hooks. They cover `apply_filters()`, `do_action()` and their `_deprecated` and `_ref_array` variants. 63 64 - **The value a filter returns is typed from its documentation.** `apply_filters()` returns the type of the first `@param` its docblock documents, rather than `mixed`. This assumes callbacks honor the documented type; one that returns something else is treated as the unusual case. 65 - **Hooks documented elsewhere are resolved.** Core's `/** This filter is documented in <file> */` convention is followed, in its action form as well, so a hook documented in another file is analyzed against its canonical docblock. A dynamic canonical name such as `"{$type}_template_hierarchy"` is matched against the literal name used at the referencing site. 66 - **Two rules check the documentation itself**: that a hook is documented at all, and that it is fired with as many arguments as its documentation describes. 67 68 Calls whose hook name contains no literal text, such as the `apply_filters_ref_array( $hook_name, $args )` re-dispatch in `plugin.php`, name no concrete hook and are skipped. 69 70 One consequence worth knowing: because a hook's documentation may live in a different file than the call inheriting it, editing a hook docblock in a file that reference comments point at discards PHPStan's result cache. Every call site inheriting that docblock has to be analyzed again, and PHPStan cannot infer that dependency on its own. 71 72 ### Errors these rules report 73 74 These identifiers are specific to WordPress, and can be ignored or baselined like any other error, as described [below](#ignoring-and-baselining-errors). 75 76 | Identifier | What it means | 77 | --- | --- | 78 | `wordpress.hookDocMissing` | The hook is fired with neither a docblock documenting it nor a reference comment. Document it, or point at wherever it is documented. | 79 | `wordpress.hookDocNoParams` | A filter's docblock documents no parameters. A filter always passes at least the value being filtered, so document that value with `@param`, plus one for each further argument. This also fires when an unrelated docblock, such as a `@var` annotation, happens to sit immediately above the call. | 80 | `wordpress.hookDocReferenceFileMissing` | A reference comment names a file that does not exist in the tree being analyzed. The path is resolved relative to the file holding the comment and to the WordPress root; one that resolves outside the tree counts as missing, since the analysis does not read it. | 81 | `wordpress.hookDocReferenceHookMissing` | The referenced file exists, but documents no hook of that name. Either the reference is stale, or the canonical docblock has moved. | 82 | `wordpress.hookParamCountMismatch` | The call passes a different number of arguments than the docblock documents `@param` tags for. Passing fewer risks an `ArgumentCountError` in a callback registered for the documented count; passing more silently drops the extra argument and leaves the documentation misleading. | 83 52 84 ## Ignoring and baselining errors 53 85 -
trunk/tests/phpstan/base.neon
r62657 r62939 12 12 tags: 13 13 - phpstan.parser.richParserNodeVisitor 14 15 # Attaches the docblock documenting a hook to the hook's call, so that the return 16 # type extension and the rules below can all read it. 17 - 18 class: WordPress\PHPStan\HookDocsVisitor 19 tags: 20 - phpstan.parser.richParserNodeVisitor 21 22 # Resolves a hook call's documentation, whether written at the call or inherited 23 # through the "This filter is documented in <file>" convention. 24 - 25 class: WordPress\PHPStan\HookDocBlock 26 27 # Types the return value of apply_filters() (and variants) from the `@param` type 28 # documented for the value being filtered. Adapted from szepeviktor/phpstan-wordpress. 29 - 30 class: WordPress\PHPStan\ApplyFiltersDynamicFunctionReturnTypeExtension 31 tags: 32 - phpstan.broker.dynamicFunctionReturnTypeExtension 33 34 # Enforces that every hook invocation is preceded by a documenting docblock or 35 # a valid "This filter is documented in <file>" reference comment. 36 - 37 class: WordPress\PHPStan\HookDocumentationRule 38 tags: 39 - phpstan.rules.rule 40 41 # Enforces that a hook invocation passes as many arguments as its documentation 42 # (inline or referenced) describes. 43 - 44 class: WordPress\PHPStan\HookParamCountRule 45 tags: 46 - phpstan.rules.rule 47 48 # Docblocks inherited from another file, and the sources above that read them, 49 # are invisible to PHPStan's dependency graph, so both are folded into the result 50 # cache key. Without this, editing a canonical hook docblock leaves the cached 51 # results of every call site inheriting it in place. 52 - 53 class: WordPress\PHPStan\HookDocsResultCacheMetaExtension 54 tags: 55 - phpstan.resultCacheMetaExtension 14 56 15 57 parameters: … … 100 142 - ../../src/xmlrpc.php 101 143 - GlobalDocBlockVisitor.php 144 - HookDocsVisitor.php 145 - HookDocBlock.php 146 - ApplyFiltersDynamicFunctionReturnTypeExtension.php 147 - HookDocumentationRule.php 148 - HookParamCountRule.php 149 - HookDocsResultCacheMetaExtension.php 102 150 bootstrapFiles: 103 151 - bootstrap.php … … 120 168 # These files are autogenerated by tools/gutenberg/copy.js. 121 169 - ../../src/wp-includes/blocks 170 # Generated output from the Gutenberg plugin's wp-build templates. 171 - ../../src/wp-includes/build 122 172 # Third-party libraries. 123 173 - ../../src/wp-admin/includes/class-ftp-pure.php
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)