diff options
178 files changed, 318 insertions, 12 deletions
diff --git a/.phan/config.php b/.phan/config.php index 3cf2086ce517..af023cc49105 100644 --- a/.phan/config.php +++ b/.phan/config.php @@ -93,7 +93,6 @@ $cfg['exclude_analysis_directory_list'] = [ ]; // These are too spammy for now. TODO enable -$cfg['null_casts_as_any_type'] = true; $cfg['suppress_issue_types'][] = 'PhanTypePossiblyInvalidDimOffset'; $cfg['suppress_issue_types'][] = 'PhanPossiblyUndeclaredVariable'; $cfg['suppress_issue_types'][] = 'PhanCompatibleAccessMethodOnTraitDefinition'; // T289813 diff --git a/includes/CategoryViewer.php b/includes/CategoryViewer.php index 4124725a1d96..b1ff8b7895d6 100644 --- a/includes/CategoryViewer.php +++ b/includes/CategoryViewer.php @@ -105,6 +105,7 @@ class CategoryViewer extends ContextSource { 'title', '1.37', function (): Title { + // @phan-suppress-next-line PhanTypeMismatchReturnNullable castFrom does not return null here return Title::castFromPageIdentity( $this->page ); }, function ( PageIdentity $page ) { @@ -243,6 +244,7 @@ class CategoryViewer extends ContextSource { $link = null; $legacyTitle = MediaWikiServices::getInstance()->getTitleFactory() ->castFromPageReference( $page ); + // @phan-suppress-next-line PhanTypeMismatchArgument castFrom does not return null here $this->getHookRunner()->onCategoryViewer__generateLink( $type, $legacyTitle, $html, $link ); if ( $link === null ) { $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer(); @@ -302,8 +304,10 @@ class CategoryViewer extends ContextSource { if ( $this->showGallery ) { $flip = $this->flip['file']; if ( $flip ) { + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable castFrom does not return null here $this->gallery->insert( $title ); } else { + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable castFrom does not return null here $this->gallery->add( $title ); } } else { diff --git a/includes/CommentFormatter/CommentFormatter.php b/includes/CommentFormatter/CommentFormatter.php index 5c2b1d816014..2a8fb15679d6 100644 --- a/includes/CommentFormatter/CommentFormatter.php +++ b/includes/CommentFormatter/CommentFormatter.php @@ -265,6 +265,7 @@ class CommentFormatter { } else { $key = $i; } + // @phan-suppress-next-line PhanTypeMismatchDimAssignment getId does not return null here $outputs[$key] = $this->preprocessRevComment( $parser, $authority, $rev, $samePage, $isPublic, $useParentheses ); } diff --git a/includes/CommentFormatter/CommentParser.php b/includes/CommentFormatter/CommentParser.php index f7f4e551d161..e569c74182b2 100644 --- a/includes/CommentFormatter/CommentParser.php +++ b/includes/CommentFormatter/CommentParser.php @@ -419,6 +419,7 @@ class CommentParser { if ( $linkMarker ) { // If the link is still valid, go ahead and replace it in! $comment = preg_replace( + // @phan-suppress-next-line PhanTypeMismatchArgumentNullableInternal linkRegexp set when used $linkRegexp, $linkMarker, $comment, diff --git a/includes/EditPage.php b/includes/EditPage.php index 025773872857..49b281300165 100644 --- a/includes/EditPage.php +++ b/includes/EditPage.php @@ -1265,6 +1265,7 @@ class EditPage implements IEditObject { $params = $request->getArray( 'preloadparams', $params ); } + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable getVal does not return null here $content = $this->getPreloadedContent( $preload, $params ); } // For existing pages, get text based on "undo" or section parameters. @@ -1454,8 +1455,11 @@ class EditPage implements IEditObject { $undoIsLatest = $this->page->getRevisionRecord()->getId() === $undoRev->getId(); return $handler->getUndoContent( + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable Content is for public use $currentContent, + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable Content is for public use $undoContent, + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable Content is for public use $undoAfterContent, $undoIsLatest ); @@ -1624,6 +1628,7 @@ class EditPage implements IEditObject { * @param Authority $performer * @return bool * @throws Exception + * @phan-assert-true-condition $page */ private function isPageExistingAndViewable( ?PageIdentity $page, Authority $performer ): bool { return $page && $page->exists() && $performer->authorizeRead( 'read', $page ); @@ -1674,7 +1679,7 @@ class EditPage implements IEditObject { /** * Attempt submission - * @param array|bool &$resultDetails See docs for $result in internalAttemptSave + * @param array|bool &$resultDetails See docs for $result in internalAttemptSave @phan-output-reference * @throws UserBlockedError|ReadOnlyError|ThrottledError|PermissionsError * @return Status */ @@ -1810,6 +1815,7 @@ class EditPage implements IEditObject { case self::AS_BLOCKED_PAGE_FOR_USER: throw new UserBlockedError( + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable Block is checked and not null $this->context->getUser()->getBlock(), $this->context->getUser(), $this->context->getLanguage(), @@ -2081,6 +2087,7 @@ class EditPage implements IEditObject { } $pageUpdater = $this->page->newPageUpdater( $user ) + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable False positive ->setContent( SlotRecord::MAIN, $content ); $pageUpdater->prepareUpdate( $flags ); @@ -2760,6 +2767,7 @@ class EditPage implements IEditObject { ( $block->isSitewide() || $this->permManager->isBlockedFrom( + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable False positive $user, $this->mTitle, true @@ -3616,6 +3624,7 @@ class EditPage implements IEditObject { ); $this->context->getOutput()->addHTML( + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable False positive, text is not null Html::textarea( $name, $builder->addNewLineAtEnd( $text ), $attribs ) ); } @@ -4164,6 +4173,7 @@ class EditPage implements IEditObject { $content = $content->addSectionHeader( $this->summary ); } + // @phan-suppress-next-line PhanTypeMismatchArgument Type mismatch on pass-by-ref args $this->getHookRunner()->onEditPageGetPreviewContent( $this, $content ); $parserResult = $this->doPreviewParse( $content ); diff --git a/includes/GlobalFunctions.php b/includes/GlobalFunctions.php index 930d1b822c39..8f6d83263952 100644 --- a/includes/GlobalFunctions.php +++ b/includes/GlobalFunctions.php @@ -1497,6 +1497,7 @@ function wfEscapeWikiText( $text ) { $repl2 = $repl2 ? '/\b(' . implode( '|', $repl2 ) . '):/i' : '/^(?!)/'; } $text = substr( strtr( "\n$text", $repl ), 1 ); + // @phan-suppress-next-line PhanTypeMismatchArgumentNullableInternal False positive $text = preg_replace( $repl2, '$1:', $text ); return $text; } @@ -2141,6 +2142,7 @@ function wfRelativePath( $path, $from ) { } // relative dots to bump us to the parent + // @phan-suppress-next-line PhanTypeMismatchArgumentNullableInternal False positive while ( count( $against ) ) { array_unshift( $pieces, '..' ); array_shift( $against ); diff --git a/includes/Linker.php b/includes/Linker.php index 3bbdaf7d83d0..adb28a740a4e 100644 --- a/includes/Linker.php +++ b/includes/Linker.php @@ -302,7 +302,9 @@ class Linker { $res = null; $dummy = new DummyLinker; if ( !Hooks::runner()->onImageBeforeProduceHTML( $dummy, $title, + // @phan-suppress-next-line PhanTypeMismatchArgument Type mismatch on pass-by-ref args $file, $frameParams, $handlerParams, $time, $res, + // @phan-suppress-next-line PhanTypeMismatchArgument Type mismatch on pass-by-ref args $parser, $query, $widthOption ) ) { return $res; diff --git a/includes/MergeHistory.php b/includes/MergeHistory.php index dda8659988d5..d2a6d41ea8ae 100644 --- a/includes/MergeHistory.php +++ b/includes/MergeHistory.php @@ -396,6 +396,7 @@ class MergeHistory { $logId = $logEntry->insert(); $logEntry->publish( $logId ); + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable castFrom does not return null here $this->hookRunner->onArticleMergeComplete( $legacySource, $legacyDest ); $this->dbw->endAtomic( __METHOD__ ); @@ -428,6 +429,7 @@ class MergeHistory { $newContent = $contentHandler->makeEmptyContent(); } else { $msg = wfMessage( 'mergehistory-redirect-text' )->inContentLanguage()->plain(); + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable castFrom does not return null here $newContent = $contentHandler->makeRedirectContent( $legacyDestTitle, $msg ); } diff --git a/includes/PageProps.php b/includes/PageProps.php index 6eac43da5e74..9e752f94034b 100644 --- a/includes/PageProps.php +++ b/includes/PageProps.php @@ -211,7 +211,9 @@ class PageProps { $pageProperties[$row->pp_propname] = $row->pp_value; } if ( $pageProperties != [] ) { + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable pageID set when used $this->cacheProperties( $pageID, $pageProperties ); + // @phan-suppress-next-line PhanTypeMismatchDimAssignment pageID set when used $values[$pageID] = $pageProperties; } } diff --git a/includes/Permissions/PermissionManager.php b/includes/Permissions/PermissionManager.php index ee9902bdee5d..146974706a32 100644 --- a/includes/Permissions/PermissionManager.php +++ b/includes/Permissions/PermissionManager.php @@ -353,6 +353,7 @@ class PermissionManager { if ( $title->equals( $user->getTalkPage() ) ) { $blocked = $block->appliesToUsertalk( $title ); } else { + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable castFrom does not return null here $blocked = $block->appliesToTitle( $title ); } } @@ -361,6 +362,7 @@ class PermissionManager { $allowUsertalk = $block->isUsertalkEditAllowed(); // Allow extensions to let a blocked user access a particular page + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable castFrom does not return null here $this->hookRunner->onUserIsBlockedFrom( $user, $title, $blocked, $allowUsertalk ); return $blocked; diff --git a/includes/Permissions/RestrictionStore.php b/includes/Permissions/RestrictionStore.php index b460f1cbf22e..6f74df4ba677 100644 --- a/includes/Permissions/RestrictionStore.php +++ b/includes/Permissions/RestrictionStore.php @@ -305,6 +305,7 @@ class RestrictionStore { if ( $this->hookContainer->isRegistered( 'TitleGetRestrictionTypes' ) ) { $this->hookRunner->onTitleGetRestrictionTypes( + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable castFrom does not return null here Title::castFromPageIdentity( $page ), $types ); } diff --git a/includes/Rest/Handler/MediaFileHandler.php b/includes/Rest/Handler/MediaFileHandler.php index 53111856fe89..878a8d54c43e 100644 --- a/includes/Rest/Handler/MediaFileHandler.php +++ b/includes/Rest/Handler/MediaFileHandler.php @@ -66,6 +66,7 @@ class MediaFileHandler extends SimpleHandler { if ( $this->file === false ) { $page = $this->getPage(); $this->file = + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable $this->repoGroup->findFile( $page, [ 'private' => $this->getAuthority() ] ) ?: null; } return $this->file; diff --git a/includes/Rest/Handler/PageContentHelper.php b/includes/Rest/Handler/PageContentHelper.php index 9f9ee62b2561..a0365109d9bc 100644 --- a/includes/Rest/Handler/PageContentHelper.php +++ b/includes/Rest/Handler/PageContentHelper.php @@ -215,7 +215,9 @@ class PageContentHelper { $revision = $this->getTargetRevision(); return [ 'id' => $page->getId(), + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable 'key' => $this->titleFormatter->getPrefixedDBkey( $page ), + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable 'title' => $this->titleFormatter->getPrefixedText( $page ), 'latest' => [ 'id' => $revision->getId(), @@ -274,6 +276,7 @@ class PageContentHelper { ); } + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable Validated by hasContent if ( !$this->authority->authorizeRead( 'read', $this->getPage() ) ) { throw new LocalizedHttpException( MessageValue::new( 'rest-permission-denied-title' )->plaintextParams( $titleText ), diff --git a/includes/Rest/Handler/RevisionContentHelper.php b/includes/Rest/Handler/RevisionContentHelper.php index 0165b21c0e0e..2c8bf19927fd 100644 --- a/includes/Rest/Handler/RevisionContentHelper.php +++ b/includes/Rest/Handler/RevisionContentHelper.php @@ -112,7 +112,9 @@ class RevisionContentHelper extends PageContentHelper { 'content_model' => $mainSlot->getModel(), 'page' => [ 'id' => $page->getId(), + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable 'key' => $this->titleFormatter->getPrefixedDBkey( $page ), + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable 'title' => $this->titleFormatter->getPrefixedText( $page ), ], 'license' => [ @@ -134,6 +136,7 @@ class RevisionContentHelper extends PageContentHelper { $comment = $revision->getComment( RevisionRecord::FOR_THIS_USER, $this->authority ); $metadata['comment'] = $comment ? $comment->text : null; + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable $parent = $this->revisionLookup->getPreviousRevision( $revision ); if ( $parent ) { $metadata['delta'] = $revision->getSize() - $parent->getSize(); @@ -171,6 +174,7 @@ class RevisionContentHelper extends PageContentHelper { ); } + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable Validated by hasContent if ( !$this->authority->authorizeRead( 'read', $this->getPage() ) ) { throw new LocalizedHttpException( MessageValue::new( 'rest-permission-denied-revision' )->plaintextParams( $revId ), diff --git a/includes/Rest/Handler/RevisionSourceHandler.php b/includes/Rest/Handler/RevisionSourceHandler.php index e3a2d55c9a1d..d9f9938b4926 100644 --- a/includes/Rest/Handler/RevisionSourceHandler.php +++ b/includes/Rest/Handler/RevisionSourceHandler.php @@ -69,6 +69,7 @@ class RevisionSourceHandler extends SimpleHandler { case 'bare': $revisionRecord = $this->contentHelper->getTargetRevision(); $body = $this->contentHelper->constructMetadata(); + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable revisionRecord is set when used $body['html_url'] = $this->constructHtmlUrl( $revisionRecord ); $response = $this->getResponseFactory()->createJson( $body ); $this->contentHelper->setCacheControl( $response ); diff --git a/includes/Rest/Handler/SearchHandler.php b/includes/Rest/Handler/SearchHandler.php index 5ff82fe0e832..c0bbf8afedc6 100644 --- a/includes/Rest/Handler/SearchHandler.php +++ b/includes/Rest/Handler/SearchHandler.php @@ -380,7 +380,9 @@ class SearchHandler extends Handler { $res = $this->buildResultFromPageInfos( $pageInfos ); $result = array_map( "array_merge", $this->buildResultFromPageInfos( $pageInfos ), + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable False positive $this->buildDescriptionsFromPageIdentities( $pageIdentities ), + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable False positive $this->buildThumbnailsFromPageIdentities( $pageIdentities ) ); $response = $this->getResponseFactory()->createJson( [ 'pages' => $result ] ); diff --git a/includes/Revision/MainSlotRoleHandler.php b/includes/Revision/MainSlotRoleHandler.php index 5b9051f92990..140caae95d83 100644 --- a/includes/Revision/MainSlotRoleHandler.php +++ b/includes/Revision/MainSlotRoleHandler.php @@ -93,6 +93,7 @@ class MainSlotRoleHandler extends SlotRoleHandler { $title = $this->titleFactory->castFromPageIdentity( $page ); $handler = $this->contentHandlerFactory->getContentHandler( $model ); + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable castFrom does not return null here return $handler->canBeUsedOn( $title ); } @@ -115,6 +116,7 @@ class MainSlotRoleHandler extends SlotRoleHandler { } else { $title = $this->titleFactory->castFromLinkTarget( $page ); } + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable castFrom notnull/Type mismatch on pass-by-ref args if ( !$this->hookRunner->onContentHandlerDefaultModelFor( $title, $model ) && $model !== null ) { return $model; } diff --git a/includes/Revision/RevisionRecord.php b/includes/Revision/RevisionRecord.php index dee267ff4edc..3356ad71d018 100644 --- a/includes/Revision/RevisionRecord.php +++ b/includes/Revision/RevisionRecord.php @@ -355,6 +355,7 @@ abstract class RevisionRecord implements WikiAwareEntity { public function getPageAsLinkTarget() { // TODO: Should be TitleValue::newFromPage( $this->mPage ), // but Title is used too much still, so let's keep propagating it + // @phan-suppress-next-line PhanTypeMismatchReturnNullable castFrom does not return null here return Title::castFromPageIdentity( $this->mPage ); } diff --git a/includes/Revision/RevisionStore.php b/includes/Revision/RevisionStore.php index 2405a7f825cf..e12be712b985 100644 --- a/includes/Revision/RevisionStore.php +++ b/includes/Revision/RevisionStore.php @@ -301,6 +301,7 @@ class RevisionStore } $page = $this->getPage( $pageId, $revId, $queryFlags ); + // @phan-suppress-next-line PhanTypeMismatchReturnNullable castFrom does not return null here return $this->titleFactory->castFromPageIdentity( $page ); } @@ -380,6 +381,7 @@ class RevisionStore // over and over later on. // When there is less need to convert to Title, this special case can // be removed. + // @phan-suppress-next-line PhanTypeMismatchReturnNullable castFrom does not return null here return $this->titleFactory->castFromPageIdentity( $page ); } else { return $page; @@ -1886,6 +1888,7 @@ class RevisionStore } } + // @phan-suppress-next-line PhanTypeMismatchReturnNullable getPageByName/newFromID should not return null return $page; } diff --git a/includes/Settings/Cache/CachedSource.php b/includes/Settings/Cache/CachedSource.php index b110b8c656e5..d73809d8ebbe 100644 --- a/includes/Settings/Cache/CachedSource.php +++ b/includes/Settings/Cache/CachedSource.php @@ -107,6 +107,7 @@ class CachedSource implements SettingsSource, SettingsIncludeLocator { ); } + // @phan-suppress-next-line PhanTypeMismatchReturn WaitConditionLoop throws or value set return $result; } diff --git a/includes/Settings/SettingsBuilder.php b/includes/Settings/SettingsBuilder.php index 2c42d65f21e5..53435446cd9c 100644 --- a/includes/Settings/SettingsBuilder.php +++ b/includes/Settings/SettingsBuilder.php @@ -275,6 +275,7 @@ class SettingsBuilder { $this->settingsConfig[ $key ] = $config[ $key ]; } } + // @phan-suppress-next-line PhanTypeMismatchReturnNullable Always set return $key; } diff --git a/includes/Setup.php b/includes/Setup.php index 956a03004c51..87871fc78005 100644 --- a/includes/Setup.php +++ b/includes/Setup.php @@ -361,6 +361,7 @@ if ( isset( $wgShortPagesNamespaceBlacklist ) ) { } // Prohibited file extensions shouldn't appear on the "allowed" list +// @phan-suppress-next-line PhanTypeMismatchArgumentNullableInternal False positive $wgFileExtensions = array_values( array_diff( $wgFileExtensions, $wgProhibitedFileExtensions ) ); // Fix path to icon images after they were moved in 1.24 diff --git a/includes/Storage/DerivedPageDataUpdater.php b/includes/Storage/DerivedPageDataUpdater.php index a812c995d2cc..980397e18c16 100644 --- a/includes/Storage/DerivedPageDataUpdater.php +++ b/includes/Storage/DerivedPageDataUpdater.php @@ -1460,6 +1460,7 @@ class DerivedPageDataUpdater implements IDBAccessObject, LoggerAwareInterface, P $recursive ); if ( $this->options['moved'] ) { + // @phan-suppress-next-line PhanTypeMismatchArgument Oldtitle is set along with moved $linksUpdate->setMoveDetails( $this->options['oldtitle'] ); } @@ -1769,6 +1770,7 @@ class DerivedPageDataUpdater implements IDBAccessObject, LoggerAwareInterface, P // updates that are not defined as being related. $update = new RefreshSecondaryDataUpdate( $this->loadbalancerFactory, + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable Already checked $triggeringUser, $this->wikiPage, $this->revision, diff --git a/includes/Storage/NameTableStoreFactory.php b/includes/Storage/NameTableStoreFactory.php index 825976decfd9..90216863a8d9 100644 --- a/includes/Storage/NameTableStoreFactory.php +++ b/includes/Storage/NameTableStoreFactory.php @@ -108,7 +108,9 @@ class NameTableStoreFactory { $this->cache, $this->logger, $tableName, + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable False positive $info['idField'], + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable False positive $info['nameField'], $info['normalizationCallback'] ?? null, $wiki, diff --git a/includes/Storage/PageUpdater.php b/includes/Storage/PageUpdater.php index ece328b3b890..02db62ec834a 100644 --- a/includes/Storage/PageUpdater.php +++ b/includes/Storage/PageUpdater.php @@ -1001,6 +1001,7 @@ class PageUpdater { // XXX: do we need PST? $this->flags |= EDIT_INTERNAL; + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable revision is checked $this->status = $this->doUpdate( $revision ); } @@ -1165,6 +1166,7 @@ class PageUpdater { // XXX: We may push this up to the "edit controller" level, see T192777. $contentHandler = $this->contentHandlerFactory->getContentHandler( $content->getModel() ); + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable getId is not null here $validationParams = new ValidationParams( $wikiPage, $this->flags, $oldid ); $prepStatus = $contentHandler->validateSave( $content, $validationParams ); @@ -1564,6 +1566,7 @@ class PageUpdater { $summary, $this->flags, $newRevisionRecord, + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable Not null already checked $editResult, $approved ); @@ -1585,6 +1588,7 @@ class PageUpdater { $summary->text, $this->flags, $newRevisionRecord, + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable Not null already checked $editResult ); } diff --git a/includes/Storage/RevertedTagUpdate.php b/includes/Storage/RevertedTagUpdate.php index c372c4f7ab84..dd39e63fd8fc 100644 --- a/includes/Storage/RevertedTagUpdate.php +++ b/includes/Storage/RevertedTagUpdate.php @@ -278,6 +278,7 @@ class RevertedTagUpdate implements DeferrableUpdate { } $this->markAsReverted( + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable revertedRevision is already checked $this->editResult->getOldestRevertedRevisionId(), $this->getTagExtraParams() ); @@ -363,6 +364,7 @@ class RevertedTagUpdate implements DeferrableUpdate { private function getNewestRevertedRevision(): ?RevisionRecord { if ( !isset( $this->newestRevertedRevision ) ) { $this->newestRevertedRevision = $this->revisionStore->getRevisionById( + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable newestRevertedRevision is checked $this->editResult->getNewestRevertedRevisionId() ); } @@ -377,6 +379,7 @@ class RevertedTagUpdate implements DeferrableUpdate { private function getOldestRevertedRevision(): ?RevisionRecord { if ( !isset( $this->oldestRevertedRevision ) ) { $this->oldestRevertedRevision = $this->revisionStore->getRevisionById( + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable oldestRevertedRevision is checked $this->editResult->getOldestRevertedRevisionId() ); } diff --git a/includes/Title.php b/includes/Title.php index 0efda72836bc..8cb2b3bccb3c 100644 --- a/includes/Title.php +++ b/includes/Title.php @@ -723,6 +723,7 @@ class Title implements LinkTarget, PageIdentity, IDBAccessObject { if ( !$title ) { $title = self::newFromText( 'Main Page' ); } + // @phan-suppress-next-line PhanTypeMismatchReturnNullable Fallback is always valid return $title; } diff --git a/includes/WebRequest.php b/includes/WebRequest.php index 239d3b903fc7..da63084c9114 100644 --- a/includes/WebRequest.php +++ b/includes/WebRequest.php @@ -1338,6 +1338,7 @@ class WebRequest { } # Allow extensions to improve our guess + // @phan-suppress-next-line PhanTypeMismatchArgument Type mismatch on pass-by-ref args Hooks::runner()->onGetIP( $ip ); if ( !$ip ) { diff --git a/includes/actions/CreditsAction.php b/includes/actions/CreditsAction.php index abd85ceee931..d1cd5698eaf4 100644 --- a/includes/actions/CreditsAction.php +++ b/includes/actions/CreditsAction.php @@ -121,6 +121,7 @@ class CreditsAction extends FormlessAction { } return $this->msg( 'lastmodifiedatby', $d, $t )->rawParams( + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable RIGOR_NONE never returns null $this->userLink( $user ) )->params( $user->getName() )->escaped(); } diff --git a/includes/actions/RawAction.php b/includes/actions/RawAction.php index a5d66b45fc8b..a9b79c991129 100644 --- a/includes/actions/RawAction.php +++ b/includes/actions/RawAction.php @@ -301,6 +301,7 @@ class RawAction extends FormlessAction { break; } + // @phan-suppress-next-line PhanTypeMismatchReturnNullable RevisionRecord::getId does not return null here return $oldid; } diff --git a/includes/actions/RollbackAction.php b/includes/actions/RollbackAction.php index ae6fe04963e3..a06310635dae 100644 --- a/includes/actions/RollbackAction.php +++ b/includes/actions/RollbackAction.php @@ -176,6 +176,7 @@ class RollbackAction extends FormAction { } $rollbackResult = $this->rollbackPageFactory + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable use of raw avoids null here ->newRollbackPage( $this->getWikiPage(), $this->getContext()->getAuthority(), $revUser ) ->setSummary( $request->getText( 'summary' ) ) ->markAsBot( $request->getBool( 'bot' ) ) diff --git a/includes/api/ApiBase.php b/includes/api/ApiBase.php index 2fca3c85d328..ec7a8574244a 100644 --- a/includes/api/ApiBase.php +++ b/includes/api/ApiBase.php @@ -1042,6 +1042,7 @@ abstract class ApiBase extends ContextSource { if ( !$titleObj->canExist() ) { $this->dieWithError( 'apierror-pagecannotexist' ); } + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable T240141 $pageObj = WikiPage::factory( $titleObj ); if ( $load !== false ) { $pageObj->loadPageData( $load ); @@ -1056,6 +1057,7 @@ abstract class ApiBase extends ContextSource { } } + // @phan-suppress-next-line PhanTypeMismatchReturnNullable requireOnlyOneParameter guard it is always set return $pageObj; } @@ -1076,6 +1078,7 @@ abstract class ApiBase extends ContextSource { if ( !$titleObj || $titleObj->isExternal() ) { $this->dieWithError( [ 'apierror-invalidtitle', wfEscapeWikiText( $params['title'] ) ] ); } + // @phan-suppress-next-line PhanTypeMismatchReturnNullable T240141 return $titleObj; } elseif ( isset( $params['pageid'] ) ) { $titleObj = Title::newFromID( $params['pageid'] ); @@ -1084,6 +1087,7 @@ abstract class ApiBase extends ContextSource { } } + // @phan-suppress-next-line PhanTypeMismatchReturnNullable requireOnlyOneParameter guard it is always set return $titleObj; } @@ -1186,6 +1190,7 @@ abstract class ApiBase extends ContextSource { [ 'nosuchusershort', wfEscapeWikiText( $params['owner'] ) ], 'bad_wlowner' ); } + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable T240141 $token = $services->getUserOptionsLookup()->getOption( $user, 'watchlisttoken' ); if ( $token == '' || !hash_equals( $token, $params['token'] ) ) { $this->dieWithError( 'apierror-bad-watchlist-token', 'bad_wltoken' ); @@ -1198,6 +1203,7 @@ abstract class ApiBase extends ContextSource { $this->checkUserRightsAny( 'viewmywatchlist' ); } + // @phan-suppress-next-line PhanTypeMismatchReturnNullable T240141 return $user; } @@ -1251,6 +1257,7 @@ abstract class ApiBase extends ContextSource { if ( is_string( $error[0] ) && isset( self::$blockMsgMap[$error[0]] ) && $user->getBlock() ) { list( $msg, $code ) = self::$blockMsgMap[$error[0]]; $status->fatal( ApiMessage::create( $msg, $code, + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable Block is checked and not null [ 'blockinfo' => $this->getBlockDetails( $user->getBlock() ) ] ) ); } else { @@ -1581,8 +1588,10 @@ abstract class ApiBase extends ContextSource { $status = new PermissionStatus(); foreach ( (array)$actions as $action ) { if ( $this->isWriteMode() ) { + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable castFrom does not return null here $this->getAuthority()->authorizeWrite( $action, $pageIdentity, $status ); } else { + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable castFrom does not return null here $this->getAuthority()->authorizeRead( $action, $pageIdentity, $status ); } } diff --git a/includes/api/ApiComparePages.php b/includes/api/ApiComparePages.php index 1b8974ada89d..b4ccad795778 100644 --- a/includes/api/ApiComparePages.php +++ b/includes/api/ApiComparePages.php @@ -455,6 +455,7 @@ class ApiComparePages extends ApiBase { // Deprecated 'fromsection'/'tosection' if ( isset( $params["{$prefix}section"] ) ) { $section = $params["{$prefix}section"]; + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable T240141 $newRev = MutableRevisionRecord::newFromParentRevision( $rev ); $content = $rev->getContent( SlotRecord::MAIN, RevisionRecord::FOR_THIS_USER, $this->getUser() ); @@ -470,6 +471,7 @@ class ApiComparePages extends ApiBase { "nosuch{$prefix}section" ); } + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable T240141 $newRev->setContent( SlotRecord::MAIN, $content ); } @@ -543,6 +545,7 @@ class ApiComparePages extends ApiBase { $popts = ParserOptions::newFromContext( $this->getContext() ); $content = $this->contentTransformer->preSaveTransform( $content, + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable T240141 $title, $this->getUser(), $popts @@ -565,6 +568,7 @@ class ApiComparePages extends ApiBase { $this->dieWithError( [ 'apierror-sectionsnotsupported', $content->getModel() ] ); } try { + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable T240141 $content = $oldContent->replaceSection( $section, $content, '' ); } catch ( TimeoutException $e ) { throw $e; @@ -589,6 +593,7 @@ class ApiComparePages extends ApiBase { } } + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable T240141 $newRev->setContent( $role, $content ); } return [ $newRev, $rev, null ]; diff --git a/includes/api/ApiEditPage.php b/includes/api/ApiEditPage.php index a767dea25ece..8b7f4d6febb8 100644 --- a/includes/api/ApiEditPage.php +++ b/includes/api/ApiEditPage.php @@ -288,8 +288,11 @@ class ApiEditPage extends ApiBase { } $newContent = $contentHandler->getUndoContent( + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable Content is for public use here $pageObj->getRevisionRecord()->getContent( SlotRecord::MAIN ), + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable Content is for public use here $undoRev->getContent( SlotRecord::MAIN ), + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable Content is for public use here $undoafterRev->getContent( SlotRecord::MAIN ), $pageObj->getRevisionRecord()->getId() === $undoRev->getId() ); @@ -531,6 +534,7 @@ class ApiEditPage extends ApiBase { // obvious that this is even possible. // @codeCoverageIgnoreStart case EditPage::AS_BLOCKED_PAGE_FOR_USER: + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable Block is checked and not null $this->dieBlocked( $user->getBlock() ); // dieBlocked prevents continuation diff --git a/includes/api/ApiFileRevert.php b/includes/api/ApiFileRevert.php index 4fefdf0577a6..84bf788af6e2 100644 --- a/includes/api/ApiFileRevert.php +++ b/includes/api/ApiFileRevert.php @@ -105,6 +105,7 @@ class ApiFileRevert extends ApiBase { // Check if the archivename is valid for this file $this->archiveName = $this->params['archivename']; + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable T240141 $oldFile = $localRepo->newFromArchiveName( $title, $this->archiveName ); if ( !$oldFile->exists() ) { $this->dieWithError( 'filerevert-badversion' ); diff --git a/includes/api/ApiFormatXml.php b/includes/api/ApiFormatXml.php index 6f7d5ce769b5..fb3cbfc02443 100644 --- a/includes/api/ApiFormatXml.php +++ b/includes/api/ApiFormatXml.php @@ -171,6 +171,7 @@ class ApiFormatXml extends ApiFormatBase { if ( $content !== null ) { if ( is_scalar( $content ) ) { + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable name is check for null in other code $retval .= $indstr . Xml::element( $name, $attributes, $content ); } else { if ( $name !== null ) { @@ -205,8 +206,10 @@ class ApiFormatXml extends ApiFormatBase { // to make sure null value doesn't produce unclosed element, // which is what Xml::element( $name, null, null ) returns if ( $value === null ) { + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable name is check for null in other code $retval .= $indstr . Xml::element( $name, $attributes ); } else { + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable name is check for null in other code $retval .= $indstr . Xml::element( $name, $attributes, $value ); } } diff --git a/includes/api/ApiImportReporter.php b/includes/api/ApiImportReporter.php index 32ece0655e32..d6815ecb9a1d 100644 --- a/includes/api/ApiImportReporter.php +++ b/includes/api/ApiImportReporter.php @@ -48,6 +48,7 @@ class ApiImportReporter extends ImportReporter { $r['invalid'] = true; } else { $titleFactory = MediaWikiServices::getInstance()->getTitleFactory(); + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable castFrom does not return null here ApiQueryBase::addTitleInfo( $r, $titleFactory->castFromPageIdentity( $pageIdentity ) ); $r['revisions'] = (int)$successCount; } diff --git a/includes/api/ApiLogin.php b/includes/api/ApiLogin.php index 6ba75dc10e33..7e30b9eddca5 100644 --- a/includes/api/ApiLogin.php +++ b/includes/api/ApiLogin.php @@ -225,6 +225,7 @@ class ApiLogin extends ApiBase { break; case 'Failed': + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable message set on error $result['reason'] = $this->formatMessage( $message ); break; diff --git a/includes/api/ApiMain.php b/includes/api/ApiMain.php index 0a384bf3d0ca..d78afce1426a 100644 --- a/includes/api/ApiMain.php +++ b/includes/api/ApiMain.php @@ -573,6 +573,7 @@ class ApiMain extends ApiBase { if ( $uselang === 'content' ) { $uselang = $services->getContentLanguage()->getCode(); } + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable getRawVal does not return null $code = RequestContext::sanitizeLangCode( $uselang ); $derivativeContext->setLanguage( $code ); if ( !$this->mInternalMode ) { @@ -968,6 +969,7 @@ class ApiMain extends ApiBase { if ( $failed ) { $this->mPrinter = null; $this->createErrorPrinter(); + // @phan-suppress-next-line PhanNonClassMethodCall False positive $this->mPrinter->forceDefaultParams(); if ( $httpCode ) { $response->statusHeader( 200 ); // Reset in case the fallback doesn't want a non-200 @@ -1264,6 +1266,7 @@ class ApiMain extends ApiBase { if ( !$this->mModuleMgr->isDefined( $value, 'format' ) ) { $value = self::API_DEFAULT_FORMAT; } + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable getVal does not return null here $this->mPrinter = $this->createPrinterByName( $value ); } @@ -1506,6 +1509,7 @@ class ApiMain extends ApiBase { } } + // @phan-suppress-next-line PhanTypeMismatchReturnNullable T240141 return $module; } diff --git a/includes/api/ApiMergeHistory.php b/includes/api/ApiMergeHistory.php index 33f06dff77b6..abcbe7237688 100644 --- a/includes/api/ApiMergeHistory.php +++ b/includes/api/ApiMergeHistory.php @@ -83,6 +83,7 @@ class ApiMergeHistory extends ApiBase { $timestamp = $params['timestamp']; // Merge! + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable T240141 $status = $this->merge( $fromTitle, $toTitle, $timestamp, $reason ); if ( !$status->isOK() ) { $this->dieStatus( $status ); diff --git a/includes/api/ApiMove.php b/includes/api/ApiMove.php index 83ae0c455115..9a274e635bee 100644 --- a/includes/api/ApiMove.php +++ b/includes/api/ApiMove.php @@ -116,6 +116,7 @@ class ApiMove extends ApiBase { // Move the page $toTitleExists = $toTitle->exists(); + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable T240141 $status = $this->movePage( $fromTitle, $toTitle, $params['reason'], !$params['noredirect'], $params['tags'] ?: [] ); if ( !$status->isOK() ) { @@ -162,6 +163,7 @@ class ApiMove extends ApiBase { // Move subpages if ( $params['movesubpages'] ) { $r['subpages'] = $this->moveSubpages( + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable T240141 $fromTitle, $toTitle, $params['reason'], @@ -189,6 +191,7 @@ class ApiMove extends ApiBase { $watchlistExpiry = $this->getExpiryFromParams( $params ); // Watch pages + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable T240141 $this->setWatch( $watch, $fromTitle, $user, 'watchmoves', $watchlistExpiry ); $this->setWatch( $watch, $toTitle, $user, 'watchmoves', $watchlistExpiry ); diff --git a/includes/api/ApiPageSet.php b/includes/api/ApiPageSet.php index 7734ced72740..d6f2d575b664 100644 --- a/includes/api/ApiPageSet.php +++ b/includes/api/ApiPageSet.php @@ -273,6 +273,7 @@ class ApiPageSet extends ApiBase { } // Create a temporary pageset to store generator's output, // add any additional fields generator may need, and execute pageset to populate titles/pageids + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable T240141 $tmpPageSet = new ApiPageSet( $dbSource, self::DISABLE_GENERATORS ); $generator->setGeneratorMode( $tmpPageSet ); $this->mCacheMode = $generator->getCacheMode( $generator->extractRequestParams() ); @@ -286,6 +287,7 @@ class ApiPageSet extends ApiBase { if ( !$isDryRun ) { $generator->executeGenerator( $this ); + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable T240141 $this->getHookRunner()->onAPIQueryGeneratorAfterExecute( $generator, $this ); } else { // Prevent warnings from being reported on these parameters @@ -1385,6 +1387,7 @@ class ApiPageSet extends ApiBase { // ILanguageConverter::findVariantLink will modify titleText and // titleObj into the canonical variant if possible $titleText = $title !== false ? $title : $titleObj->getPrefixedText(); + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable castFrom does not return null here $this->languageConverter->findVariantLink( $titleText, $titleObj ); $titleWasConverted = $unconvertedTitle !== $titleObj->getPrefixedText(); } @@ -1420,6 +1423,7 @@ class ApiPageSet extends ApiBase { } } else { // Regular page + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable castFrom does not return null here $linkBatch->addObj( $titleObj ); } } diff --git a/includes/api/ApiParamInfo.php b/includes/api/ApiParamInfo.php index 9ed6a49d2e8c..8e3fbd47365e 100644 --- a/includes/api/ApiParamInfo.php +++ b/includes/api/ApiParamInfo.php @@ -86,6 +86,7 @@ class ApiParamInfo extends ApiBase { } continue; } + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable recursive is set when used $submodules = $this->listAllSubmodules( $module, $recursive ); if ( $submodules ) { $modules = array_merge( $modules, $submodules ); diff --git a/includes/api/ApiParse.php b/includes/api/ApiParse.php index bb852afd910d..d00b425f59df 100644 --- a/includes/api/ApiParse.php +++ b/includes/api/ApiParse.php @@ -819,6 +819,7 @@ class ApiParse extends ApiBase { $this->dieWithError( [ 'apierror-sectionsnotsupported-what', $what ], 'nosuchsection' ); } + // @phan-suppress-next-line PhanTypeMismatchReturnNullable T240141 return $section; } diff --git a/includes/api/ApiQueryBase.php b/includes/api/ApiQueryBase.php index fedcdd6286ed..9e622ed810af 100644 --- a/includes/api/ApiQueryBase.php +++ b/includes/api/ApiQueryBase.php @@ -443,7 +443,7 @@ abstract class ApiQueryBase extends ApiBase { * @since 1.28 * @param stdClass $row Database row * @param array &$data Data to be added to the result - * @param array &$hookData Hook data from ApiQueryBase::select() + * @param array &$hookData Hook data from ApiQueryBase::select() @phan-output-reference * @return bool Return false if row processing should end with continuation */ protected function processRow( $row, array &$data, array &$hookData ) { diff --git a/includes/api/ApiQueryContributors.php b/includes/api/ApiQueryContributors.php index 0b841c2dd422..adba44a3987f 100644 --- a/includes/api/ApiQueryContributors.php +++ b/includes/api/ApiQueryContributors.php @@ -219,6 +219,7 @@ class ApiQueryContributors extends ApiQueryBase { 'ug_expiry IS NULL OR ug_expiry >= ' . $db->addQuotes( $db->timestamp() ) ] ] ] ); + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable excludeGroups is set when used $this->addWhereIf( 'ug_user IS NULL', $excludeGroups ); } diff --git a/includes/api/ApiQueryInfo.php b/includes/api/ApiQueryInfo.php index 718a5e2f7f8c..f680681639c4 100644 --- a/includes/api/ApiQueryInfo.php +++ b/includes/api/ApiQueryInfo.php @@ -364,6 +364,7 @@ class ApiQueryInfo extends ApiQueryBase { $pageInfo['preload'] = ''; } else { $text = null; + // @phan-suppress-next-line PhanTypeMismatchArgument Type mismatch on pass-by-ref args $this->getHookRunner()->onEditFormPreloadText( $text, $title ); $pageInfo['preload'] = $text; diff --git a/includes/api/ApiQueryLogEvents.php b/includes/api/ApiQueryLogEvents.php index a2f6d15ed367..48e543e8ba83 100644 --- a/includes/api/ApiQueryLogEvents.php +++ b/includes/api/ApiQueryLogEvents.php @@ -165,7 +165,9 @@ class ApiQueryLogEvents extends ApiQueryBase { ); } + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable T240141 $this->addWhereFld( 'log_type', $type ); + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable T240141 $this->addWhereFld( 'log_action', $action ); } elseif ( $params['type'] !== null ) { $this->addWhereFld( 'log_type', $params['type'] ); @@ -322,6 +324,7 @@ class ApiQueryLogEvents extends ApiQueryBase { } if ( LogEventsList::userCan( $row, LogPage::DELETED_ACTION, $user ) ) { if ( $this->fld_title ) { + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable title is set when used ApiQueryBase::addTitleInfo( $vals, $title ); } if ( $this->fld_ids ) { diff --git a/includes/api/ApiQueryQueryPage.php b/includes/api/ApiQueryQueryPage.php index 406e36f61f81..b5345356f318 100644 --- a/includes/api/ApiQueryQueryPage.php +++ b/includes/api/ApiQueryQueryPage.php @@ -83,6 +83,7 @@ class ApiQueryQueryPage extends ApiQueryGeneratorBase { 'Special page ' . $name . ' is not a QueryPage' ); } + // @phan-suppress-next-line PhanTypeMismatchReturnNullable T240141 return $qp; } diff --git a/includes/api/ApiQueryRevisionsBase.php b/includes/api/ApiQueryRevisionsBase.php index 88a2d978dbf8..90e8e7984374 100644 --- a/includes/api/ApiQueryRevisionsBase.php +++ b/includes/api/ApiQueryRevisionsBase.php @@ -206,6 +206,7 @@ abstract class ApiQueryRevisionsBase extends ApiQueryGeneratorBase { if ( !$difftoRev ) { $this->dieWithError( [ 'apierror-nosuchrevid', $params['diffto'] ] ); } + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable T240141 $revDel = $this->checkRevDel( $difftoRev, RevisionRecord::DELETED_TEXT ); if ( $revDel & self::CANNOT_VIEW ) { $this->addWarning( [ 'apiwarn-difftohidden', $difftoRev->getId() ] ); diff --git a/includes/api/ApiQueryWatchlist.php b/includes/api/ApiQueryWatchlist.php index 8a3c4268293b..b7577a7427b3 100644 --- a/includes/api/ApiQueryWatchlist.php +++ b/includes/api/ApiQueryWatchlist.php @@ -341,6 +341,7 @@ class ApiQueryWatchlist extends ApiQueryGeneratorBase { ) ) { if ( $this->fld_title ) { + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable castFrom does not return null here ApiQueryBase::addTitleInfo( $vals, $title ); } if ( $this->fld_ids ) { diff --git a/includes/api/ApiResult.php b/includes/api/ApiResult.php index a4ce67947d9c..793d5e930fe2 100644 --- a/includes/api/ApiResult.php +++ b/includes/api/ApiResult.php @@ -899,6 +899,7 @@ class ApiResult implements ApiSerializable { $keepMetadata = &$metadata; break; case 'bc': + // @phan-suppress-next-line PhanTypeMismatchArgumentNullableInternal Type mismatch on pass-by-ref args $keepMetadata = array_intersect_key( $metadata, [ self::META_INDEXED_TAG_NAME => 1, self::META_SUBELEMENTS => 1, @@ -943,6 +944,7 @@ class ApiResult implements ApiSerializable { ksort( $data ); $data = array_values( $data ); $metadata[self::META_TYPE] = 'array'; + // @phan-suppress-next-line PhanTypeMismatchReturnNullable Type mismatch on pass-by-ref args return $data + $keepMetadata; case 'kvp': @@ -992,6 +994,7 @@ class ApiResult implements ApiSerializable { } $metadata[self::META_TYPE] = 'array'; + // @phan-suppress-next-line PhanTypeMismatchReturnNullable Type mismatch on pass-by-ref args return $ret + $keepMetadata; default: diff --git a/includes/api/ApiRevisionDelete.php b/includes/api/ApiRevisionDelete.php index 7db62b9162d6..6eeb62434e0f 100644 --- a/includes/api/ApiRevisionDelete.php +++ b/includes/api/ApiRevisionDelete.php @@ -93,6 +93,7 @@ class ApiRevisionDelete extends ApiBase { // TODO: replace use of PermissionManager if ( $this->getPermissionManager()->isBlockedFrom( $user, $targetObj ) ) { + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable Block is checked and not null $this->dieBlocked( $user->getBlock() ); } diff --git a/includes/api/ApiTag.php b/includes/api/ApiTag.php index 2a4634a26018..1338feaf5191 100644 --- a/includes/api/ApiTag.php +++ b/includes/api/ApiTag.php @@ -120,6 +120,7 @@ class ApiTag extends ApiBase { $idResult += $this->getErrorFormatter()->formatMessage( ApiMessage::create( 'apierror-blocked', 'blocked', + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable Block is checked and not null [ 'blockinfo' => $this->getBlockDetails( $user->getBlock() ) ] ) ); return $idResult; @@ -137,6 +138,7 @@ class ApiTag extends ApiBase { $idResult += $this->getErrorFormatter()->formatMessage( ApiMessage::create( 'apierror-blocked', 'blocked', + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable Block is checked and not null [ 'blockinfo' => $this->getBlockDetails( $user->getBlock() ) ] ) ); return $idResult; diff --git a/includes/api/ApiUnblock.php b/includes/api/ApiUnblock.php index cb124cf1899e..9fb3a370dd8c 100644 --- a/includes/api/ApiUnblock.php +++ b/includes/api/ApiUnblock.php @@ -92,6 +92,7 @@ class ApiUnblock extends ApiBase { $this->dieWithError( $status, null, + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable Block is checked and not null [ 'blockinfo' => $this->getBlockDetails( $performer->getBlock() ) ] ); } diff --git a/includes/api/ApiUpload.php b/includes/api/ApiUpload.php index 0c8ee166da35..04a5c73dd746 100644 --- a/includes/api/ApiUpload.php +++ b/includes/api/ApiUpload.php @@ -596,6 +596,7 @@ class ApiUpload extends ApiBase { // Check blocks if ( $user->isBlockedFromUpload() ) { + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable Block is checked and not null $this->dieBlocked( $user->getBlock() ); } diff --git a/includes/auth/AuthManager.php b/includes/auth/AuthManager.php index 829b008fc19e..a273017439f0 100644 --- a/includes/auth/AuthManager.php +++ b/includes/auth/AuthManager.php @@ -1167,6 +1167,7 @@ class AuthManager implements LoggerAwareInterface { $req->username = $username; $req->returnToUrl = $returnToUrl; if ( $req instanceof UserDataAuthenticationRequest ) { + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable user should be checked and valid here $status = $req->populateUser( $user ); if ( !$status->isGood() ) { $status = Status::wrap( $status ); diff --git a/includes/auth/AuthenticationRequest.php b/includes/auth/AuthenticationRequest.php index 6d0b9e82e00a..87c90ce879d1 100644 --- a/includes/auth/AuthenticationRequest.php +++ b/includes/auth/AuthenticationRequest.php @@ -302,6 +302,7 @@ abstract class AuthenticationRequest { } elseif ( $username !== $req->username ) { $requestClass = get_class( $req ); throw new \UnexpectedValueException( "Conflicting username fields: \"{$req->username}\" from " + // @phan-suppress-next-line PhanTypeSuspiciousStringExpression $otherClass always set . "$requestClass::\$username vs. \"$username\" from $otherClass::\$username" ); } } @@ -350,6 +351,7 @@ abstract class AuthenticationRequest { // If there is a primary not requiring this field, no matter how many others do, // authentication can proceed without it. || $req->required === self::PRIMARY_REQUIRED + // @phan-suppress-next-line PhanTypeMismatchArgumentNullableInternal False positive && !in_array( $name, $sharedRequiredPrimaryFields, true ) ) { $options['optional'] = true; diff --git a/includes/block/BlockManager.php b/includes/block/BlockManager.php index 0d9d78f98fd2..d848921b1cfc 100644 --- a/includes/block/BlockManager.php +++ b/includes/block/BlockManager.php @@ -332,6 +332,7 @@ class BlockManager { $databaseBlocks[$block->getParentBlockId()] = $block; } } else { + // @phan-suppress-next-line PhanTypeMismatchDimAssignment getId is not null here $databaseBlocks[$block->getId()] = $block; } } diff --git a/includes/block/Restriction/PageRestriction.php b/includes/block/Restriction/PageRestriction.php index 0e37ae6cf903..eef894a522fd 100644 --- a/includes/block/Restriction/PageRestriction.php +++ b/includes/block/Restriction/PageRestriction.php @@ -112,6 +112,7 @@ class PageRestriction extends AbstractRestriction { } $restriction = new self( 0, $title->getArticleID() ); + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable Title is always valid $restriction->setTitle( $title ); return $restriction; diff --git a/includes/cache/BacklinkCache.php b/includes/cache/BacklinkCache.php index abe752e8c916..716f81507911 100644 --- a/includes/cache/BacklinkCache.php +++ b/includes/cache/BacklinkCache.php @@ -282,6 +282,7 @@ class BacklinkCache { return $prefixes[$table]; } else { $prefix = null; + // @phan-suppress-next-line PhanTypeMismatchArgument Type mismatch on pass-by-ref args $this->getHookRunner()->onBacklinkCacheGetPrefix( $table, $prefix ); if ( $prefix ) { return $prefix; @@ -331,7 +332,11 @@ class BacklinkCache { default: $conds = null; $this->getHookRunner()->onBacklinkCacheGetConditions( $table, - Title::castFromPageReference( $this->page ), $conds ); + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable castFrom does not return null here + Title::castFromPageReference( $this->page ), + // @phan-suppress-next-line PhanTypeMismatchArgument Type mismatch on pass-by-ref args + $conds + ); if ( !$conds ) { throw new MWException( "Invalid table \"$table\" in " . __CLASS__ ); } diff --git a/includes/cache/HtmlCacheUpdater.php b/includes/cache/HtmlCacheUpdater.php index fc4cfc7be5fa..b5965a5d62ee 100644 --- a/includes/cache/HtmlCacheUpdater.php +++ b/includes/cache/HtmlCacheUpdater.php @@ -175,6 +175,7 @@ class HtmlCacheUpdater { } if ( $this->useFileCache ) { + // @phan-suppress-next-line PhanTypeMismatchArgument castFrom does not return null here $update = HtmlFileCacheUpdate::newFromPages( $pageIdentities ); if ( $this->fieldHasFlag( $flags, self::PURGE_PRESEND ) ) { DeferredUpdates::addUpdate( $update, DeferredUpdates::PRESEND ); @@ -188,6 +189,7 @@ class HtmlCacheUpdater { $urls = []; foreach ( $pageIdentities as $pi ) { /** @var PageIdentity $pi */ + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable castFrom does not return null here $urls = array_merge( $urls, $this->getUrls( $pi, $flags ) ); } $this->purgeUrls( $urls, $flags ); @@ -235,6 +237,7 @@ class HtmlCacheUpdater { // Extensions may add novel ways to access this content $append = []; $mode = $flags & self::PURGE_URLS_LINKSUPDATE_ONLY; + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable castFrom does not return null here $this->hookRunner->onHtmlCacheUpdaterAppendUrls( $title, $mode, $append ); $urls = array_merge( $urls, $append ); @@ -244,6 +247,7 @@ class HtmlCacheUpdater { $urls = array_merge( $urls, $append ); // Legacy. TODO: Deprecate this + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable castFrom does not return null here $this->hookRunner->onTitleSquidURLs( $title, $urls ); return $urls; diff --git a/includes/cache/MessageCache.php b/includes/cache/MessageCache.php index ee9cb52ce265..3c782eb58031 100644 --- a/includes/cache/MessageCache.php +++ b/includes/cache/MessageCache.php @@ -1065,6 +1065,7 @@ class MessageCache implements LoggerAwareInterface { } $message = $this->getMsgFromNamespace( + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable uckey is set when used $this->getMessagePageName( $code, $uckey ), $code ); if ( $message !== false ) { diff --git a/includes/collation/IcuCollation.php b/includes/collation/IcuCollation.php index f53511f6fe2a..8eb8465daa8f 100644 --- a/includes/collation/IcuCollation.php +++ b/includes/collation/IcuCollation.php @@ -260,6 +260,7 @@ class IcuCollation extends Collation { } $this->mainCollator = $mainCollator; + // @phan-suppress-next-line PhanPossiblyNullTypeMismatchProperty successed before, no null check needed $this->primaryCollator = Collator::create( $locale ); $this->primaryCollator->setStrength( Collator::PRIMARY ); diff --git a/includes/config/EtcdConfig.php b/includes/config/EtcdConfig.php index 50601683a887..77ac3ac612f4 100644 --- a/includes/config/EtcdConfig.php +++ b/includes/config/EtcdConfig.php @@ -133,14 +133,12 @@ class EtcdConfig implements Config, LoggerAwareInterface { public function has( $name ) { $this->load(); - // @phan-suppress-next-line PhanTypeArraySuspiciousNullable procCache is set after load() return array_key_exists( $name, $this->procCache['config'] ); } public function get( $name ) { $this->load(); - // @phan-suppress-next-line PhanTypeArraySuspiciousNullable procCache is set after load() if ( !array_key_exists( $name, $this->procCache['config'] ) ) { throw new ConfigException( "No entry found for '$name'." ); } @@ -150,7 +148,6 @@ class EtcdConfig implements Config, LoggerAwareInterface { public function getModifiedIndex() { $this->load(); - // @phan-suppress-next-line PhanTypeArraySuspiciousNullable procCache is set after load() return $this->procCache['modifiedIndex']; } @@ -228,9 +225,11 @@ class EtcdConfig implements Config, LoggerAwareInterface { if ( $loop->invoke() !== WaitConditionLoop::CONDITION_REACHED ) { // No cached value exists and etcd query failed; throw an error + // @phan-suppress-next-line PhanTypeSuspiciousStringExpression WaitConditionLoop throws or error set throw new ConfigException( "Failed to load configuration from etcd: $error" ); } + // @phan-suppress-next-line PhanTypeMismatchProperty WaitConditionLoop throws ore data set $this->procCache = $data; } diff --git a/includes/content/ContentHandler.php b/includes/content/ContentHandler.php index 1b03bb59c037..7c6dcfa7d3a6 100644 --- a/includes/content/ContentHandler.php +++ b/includes/content/ContentHandler.php @@ -1695,6 +1695,7 @@ abstract class ContentHandler { $po = new ParserOutput(); $parserOptions->registerWatcher( [ $po, 'recordOption' ] ); if ( Hooks::runner()->onContentGetParserOutput( + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable castFrom does not return null here $content, $title, $cpoParams->getRevId(), $parserOptions, $cpoParams->getGenerateHtml(), $po ) ) { // Save and restore the old value, just in case something is reusing @@ -1715,6 +1716,7 @@ abstract class ContentHandler { $parserOptions->setRedirectTarget( $oldRedir ); } + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable castFrom does not return null here Hooks::runner()->onContentAlterParserOutput( $content, $title, $po ); $parserOptions->registerWatcher( null ); @@ -1805,6 +1807,7 @@ abstract class ContentHandler { $legacyTitle = $services->getTitleFactory()->castFromPageReference( $params->getPage() ); return $content->preSaveTransform( + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable castFrom does not return null here $legacyTitle, $legacyUser, $params->getParserOptions() @@ -1826,6 +1829,7 @@ abstract class ContentHandler { $services = MediaWikiServices::getInstance(); $legacyTitle = $services->getTitleFactory()->castFromPageReference( $params->getPage() ); return $content->preloadTransform( + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable castFrom does not return null here $legacyTitle, $params->getParserOptions(), $params->getParams() @@ -1847,6 +1851,7 @@ abstract class ContentHandler { $services = MediaWikiServices::getInstance(); $legacyTitle = $services->getTitleFactory()->castFromPageReference( $cpoParams->getPage() ); return $content->getParserOutput( + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable castFrom does not return null here $legacyTitle, $cpoParams->getRevId(), $cpoParams->getParserOptions(), diff --git a/includes/content/ContentHandlerFactory.php b/includes/content/ContentHandlerFactory.php index 1e6cef3421a2..828659951dd9 100644 --- a/includes/content/ContentHandlerFactory.php +++ b/includes/content/ContentHandlerFactory.php @@ -268,6 +268,7 @@ final class ContentHandlerFactory implements IContentHandlerFactory { */ private function createContentHandlerFromHook( string $modelID ): ContentHandler { $contentHandler = null; + // @phan-suppress-next-line PhanTypeMismatchArgument Type mismatch on pass-by-ref args $this->hookRunner->onContentHandlerForModelID( $modelID, $contentHandler ); $this->validateContentHandler( $modelID, $contentHandler ); diff --git a/includes/content/CssContent.php b/includes/content/CssContent.php index bcdfc13ea410..c006b86d086d 100644 --- a/includes/content/CssContent.php +++ b/includes/content/CssContent.php @@ -56,6 +56,7 @@ class CssContent extends TextContent { return $this; } + // @phan-suppress-next-line PhanTypeMismatchReturnSuperType False positive return $this->getContentHandler()->makeRedirectContent( $target ); } diff --git a/includes/content/JavaScriptContent.php b/includes/content/JavaScriptContent.php index 1db4f8016cae..3510e01a8ee8 100644 --- a/includes/content/JavaScriptContent.php +++ b/includes/content/JavaScriptContent.php @@ -59,6 +59,7 @@ class JavaScriptContent extends TextContent { return $this; } + // @phan-suppress-next-line PhanTypeMismatchReturnSuperType False positive return $this->getContentHandler()->makeRedirectContent( $target ); } diff --git a/includes/content/WikitextContent.php b/includes/content/WikitextContent.php index bc9f217fa220..ac8a8f67be6c 100644 --- a/includes/content/WikitextContent.php +++ b/includes/content/WikitextContent.php @@ -80,6 +80,7 @@ class WikitextContent extends TextContent { * @see Content::replaceSection() */ public function replaceSection( $sectionId, Content $with, $sectionTitle = '' ) { + // @phan-suppress-previous-line PhanParamSignatureMismatch False positive $myModelId = $this->getModel(); $sectionModelId = $with->getModel(); @@ -253,6 +254,7 @@ class WikitextContent extends TextContent { $title = $context->getTitle(); } $contentRenderer = MediaWikiServices::getInstance()->getContentRenderer(); + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable getTitle does not return null here $po = $contentRenderer->getParserOutput( $this, $title, null, null, false ); $links = $po->getLinks(); $hasLinks = !empty( $links ); diff --git a/includes/content/WikitextContentHandler.php b/includes/content/WikitextContentHandler.php index 943b78ff87a3..aefffc70df2f 100644 --- a/includes/content/WikitextContentHandler.php +++ b/includes/content/WikitextContentHandler.php @@ -291,6 +291,7 @@ class WikitextContentHandler extends TextContentHandler { list( $redir, $text ) = $content->getRedirectTargetAndText(); $parserOutput = $services->getParser()->getFreshParser() + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable castFrom does not return null here ->parse( $text, $title, $parserOptions, true, true, $revId ); // Add redirect indicator at the top diff --git a/includes/debug/logger/monolog/LegacyHandler.php b/includes/debug/logger/monolog/LegacyHandler.php index c900f2213532..41f0c22e7a0b 100644 --- a/includes/debug/logger/monolog/LegacyHandler.php +++ b/includes/debug/logger/monolog/LegacyHandler.php @@ -153,6 +153,7 @@ class LegacyHandler extends AbstractProcessingHandler { $this->sink = null; throw new UnexpectedValueException( sprintf( 'The stream or file "%s" could not be opened: %s', + // @phan-suppress-next-line PhanTypeMismatchArgumentInternalProbablyReal Set by error handler $this->uri, $this->error ) ); } diff --git a/includes/debug/logger/monolog/LineFormatter.php b/includes/debug/logger/monolog/LineFormatter.php index f973758abf79..c98d3069edf1 100644 --- a/includes/debug/logger/monolog/LineFormatter.php +++ b/includes/debug/logger/monolog/LineFormatter.php @@ -145,12 +145,14 @@ class LineFormatter extends MonologLineFormatter { ]; $e = array_merge( $defaults, $e ); + // @phan-suppress-next-line PhanTypeMismatchArgumentNullableInternal class is always set $which = is_a( $e['class'], Error::class, true ) ? 'Error' : 'Exception'; $str = "\n[$which {$e['class']}] (" . "{$e['file']}:{$e['line']}) {$e['message']}"; if ( $this->includeStacktraces && $e['trace'] ) { $str .= "\n" . + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable trace is always set MWExceptionHandler::prettyPrintTrace( $e['trace'], ' ' ); } diff --git a/includes/deferred/LinksUpdate/LinksUpdate.php b/includes/deferred/LinksUpdate/LinksUpdate.php index 5f3ee16cf876..c528dacfaa52 100644 --- a/includes/deferred/LinksUpdate/LinksUpdate.php +++ b/includes/deferred/LinksUpdate/LinksUpdate.php @@ -93,6 +93,7 @@ class LinksUpdate extends DataUpdate { public function __construct( PageIdentity $page, ParserOutput $parserOutput, $recursive = true ) { parent::__construct(); + // @phan-suppress-next-line PhanPossiblyNullTypeMismatchProperty castFrom does not return null here $this->mTitle = Title::castFromPageIdentity( $page ); $this->mParserOutput = $parserOutput; @@ -359,10 +360,12 @@ class LinksUpdate extends DataUpdate { if ( !$backlinkCache ) { wfDeprecatedMsg( __METHOD__ . " needs a BacklinkCache object, null passed", '1.37' ); $backlinkCache = MediaWikiServices::getInstance()->getBacklinkCacheFactory() + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable castFrom does not return null here ->getBacklinkCache( $title ); } if ( $backlinkCache->hasLinks( $table ) ) { $job = new RefreshLinksJob( + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable castFrom does not return null here $title, [ 'table' => $table, diff --git a/includes/deferred/LinksUpdate/TitleLinksTable.php b/includes/deferred/LinksUpdate/TitleLinksTable.php index 8a28638d8ced..921d330c358d 100644 --- a/includes/deferred/LinksUpdate/TitleLinksTable.php +++ b/includes/deferred/LinksUpdate/TitleLinksTable.php @@ -28,6 +28,7 @@ abstract class TitleLinksTable extends LinksTable { * @return Title */ protected function makeTitle( $linkId ): Title { + // @phan-suppress-next-line PhanTypeMismatchReturnNullable castFrom does not return null here return Title::castFromPageReference( $this->makePageReferenceValue( $linkId ) ); } diff --git a/includes/diff/DifferenceEngine.php b/includes/diff/DifferenceEngine.php index af319860ee97..473ac64408d4 100644 --- a/includes/diff/DifferenceEngine.php +++ b/includes/diff/DifferenceEngine.php @@ -1916,6 +1916,7 @@ class DifferenceEngine extends ContextSource { $newid = intval( $new ); } + // @phan-suppress-next-line PhanTypeMismatchReturn getId does not return null here return [ $oldid, $newid ]; } @@ -1937,6 +1938,7 @@ class DifferenceEngine extends ContextSource { } $this->hookRunner->onNewDifferenceEngine( + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable False positive $this->getTitle(), $this->mOldid, $this->mNewid, $old, $new ); } diff --git a/includes/diff/DifferenceEngineSlotDiffRenderer.php b/includes/diff/DifferenceEngineSlotDiffRenderer.php index e371fb7d5afa..0cbededab372 100644 --- a/includes/diff/DifferenceEngineSlotDiffRenderer.php +++ b/includes/diff/DifferenceEngineSlotDiffRenderer.php @@ -54,6 +54,7 @@ class DifferenceEngineSlotDiffRenderer extends SlotDiffRenderer { /** @inheritDoc */ public function getDiff( Content $oldContent = null, Content $newContent = null ) { $this->normalizeContents( $oldContent, $newContent ); + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable Null handled by normalizeContents return $this->differenceEngine->generateContentDiffBody( $oldContent, $newContent ); } diff --git a/includes/exception/MWExceptionHandler.php b/includes/exception/MWExceptionHandler.php index 2e5d4e1f2e94..36e2553a14f1 100644 --- a/includes/exception/MWExceptionHandler.php +++ b/includes/exception/MWExceptionHandler.php @@ -287,6 +287,7 @@ class MWExceptionHandler { break; } + // @phan-suppress-next-line PhanTypeMismatchArgumentNullableInternal False positive $e = new ErrorException( $prefix . $message, 0, $level, $file, $line ); self::logError( $e, 'error', $severity, self::CAUGHT_BY_HANDLER ); diff --git a/includes/exception/PermissionsError.php b/includes/exception/PermissionsError.php index 79e3688c3d1e..38f655cbd35a 100644 --- a/includes/exception/PermissionsError.php +++ b/includes/exception/PermissionsError.php @@ -58,6 +58,7 @@ class PermissionsError extends ErrorPageError { $groups = []; foreach ( MediaWikiServices::getInstance() ->getGroupPermissionsLookup() + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable Null on permission is check when used here ->getGroupsWithPermission( $this->permission ) as $group ) { $groups[] = UserGroupMembership::getLink( $group, RequestContext::getMain(), 'wiki' ); diff --git a/includes/export/WikiExporter.php b/includes/export/WikiExporter.php index b2716906d086..aaf6960498d4 100644 --- a/includes/export/WikiExporter.php +++ b/includes/export/WikiExporter.php @@ -559,6 +559,7 @@ class WikiExporter { throw new LogicException( 'Error while processing a stream of slot rows' ); } + // @phan-suppress-next-line PhanTypeMismatchReturnNullable False positive return $lastRow; } diff --git a/includes/filerepo/file/MediaFileTrait.php b/includes/filerepo/file/MediaFileTrait.php index 5139c69e4696..8db25732db43 100644 --- a/includes/filerepo/file/MediaFileTrait.php +++ b/includes/filerepo/file/MediaFileTrait.php @@ -80,6 +80,7 @@ trait MediaFileTrait { foreach ( $transforms as $transformType => $transform ) { $responseFile[$transformType] = $this->getTransformInfo( $file, + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable False positive $duration, $transform['maxWidth'], $transform['maxHeight'] diff --git a/includes/htmlform/fields/HTMLMultiSelectField.php b/includes/htmlform/fields/HTMLMultiSelectField.php index f9720d556beb..e54049585642 100644 --- a/includes/htmlform/fields/HTMLMultiSelectField.php +++ b/includes/htmlform/fields/HTMLMultiSelectField.php @@ -270,6 +270,7 @@ class HTMLMultiSelectField extends HTMLFormField implements HTMLNestedFilterable if ( $this->isSubmitAttempt( $request ) || $fromRequest ) { // Checkboxes are just not added to the request arrays if they're not checked, // so it's perfectly possible for there not to be an entry at all + // @phan-suppress-next-line PhanTypeMismatchReturnNullable getArray does not return null return $fromRequest; } else { // That's ok, the user has not yet submitted the form, so show the defaults diff --git a/includes/import/WikiImporter.php b/includes/import/WikiImporter.php index d40a39c8f9f8..1537dc1b9ad9 100644 --- a/includes/import/WikiImporter.php +++ b/includes/import/WikiImporter.php @@ -579,6 +579,7 @@ class WikiImporter { } $title = Title::castFromPageIdentity( $pageIdentity ); + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable castFrom does not return null here return $this->hookRunner->onAfterImportPage( $title, $foreignTitle, $revCount, $sRevCount, $pageInfo ); } diff --git a/includes/installer/WebInstaller.php b/includes/installer/WebInstaller.php index 64735349fc08..3d2d811af687 100644 --- a/includes/installer/WebInstaller.php +++ b/includes/installer/WebInstaller.php @@ -261,6 +261,7 @@ class WebInstaller extends Installer { # Execute the page. $this->currentPageName = $page->getName(); + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable pageName is not null here $this->startPageWrapper( $pageName ); if ( $page->isSlow() ) { @@ -274,6 +275,7 @@ class WebInstaller extends Installer { if ( $result == 'skip' ) { # Page skipped without explicit submission. # Skip it when we click "back" so that we don't just go forward again. + // @phan-suppress-next-line PhanTypeMismatchDimAssignment pageName is not null here $this->skippedPages[$pageName] = true; $result = 'continue'; } else { diff --git a/includes/jobqueue/jobs/HTMLCacheUpdateJob.php b/includes/jobqueue/jobs/HTMLCacheUpdateJob.php index f344f0d83d37..87ead3ec1ac1 100644 --- a/includes/jobqueue/jobs/HTMLCacheUpdateJob.php +++ b/includes/jobqueue/jobs/HTMLCacheUpdateJob.php @@ -61,6 +61,7 @@ class HTMLCacheUpdateJob extends Job { public static function newForBacklinks( PageReference $page, $table, $params = [] ) { $title = Title::castFromPageReference( $page ); return new self( + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable castFrom does not return null here $title, [ 'table' => $table, diff --git a/includes/language/Language.php b/includes/language/Language.php index b7d36f338986..5a6726083e6b 100644 --- a/includes/language/Language.php +++ b/includes/language/Language.php @@ -3466,6 +3466,7 @@ class Language { } $text = implode( $comma, $list ) . $and . $space . $text; } + // @phan-suppress-next-line PhanTypeMismatchReturnNullable False positive return $text; } diff --git a/includes/language/LanguageConverterFactory.php b/includes/language/LanguageConverterFactory.php index c6ad20b17610..ec1e2efd2e1d 100644 --- a/includes/language/LanguageConverterFactory.php +++ b/includes/language/LanguageConverterFactory.php @@ -177,6 +177,7 @@ class LanguageConverterFactory { if ( isset( $this->cache[$lang->getCode()] ) ) { return $this->cache[$lang->getCode()]; } + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable False positive $converter = $this->instantiateConverter( $lang ); $this->cache[$lang->getCode()] = $converter; return $converter; diff --git a/includes/language/LanguageNameUtils.php b/includes/language/LanguageNameUtils.php index 0e6a4024df90..c7549f36d354 100644 --- a/includes/language/LanguageNameUtils.php +++ b/includes/language/LanguageNameUtils.php @@ -217,6 +217,7 @@ class LanguageNameUtils { if ( $inLanguage !== self::AUTONYMS ) { # TODO: also include for self::AUTONYMS, when this code is more efficient + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable False positive $this->hookRunner->onLanguageGetTranslatedLanguageNames( $names, $inLanguage ); } diff --git a/includes/language/Message.php b/includes/language/Message.php index 13ebeab1b298..c10a399b3eb7 100644 --- a/includes/language/Message.php +++ b/includes/language/Message.php @@ -1496,6 +1496,7 @@ class Message implements MessageSpecifier, Serializable { // NOTE: The constructor makes sure keysToTry isn't empty, // so we know that $key and $message are initialized. + // @phan-suppress-next-line PhanPossiblyNullTypeMismatchProperty False positive $this->key = $key; $this->message = $message; } diff --git a/includes/libs/HashRing.php b/includes/libs/HashRing.php index 2a3962b58b01..174be5a187e0 100644 --- a/includes/libs/HashRing.php +++ b/includes/libs/HashRing.php @@ -152,6 +152,7 @@ class HashRing implements Serializable { break; // all nodes visited } } + // @phan-suppress-next-line PhanTypeMismatchDimFetchNullable False positive $nodeLocation = $ring[$currentIndex][self::KEY_LOCATION]; if ( !in_array( $nodeLocation, $locations, true ) ) { // Ignore other nodes for the same locations already added diff --git a/includes/libs/MWCryptHash.php b/includes/libs/MWCryptHash.php index b89459398443..8e94e769b34f 100644 --- a/includes/libs/MWCryptHash.php +++ b/includes/libs/MWCryptHash.php @@ -79,6 +79,7 @@ class MWCryptHash { self::$hashLength[$key] = strlen( self::hash( '', $raw ) ); } + // @phan-suppress-next-line PhanTypeMismatchReturnNullable False positive return self::$hashLength[$key]; } diff --git a/includes/libs/ParamValidator/SimpleCallbacks.php b/includes/libs/ParamValidator/SimpleCallbacks.php index f0afe71177f2..804bbf6e081d 100644 --- a/includes/libs/ParamValidator/SimpleCallbacks.php +++ b/includes/libs/ParamValidator/SimpleCallbacks.php @@ -52,6 +52,7 @@ class SimpleCallbacks implements Callbacks { $file = new UploadedFile( $file ); $this->files[$name] = $file; } + // @phan-suppress-next-line PhanTypeMismatchReturnNullable False positive return $file; } diff --git a/includes/libs/filebackend/fileiteration/SwiftFileBackendList.php b/includes/libs/filebackend/fileiteration/SwiftFileBackendList.php index 7f2f7b8a09af..45f3f4cd6f6c 100644 --- a/includes/libs/filebackend/fileiteration/SwiftFileBackendList.php +++ b/includes/libs/filebackend/fileiteration/SwiftFileBackendList.php @@ -130,7 +130,7 @@ abstract class SwiftFileBackendList implements Iterator { * * @param string $container Resolved container name * @param string $dir Resolved path relative to container - * @param string &$after + * @param string &$after @phan-output-reference * @param int $limit * @param array $params * @return Traversable|array diff --git a/includes/libs/iterators/NotRecursiveIterator.php b/includes/libs/iterators/NotRecursiveIterator.php index 52ca61b44923..22ff7e7bd4ba 100644 --- a/includes/libs/iterators/NotRecursiveIterator.php +++ b/includes/libs/iterators/NotRecursiveIterator.php @@ -30,6 +30,7 @@ class NotRecursiveIterator extends IteratorDecorator implements RecursiveIterato } public function getChildren() { + // @phan-suppress-next-line PhanTypeMismatchReturnProbablyReal False positive return null; } } diff --git a/includes/libs/lockmanager/LockManager.php b/includes/libs/lockmanager/LockManager.php index 50437e910b3e..d26016817fd3 100644 --- a/includes/libs/lockmanager/LockManager.php +++ b/includes/libs/lockmanager/LockManager.php @@ -152,6 +152,7 @@ abstract class LockManager { ); $loop->invoke(); + // @phan-suppress-next-line PhanTypeMismatchReturn WaitConditionLoop throws or status is set return $status; } diff --git a/includes/libs/mime/MimeAnalyzer.php b/includes/libs/mime/MimeAnalyzer.php index 15d2d99ac5ee..a5d37d19951b 100644 --- a/includes/libs/mime/MimeAnalyzer.php +++ b/includes/libs/mime/MimeAnalyzer.php @@ -895,6 +895,7 @@ class MimeAnalyzer implements LoggerAwareInterface { } else { $this->logger->info( __METHOD__ . ": unable to identify type of ZIP archive" ); } + // @phan-suppress-next-line PhanTypeMismatchReturnNullable mime should be always set return $mime; } @@ -1009,6 +1010,7 @@ class MimeAnalyzer implements LoggerAwareInterface { // If MIME type is unknown, guess it if ( !$mime ) { + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable False positive $mime = $this->guessMimeType( $path, false ); } diff --git a/includes/libs/objectcache/MemcachedPhpBagOStuff.php b/includes/libs/objectcache/MemcachedPhpBagOStuff.php index 465ebe20769e..ba78a7814062 100644 --- a/includes/libs/objectcache/MemcachedPhpBagOStuff.php +++ b/includes/libs/objectcache/MemcachedPhpBagOStuff.php @@ -63,6 +63,7 @@ class MemcachedPhpBagOStuff extends MemcachedBagOStuff { // T257003: only require "gets" (instead of "get") when a CAS token is needed return $getToken + // @phan-suppress-next-line PhanTypeMismatchArgument False positive ? $this->client->get( $routeKey, $casToken ) : $this->client->get( $routeKey ); } diff --git a/includes/libs/objectcache/wancache/WANObjectCache.php b/includes/libs/objectcache/wancache/WANObjectCache.php index 5f63b6f6bbe4..8a6dde61a65b 100644 --- a/includes/libs/objectcache/wancache/WANObjectCache.php +++ b/includes/libs/objectcache/wancache/WANObjectCache.php @@ -1655,6 +1655,7 @@ class WANObjectCache implements $hasLock = $useRegenerationLock && $this->claimStampedeLock( $key ); if ( $useRegenerationLock && !$hasLock ) { // Determine if there is stale or volatile cached value that is still usable + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable False positive if ( $this->isValid( $volValue, $volState[self::RES_AS_OF], $minAsOf ) ) { $this->logger->debug( "fetchOrRegenerate($key): returning stale value" ); $this->stats->timing( diff --git a/includes/libs/rdbms/database/Database.php b/includes/libs/rdbms/database/Database.php index fad838b8bbd1..838bf69fc03f 100644 --- a/includes/libs/rdbms/database/Database.php +++ b/includes/libs/rdbms/database/Database.php @@ -5101,6 +5101,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware } if ( $this->fieldHasBit( $flags, self::LOCK_TIMESTAMP ) ) { + // @phan-suppress-next-line PhanTypeMismatchReturnNullable Possible null is documented on the constant return $lockTsUnix; } else { return $locked; diff --git a/includes/libs/rdbms/database/DatabaseMysqli.php b/includes/libs/rdbms/database/DatabaseMysqli.php index 79b5320bfab1..2583bcaa8218 100644 --- a/includes/libs/rdbms/database/DatabaseMysqli.php +++ b/includes/libs/rdbms/database/DatabaseMysqli.php @@ -125,6 +125,7 @@ class DatabaseMysqli extends DatabaseMysqlBase { } $mysqli->options( MYSQLI_OPT_CONNECT_TIMEOUT, 3 ); + // @phan-suppress-next-line PhanTypeMismatchArgumentNullableInternal socket seems set when used $ok = $mysqli->real_connect( $realServer, $user, $password, $db, $port, $socket, $flags ); return $ok ? $mysqli : null; diff --git a/includes/libs/rdbms/database/DatabasePostgres.php b/includes/libs/rdbms/database/DatabasePostgres.php index b814f3134a01..194d955a270b 100644 --- a/includes/libs/rdbms/database/DatabasePostgres.php +++ b/includes/libs/rdbms/database/DatabasePostgres.php @@ -248,6 +248,7 @@ class DatabasePostgres extends Database { ); $row = $res->fetchRow(); + // @phan-suppress-next-line PhanTypeMismatchReturnProbablyReal Return type is undefined for no lastval return $row[0] === null ? null : (int)$row[0]; } diff --git a/includes/libs/rdbms/database/DatabaseSqlite.php b/includes/libs/rdbms/database/DatabaseSqlite.php index 039bf91fd7fe..614181c47d22 100644 --- a/includes/libs/rdbms/database/DatabaseSqlite.php +++ b/includes/libs/rdbms/database/DatabaseSqlite.php @@ -113,6 +113,7 @@ class DatabaseSqlite extends Database { $p['tablePrefix'] = ''; /** @var DatabaseSqlite $db */ $db = Database::factory( 'sqlite', $p ); + '@phan-var DatabaseSqlite $db'; return $db; } @@ -249,6 +250,7 @@ class DatabaseSqlite extends Database { protected function closeConnection() { $this->conn = null; // Release all locks, via FSLockManager::__destruct, as the base class expects + // @phan-suppress-next-line PhanTypeMismatchPropertyProbablyReal Expected null $this->lockMgr = null; return true; diff --git a/includes/libs/uuid/GlobalIdGenerator.php b/includes/libs/uuid/GlobalIdGenerator.php index 62e42c106ebe..c27a7e74b774 100644 --- a/includes/libs/uuid/GlobalIdGenerator.php +++ b/includes/libs/uuid/GlobalIdGenerator.php @@ -632,6 +632,7 @@ class GlobalIdGenerator { $ts = bcadd( $ts, (string)$delta ); // wrap around $ts = bcmod( $ts, bcpow( '2', '60' ) ); + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable Only null if second arg is 0 $id_bin = \Wikimedia\base_convert( $ts, 10, 2, 60 ); } else { throw new RuntimeException( 'bcmath or gmp extension required for 32 bit machines.' ); @@ -661,6 +662,7 @@ class GlobalIdGenerator { $csv = trim( ( $this->shellCallback )( 'getmac /NH /FO CSV' ) ); $line = substr( $csv, 0, strcspn( $csv, "\n" ) ); $info = str_getcsv( $line ); + // @phan-suppress-next-line PhanTypeMismatchArgumentNullableInternal False positive $nodeId = isset( $info[0] ) ? str_replace( '-', '', $info[0] ) : ''; } elseif ( is_executable( '/sbin/ifconfig' ) ) { // Linux/BSD/Solaris/OS X diff --git a/includes/libs/virtualrest/RestbaseVirtualRESTService.php b/includes/libs/virtualrest/RestbaseVirtualRESTService.php index a14fb9d1142e..ff6a5f713521 100644 --- a/includes/libs/virtualrest/RestbaseVirtualRESTService.php +++ b/includes/libs/virtualrest/RestbaseVirtualRESTService.php @@ -61,6 +61,7 @@ class RestbaseVirtualRESTService extends VirtualRESTService { 'fixedUrl' => false, ], $params ); // Ensure that the url parameter has a trailing slash. + // @phan-suppress-next-line PhanTypeMismatchArgumentNullableInternal url has default value if ( substr( $mparams['url'], -1 ) !== '/' ) { $mparams['url'] .= '/'; } @@ -70,6 +71,7 @@ class RestbaseVirtualRESTService extends VirtualRESTService { $mparams['domain'] = preg_replace( '/^((https?:)?\/\/)?([^\/:]+?)(:\d+)?\/?$/', '$3', + // @phan-suppress-next-line PhanTypeMismatchArgumentNullableInternal domain has default value $mparams['domain'] ); parent::__construct( $mparams ); diff --git a/includes/linker/LinkRenderer.php b/includes/linker/LinkRenderer.php index 388b4474cdfe..6e7402bf9091 100644 --- a/includes/linker/LinkRenderer.php +++ b/includes/linker/LinkRenderer.php @@ -181,6 +181,7 @@ class LinkRenderer { private function runBeginHook( $target, &$text, &$extraAttribs, &$query, $isKnown ) { $ret = null; if ( !$this->hookRunner->onHtmlPageLinkRendererBegin( + // @phan-suppress-next-line PhanTypeMismatchArgument Type mismatch on pass-by-ref args $this, $this->castToTitle( $target ), $text, $extraAttribs, $query, $ret ) ) { return $ret; @@ -328,6 +329,7 @@ class LinkRenderer { private function buildAElement( $target, $text, array $attribs, $isKnown ) { $ret = null; if ( !$this->hookRunner->onHtmlPageLinkRendererEnd( + // @phan-suppress-next-line PhanTypeMismatchArgument Type mismatch on pass-by-ref args $this, $this->castToLinkTarget( $target ), $isKnown, $text, $attribs, $ret ) ) { return $ret; @@ -460,6 +462,7 @@ class LinkRenderer { return Title::newFromLinkTarget( $target ); } // $target instanceof PageReference + // @phan-suppress-next-line PhanTypeMismatchReturnNullable castFrom does not return null here return Title::castFromPageReference( $target ); } @@ -469,6 +472,7 @@ class LinkRenderer { */ private function castToLinkTarget( $target ): LinkTarget { if ( $target instanceof PageReference ) { + // @phan-suppress-next-line PhanTypeMismatchReturnNullable castFrom does not return null here return Title::castFromPageReference( $target ); } // $target instanceof LinkTarget diff --git a/includes/logging/BlockLogFormatter.php b/includes/logging/BlockLogFormatter.php index 77fbfa30a5e3..87318deb4b66 100644 --- a/includes/logging/BlockLogFormatter.php +++ b/includes/logging/BlockLogFormatter.php @@ -305,6 +305,7 @@ class BlockLogFormatter extends LogFormatter { } if ( isset( $ret['restrictions']['namespaces'] ) ) { + // @phan-suppress-next-line PhanTypeMismatchArgument False positive ApiResult::setIndexedTagName( $ret['restrictions']['namespaces'], 'ns' ); } diff --git a/includes/logging/LogPager.php b/includes/logging/LogPager.php index b3362aa6f984..f9935a0053b3 100644 --- a/includes/logging/LogPager.php +++ b/includes/logging/LogPager.php @@ -289,6 +289,7 @@ class LogPager extends ReverseChronologicalPager { $this->mConds['log_namespace'] = $ns; if ( $doUserRightsLogLike ) { $params = [ $name . $interwikiDelimiter ]; + // @phan-suppress-next-line PhanTypeMismatchArgumentNullableInternal $database is notnull when reached here foreach ( explode( '*', $database ) as $databasepart ) { $params[] = $databasepart; $params[] = $db->anyString(); diff --git a/includes/logging/ManualLogEntry.php b/includes/logging/ManualLogEntry.php index e938d95e0c10..577a54b8cbaa 100644 --- a/includes/logging/ManualLogEntry.php +++ b/includes/logging/ManualLogEntry.php @@ -162,6 +162,7 @@ class ManualLogEntry extends LogEntryBase implements Taggable { */ public function setTarget( $target ) { if ( $target instanceof PageReference ) { + // @phan-suppress-next-line PhanPossiblyNullTypeMismatchProperty castFrom does not return null here $this->target = Title::castFromPageReference( $target ); } elseif ( $target instanceof LinkTarget ) { $this->target = Title::newFromLinkTarget( $target ); diff --git a/includes/media/SvgHandler.php b/includes/media/SvgHandler.php index 7d26acb81072..ce30259a58c7 100644 --- a/includes/media/SvgHandler.php +++ b/includes/media/SvgHandler.php @@ -355,8 +355,10 @@ class SvgHandler extends ImageHandler { $err = wfShellExecWithStderr( $cmd, $retval, $env ); } } + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable False positive $removed = $this->removeBadFile( $dstPath, $retval ); if ( $retval != 0 || $removed ) { + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable cmd is set when used $this->logErrorForExternalProcess( $retval, $err, $cmd ); return new MediaTransformError( 'thumbnail_error', $width, $height, $err ); } diff --git a/includes/media/ThumbnailImage.php b/includes/media/ThumbnailImage.php index b49ecaf53ed9..0a7349174f6d 100644 --- a/includes/media/ThumbnailImage.php +++ b/includes/media/ThumbnailImage.php @@ -73,6 +73,7 @@ class ThumbnailImage extends MediaTransformOutput { # These should be integers when they get here. # If not, there's a bug somewhere. But let's at # least produce valid HTML code regardless. + // @phan-suppress-next-line PhanTypeMismatchArgumentInternal Confused by old signature $this->width = (int)round( $actualParams['width'] ); $this->height = (int)round( $actualParams['height'] ); diff --git a/includes/objectcache/SqlBagOStuff.php b/includes/objectcache/SqlBagOStuff.php index 6235e4d0e4dc..76dc7004230b 100644 --- a/includes/objectcache/SqlBagOStuff.php +++ b/includes/objectcache/SqlBagOStuff.php @@ -1669,6 +1669,7 @@ class SqlBagOStuff extends MediumSpecificBagOStuff { if ( $lb->getServerAttributes( $lb->getWriterIndex() )[Database::ATTR_DB_LEVEL_LOCKING] ) { // Use the main connection to avoid transaction deadlocks + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable dbDomain should be not null here $conn = $lb->getMaintenanceConnectionRef( DB_PRIMARY, [], $dbDomain ); } else { // If the RDBMs has row/table/page level locking, then use separate auto-commit @@ -1676,6 +1677,7 @@ class SqlBagOStuff extends MediumSpecificBagOStuff { $conn = $lb->getMaintenanceConnectionRef( $this->replicaOnly ? DB_REPLICA : DB_PRIMARY, [], + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable dbDomain should be not null here $dbDomain, $lb::CONN_TRX_AUTOCOMMIT ); @@ -1714,6 +1716,7 @@ class SqlBagOStuff extends MediumSpecificBagOStuff { $this->conns[$shardIndex] = $conn; } + // @phan-suppress-next-line PhanTypeMismatchReturnNullable False positive return $this->conns[$shardIndex]; } diff --git a/includes/page/Article.php b/includes/page/Article.php index 540363f97b00..94d9995f9c09 100644 --- a/includes/page/Article.php +++ b/includes/page/Article.php @@ -168,6 +168,7 @@ class Article implements Page { } $page = null; + // @phan-suppress-next-line PhanTypeMismatchArgument Type mismatch on pass-by-ref args Hooks::runner()->onArticleFromTitle( $title, $page, $context ); if ( !$page ) { switch ( $title->getNamespace() ) { @@ -1583,6 +1584,7 @@ class Article implements Page { $tdtime = $language->userTime( $timestamp, $user ); # Show user links if allowed to see them. If hidden, then show them only if requested... + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable revisionRecord known to exists $userlinks = Linker::revUserTools( $revisionRecord, !$unhide ); $infomsg = $current && !$context->msg( 'revision-info-current' )->isDisabled() @@ -1606,6 +1608,7 @@ class Article implements Page { $revisionUser ? $revisionUser->getName() : '' ) ->rawParams( Linker::revComment( + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable revisionRecord known to exists $revisionRecord, true, true @@ -1632,6 +1635,7 @@ class Article implements Page { 'oldid' => $oldid ] + $extraParams ); + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable revisionRecord known to exists $prevExist = (bool)$this->revisionStore->getPreviousRevision( $revisionRecord ); $prevlink = $prevExist ? $this->linkRenderer->makeKnownLink( @@ -1680,6 +1684,7 @@ class Article implements Page { $cdel = Linker::getRevDeleteLink( $user, + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable revisionRecord known to exists $revisionRecord, $this->getTitle() ); diff --git a/includes/page/DeletePage.php b/includes/page/DeletePage.php index 427921dd850e..4891a5ee2714 100644 --- a/includes/page/DeletePage.php +++ b/includes/page/DeletePage.php @@ -352,7 +352,7 @@ class DeletePage { public function deletionWasScheduled(): bool { wfDeprecated( __METHOD__, '1.38' ); $this->assertDeletionAttempted(); - // @phan-suppress-next-line PhanTypeArraySuspiciousNullable + // @phan-suppress-next-line PhanTypeArraySuspiciousNullable,PhanTypeMismatchReturnNullable return $this->wasScheduled[self::PAGE_BASE]; } @@ -482,6 +482,7 @@ class DeletePage { } // NOTE: If the page deletion above failed because the page is no longer there (e.g. race condition) we'll // still try to delete the talk page, since it was the user's intention anyway. + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable talkReason is set when used $status->merge( $this->deleteInternal( $this->associatedTalk, self::PAGE_TALK, $talkReason ) ); return $status; } diff --git a/includes/page/ImagePage.php b/includes/page/ImagePage.php index aacef83f8565..b629a67d22ec 100644 --- a/includes/page/ImagePage.php +++ b/includes/page/ImagePage.php @@ -81,8 +81,10 @@ class ImagePage extends Article { $img = $services->getRepoGroup()->getLocalRepo()->newFile( $this->getTitle() ); } } + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable should be set $this->getPage()->setFile( $img ); if ( !$this->displayImg ) { // not set by hook? + // @phan-suppress-next-line PhanPossiblyNullTypeMismatchProperty should be set $this->displayImg = $img; } $this->repo = $img->getRepo(); diff --git a/includes/page/UndeletePage.php b/includes/page/UndeletePage.php index 071e8a1cb133..e6ba9fd2f867 100644 --- a/includes/page/UndeletePage.php +++ b/includes/page/UndeletePage.php @@ -424,6 +424,7 @@ class UndeletePage { // NOTE: article ID may not be known yet. validateSave() should not modify the database. $contentHandler = $this->contentHandlerFactory->getContentHandler( $content->getModel() ); $validationParams = new ValidationParams( $wikiPage, 0 ); + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable RAW never returns null $status = $contentHandler->validateSave( $content, $validationParams ); if ( !$status->isOK() ) { $dbw->endAtomic( __METHOD__ ); @@ -537,6 +538,7 @@ class UndeletePage { // XXX: updateRevisionOn should probably move into a PageStore service. $wasnew = $wikiPage->updateRevisionOn( $dbw, + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable revision set when used $revision, $created ? 0 : $wikiPage->getLatest() ); @@ -556,6 +558,7 @@ class UndeletePage { ]; $updater = $this->pageUpdaterFactory->newDerivedPageDataUpdater( $wikiPage ); + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable revision set when used $updater->prepareUpdate( $revision, $options ); $updater->doUpdates(); } diff --git a/includes/page/WikiPage.php b/includes/page/WikiPage.php index c9a554d0db21..2cc17407e33a 100644 --- a/includes/page/WikiPage.php +++ b/includes/page/WikiPage.php @@ -178,6 +178,7 @@ class WikiPage implements Page, IDBAccessObject, PageRecord { throw new InvalidArgumentException( "WikiPage constructed on a Title that cannot exist as a page: $title" ); } + // @phan-suppress-next-line PhanPossiblyNullTypeMismatchProperty castFrom does not return null here $this->mTitle = $title; } diff --git a/includes/page/WikiPageFactory.php b/includes/page/WikiPageFactory.php index 318582fd4898..267e3b3909c4 100644 --- a/includes/page/WikiPageFactory.php +++ b/includes/page/WikiPageFactory.php @@ -69,18 +69,22 @@ class WikiPageFactory { $title = Title::castFromPageIdentity( $pageIdentity ); $page = null; + // @phan-suppress-next-line PhanTypeMismatchArgument castFrom does not return null here if ( !$this->wikiPageFactoryHookRunner->onWikiPageFactory( $title, $page ) ) { return $page; } switch ( $ns ) { case NS_FILE: + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable castFrom does not return null here $page = new WikiFilePage( $title ); break; case NS_CATEGORY: + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable castFrom does not return null here $page = new WikiCategoryPage( $title ); break; default: + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable castFrom does not return null here $page = new WikiPage( $title ); } diff --git a/includes/parser/BlockLevelPass.php b/includes/parser/BlockLevelPass.php index f0da863db89d..a8d383818e1e 100644 --- a/includes/parser/BlockLevelPass.php +++ b/includes/parser/BlockLevelPass.php @@ -419,6 +419,7 @@ class BlockLevelPass { } } while ( $prefixLength ) { + // @phan-suppress-next-line PhanTypeArraySuspicious $prefix set if $prefixLength is set $output .= $this->closeList( $prefix2[$prefixLength - 1] ); --$prefixLength; // Note that a paragraph is only ever opened when `prefixLength` diff --git a/includes/parser/Parser.php b/includes/parser/Parser.php index 816279eb0d80..4c1f5a5b1c6b 100644 --- a/includes/parser/Parser.php +++ b/includes/parser/Parser.php @@ -677,6 +677,7 @@ class Parser { // Strip U+0000 NULL (T159174) $text = str_replace( "\000", '', $text ); + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable False positive $this->startParse( $page, $options, self::OT_HTML, $clearState ); $this->currentRevisionCache = null; @@ -2215,6 +2216,7 @@ class Parser { $this->mOutput->addExternalLink( $url ); } + // @phan-suppress-next-line PhanTypeMismatchReturnNullable False positive from array_shift return $s; } @@ -2493,6 +2495,7 @@ class Parser { } if ( $useLinkPrefixExtension ) { + // @phan-suppress-next-line PhanTypeMismatchArgumentNullableInternal $e2 is set under this condition if ( preg_match( $e2, $s, $m ) ) { list( , $s, $prefix ) = $m; } else { @@ -2733,9 +2736,11 @@ class Parser { # batch file existence checks for NS_FILE and NS_MEDIA if ( $iw == '' && $nt->isAlwaysKnown() ) { $this->mOutput->addLink( $nt ); + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable $prefix is set when used here $s .= $this->makeKnownLinkHolder( $nt, $text, $trail, $prefix ); } else { # Links will be added to the output link list after checking + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable $prefix is set when used here $s .= $holders->makeHolder( $nt, $text, $trail, $prefix ); } } @@ -2834,6 +2839,7 @@ class Parser { $ret = null; $originalIndex = $index; $this->hookRunner->onParserGetVariableValueSwitch( + // @phan-suppress-next-line PhanTypeMismatchArgument Type mismatch on pass-by-ref args $this, $this->mVarCache, $index, $ret, $frame ); if ( $index !== $originalIndex ) { @@ -3567,6 +3573,7 @@ class Parser { $revRecord = MediaWikiServices::getInstance() ->getRevisionLookup() + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable castFrom does not return null here ->getKnownCurrentRevision( $page ); return $revRecord; } @@ -4109,6 +4116,7 @@ class Parser { $this->mOutput->setPageProperty( $key, '' ); } + // @phan-suppress-next-line PhanTypeMismatchReturnNullable False positive return $text; } @@ -4549,6 +4557,7 @@ class Parser { if ( $clearState ) { $magicScopeVariable = $this->lock(); } + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable False positive $this->startParse( $page, $options, self::OT_WIKI, $clearState ); $this->setUser( $user ); diff --git a/includes/parser/ParserCache.php b/includes/parser/ParserCache.php index feb868f12b2c..40246d17e8d9 100644 --- a/includes/parser/ParserCache.php +++ b/includes/parser/ParserCache.php @@ -505,6 +505,7 @@ class ParserCache { $this->cache->set( $pageKey, $metadataData, $expire ); $title = $this->titleFactory->castFromPageIdentity( $page ); + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable castFrom does not return null here $this->hookRunner->onParserCacheSaveComplete( $this, $parserOutput, $title, $popts, $revId ); $this->logger->debug( 'Saved in parser cache', [ diff --git a/includes/parser/Preprocessor.php b/includes/parser/Preprocessor.php index ffacba8b000b..b87ce52d13b9 100644 --- a/includes/parser/Preprocessor.php +++ b/includes/parser/Preprocessor.php @@ -93,6 +93,7 @@ abstract class Preprocessor { * @internal */ public function resetParser( ?Parser $parser ) { + // @phan-suppress-next-line PhanPossiblyNullTypeMismatchProperty For internal use only $this->parser = $parser; } diff --git a/includes/parser/Sanitizer.php b/includes/parser/Sanitizer.php index 3858666e90ea..a08b3af59ce7 100644 --- a/includes/parser/Sanitizer.php +++ b/includes/parser/Sanitizer.php @@ -225,7 +225,9 @@ class Sanitizer { # Populate $htmlpairs and $htmlelements with the $extratags and $removetags arrays $extratags = array_fill_keys( $extratags, true ); $removetags = array_fill_keys( $removetags, true ); + // @phan-suppress-next-line PhanTypeMismatchArgumentNullableInternal The static var is always set $htmlpairs = array_merge( $extratags, $htmlpairsStatic ); + // @phan-suppress-next-line PhanTypeMismatchArgumentNullableInternal The static var is always set $htmlelements = array_diff_key( array_merge( $extratags, $htmlelementsStatic ), $removetags ); $result = [ diff --git a/includes/rcfeed/FormattedRCFeed.php b/includes/rcfeed/FormattedRCFeed.php index 36e279130d6b..e51e89ba6e1d 100644 --- a/includes/rcfeed/FormattedRCFeed.php +++ b/includes/rcfeed/FormattedRCFeed.php @@ -61,6 +61,7 @@ abstract class FormattedRCFeed extends RCFeed { // @codeCoverageIgnoreStart // T109544 - If a feed formatter returns null, this will otherwise cause an // error in at least RedisPubSubFeedEngine. Not sure best to handle this. + // @phan-suppress-next-line PhanTypeMismatchReturnProbablyReal return; // @codeCoverageIgnoreEnd } diff --git a/includes/revisionlist/RevisionItem.php b/includes/revisionlist/RevisionItem.php index 560e936a8de8..a9c2604d502c 100644 --- a/includes/revisionlist/RevisionItem.php +++ b/includes/revisionlist/RevisionItem.php @@ -111,6 +111,7 @@ class RevisionItem extends RevisionItemBase { } $linkRenderer = $this->getLinkRenderer(); return $linkRenderer->makeKnownLink( + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable castFrom does not return null here Title::castFromPageIdentity( $this->list->getPage() ), $date, [], diff --git a/includes/revisionlist/RevisionListBase.php b/includes/revisionlist/RevisionListBase.php index 88bf2a1f45c1..42feb453fc2f 100644 --- a/includes/revisionlist/RevisionListBase.php +++ b/includes/revisionlist/RevisionListBase.php @@ -49,6 +49,7 @@ abstract class RevisionListBase extends ContextSource implements Iterator { */ public function __construct( IContextSource $context, PageIdentity $page ) { $this->setContext( $context ); + // @phan-suppress-next-line PhanPossiblyNullTypeMismatchProperty castFrom does not return null here $this->title = Title::castFromPageIdentity( $page ); $this->deprecatePublicPropertyFallback( 'title', '1.37', function () { diff --git a/includes/search/SearchNearMatcher.php b/includes/search/SearchNearMatcher.php index ab315d9a46df..f72284b11ad3 100644 --- a/includes/search/SearchNearMatcher.php +++ b/includes/search/SearchNearMatcher.php @@ -165,6 +165,7 @@ class SearchNearMatcher { // Give hooks a chance at better match variants $title = null; + // @phan-suppress-next-line PhanTypeMismatchArgument Type mismatch on pass-by-ref args if ( !$this->hookRunner->onSearchGetNearMatch( $term, $title ) ) { return $title; } diff --git a/includes/search/searchwidgets/BasicSearchResultSetWidget.php b/includes/search/searchwidgets/BasicSearchResultSetWidget.php index 4668926597d3..d3a01f121107 100644 --- a/includes/search/searchwidgets/BasicSearchResultSetWidget.php +++ b/includes/search/searchwidgets/BasicSearchResultSetWidget.php @@ -59,6 +59,7 @@ class BasicSearchResultSetWidget { $out = ''; if ( $hasTitle ) { $out .= $this->header( $this->specialPage->msg( 'titlematches' ) ) + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable titleResultSet is set when used here . $this->renderResultSet( $titleResultSet, $offset ); } @@ -67,6 +68,7 @@ class BasicSearchResultSetWidget { $out .= "<div class='mw-search-visualclear'></div>" . $this->header( $this->specialPage->msg( 'textmatches' ) ); } + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable textResultSet is set when used $out .= $this->renderResultSet( $textResultSet, $offset ); } diff --git a/includes/search/searchwidgets/FullSearchResultWidget.php b/includes/search/searchwidgets/FullSearchResultWidget.php index c622e5782f0b..7e5141173474 100644 --- a/includes/search/searchwidgets/FullSearchResultWidget.php +++ b/includes/search/searchwidgets/FullSearchResultWidget.php @@ -90,6 +90,7 @@ class FullSearchResultWidget implements SearchResultWidget { $terms = $result instanceof \SqlSearchResult ? $result->getTermMatches() : []; if ( !$this->hookRunner->onShowSearchHit( $this->specialPage, $result, $terms, $link, $redirect, $section, $extract, $score, + // @phan-suppress-next-line PhanTypeMismatchArgument Type mismatch on pass-by-ref args $desc, $date, $related, $html ) ) { return $html; diff --git a/includes/session/SessionBackend.php b/includes/session/SessionBackend.php index 8d4c94e10b5a..33ee78c55b63 100644 --- a/includes/session/SessionBackend.php +++ b/includes/session/SessionBackend.php @@ -858,6 +858,7 @@ final class SessionBackend { } $this->persistenceChangeData = [ 'id' => $id, 'user' => $user, 'message' => $message ]; + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable message always set $this->logger->info( $message, [ 'id' => $id, 'provider' => get_class( $this->getProvider() ), diff --git a/includes/session/SessionManager.php b/includes/session/SessionManager.php index bc04e67556ae..38857f76ac8b 100644 --- a/includes/session/SessionManager.php +++ b/includes/session/SessionManager.php @@ -1118,6 +1118,7 @@ class SessionManager implements SessionManagerInterface { 'userAgent' => $session->getRequest()->getHeader( 'user-agent' ), ]; $logger = \MediaWiki\Logger\LoggerFactory::getInstance( 'session-ip' ); + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable message is set when used here $logger->log( $logLevel, $message, $logData ); } } diff --git a/includes/shell/ShellboxClientFactory.php b/includes/shell/ShellboxClientFactory.php index 348408ab732c..d80c672ee735 100644 --- a/includes/shell/ShellboxClientFactory.php +++ b/includes/shell/ShellboxClientFactory.php @@ -114,6 +114,7 @@ class ShellboxClientFactory { if ( $this->urls === null || !strlen( $this->key ) ) { return null; } + // @phan-suppress-next-line PhanTypeMismatchDimFetchNullable False positive $url = $this->urls[$service] ?? $this->urls['default'] ?? null; if ( !is_string( $url ) ) { return null; diff --git a/includes/skins/Skin.php b/includes/skins/Skin.php index eefa167d638e..969200e5b69a 100644 --- a/includes/skins/Skin.php +++ b/includes/skins/Skin.php @@ -477,6 +477,7 @@ abstract class Skin extends ContextSource { * @return Title */ public function getRelevantTitle() { + // @phan-suppress-next-line PhanTypeMismatchReturnNullable title is set return $this->mRelevantTitle ?? $this->getTitle(); } diff --git a/includes/specialpage/QueryPage.php b/includes/specialpage/QueryPage.php index 807246bddcfd..73c00f094dee 100644 --- a/includes/specialpage/QueryPage.php +++ b/includes/specialpage/QueryPage.php @@ -210,6 +210,7 @@ abstract class QueryPage extends SpecialPage { * @since 1.18 */ public function getQueryInfo() { + // @phan-suppress-next-line PhanTypeMismatchReturnProbablyReal null needed for b/c checks return null; } diff --git a/includes/specials/SpecialApiHelp.php b/includes/specials/SpecialApiHelp.php index c725d106e1e6..4b739e3b9508 100644 --- a/includes/specials/SpecialApiHelp.php +++ b/includes/specials/SpecialApiHelp.php @@ -76,6 +76,7 @@ class SpecialApiHelp extends UnlistedSpecialPage { $main = new ApiMain( $this->getContext(), false ); try { + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable False positive $module = $main->getModuleFromPath( $moduleName ); } catch ( ApiUsageException $ex ) { $this->getOutput()->addHTML( Html::rawElement( 'span', [ 'class' => 'error' ], diff --git a/includes/specials/SpecialContributions.php b/includes/specials/SpecialContributions.php index 2feb31c3c9fc..14e3a4092dee 100644 --- a/includes/specials/SpecialContributions.php +++ b/includes/specials/SpecialContributions.php @@ -143,6 +143,7 @@ class SpecialContributions extends IncludableSpecialPage { $request = $this->getRequest(); $target = $par ?? $request->getVal( 'target', '' ); + '@phan-var string $target'; // getVal does not return null here $this->opts['deletedOnly'] = $request->getBool( 'deletedOnly' ); diff --git a/includes/specials/SpecialEditTags.php b/includes/specials/SpecialEditTags.php index 334dfc73b589..328211c0d777 100644 --- a/includes/specials/SpecialEditTags.php +++ b/includes/specials/SpecialEditTags.php @@ -142,6 +142,7 @@ class SpecialEditTags extends UnlistedSpecialPage { ) ) { throw new UserBlockedError( + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable Block is checked and not null $user->getBlock(), $user, $this->getLanguage(), diff --git a/includes/specials/SpecialEmailUser.php b/includes/specials/SpecialEmailUser.php index b8220739ecaf..17295bc652c3 100644 --- a/includes/specials/SpecialEmailUser.php +++ b/includes/specials/SpecialEmailUser.php @@ -157,6 +157,7 @@ class SpecialEmailUser extends UnlistedSpecialPage { case 'badaccess': throw new PermissionsError( 'sendemail' ); case 'blockedemailuser': + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable Block is checked and not null throw new UserBlockedError( $this->getUser()->getBlock() ); case 'actionthrottledtext': throw new ThrottledError; @@ -179,8 +180,10 @@ class SpecialEmailUser extends UnlistedSpecialPage { // if the user opens Special:EmailUser/Florian (e.g.). So check, if the user did that // and show the "Send email to user" form directly, if so. Show the "enter username" // form, otherwise. + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable target is set $this->mTargetObj = self::getTarget( $this->mTarget, $this->getUser() ); if ( !$this->mTargetObj instanceof User ) { + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable target is set $this->userForm( $this->mTarget ); } else { $this->sendEmailForm(); diff --git a/includes/specials/SpecialExport.php b/includes/specials/SpecialExport.php index c62d70ee9b27..7876307f6ad8 100644 --- a/includes/specials/SpecialExport.php +++ b/includes/specials/SpecialExport.php @@ -210,6 +210,7 @@ class SpecialExport extends SpecialPage { $request->response()->header( "Content-disposition: attachment;filename={$filename}" ); } + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable history is set when used $this->doExport( $page, $history, $list_authors, $exportall ); return; diff --git a/includes/specials/SpecialFilepath.php b/includes/specials/SpecialFilepath.php index 618fd1da4886..4ad735d85c64 100644 --- a/includes/specials/SpecialFilepath.php +++ b/includes/specials/SpecialFilepath.php @@ -51,6 +51,7 @@ class SpecialFilepath extends RedirectSpecialPage { $this->mAddedRedirectParams['wpvalue'] = $file; $redirect = SpecialPage::getSafeTitleFor( 'Redirect', 'file' ); } + // @phan-suppress-next-line PhanTypeMismatchReturnNullable Known to be valid return $redirect; } diff --git a/includes/specials/SpecialImport.php b/includes/specials/SpecialImport.php index 988e01054c8a..104be366a85e 100644 --- a/includes/specials/SpecialImport.php +++ b/includes/specials/SpecialImport.php @@ -177,6 +177,7 @@ class SpecialImport extends SpecialPage { $frompage = $request->getText( 'frompage' ); $includeTemplates = $request->getCheck( 'interwikiTemplates' ); $source = ImportStreamSource::newFromInterwiki( + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable False positive $fullInterwikiPrefix, $frompage, $history, @@ -217,6 +218,7 @@ class SpecialImport extends SpecialPage { return; } } + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable False positive $importer->setUsernamePrefix( $fullInterwikiPrefix, $assignKnownUsers ); $out->addWikiMsg( "importstart" ); @@ -224,6 +226,7 @@ class SpecialImport extends SpecialPage { $reporter = new ImportReporter( $importer, $isUpload, + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable False positive $fullInterwikiPrefix, $logcomment ); diff --git a/includes/specials/SpecialRandomPage.php b/includes/specials/SpecialRandomPage.php index 6378ef976d4c..921b2207990b 100644 --- a/includes/specials/SpecialRandomPage.php +++ b/includes/specials/SpecialRandomPage.php @@ -125,6 +125,7 @@ class SpecialRandomPage extends SpecialPage { if ( !$this->getHookRunner()->onSpecialRandomGetRandomTitle( $randstr, $this->isRedir, $this->namespaces, + // @phan-suppress-next-line PhanTypeMismatchArgument Type mismatch on pass-by-ref args $this->extra, $title ) ) { return $title; diff --git a/includes/specials/SpecialRedirect.php b/includes/specials/SpecialRedirect.php index 80abcd05cf2c..e27e58f22951 100644 --- a/includes/specials/SpecialRedirect.php +++ b/includes/specials/SpecialRedirect.php @@ -123,6 +123,7 @@ class SpecialRedirect extends FormSpecialPage { } catch ( MalformedTitleException $e ) { return Status::newFatal( $e->getMessageObject() ); } + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable False positive $file = $this->repoGroup->findFile( $title ); if ( !$file || !$file->exists() ) { @@ -269,6 +270,7 @@ class SpecialRedirect extends FormSpecialPage { if ( $this->mValue !== null ) { $this->getOutput()->setStatusCode( 404 ); + // @phan-suppress-next-line PhanTypeMismatchReturnNullable Null of $status seems unreachable return $status; } diff --git a/includes/specials/SpecialRevisionDelete.php b/includes/specials/SpecialRevisionDelete.php index 9c69780d1aee..8a86973f030f 100644 --- a/includes/specials/SpecialRevisionDelete.php +++ b/includes/specials/SpecialRevisionDelete.php @@ -205,6 +205,7 @@ class SpecialRevisionDelete extends UnlistedSpecialPage { ) ) { throw new UserBlockedError( + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable Block is checked and not null $user->getBlock(), $user, $this->getLanguage(), diff --git a/includes/specials/SpecialSearch.php b/includes/specials/SpecialSearch.php index 773b39df7f30..246a0d69e4d8 100644 --- a/includes/specials/SpecialSearch.php +++ b/includes/specials/SpecialSearch.php @@ -879,6 +879,7 @@ class SpecialSearch extends SpecialPage { } $prevNext = + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable offset is not null $this->buildPrevNextNavigation( $offset, $this->limit, $this->powerSearchOptions() + [ 'search' => $newSearchTerm ], $this->limit + $this->offset >= $totalRes ); diff --git a/includes/specials/SpecialUnblock.php b/includes/specials/SpecialUnblock.php index f419c5b53704..50e7fafed607 100644 --- a/includes/specials/SpecialUnblock.php +++ b/includes/specials/SpecialUnblock.php @@ -115,16 +115,20 @@ class SpecialUnblock extends SpecialPage { if ( $form->show() ) { switch ( $this->type ) { case DatabaseBlock::TYPE_IP: + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable target is set when type is set $out->addWikiMsg( 'unblocked-ip', wfEscapeWikiText( $this->target ) ); break; case DatabaseBlock::TYPE_USER: + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable target is set when type is set $out->addWikiMsg( 'unblocked', wfEscapeWikiText( $this->target ) ); break; case DatabaseBlock::TYPE_RANGE: + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable target is set when type is set $out->addWikiMsg( 'unblocked-range', wfEscapeWikiText( $this->target ) ); break; case DatabaseBlock::TYPE_ID: case DatabaseBlock::TYPE_AUTO: + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable target is set when type is set $out->addWikiMsg( 'unblocked-id', wfEscapeWikiText( $this->target ) ); break; } diff --git a/includes/specials/SpecialUndelete.php b/includes/specials/SpecialUndelete.php index 947b55beb828..757fcf499e9e 100644 --- a/includes/specials/SpecialUndelete.php +++ b/includes/specials/SpecialUndelete.php @@ -275,6 +275,7 @@ class SpecialUndelete extends SpecialPage { // the target, show a block error. if ( $this->mTargetObj && $this->permissionManager->isBlockedFrom( $user, $this->mTargetObj ) ) { + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable Block is checked and not null throw new UserBlockedError( $user->getBlock() ); } diff --git a/includes/specials/SpecialUpload.php b/includes/specials/SpecialUpload.php index 5f605109d1f8..5c1f09abfda1 100644 --- a/includes/specials/SpecialUpload.php +++ b/includes/specials/SpecialUpload.php @@ -208,6 +208,7 @@ class SpecialUpload extends SpecialPage { # Check blocks if ( $user->isBlockedFromUpload() ) { throw new UserBlockedError( + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable Block is checked and not null $user->getBlock(), $user, $this->getLanguage(), diff --git a/includes/specials/SpecialVersion.php b/includes/specials/SpecialVersion.php index 1b356d3b7087..0308d2d49d63 100644 --- a/includes/specials/SpecialVersion.php +++ b/includes/specials/SpecialVersion.php @@ -911,6 +911,7 @@ class SpecialVersion extends SpecialPage { // ... now get the authors for this extension $authors = $extension['author'] ?? []; + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable path is set when there is a name $authors = $this->listAuthors( $authors, $extension['name'], $extensionPath ); // Finally! Create the table diff --git a/includes/specials/SpecialWhatLinksHere.php b/includes/specials/SpecialWhatLinksHere.php index 4271ad76d0af..901643b10f84 100644 --- a/includes/specials/SpecialWhatLinksHere.php +++ b/includes/specials/SpecialWhatLinksHere.php @@ -426,6 +426,7 @@ class SpecialWhatLinksHere extends IncludableSpecialPage { $out->addHTML( $this->listEnd() ); if ( $level == 0 && !$this->including() ) { + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable prevnext is set when used $out->addHTML( $prevnext ); } } diff --git a/includes/specials/helpers/ImportReporter.php b/includes/specials/helpers/ImportReporter.php index 7ed533e7ea5c..b620da1b2ee0 100644 --- a/includes/specials/helpers/ImportReporter.php +++ b/includes/specials/helpers/ImportReporter.php @@ -170,6 +170,7 @@ class ImportReporter extends ContextSource { $logEntry->setPerformer( $this->getUser() ); $logEntry->setParameters( $logParams ); // Make sure the null revision will be tagged as well + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable T303637 $logEntry->setAssociatedRevId( $nullRevId ); if ( count( $this->logTags ) ) { $logEntry->addTags( $this->logTags ); diff --git a/includes/specials/pagers/ContribsPager.php b/includes/specials/pagers/ContribsPager.php index 5a51c89a985d..f4e7a0e6475f 100644 --- a/includes/specials/pagers/ContribsPager.php +++ b/includes/specials/pagers/ContribsPager.php @@ -182,6 +182,7 @@ class ContribsPager extends RangeChronologicalPager { // ContribsPagerTest and does not cause newFromName() to return // false. It's probably not used by any production code. $this->target = $options['target'] ?? ''; + // @phan-suppress-next-line PhanPossiblyNullTypeMismatchProperty RIGOR_NONE never returns null $this->targetUser = $services->getUserFactory()->newFromName( $this->target, UserFactory::RIGOR_NONE ); @@ -693,6 +694,7 @@ class ContribsPager extends RangeChronologicalPager { $attribs['data-mw-revid'] = $revRecord->getId(); $link = $linkRenderer->makeLink( + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable castFrom does not return null here $page, $page->getPrefixedText(), [ 'class' => 'mw-contributions-title' ], @@ -707,7 +709,9 @@ class ContribsPager extends RangeChronologicalPager { $classes[] = 'mw-contributions-current'; # Add rollback link if ( !$row->page_is_new && + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable castFrom does not return null here $this->getAuthority()->probablyCan( 'rollback', $page ) && + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable castFrom does not return null here $this->getAuthority()->probablyCan( 'edit', $page ) ) { $this->setPreventClickjacking( true ); @@ -723,6 +727,7 @@ class ContribsPager extends RangeChronologicalPager { $revRecord->userCan( RevisionRecord::DELETED_TEXT, $this->getAuthority() ) ) { $difftext = $linkRenderer->makeKnownLink( + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable castFrom does not return null here $page, new HtmlArmor( $this->messages['diff'] ), [ 'class' => 'mw-changeslist-diff' ], @@ -735,6 +740,7 @@ class ContribsPager extends RangeChronologicalPager { $difftext = $this->messages['diff']; } $histlink = $linkRenderer->makeKnownLink( + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable castFrom does not return null here $page, new HtmlArmor( $this->messages['hist'] ), [ 'class' => 'mw-changeslist-history' ], @@ -798,6 +804,7 @@ class ContribsPager extends RangeChronologicalPager { $flags[] = ChangesList::flag( 'minor' ); } + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable castFrom does not return null here $del = Linker::getRevDeleteLink( $user, $revRecord, $page ); if ( $del !== '' ) { $del .= ' '; diff --git a/includes/tidy/RemexCompatMunger.php b/includes/tidy/RemexCompatMunger.php index ce9b36cc9fc0..a05e30e04072 100644 --- a/includes/tidy/RemexCompatMunger.php +++ b/includes/tidy/RemexCompatMunger.php @@ -428,6 +428,7 @@ class RemexCompatMunger implements TreeHandler { $fakeElement->userData = $rNode; $this->serializer->removeNode( $fakeElement, $pos ); } + // @phan-suppress-next-line PhanTypeMismatchReturnNullable False positive return $node; } diff --git a/includes/title/MediaWikiTitleCodec.php b/includes/title/MediaWikiTitleCodec.php index f70aa9fc0e40..4ef10f00b58c 100644 --- a/includes/title/MediaWikiTitleCodec.php +++ b/includes/title/MediaWikiTitleCodec.php @@ -550,6 +550,8 @@ class MediaWikiTitleCodec implements TitleFormatter, TitleParser { // inconsistent. Same for talk/userpages. Keep them normalized instead. if ( $parts['namespace'] === NS_USER || $parts['namespace'] === NS_USER_TALK ) { $dbkey = IPUtils::sanitizeIP( $dbkey ); + // IPUtils::sanitizeIP return null only for bad input + '@phan-var string $dbkey'; } // Any remaining initial :s are illegal. diff --git a/includes/upload/UploadBase.php b/includes/upload/UploadBase.php index 8a402934ea48..0399fd34de01 100644 --- a/includes/upload/UploadBase.php +++ b/includes/upload/UploadBase.php @@ -198,6 +198,7 @@ abstract class UploadBase { // Give hooks the chance to handle this request /** @var self|null $className */ $className = null; + // @phan-suppress-next-line PhanTypeMismatchArgument Type mismatch on pass-by-ref args Hooks::runner()->onUploadCreateFromRequest( $type, $className ); if ( $className === null ) { $className = 'UploadFrom' . $type; @@ -941,6 +942,7 @@ abstract class UploadBase { $props = $this->mFileProps; $error = null; + // @phan-suppress-next-line PhanTypeMismatchArgument Type mismatch on pass-by-ref args $this->getHookRunner()->onUploadVerifyUpload( $this, $user, $props, $comment, $pageText, $error ); if ( $error ) { if ( !is_array( $error ) ) { diff --git a/includes/upload/UploadFromChunks.php b/includes/upload/UploadFromChunks.php index c705f3f32170..d71782c82cce 100644 --- a/includes/upload/UploadFromChunks.php +++ b/includes/upload/UploadFromChunks.php @@ -196,6 +196,7 @@ class UploadFromChunks extends UploadFromFile { } $tAmount = microtime( true ) - $tStart; + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable tmpFile is set when tmpPath is set here $this->mStashFile->setLocalReference( $tmpFile ); // reuse (e.g. for getImageInfo()) wfDebugLog( 'fileconcatenate', "Stashed combined file ($i chunks) in $tAmount seconds." ); diff --git a/includes/upload/UploadFromFile.php b/includes/upload/UploadFromFile.php index a8c3269b4ef4..f6e5facc2ed4 100644 --- a/includes/upload/UploadFromFile.php +++ b/includes/upload/UploadFromFile.php @@ -43,6 +43,7 @@ class UploadFromFile extends UploadBase { $desiredDestName = $upload->getName(); } + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable getName only null on failure $this->initialize( $desiredDestName, $upload ); } diff --git a/includes/upload/UploadFromUrl.php b/includes/upload/UploadFromUrl.php index 45741529af6d..431323094eef 100644 --- a/includes/upload/UploadFromUrl.php +++ b/includes/upload/UploadFromUrl.php @@ -322,6 +322,7 @@ class UploadFromUrl extends UploadBase { ); } + // @phan-suppress-next-line PhanTypeMismatchReturnNullable Always set after the loop return $status; } } diff --git a/includes/user/User.php b/includes/user/User.php index 487745e8e86e..dac7dd4ec323 100644 --- a/includes/user/User.php +++ b/includes/user/User.php @@ -1794,6 +1794,7 @@ class User implements Authority, UserIdentity, UserEmailContact { public function getBlockId() { wfDeprecated( __METHOD__, '1.38' ); $this->getBlockedStatus(); + // @phan-suppress-next-line PhanTypeMismatchReturnNullable getId does not return null here return ( $this->mBlock ? $this->mBlock->getId() : false ); } @@ -3291,7 +3292,7 @@ class User implements Authority, UserIdentity, UserEmailContact { * @note Call saveSettings() after calling this function to commit * this change to the database. * - * @param string &$expiration Accepts the expiration time + * @param string &$expiration Accepts the expiration time @phan-output-reference * @return string New token */ protected function confirmationToken( &$expiration ) { diff --git a/includes/user/UserFactory.php b/includes/user/UserFactory.php index 352dc6ebe908..5732cd9280c8 100644 --- a/includes/user/UserFactory.php +++ b/includes/user/UserFactory.php @@ -115,6 +115,7 @@ class UserFactory implements IDBAccessObject, UserRigorOptions { } else { $user = new User(); } + // @phan-suppress-next-line PhanTypeMismatchReturnNullable Checked by isIp return $user; } diff --git a/includes/user/UserGroupManager.php b/includes/user/UserGroupManager.php index 72de1b73f8e1..6e7d3660360e 100644 --- a/includes/user/UserGroupManager.php +++ b/includes/user/UserGroupManager.php @@ -576,6 +576,7 @@ class UserGroupManager implements IDBAccessObject { default: $result = null; $this->hookRunner->onAutopromoteCondition( $cond[0], + // @phan-suppress-next-line PhanTypeMismatchArgument Type mismatch on pass-by-ref args array_slice( $cond, 1 ), $user, $result ); if ( $result === null ) { throw new InvalidArgumentException( diff --git a/includes/utils/MWFileProps.php b/includes/utils/MWFileProps.php index 37481a425e3c..21921bcd176f 100644 --- a/includes/utils/MWFileProps.php +++ b/includes/utils/MWFileProps.php @@ -79,10 +79,12 @@ class MWFileProps { # Unclear if callers of this method expect that. $info['mime'] = $this->magic->improveTypeFromExtension( $info['file-mime'], $ext ); + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable See XXX above list( $info['major_mime'], $info['minor_mime'] ) = File::splitMime( $info['mime'] ); $info['media_type'] = $this->magic->getMediaType( $path, $info['mime'] ); # Height, width and metadata + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable See XXX above $handler = MediaHandler::getHandler( $info['mime'] ); if ( $handler ) { $sizeAndMetadata = $handler->getSizeAndMetadataWithFallback( $fsFile, $path ); diff --git a/includes/watcheditem/WatchedItemStore.php b/includes/watcheditem/WatchedItemStore.php index 19e142f4c0de..4c97204ccbee 100644 --- a/includes/watcheditem/WatchedItemStore.php +++ b/includes/watcheditem/WatchedItemStore.php @@ -1448,6 +1448,7 @@ class WatchedItemStore implements WatchedItemStoreInterface, StatsdAwareInterfac } } if ( $seenTime === null ) { + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable getId does not return null here $seenTime = $this->revisionLookup->getTimestampFromId( $id ); } diff --git a/maintenance/benchmarks/benchmarkLruHash.php b/maintenance/benchmarks/benchmarkLruHash.php index 0669fd64cbb2..764a20f76b8e 100644 --- a/maintenance/benchmarks/benchmarkLruHash.php +++ b/maintenance/benchmarks/benchmarkLruHash.php @@ -63,6 +63,7 @@ class BenchmarkLruHash extends Benchmarker { if ( !$method || $method === 'set' ) { $hObj = null; + '@phan-var BagOStuff $hObj'; $benches['HashBagOStuff::set'] = [ 'setup' => static function () use ( &$hObj, $max ) { $hObj = new HashBagOStuff( [ 'maxKeys' => $max ] ); @@ -74,6 +75,7 @@ class BenchmarkLruHash extends Benchmarker { } ]; $mObj = null; + '@phan-var MapCacheLRU $mObj'; $benches['MapCacheLRU::set'] = [ 'setup' => static function () use ( &$mObj, $max ) { $mObj = new MapCacheLRU( $max ); @@ -88,6 +90,7 @@ class BenchmarkLruHash extends Benchmarker { if ( !$method || $method === 'get' ) { $hObj = null; + '@phan-var BagOStuff $hObj'; $benches['HashBagOStuff::get'] = [ 'setup' => static function () use ( &$hObj, $max, $keys ) { $hObj = new HashBagOStuff( [ 'maxKeys' => $max ] ); @@ -102,6 +105,7 @@ class BenchmarkLruHash extends Benchmarker { } ]; $mObj = null; + '@phan-var MapCacheLRU $mObj'; $benches['MapCacheLRU::get'] = [ 'setup' => static function () use ( &$mObj, $max, $keys ) { $mObj = new MapCacheLRU( $max ); diff --git a/maintenance/benchmarks/benchmarkParse.php b/maintenance/benchmarks/benchmarkParse.php index 3974f56153d1..b63229361261 100644 --- a/maintenance/benchmarks/benchmarkParse.php +++ b/maintenance/benchmarks/benchmarkParse.php @@ -160,6 +160,7 @@ class BenchmarkParse extends Maintenance { private function runParser( RevisionRecord $revision ) { $content = $revision->getContent( SlotRecord::MAIN ); $contentRenderer = MediaWikiServices::getInstance()->getContentRenderer(); + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable getId does not return null here $contentRenderer->getParserOutput( $content, $revision->getPage(), $revision->getId() ); if ( $this->clearLinkCache ) { $this->linkCache->clear(); diff --git a/maintenance/cleanupCaps.php b/maintenance/cleanupCaps.php index 9b0a2eefc0dc..b0a49e0af76b 100644 --- a/maintenance/cleanupCaps.php +++ b/maintenance/cleanupCaps.php @@ -93,6 +93,7 @@ class CleanupCaps extends TableCleanup { } $ok = $this->movePage( $current, + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable target is always valid $target, 'Converting page title to first-letter uppercase', false diff --git a/maintenance/cleanupSpam.php b/maintenance/cleanupSpam.php index eb26b910ffc4..005573e857ba 100644 --- a/maintenance/cleanupSpam.php +++ b/maintenance/cleanupSpam.php @@ -153,6 +153,7 @@ class CleanupSpam extends Maintenance { while ( $rev && ( $rev->isDeleted( RevisionRecord::DELETED_TEXT ) || LinkFilter::matchEntry( + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable RAW never returns null $rev->getContent( SlotRecord::MAIN, RevisionRecord::RAW ), $domain, $protocol @@ -175,6 +176,7 @@ class CleanupSpam extends Maintenance { $this->output( "reverting\n" ); $page->doUserEditContent( + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable RAW never returns null $content, $performer, wfMessage( 'spam_reverting', $domain )->inContentLanguage()->text(), diff --git a/maintenance/cleanupUsersWithNoId.php b/maintenance/cleanupUsersWithNoId.php index 47f74cf7351c..add5b3b6a397 100644 --- a/maintenance/cleanupUsersWithNoId.php +++ b/maintenance/cleanupUsersWithNoId.php @@ -205,6 +205,7 @@ class CleanupUsersWithNoId extends LoggedUpdateMaintenance { $counter += $dbw->affectedRows(); } + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable row is set list( $next, $display ) = $this->makeNextCond( $dbw, $orderby, $row ); $this->output( "... $display\n" ); $lbFactory->waitForReplication(); diff --git a/maintenance/eval.php b/maintenance/eval.php index 949fbfe53f82..4a1dcd1cd21b 100644 --- a/maintenance/eval.php +++ b/maintenance/eval.php @@ -77,6 +77,7 @@ while ( ( $__line = Maintenance::readconsole() ) !== false ) { } if ( $__useReadline ) { readline_add_history( $__line ); + // @phan-suppress-next-line PhanTypeMismatchArgumentNullableInternal readline_write_history( $__historyFile ); } try { diff --git a/maintenance/importImages.php b/maintenance/importImages.php index 24fa1f151ca3..1eed327e4928 100644 --- a/maintenance/importImages.php +++ b/maintenance/importImages.php @@ -160,6 +160,7 @@ class ImportImages extends Maintenance { if ( !$user instanceof User ) { $user = User::newSystemUser( User::MAINTENANCE_SCRIPT_USER, [ 'steal' => true ] ); } + '@phan-var User $user'; StubGlobalUser::setUser( $user ); # Get block check. If a value is given, this specified how often the check is performed @@ -351,6 +352,7 @@ class ImportImages extends Maintenance { $summary, $commentText, $user, + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable $props, $timestamp, $tags diff --git a/maintenance/importSiteScripts.php b/maintenance/importSiteScripts.php index d7fd8d6b7d5e..9af47284b940 100644 --- a/maintenance/importSiteScripts.php +++ b/maintenance/importSiteScripts.php @@ -47,6 +47,7 @@ class ImportSiteScripts extends Maintenance { } else { $user = User::newFromName( $username ); } + '@phan-var User $user'; StubGlobalUser::setUser( $user ); $baseUrl = $this->getArg( 1 ); diff --git a/maintenance/includes/Maintenance.php b/maintenance/includes/Maintenance.php index b0fac2e4abcb..ac9ed34c6c12 100644 --- a/maintenance/includes/Maintenance.php +++ b/maintenance/includes/Maintenance.php @@ -1234,6 +1234,7 @@ abstract class Maintenance { */ protected function afterFinalSetup() { if ( defined( 'MW_CMDLINE_CALLBACK' ) ) { + // @phan-suppress-next-line PhanTypeMismatchArgumentNullableInternal False positive call_user_func( MW_CMDLINE_CALLBACK ); } } @@ -1709,6 +1710,7 @@ abstract class Maintenance { } } + // @phan-suppress-next-line PhanTypeMismatchReturnNullable T240141 return $user; } } diff --git a/maintenance/includes/MigrateActors.php b/maintenance/includes/MigrateActors.php index c2cf36aaeebc..0fcb90f7d4c8 100644 --- a/maintenance/includes/MigrateActors.php +++ b/maintenance/includes/MigrateActors.php @@ -531,6 +531,7 @@ class MigrateActors extends LoggedUpdateMaintenance { $dbw->insert( 'log_search', $ins, __METHOD__, [ 'IGNORE' ] ); $countInserted += $dbw->affectedRows(); + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable lastRow is set when used here list( $next, $display ) = $this->makeNextCond( $dbw, $primaryKey, $lastRow ); $this->output( "... target_author_id, $display\n" ); $lbFactory->waitForReplication(); diff --git a/maintenance/mcc.php b/maintenance/mcc.php index 2d83064c28ad..f85eba46006c 100644 --- a/maintenance/mcc.php +++ b/maintenance/mcc.php @@ -165,7 +165,6 @@ do { $res = $mcc->get( $args[0] ); $hv = $mcc->_hashfunc( $args[0] ); for ( $i = 0; $i < 3; $i++ ) { - // @phan-suppress-next-line PhanTypeArraySuspiciousNullable print $mcc->_buckets[$hv % $mcc->_bucketcount] . "\n"; $hv += $mcc->_hashfunc( $i . $args[0] ); } diff --git a/maintenance/migrateImageCommentTemp.php b/maintenance/migrateImageCommentTemp.php index f8b45058db1d..9d7e1ccabd4f 100644 --- a/maintenance/migrateImageCommentTemp.php +++ b/maintenance/migrateImageCommentTemp.php @@ -107,6 +107,7 @@ class MigrateImageCommentTemp extends LoggedUpdateMaintenance { break; } + // @phan-suppress-next-line PhanTypeSuspiciousStringExpression last is not-null when used $this->output( "... $last, updated $updated, deleted $deleted\n" ); $conds = [ 'imgcomment_name > ' . $dbw->addQuotes( $last ) ]; } diff --git a/maintenance/migrateRevisionActorTemp.php b/maintenance/migrateRevisionActorTemp.php index 549daba8dd01..23c6e8e4818b 100644 --- a/maintenance/migrateRevisionActorTemp.php +++ b/maintenance/migrateRevisionActorTemp.php @@ -87,6 +87,7 @@ class MigrateRevisionActorTemp extends LoggedUpdateMaintenance { break; } + // @phan-suppress-next-line PhanTypeSuspiciousStringExpression last is not-null when used $this->output( "... rev_id=$last, updated $updated\n" ); $conds = [ 'rev_id > ' . $dbw->addQuotes( $last ) ]; diff --git a/maintenance/populateImageSha1.php b/maintenance/populateImageSha1.php index 34d289d6924c..77e4e90db157 100644 --- a/maintenance/populateImageSha1.php +++ b/maintenance/populateImageSha1.php @@ -144,6 +144,7 @@ class PopulateImageSha1 extends LoggedUpdateMaintenance { $sql = "UPDATE $imageTable SET img_sha1=" . $dbw->addQuotes( $sha1 ) . " WHERE img_name=" . $dbw->addQuotes( $file->getName() ); if ( $method == 'pipe' ) { + // @phan-suppress-next-line PhanTypeMismatchArgumentNullableInternal pipe is set when used fwrite( $pipe, "$sql;\n" ); } else { $dbw->query( $sql, __METHOD__ ); @@ -165,6 +166,7 @@ class PopulateImageSha1 extends LoggedUpdateMaintenance { " WHERE (oi_name=" . $dbw->addQuotes( $oldFile->getName() ) . " AND" . " oi_archive_name=" . $dbw->addQuotes( $oldFile->getArchiveName() ) . ")"; if ( $method == 'pipe' ) { + // @phan-suppress-next-line PhanTypeMismatchArgumentNullableInternal pipe is set when used fwrite( $pipe, "$sql;\n" ); } else { $dbw->query( $sql, __METHOD__ ); @@ -175,7 +177,9 @@ class PopulateImageSha1 extends LoggedUpdateMaintenance { $i++; } if ( $method == 'pipe' ) { + // @phan-suppress-next-line PhanTypeMismatchArgumentNullableInternal pipe is set when used fflush( $pipe ); + // @phan-suppress-next-line PhanTypeMismatchArgumentNullableInternal pipe is set when used pclose( $pipe ); } $t += microtime( true ); diff --git a/maintenance/storage/storageTypeStats.php b/maintenance/storage/storageTypeStats.php index 3a596ac24736..ee7357be490e 100644 --- a/maintenance/storage/storageTypeStats.php +++ b/maintenance/storage/storageTypeStats.php @@ -83,6 +83,7 @@ SQL; } $class = $row->class; $count = $row->count; + // @phan-suppress-next-line PhanImpossibleConditionInLoop False positive if ( !isset( $stats[$flags][$class] ) ) { $stats[$flags][$class] = [ 'count' => 0, diff --git a/maintenance/updateExtensionJsonSchema.php b/maintenance/updateExtensionJsonSchema.php index d00afd46e59e..1505ce80752f 100644 --- a/maintenance/updateExtensionJsonSchema.php +++ b/maintenance/updateExtensionJsonSchema.php @@ -59,7 +59,7 @@ class UpdateExtensionJsonSchema extends Maintenance { if ( isset( $json['requires'][ExtensionRegistry::MEDIAWIKI_CORE] ) ) { $versionParser = new VersionParser(); $currentRequired = $versionParser->parseConstraints( - // @phan-suppress-next-line PhanTypeInvalidDimOffset isset check exists + // @phan-suppress-next-line PhanTypeInvalidDimOffset,PhanTypeMismatchArgument isset check exists $json['requires'][ExtensionRegistry::MEDIAWIKI_CORE] ); $newRequired = $versionParser->parseConstraints( |