From 350e9b88c12648c5c2fcb1a91c23b3575771ca04 Mon Sep 17 00:00:00 2001 From: Daimona Eaytoy Date: Sat, 8 Oct 2022 14:15:06 +0200 Subject: [PATCH] Fixes for the phan upgrade, part 1 Mainly, document some parameters as non-empty-array so that phan knows the list of arguments won't be empty when unpacking. In EditPage, account for hooks potentially unsetting the copyright notice. Also rewrite some code in LogPager, so it's hopefully easier for phan to understand what's going on. Change-Id: Ic0638571554424098d0743db32dd46723a08e103 --- includes/EditPage.php | 3 +++ includes/OutputPage.php | 1 + includes/Permissions/PermissionManager.php | 1 + includes/Status.php | 2 ++ includes/api/ApiBase.php | 1 + includes/auth/ButtonAuthenticationRequest.php | 4 ++-- .../ResetPasswordSecondaryAuthenticationProvider.php | 2 ++ includes/block/AbstractBlock.php | 1 + includes/diff/DifferenceEngine.php | 1 + includes/htmlform/HTMLForm.php | 7 ++++++- includes/logging/LogPager.php | 9 ++++++--- 11 files changed, 26 insertions(+), 6 deletions(-) diff --git a/includes/EditPage.php b/includes/EditPage.php index 95a7b2ee826..e6c7d45e151 100644 --- a/includes/EditPage.php +++ b/includes/EditPage.php @@ -4096,6 +4096,9 @@ class EditPage implements IEditObject { $title = Title::castFromPageReference( $page ); // @phan-suppress-next-line PhanTypeMismatchArgumentNullable $title is not null because $page isn't Hooks::runner()->onEditPageCopyrightWarning( $title, $copywarnMsg ); + if ( !$copywarnMsg ) { + return ''; + } $msg = $localizer->msg( ...$copywarnMsg )->page( $page ); return Html::rawElement( 'div', [ 'id' => 'editpage-copywarn' ], $msg->$format() ); diff --git a/includes/OutputPage.php b/includes/OutputPage.php index a8333d5f974..3b012d833ea 100644 --- a/includes/OutputPage.php +++ b/includes/OutputPage.php @@ -3091,6 +3091,7 @@ class OutputPage extends ContextSource { * * @deprecated since 1.36. Use ::formatPermissionStatus instead * @param array $errors Array of arrays returned by PermissionManager::getPermissionErrors + * @phan-param non-empty-array[] $errors * @param string|null $action Action that was denied or null if unknown * @return string The wikitext error-messages, formatted into a list. */ diff --git a/includes/Permissions/PermissionManager.php b/includes/Permissions/PermissionManager.php index 05aa7a06eb4..5e1ee8821c2 100644 --- a/includes/Permissions/PermissionManager.php +++ b/includes/Permissions/PermissionManager.php @@ -334,6 +334,7 @@ class PermissionManager { * whose corresponding errors may be ignored. * * @return array[] Array of arrays of the arguments to wfMessage to explain permissions problems. + * @phan-return non-empty-array[] */ public function getPermissionErrors( $action, diff --git a/includes/Status.php b/includes/Status.php index 92ec52bb190..4743172074d 100644 --- a/includes/Status.php +++ b/includes/Status.php @@ -351,6 +351,7 @@ class Status extends StatusValue { * * @return array[] A list in which each entry is an array with a message key as its first element. * The remaining array elements are the message parameters. + * @phan-return non-empty-array[] * @deprecated since 1.25 */ public function getErrorsArray() { @@ -362,6 +363,7 @@ class Status extends StatusValue { * * @return array[] A list in which each entry is an array with a message key as its first element. * The remaining array elements are the message parameters. + * @phan-return non-empty-array[] * @deprecated since 1.25 */ public function getWarningsArray() { diff --git a/includes/api/ApiBase.php b/includes/api/ApiBase.php index 5430fff45a5..d62955dd214 100644 --- a/includes/api/ApiBase.php +++ b/includes/api/ApiBase.php @@ -1213,6 +1213,7 @@ abstract class ApiBase extends ContextSource { * * @since 1.25 * @param string|array|Message $msg + * @phan-param string|non-empty-array|Message $msg * @param IContextSource $context * @param array|null $params * @return Message|null diff --git a/includes/auth/ButtonAuthenticationRequest.php b/includes/auth/ButtonAuthenticationRequest.php index 242ae9b636b..f6c7b6a5084 100644 --- a/includes/auth/ButtonAuthenticationRequest.php +++ b/includes/auth/ButtonAuthenticationRequest.php @@ -102,14 +102,14 @@ class ButtonAuthenticationRequest extends AuthenticationRequest { $data['label'] = new RawMessage( '$1', $data['name'] ); } elseif ( is_string( $data['label'] ) ) { $data['label'] = new Message( $data['label'] ); - } elseif ( is_array( $data['label'] ) ) { + } elseif ( is_array( $data['label'] ) && $data['label'] ) { $data['label'] = Message::newFromKey( ...$data['label'] ); } if ( !isset( $data['help'] ) ) { $data['help'] = new RawMessage( '$1', $data['name'] ); } elseif ( is_string( $data['help'] ) ) { $data['help'] = new Message( $data['help'] ); - } elseif ( is_array( $data['help'] ) ) { + } elseif ( is_array( $data['help'] ) && $data['help'] ) { $data['help'] = Message::newFromKey( ...$data['help'] ); } $ret = new static( $data['name'], $data['label'], $data['help'] ); diff --git a/includes/auth/ResetPasswordSecondaryAuthenticationProvider.php b/includes/auth/ResetPasswordSecondaryAuthenticationProvider.php index 25a17544f1f..5291d2492e8 100644 --- a/includes/auth/ResetPasswordSecondaryAuthenticationProvider.php +++ b/includes/auth/ResetPasswordSecondaryAuthenticationProvider.php @@ -113,7 +113,9 @@ class ResetPasswordSecondaryAuthenticationProvider extends AbstractSecondaryAuth ); } + /** @var PasswordAuthenticationRequest $req */ $req = AuthenticationRequest::getRequestByClass( $reqs, get_class( $needReq ) ); + '@phan-var PasswordAuthenticationRequest $req'; if ( !$req || !array_key_exists( 'retype', $req->getFieldInfo() ) ) { return AuthenticationResponse::newUI( $needReqs, $data->msg, 'warning' ); } diff --git a/includes/block/AbstractBlock.php b/includes/block/AbstractBlock.php index 38ce95b67e1..2106177b264 100644 --- a/includes/block/AbstractBlock.php +++ b/includes/block/AbstractBlock.php @@ -428,6 +428,7 @@ abstract class AbstractBlock implements Block { * @return array A message array: either a list of strings, the first of which * is the message key and the remaining ones the parameters, or an array with * a single MessageSpecifier object. + * @phan-return non-empty-array */ public function getPermissionsError( IContextSource $context ) { $message = MediaWikiServices::getInstance() diff --git a/includes/diff/DifferenceEngine.php b/includes/diff/DifferenceEngine.php index 7b33be096c7..7349739717c 100644 --- a/includes/diff/DifferenceEngine.php +++ b/includes/diff/DifferenceEngine.php @@ -1308,6 +1308,7 @@ class DifferenceEngine extends ContextSource { * @since 1.31 * * @return string[] + * @phan-return non-empty-array * @throws MWException */ protected function getDiffBodyCacheKeyParams() { diff --git a/includes/htmlform/HTMLForm.php b/includes/htmlform/HTMLForm.php index 58176fc6f8c..b6e34e58ece 100644 --- a/includes/htmlform/HTMLForm.php +++ b/includes/htmlform/HTMLForm.php @@ -214,6 +214,10 @@ class HTMLForm extends ContextSource { protected $mCancelTarget; protected $mSubmitCallback; + /** + * @var array[] + * @phan-var non-empty-array[] + */ protected $mValidationErrorMessage; protected $mPre = ''; @@ -768,8 +772,9 @@ class HTMLForm extends ContextSource { /** * Set a message to display on a validation error. * - * @param array $msg Array of valid inputs to wfMessage() + * @param array[] $msg Array of valid inputs to wfMessage() * (so each entry must itself be an array of arguments) + * @phan-param non-empty-array[] $msg * * @return HTMLForm $this for chaining calls (since 1.20) */ diff --git a/includes/logging/LogPager.php b/includes/logging/LogPager.php index 1d8734a511e..5594315e6c8 100644 --- a/includes/logging/LogPager.php +++ b/includes/logging/LogPager.php @@ -292,11 +292,14 @@ class LogPager extends ReverseChronologicalPager { $params = [ $name . $interwikiDelimiter ]; // @phan-suppress-next-next-line PhanPossiblyUndeclaredVariable $database is set when reached here // @phan-suppress-next-line PhanTypeMismatchArgumentNullableInternal $database is set when reached here - foreach ( explode( '*', $database ) as $databasepart ) { + $databaseParts = explode( '*', $database ); + $databasePartCount = count( $databaseParts ); + foreach ( $databaseParts as $i => $databasepart ) { $params[] = $databasepart; - $params[] = $db->anyString(); + if ( $i < $databasePartCount - 1 ) { + $params[] = $db->anyString(); + } } - array_pop( $params ); // Get rid of the last % we added. $this->mConds[] = 'log_title' . $db->buildLike( ...$params ); } elseif ( $pattern && !$this->getConfig()->get( MainConfigNames::MiserMode ) ) { $this->mConds[] = 'log_title' . $db->buildLike( $page->getDBkey(), $db->anyString() );