Skip to content

Add additional parameter and return type information to stubs #28

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Mar 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"require-dev": {
"php": "~7.3 || ~8.0",
"nikic/php-parser": "< 4.12.0",
"php-stubs/generator": "^0.8.0",
"php-stubs/generator": "dev-master",
"phpdocumentor/reflection-docblock": "^5.3",
"phpstan/phpstan": "^1.2"
},
Expand Down
30 changes: 30 additions & 0 deletions functionMap.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

$httpReturnType = 'array{headers: \Requests_Utility_CaseInsensitiveDictionary, body: string, response: array{code: int,message: string}, cookies: array<int, \WP_HTTP_Cookie>, filename: string|null, http_response: \WP_HTTP_Requests_Response}|\WP_Error';

/**
* This array is in the same format as the function map array in PHPStan:
*
* '<function_name>' => ['<return_type>, '<arg_name>'=>'<arg_type>']
*
* @link https://github.com/phpstan/phpstan-src/blob/1.5.x/resources/functionMap.php
*/
return [
'add_meta_box' => ['void', 'context'=>'"normal"|"side"|"advanced"', 'priority'=>'"high"|"core"|"default"|"low"'],
'remove_meta_box' => ['void', 'context'=>'"normal"|"side"|"advanced"'],
'WP_Http::get' => [$httpReturnType],
'WP_Http::head' => [$httpReturnType],
'WP_Http::post' => [$httpReturnType],
'WP_Http::request' => [$httpReturnType],
'WP_List_Table::bulk_actions' => ['void', 'which'=>'"top"|"bottom"'],
'WP_List_Table::display_tablenav' => ['void', 'which'=>'"top"|"bottom"'],
'WP_List_Table::pagination' => ['void', 'which'=>'"top"|"bottom"'],
'wp_remote_get' => [$httpReturnType],
'wp_remote_head' => [$httpReturnType],
'wp_remote_post' => [$httpReturnType],
'wp_remote_request' => [$httpReturnType],
'wp_safe_remote_get' => [$httpReturnType],
'wp_safe_remote_head' => [$httpReturnType],
'wp_safe_remote_post' => [$httpReturnType],
'wp_safe_remote_request' => [$httpReturnType],
];
74 changes: 74 additions & 0 deletions visitor.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@
*/
private $docBlockFactory;

/**
* @var ?array<string,array<int|string,string>>
*/
private $functionMap = null;

/**
* @var string
*/
private $currentSymbolName;

public function __construct()
{
$this->docBlockFactory = \phpDocumentor\Reflection\DocBlockFactory::createInstance();
Expand All @@ -38,12 +48,39 @@ public function enterNode(Node $node)
return null;
}

$this->currentSymbolName = $node->name->name;

if ($node instanceof ClassMethod) {
/** @var \PhpParser\Node\Stmt\Class_ $parent */
$parent = $this->stack[count($this->stack) - 2];

if (isset($parent->name)) {
$this->currentSymbolName = sprintf(
'%1$s::%2$s',
$parent->name->name,
$node->name->name
);
}
}

$newDocComment = $this->addArrayHashNotation($docComment);

if ($newDocComment !== null) {
$node->setDocComment($newDocComment);
}

$docComment = $node->getDocComment();

if (!($docComment instanceof Doc)) {
return null;
}

$newDocComment = $this->addAdditionalParams($docComment);

if ($newDocComment !== null) {
$node->setDocComment($newDocComment);
}

return null;
}

Expand Down Expand Up @@ -100,6 +137,43 @@ private function addArrayHashNotation(Doc $docComment): ?Doc
return new Doc($newDocComment, $docComment->getLine(), $docComment->getFilePos());
}

private function addAdditionalParams(Doc $docComment): ?Doc
{
if (! isset($this->functionMap)) {
$this->functionMap = require __DIR__ . '/functionMap.php';
}

if (! isset($this->functionMap[$this->currentSymbolName])) {
return null;
}

$parameters = $this->functionMap[$this->currentSymbolName];
$returnType = array_shift($parameters);
$additions = [];

foreach ($parameters as $paramName => $paramType) {
$additions[] = sprintf(
'@phpstan-param %s $%s',
$paramType,
$paramName
);
}

$additions[] = sprintf(
'@phpstan-return %s',
$returnType
);

$docCommentText = $docComment->getText();
$newDocComment = sprintf(
"%s\n * %s\n */",
substr($docCommentText, 0, -4),
implode("\n * ", $additions)
);

return new Doc($newDocComment, $docComment->getLine(), $docComment->getFilePos());
}

