Skip to content

Commit bd3f20e

Browse files
committed
Build/Test Tools: Integrate PHPStan into the core development workflow.
This change introduces PHPStan static analysis configured at [https://phpstan.org/user-guide/rule-levels rule level 0], which includes: "basic checks, unknown classes, unknown functions, unknown methods called on `$this`, wrong number of arguments passed to those methods and functions, always undefined variables". Contributors may elect for a higher PHPStan rule level by creating a `phpstan.neon` which overrides `phpstan.neon.dist`. * Fix various PHPStan level 0 errors by adding `@phpstan-ignore` comments, updating PHPDoc types, and adding missing return values. * Remove existing `@phpstan-ignore` comments that are now obsolete or inapplicable for level 0. * Add a new GitHub Actions workflow for PHPStan Static Analysis. Reports are currently provided as warnings with inline annotations in pull requests and do not fail the build. * Add a `phpstan` Grunt task and include it in the `precommit:php` task to run before `phpunit`. * Introduce a `typecheck:php` npm script and a `composer phpstan` script to run analysis in local development environments. * Add documentation for PHPStan usage in `tests/phpstan/README.md`. Developed in WordPress/wordpress-develop#10419 Props justlevine, westonruter, johnbillion, desrosj, SirLouen, dmsnell, oglekler, joehoyle, jorbin. See #64238, #63268, #52217, #51423. Fixes #61175. Built from https://develop.svn.wordpress.org/trunk@61699 git-svn-id: http://core.svn.wordpress.org/trunk@61007 1a063a9b-81f0-0310-95a4-ce76da25c4cd
1 parent a70f256 commit bd3f20e

10 files changed

Lines changed: 19 additions & 8 deletions

wp-admin/includes/class-wp-filesystem-ssh2.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -670,9 +670,11 @@ public function size( $file ) {
670670
* Default 0.
671671
* @param int $atime Optional. Access time to set for file.
672672
* Default 0.
673+
* @return false Always returns false because not implemented.
673674
*/
674675
public function touch( $file, $time = 0, $atime = 0 ) {
675676
// Not implemented.
677+
return false;
676678
}
677679

678680
/**

wp-admin/press-this.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ function wp_load_press_this() {
2222
403
2323
);
2424
} elseif ( is_plugin_active( $plugin_file ) ) {
25-
include WP_PLUGIN_DIR . '/press-this/class-wp-press-this-plugin.php';
26-
$wp_press_this = new WP_Press_This_Plugin();
25+
include WP_PLUGIN_DIR . '/press-this/class-wp-press-this-plugin.php'; // @phpstan-ignore include.fileNotFound
26+
$wp_press_this = new WP_Press_This_Plugin(); // @phpstan-ignore class.notFound
2727
$wp_press_this->html();
2828
} elseif ( current_user_can( 'activate_plugins' ) ) {
2929
if ( file_exists( WP_PLUGIN_DIR . '/' . $plugin_file ) ) {

wp-includes/class-wp-scripts.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1186,7 +1186,7 @@ private function get_highest_fetchpriority_with_dependents( string $handle, arra
11861186
}
11871187
}
11881188
}
1189-
$stored_results[ $handle ] = $priorities[ $highest_priority_index ]; // @phpstan-ignore parameterByRef.type (We know the index is valid and that this will be a string.)
1189+
$stored_results[ $handle ] = $priorities[ $highest_priority_index ];
11901190
return $priorities[ $highest_priority_index ];
11911191
}
11921192

wp-includes/class-wp-theme-json.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3542,7 +3542,7 @@ public function get_svg_filters( $origins ) {
35423542
* @param array $theme_json The theme.json like structure to inspect.
35433543
* @param array $path Path to inspect.
35443544
* @param bool|array $override Data to compute whether to override the preset.
3545-
* @return bool
3545+
* @return bool|null True if the preset should override the defaults, false if not. Null if the override parameter is invalid.
35463546
*/
35473547
protected static function should_override_preset( $theme_json, $path, $override ) {
35483548
_deprecated_function( __METHOD__, '6.0.0', 'get_metadata_boolean' );
@@ -3577,6 +3577,8 @@ protected static function should_override_preset( $theme_json, $path, $override
35773577

35783578
return true;
35793579
}
3580+
3581+
return null;
35803582
}
35813583

35823584
/**

wp-includes/functions.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3765,6 +3765,9 @@ function wp_nonce_ays( $action ) {
37653765
* is a WP_Error.
37663766
* @type bool $exit Whether to exit the process after completion. Default true.
37673767
* }
3768+
* @return never|void Returns void if `$args['exit']` is false, otherwise exits.
3769+
*
3770+
* @phpstan-return ( $args['exit'] is false ? void : never )
37683771
*/
37693772
function wp_die( $message = '', $title = '', $args = array() ) {
37703773
global $wp_query;

wp-includes/html-api/class-wp-html-processor.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@
139139
*
140140
* @see WP_HTML_Tag_Processor
141141
* @see https://html.spec.whatwg.org/
142+
* @phpstan-consistent-constructor
142143
*/
143144
class WP_HTML_Processor extends WP_HTML_Tag_Processor {
144145
/**
@@ -583,6 +584,7 @@ private function create_fragment_at_current_node( string $html ) {
583584
* @since 6.7.0
584585
*
585586
* @param string $message Explains support is missing in order to parse the current node.
587+
* @return never
586588
*/
587589
private function bail( string $message ) {
588590
$here = $this->bookmarks[ $this->state->current_token->bookmark_name ];

wp-includes/media.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4116,7 +4116,7 @@ function get_taxonomies_for_attachments( $output = 'names' ) {
41164116
* false otherwise.
41174117
*/
41184118
function is_gd_image( $image ) {
4119-
if ( $image instanceof GdImage
4119+
if ( $image instanceof GdImage // @phpstan-ignore class.notFound (Only available with PHP8+.)
41204120
|| is_resource( $image ) && 'gd' === get_resource_type( $image )
41214121
) {
41224122
return true;

wp-includes/style-engine/class-wp-style-engine-css-rules-store.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
* Holds, sanitizes, processes, and prints CSS declarations for the style engine.
1414
*
1515
* @since 6.1.0
16+
*
17+
* @phpstan-consistent-constructor
1618
*/
1719
#[AllowDynamicProperties]
1820
class WP_Style_Engine_CSS_Rules_Store {

wp-includes/template.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -796,7 +796,7 @@ function load_template( $_template_file, $load_once = true, $args = array() ) {
796796
}
797797

798798
if ( isset( $s ) ) {
799-
$s = esc_attr( $s );
799+
$s = esc_attr( $s ); // @phpstan-ignore variable.undefined (It's extracted from query vars.)
800800
}
801801

802802
/**
@@ -976,7 +976,7 @@ static function ( int $level, string $message, ?string $file = null, ?int $line
976976
}
977977

978978
// Display a caught exception as an error since it prevents any of the output buffer filters from applying.
979-
if ( $did_just_catch ) { // @phpstan-ignore if.alwaysFalse (The variable is set in the catch block below.)
979+
if ( $did_just_catch ) {
980980
$level = E_USER_ERROR;
981981
}
982982

wp-includes/version.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
*
1717
* @global string $wp_version
1818
*/
19-
$wp_version = '7.0-alpha-61698';
19+
$wp_version = '7.0-alpha-61699';
2020

2121
/**
2222
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.

0 commit comments

Comments
 (0)