From 59a17c0263c0412715f9626f1d7e8e7e0a06dcfe Mon Sep 17 00:00:00 2001 From: Marian <42134098+IanDelMar@users.noreply.github.com> Date: Thu, 21 Aug 2025 23:49:42 +0200 Subject: [PATCH] Narrow types for WP_Dependencies --- functionMap.php | 3 +++ phpstan.neon.dist | 2 +- tests/Faker.php | 3 +++ tests/TypeInferenceTest.php | 1 + tests/data/Faker.php | 3 +++ tests/data/wp_dependencies.php | 34 ++++++++++++++++++++++++++++++++++ wordpress-stubs.php | 4 ++++ 7 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 tests/data/wp_dependencies.php diff --git a/functionMap.php b/functionMap.php index b7ef789..cc78ec9 100644 --- a/functionMap.php +++ b/functionMap.php @@ -238,6 +238,9 @@ 'WP_Block_List::offsetGet' => ['\WP_Block|null', 'offset' => 'int'], 'WP_Block_List::offsetSet' => ['void', 'offset' => 'int|null'], 'WP_Block_List::offsetUnset' => ['void', 'offset' => 'int'], + 'WP_Dependencies::$groups' => [null, '@phpstan-var' => 'array'], + 'WP_Dependencies::get_etag' => ['non-falsy-string'], + 'WP_Dependencies::query' => ["(\$handle is not non-empty-string ? false : (\$status is not TStatus ? false : (\$status is 'registered'|'scripts' ? _WP_Dependency|false : bool)))", '@phpstan-template TStatus' => "'registered'|'scripts'|'enqueued'|'queued'|'to_do'|'to_print'|'done'|'printed'"], 'WP_Filesystem_Base::dirlist' => [$filesystemDirlistReturnType], 'WP_Filesystem_Direct::dirlist' => [$filesystemDirlistReturnType], 'WP_Filesystem_FTPext::dirlist' => [$filesystemDirlistReturnType], diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 5824fb9..1457383 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -15,7 +15,7 @@ parameters: - path: tests/Faker.php identifier: class.notFound - count: 13 + count: 16 - # PHPStan\Analyser\Analyser::analyse() # PHPStan\Analyser\AnalyserResult::getErrors() diff --git a/tests/Faker.php b/tests/Faker.php index 3c0a4cd..0358f9f 100644 --- a/tests/Faker.php +++ b/tests/Faker.php @@ -30,11 +30,14 @@ * @method static \stdClass stdClass() * @method static \WP_Block wpBlock() * @method static \WP_Comment wpComment() + * @method static \WP_Dependencies wpDependencies() * @method static \WP_Error wpError() * @method static \WP_Post wpPost() * @method static \WP_Query wpQuery() * @method static \WP_REST_Request wpRestRequest() * @method static \WP_REST_Response wpRestResponse() + * @method static \WP_Scripts wpScripts() + * @method static \WP_Styles wpStyles() * @method static \WP_Term wpTerm() * @method static \WP_Theme wpTheme() * @method static \WP_Translations wpTranslations() diff --git a/tests/TypeInferenceTest.php b/tests/TypeInferenceTest.php index c1f2080..09f26cc 100644 --- a/tests/TypeInferenceTest.php +++ b/tests/TypeInferenceTest.php @@ -78,6 +78,7 @@ public function dataFileAsserts(): iterable yield from $this->gatherAssertTypes(__DIR__ . '/data/wp_create_nonce.php'); yield from $this->gatherAssertTypes(__DIR__ . '/data/wp_cron.php'); yield from $this->gatherAssertTypes(__DIR__ . '/data/wp_debug_backtrace_summary.php'); + yield from $this->gatherAssertTypes(__DIR__ . '/data/wp_dependencies.php'); yield from $this->gatherAssertTypes(__DIR__ . '/data/wp_die.php'); yield from $this->gatherAssertTypes(__DIR__ . '/data/wp_dropdown_languages.php'); yield from $this->gatherAssertTypes(__DIR__ . '/data/wp_error_parameter.php'); diff --git a/tests/data/Faker.php b/tests/data/Faker.php index 0237af0..2924297 100644 --- a/tests/data/Faker.php +++ b/tests/data/Faker.php @@ -75,11 +75,14 @@ // WordPress assertType('WP_Block', Faker::wpBlock()); assertType('WP_Comment', Faker::wpComment()); +assertType('WP_Dependencies', Faker::wpDependencies()); assertType('WP_Error', Faker::wpError()); assertType('WP_Post', Faker::wpPost()); assertType('WP_Query', Faker::wpQuery()); assertType('WP_REST_Request', Faker::wpRestRequest()); assertType('WP_REST_Response', Faker::wpRestResponse()); +assertType('WP_Scripts', Faker::wpScripts()); +assertType('WP_Styles', Faker::wpStyles()); assertType('WP_Term', Faker::wpTerm()); assertType('WP_Theme', Faker::wpTheme()); assertType('WP_Translations', Faker::wpTranslations()); diff --git a/tests/data/wp_dependencies.php b/tests/data/wp_dependencies.php new file mode 100644 index 0000000..9213847 --- /dev/null +++ b/tests/data/wp_dependencies.php @@ -0,0 +1,34 @@ +', Faker::wpDependencies()->groups); +assertType('array', Faker::wpScripts()->groups); +assertType('array', Faker::wpStyles()->groups); + +assertType('non-falsy-string', Faker::wpDependencies()->get_etag(Faker::array(Faker::string()))); +assertType('non-falsy-string', Faker::wpScripts()->get_etag(Faker::array(Faker::string()))); +assertType('non-falsy-string', Faker::wpStyles()->get_etag(Faker::array(Faker::string()))); + +// Always false if $handle is not non-empty-string +assertType('false', Faker::wpDependencies()->query(null, Faker::string())); +assertType('false', Faker::wpDependencies()->query('', Faker::string())); +assertType('false', Faker::wpScripts()->query('', Faker::string())); +assertType('false', Faker::wpStyles()->query('', Faker::string())); + +assertType('_WP_Dependency|false', Faker::wpDependencies()->query(Faker::nonEmptyString(), 'registered')); +assertType('_WP_Dependency|false', Faker::wpDependencies()->query(Faker::nonEmptyString(), 'scripts')); +assertType('bool', Faker::wpDependencies()->query(Faker::nonEmptyString(), 'enqueued')); +assertType('bool', Faker::wpDependencies()->query(Faker::nonEmptyString(), 'queued')); +assertType('bool', Faker::wpDependencies()->query(Faker::nonEmptyString(), 'to_do')); +assertType('bool', Faker::wpDependencies()->query(Faker::nonEmptyString(), 'to_print')); +assertType('bool', Faker::wpDependencies()->query(Faker::nonEmptyString(), 'done')); +assertType('bool', Faker::wpDependencies()->query(Faker::nonEmptyString(), 'printed')); +assertType('_WP_Dependency|false', Faker::wpScripts()->query(Faker::nonEmptyString(), 'registered')); +assertType('bool', Faker::wpScripts()->query(Faker::nonEmptyString(), 'enqueued')); +assertType('_WP_Dependency|false', Faker::wpStyles()->query(Faker::nonEmptyString(), 'registered')); +assertType('bool', Faker::wpStyles()->query(Faker::nonEmptyString(), 'enqueued')); diff --git a/wordpress-stubs.php b/wordpress-stubs.php index 3f17f0d..63cfde9 100644 --- a/wordpress-stubs.php +++ b/wordpress-stubs.php @@ -37438,6 +37438,7 @@ class WP_Dependencies * @since 2.8.0 * * @var (int|false)[] + * @phpstan-var array */ public $groups = array(); /** @@ -37617,6 +37618,8 @@ protected function recurse_deps($queue, $handle) * @param string $handle Name of the item. Should be unique. * @param string $status Optional. Status of the item to query. Default 'registered'. * @return bool|_WP_Dependency Found, or object Item data. + * @phpstan-template TStatus 'registered'|'scripts'|'enqueued'|'queued'|'to_do'|'to_print'|'done'|'printed' + * @phpstan-return ($handle is not non-empty-string ? false : ($status is not TStatus ? false : ($status is 'registered'|'scripts' ? _WP_Dependency|false : bool))) */ public function query($handle, $status = 'registered') { @@ -37643,6 +37646,7 @@ public function set_group($handle, $recursion, $group) * * @param string[] $load Array of script or style handles to load. * @return string Etag header. + * @phpstan-return non-falsy-string */ public function get_etag($load) {