private function getAdditionFromParam(Param $tag): ?string
{
$tagDescription = $tag->getDescription();
Expand Down
23 changes: 23 additions & 0 deletions wordpress-stubs.php
Original file line number Diff line number Diff line change
Expand Up @@ -4290,6 +4290,8 @@ protected function get_bulk_actions()
*
* @param string $which The location of the bulk actions: 'top' or 'bottom'.
* This is designated as optional for backward compatibility.
* @phpstan-param "top"|"bottom" $which
* @phpstan-return void
*/
protected function bulk_actions($which = '')
{
Expand Down Expand Up @@ -4378,6 +4380,8 @@ protected function get_items_per_page($option, $default = 20)
* @since 3.1.0
*
* @param string $which
* @phpstan-param "top"|"bottom" $which
* @phpstan-return void
*/
protected function pagination($which)
{
Expand Down Expand Up @@ -4494,6 +4498,8 @@ protected function get_table_classes()
*
* @since 3.1.0
* @param string $which
* @phpstan-param "top"|"bottom" $which
* @phpstan-return void
*/
protected function display_tablenav($which)
{
Expand Down Expand Up @@ -40697,6 +40703,7 @@ class WP_Http
* filename?: string,
* limit_response_size?: int,
* } $args
* @phpstan-return array{headers: \Requests_Utility_CaseInsensitiveDictionary, body: string, response: array{code: int,message: string}, cookies: array<int, \WP_HTTP_Cookie>, filename: string|null, http_response: \WP_HTTP_Requests_Response}|\WP_Error
*/
public function request($url, $args = array())
{
Expand Down Expand Up @@ -40785,6 +40792,7 @@ private function _dispatch_request($url, $args)
* @param string|array $args Optional. Override the defaults.
* @return array|WP_Error Array containing 'headers', 'body', 'response', 'cookies', 'filename'.
* A WP_Error instance upon error.
* @phpstan-return array{headers: \Requests_Utility_CaseInsensitiveDictionary, body: string, response: array{code: int,message: string}, cookies: array<int, \WP_HTTP_Cookie>, filename: string|null, http_response: \WP_HTTP_Requests_Response}|\WP_Error
*/
public function post($url, $args = array())
{
Expand All @@ -40800,6 +40808,7 @@ public function post($url, $args = array())
* @param string|array $args Optional. Override the defaults.
* @return array|WP_Error Array containing 'headers', 'body', 'response', 'cookies', 'filename'.
* A WP_Error instance upon error.
* @phpstan-return array{headers: \Requests_Utility_CaseInsensitiveDictionary, body: string, response: array{code: int,message: string}, cookies: array<int, \WP_HTTP_Cookie>, filename: string|null, http_response: \WP_HTTP_Requests_Response}|\WP_Error
*/
public function get($url, $args = array())
{
Expand All @@ -40815,6 +40824,7 @@ public function get($url, $args = array())
* @param string|array $args Optional. Override the defaults.
* @return array|WP_Error Array containing 'headers', 'body', 'response', 'cookies', 'filename'.
* A WP_Error instance upon error.
* @phpstan-return array{headers: \Requests_Utility_CaseInsensitiveDictionary, body: string, response: array{code: int,message: string}, cookies: array<int, \WP_HTTP_Cookie>, filename: string|null, http_response: \WP_HTTP_Requests_Response}|\WP_Error
*/
public function head($url, $args = array())
{
Expand Down Expand Up @@ -81891,6 +81901,9 @@ function wp_import_upload_form($action)
* @param array $callback_args Optional. Data that should be set as the $args property
* of the box array (which is the second parameter passed
* to your callback). Default null.
* @phpstan-param "normal"|"side"|"advanced" $context
* @phpstan-param "high"|"core"|"default"|"low" $priority
* @phpstan-return void
*/
function add_meta_box($id, $title, $callback, $screen = \null, $context = 'advanced', $priority = 'default', $callback_args = \null)
{
Expand Down Expand Up @@ -81970,6 +81983,8 @@ function do_meta_boxes($screen, $context, $object)
* include 'normal', 'side', and 'advanced'. Comments screen contexts
* include 'normal' and 'side'. Menus meta boxes (accordion sections)
* all use the 'side' context.
* @phpstan-param "normal"|"side"|"advanced" $context
* @phpstan-return void
*/
function remove_meta_box($id, $screen, $context)
{
Expand Down Expand Up @@ -104003,6 +104018,7 @@ function _wp_http_get_object()
* @param string $url URL to retrieve.
* @param array $args Optional. Request arguments. Default empty array.
* @return array|WP_Error The response or WP_Error on failure.
* @phpstan-return array{headers: \Requests_Utility_CaseInsensitiveDictionary, body: string, response: array{code: int,message: string}, cookies: array<int, \WP_HTTP_Cookie>, filename: string|null, http_response: \WP_HTTP_Requests_Response}|\WP_Error
*/
function wp_safe_remote_request($url, $args = array())
{
Expand All @@ -104021,6 +104037,7 @@ function wp_safe_remote_request($url, $args = array())
* @param string $url URL to retrieve.
* @param array $args Optional. Request arguments. Default empty array.
* @return array|WP_Error The response or WP_Error on failure.
* @phpstan-return array{headers: \Requests_Utility_CaseInsensitiveDictionary, body: string, response: array{code: int,message: string}, cookies: array<int, \WP_HTTP_Cookie>, filename: string|null, http_response: \WP_HTTP_Requests_Response}|\WP_Error
*/
function wp_safe_remote_get($url, $args = array())
{
Expand All @@ -104039,6 +104056,7 @@ function wp_safe_remote_get($url, $args = array())
* @param string $url URL to retrieve.
* @param array $args Optional. Request arguments. Default empty array.
* @return array|WP_Error The response or WP_Error on failure.
* @phpstan-return array{headers: \Requests_Utility_CaseInsensitiveDictionary, body: string, response: array{code: int,message: string}, cookies: array<int, \WP_HTTP_Cookie>, filename: string|null, http_response: \WP_HTTP_Requests_Response}|\WP_Error
*/
function wp_safe_remote_post($url, $args = array())
{
Expand All @@ -104057,6 +104075,7 @@ function wp_safe_remote_post($url, $args = array())
* @param string $url URL to retrieve.
* @param array $args Optional. Request arguments. Default empty array.
* @return array|WP_Error The response or WP_Error on failure.
* @phpstan-return array{headers: \Requests_Utility_CaseInsensitiveDictionary, body: string, response: array{code: int,message: string}, cookies: array<int, \WP_HTTP_Cookie>, filename: string|null, http_response: \WP_HTTP_Requests_Response}|\WP_Error
*/
function wp_safe_remote_head($url, $args = array())
{
Expand Down Expand Up @@ -104097,6 +104116,7 @@ function wp_safe_remote_head($url, $args = array())
* cookies: WP_HTTP_Cookie[],
* http_response: WP_HTTP_Requests_Response|null,
* }
* @phpstan-return array{headers: \Requests_Utility_CaseInsensitiveDictionary, body: string, response: array{code: int,message: string}, cookies: array<int, \WP_HTTP_Cookie>, filename: string|null, http_response: \WP_HTTP_Requests_Response}|\WP_Error
*/
function wp_remote_request($url, $args = array())
{
Expand All @@ -104112,6 +104132,7 @@ function wp_remote_request($url, $args = array())
* @param string $url URL to retrieve.
* @param array $args Optional. Request arguments. Default empty array.
* @return array|WP_Error The response or WP_Error on failure.
* @phpstan-return array{headers: \Requests_Utility_CaseInsensitiveDictionary, body: string, response: array{code: int,message: string}, cookies: array<int, \WP_HTTP_Cookie>, filename: string|null, http_response: \WP_HTTP_Requests_Response}|\WP_Error
*/
function wp_remote_get($url, $args = array())
{
Expand All @@ -104127,6 +104148,7 @@ function wp_remote_get($url, $args = array())
* @param string $url URL to retrieve.
* @param array $args Optional. Request arguments. Default empty array.
* @return array|WP_Error The response or WP_Error on failure.
* @phpstan-return array{headers: \Requests_Utility_CaseInsensitiveDictionary, body: string, response: array{code: int,message: string}, cookies: array<int, \WP_HTTP_Cookie>, filename: string|null, http_response: \WP_HTTP_Requests_Response}|\WP_Error
*/
function wp_remote_post($url, $args = array())
{
Expand All @@ -104142,6 +104164,7 @@ function wp_remote_post($url, $args = array())
* @param string $url URL to retrieve.
* @param array $args Optional. Request arguments. Default empty array.
* @return array|WP_Error The response or WP_Error on failure.
* @phpstan-return array{headers: \Requests_Utility_CaseInsensitiveDictionary, body: string, response: array{code: int,message: string}, cookies: array<int, \WP_HTTP_Cookie>, filename: string|null, http_response: \WP_HTTP_Requests_Response}|\WP_Error
*/
function wp_remote_head($url, $args = array())
{
Expand Down