Unsuppress another phan issue (part 7)
authorDaimona Eaytoy <daimona.wiki@gmail.com>
Sat, 31 Aug 2019 16:14:38 +0000 (18:14 +0200)
committerKrinkle <krinklemail@gmail.com>
Tue, 3 Sep 2019 17:19:21 +0000 (17:19 +0000)
Bug: T231636
Depends-On: I2cd24e73726394e3200a570c45d5e86b6849bfa9
Depends-On: I4fa3e6aad872434ca397325ed7a83f94973661d0
Change-Id: Ie6233561de78457cae5e4e44e220feec2d1272d8

112 files changed:
.phan/config.php
.phan/internal_stubs/dom.phan_php [new file with mode: 0644]
.phan/stubs/mail.php
includes/FileDeleteForm.php
includes/Navigation/PrevNextNavigationRenderer.php
includes/OutputPage.php
includes/Rest/SimpleHandler.php
includes/Revision/MutableRevisionRecord.php
includes/Storage/PageUpdater.php
includes/Title.php
includes/TitleArray.php
includes/actions/RevertAction.php
includes/api/ApiDelete.php
includes/api/ApiErrorFormatter.php
includes/api/ApiExpandTemplates.php
includes/api/ApiFeedWatchlist.php
includes/api/ApiImageRotate.php
includes/api/ApiMain.php
includes/api/ApiMessageTrait.php
includes/api/ApiOpenSearch.php
includes/api/ApiParse.php
includes/api/ApiQuery.php
includes/api/ApiQueryBlocks.php
includes/api/ApiQueryImageInfo.php
includes/api/ApiQueryRevisionsBase.php
includes/auth/RememberMeAuthenticationRequest.php
includes/block/BlockManager.php
includes/block/Restriction/PageRestriction.php
includes/block/Restriction/Restriction.php
includes/changes/ChangesListBooleanFilterGroup.php
includes/changes/ChangesListFilterGroup.php
includes/changes/ChangesListStringOptionsFilterGroup.php
includes/changetags/ChangeTagsList.php
includes/content/TextContent.php
includes/content/TextContentHandler.php
includes/content/UnknownContentHandler.php
includes/content/WikitextContent.php
includes/deferred/DeferredUpdates.php
includes/diff/TextSlotDiffRenderer.php
includes/export/WikiExporter.php
includes/export/XmlDumpWriter.php
includes/filerepo/file/File.php
includes/filerepo/file/LocalFile.php
includes/filerepo/file/LocalFileMoveBatch.php
includes/htmlform/HTMLFormElement.php
includes/http/MWHttpRequest.php
includes/import/ImportableUploadRevisionImporter.php
includes/installer/DatabaseInstaller.php
includes/installer/DatabaseUpdater.php
includes/installer/Installer.php
includes/installer/MysqlInstaller.php
includes/installer/MysqlUpdater.php
includes/installer/PostgresInstaller.php
includes/installer/WebInstaller.php
includes/installer/WebInstallerOutput.php
includes/page/ImageHistoryList.php
includes/page/ImagePage.php
includes/page/Page.php
includes/parser/PPDPart_Hash.php
includes/parser/PPDStack.php
includes/parser/PPDStackElement_Hash.php
includes/parser/PPFrame_DOM.php
includes/parser/PPNode_DOM.php
includes/parser/Parser.php
includes/parser/Preprocessor_Hash.php
includes/password/LayeredParameterizedPassword.php
includes/poolcounter/PoolCounterRedis.php
includes/preferences/DefaultPreferencesFactory.php
includes/profiler/output/ProfilerOutputDump.php
includes/revisiondelete/RevDelArchivedFileItem.php
includes/revisiondelete/RevDelFileList.php
includes/revisiondelete/RevDelList.php
includes/revisiondelete/RevDelRevisionItem.php
includes/search/SearchResultSetTrait.php
includes/session/PHPSessionHandler.php
includes/session/SessionInfo.php
includes/session/SessionManager.php
includes/skins/SkinTemplate.php
includes/specialpage/LoginSignupSpecialPage.php
includes/specialpage/SpecialPageFactory.php
includes/specials/SpecialBlock.php
includes/specials/SpecialExpandTemplates.php
includes/specials/SpecialRecentChanges.php
includes/specials/SpecialUndelete.php
includes/specials/SpecialUserrights.php
includes/specials/SpecialWatchlist.php
includes/specials/pagers/BlockListPager.php
includes/user/BotPassword.php
includes/utils/AvroValidator.php
languages/Language.php
languages/LanguageConverter.php
maintenance/Maintenance.php
maintenance/addSite.php
maintenance/archives/upgradeLogging.php
maintenance/checkLess.php
maintenance/cleanupUploadStash.php
maintenance/compareParsers.php
maintenance/convertLinks.php
maintenance/deleteArchivedFiles.php
maintenance/eraseArchivedFile.php
maintenance/importDump.php
maintenance/importImages.php
maintenance/nukeNS.php
maintenance/populateImageSha1.php
maintenance/preprocessDump.php
maintenance/preprocessorFuzzTest.php
maintenance/rebuildImages.php
maintenance/storage/checkStorage.php
maintenance/update.php
maintenance/updateExtensionJsonSchema.php
maintenance/userDupes.inc
maintenance/wrapOldPasswords.php

index e02dba7..fe63e47 100644 (file)
@@ -87,8 +87,6 @@ $cfg['suppress_issue_types'] = array_merge( $cfg['suppress_issue_types'], [
        "PhanUndeclaredConstant",
        // approximate error count: 60
        "PhanTypeMismatchArgument",
-       // approximate error count: 219
-       "PhanUndeclaredMethod",
        // approximate error count: 752
        "PhanUndeclaredProperty",
 ] );
diff --git a/.phan/internal_stubs/dom.phan_php b/.phan/internal_stubs/dom.phan_php
new file mode 100644 (file)
index 0000000..608e3a1
--- /dev/null
@@ -0,0 +1,420 @@
+<?php
+// These stubs were generated by the phan stub generator.
+// @phan-stub-for-extension dom@20031129
+
+namespace {
+class DOMAttr extends \DOMNode {
+
+    // properties
+    public $name;
+    public $ownerElement;
+    public $schemaTypeInfo;
+    public $specified;
+    public $value;
+
+    // methods
+    public function isId() {}
+    public function __construct($name, $value = null) {}
+}
+
+class DOMCdataSection extends \DOMText {
+
+    // methods
+    public function __construct($value) {}
+}
+
+class DOMCharacterData extends \DOMNode {
+
+    // properties
+    public $data;
+    public $length;
+
+    // methods
+    public function substringData($offset, $count) {}
+    public function appendData($arg) {}
+    public function insertData($offset, $arg) {}
+    public function deleteData($offset, $count) {}
+    public function replaceData($offset, $count, $arg) {}
+}
+
+class DOMComment extends \DOMCharacterData {
+
+    // methods
+    public function __construct($value = null) {}
+}
+
+class DOMConfiguration {
+
+    // methods
+    public function setParameter($name, $value) {}
+    public function getParameter($name = null) {}
+    public function canSetParameter($name = null, $value = null) {}
+}
+
+class DOMDocument extends \DOMNode {
+
+    // properties
+    public $actualEncoding;
+    public $config;
+    public $doctype;
+    public $documentElement;
+    public $documentURI;
+    public $encoding;
+    public $formatOutput;
+    public $implementation;
+    public $preserveWhiteSpace;
+    public $recover;
+    public $resolveExternals;
+    public $standalone;
+    public $strictErrorChecking;
+    public $substituteEntities;
+    public $validateOnParse;
+    public $version;
+    public $xmlEncoding;
+    public $xmlStandalone;
+    public $xmlVersion;
+
+    // methods
+    public function createElement($tagName, $value = null) {}
+    public function createDocumentFragment() {}
+    public function createTextNode($data) {}
+    public function createComment($data) {}
+    public function createCDATASection($data) {}
+    public function createProcessingInstruction($target, $data) {}
+    public function createAttribute($name) {}
+    public function createEntityReference($name) {}
+    public function getElementsByTagName($tagName) {}
+    public function importNode(\DOMNode $importedNode, $deep) {}
+    public function createElementNS($namespaceURI, $qualifiedName, $value = null) {}
+    public function createAttributeNS($namespaceURI, $qualifiedName) {}
+    public function getElementsByTagNameNS($namespaceURI, $localName) {}
+    public function getElementById($elementId) {}
+    public function adoptNode(\DOMNode $source) {}
+    public function normalizeDocument() {}
+    public function renameNode(\DOMNode $node, $namespaceURI, $qualifiedName) {}
+    public function load($source, $options = null) {}
+    public function save($file) {}
+    public function loadXML($source, $options = null) {}
+    public function saveXML(\DOMNode $node = null, $options = null) {}
+    public function __construct($version = null, $encoding = null) {}
+    public function validate() {}
+    public function xinclude($options = null) {}
+    public function loadHTML($source, $options = null) {}
+    public function loadHTMLFile($source, $options = null) {}
+    public function saveHTML() {}
+    public function saveHTMLFile($file) {}
+    public function schemaValidate($filename) {}
+    public function schemaValidateSource($source) {}
+    public function relaxNGValidate($filename) {}
+    public function relaxNGValidateSource($source) {}
+    public function registerNodeClass($baseClass, $extendedClass) {}
+}
+
+class DOMDocumentFragment extends \DOMNode {
+
+    // properties
+    public $name;
+
+    // methods
+    public function __construct() {}
+    public function appendXML($data) {}
+}
+
+class DOMDocumentType extends \DOMNode {
+
+    // properties
+    public $entities;
+    public $internalSubset;
+    public $name;
+    public $notations;
+    public $publicId;
+    public $systemId;
+}
+
+class DOMDomError {
+}
+
+class DOMElement extends \DOMNode {
+
+    // properties
+    public $schemaTypeInfo;
+    public $tagName;
+
+    // methods
+    public function getAttribute($name) {}
+    public function setAttribute($name, $value) {}
+    public function removeAttribute($name) {}
+    public function getAttributeNode($name) {}
+    public function setAttributeNode(\DOMAttr $newAttr) {}
+    public function removeAttributeNode(\DOMAttr $oldAttr) {}
+    public function getElementsByTagName($name) {}
+    public function getAttributeNS($namespaceURI, $localName) {}
+    public function setAttributeNS($namespaceURI, $qualifiedName, $value) {}
+    public function removeAttributeNS($namespaceURI, $localName) {}
+    public function getAttributeNodeNS($namespaceURI, $localName) {}
+    public function setAttributeNodeNS(\DOMAttr $newAttr) {}
+    public function getElementsByTagNameNS($namespaceURI, $localName) {}
+    public function hasAttribute($name) {}
+    public function hasAttributeNS($namespaceURI, $localName) {}
+    public function setIdAttribute($name, $isId) {}
+    public function setIdAttributeNS($namespaceURI, $localName, $isId) {}
+    public function setIdAttributeNode(\DOMAttr $attr, $isId) {}
+    public function __construct($name, $value = null, $uri = null) {}
+}
+
+class DOMEntity extends \DOMNode {
+
+    // properties
+    public $actualEncoding;
+    public $encoding;
+    public $notationName;
+    public $publicId;
+    public $systemId;
+    public $version;
+}
+
+class DOMEntityReference extends \DOMNode {
+
+    // properties
+    public $name;
+
+    // methods
+    public function __construct($name) {}
+}
+
+class DOMErrorHandler {
+
+    // methods
+    public function handleError(\DOMDomError $error) {}
+}
+
+final class DOMException extends \Exception {
+
+    // properties
+    public $code;
+    protected $message;
+    protected $file;
+    protected $line;
+}
+
+class DOMImplementation {
+
+    // properties
+    public $name;
+
+    // methods
+    public function getFeature($feature, $version) {}
+    public function hasFeature() {}
+    public function createDocumentType($qualifiedName, $publicId, $systemId) {}
+    public function createDocument($namespaceURI, $qualifiedName, \DOMDocumentType $docType) {}
+}
+
+class DOMImplementationList {
+
+    // methods
+    public function item($index) {}
+}
+
+class DOMImplementationSource {
+
+    // methods
+    public function getDomimplementation($features) {}
+    public function getDomimplementations($features) {}
+}
+
+class DOMLocator {
+}
+
+class DOMNameList {
+
+    // methods
+    public function getName($index) {}
+    public function getNamespaceURI($index) {}
+}
+
+class DOMNameSpaceNode {
+}
+
+class DOMNamedNodeMap implements \Traversable, \Countable {
+
+    // properties
+    public $length;
+
+    // methods
+    public function getNamedItem($name) {}
+    public function setNamedItem(\DOMNode $arg) {}
+    public function removeNamedItem($name = null) {}
+    public function item($index = null) {}
+    public function getNamedItemNS($namespaceURI = null, $localName = null) {}
+    public function setNamedItemNS(\DOMNode $arg = null) {}
+    public function removeNamedItemNS($namespaceURI = null, $localName = null) {}
+    public function count() {}
+}
+
+class DOMNode {
+
+    // properties
+    public $attributes;
+    public $baseURI;
+    public $childNodes;
+    public $firstChild;
+    public $lastChild;
+    public $localName;
+    public $namespaceURI;
+    public $nextSibling;
+    public $nodeName;
+    public $nodeType;
+    public $nodeValue;
+    public $ownerDocument;
+    public $parentNode;
+    public $prefix;
+    public $previousSibling;
+    public $textContent;
+
+    // methods
+    public function insertBefore(\DOMNode $newChild, \DOMNode $refChild = null) {}
+    public function replaceChild(\DOMNode $newChild, \DOMNode $oldChild) {}
+    public function removeChild(\DOMNode $oldChild) {}
+    public function appendChild(\DOMNode $newChild) {}
+    public function hasChildNodes() {}
+    public function cloneNode($deep = null) {}
+    public function normalize() {}
+    public function isSupported($feature, $version) {}
+    public function hasAttributes() {}
+    public function compareDocumentPosition(\DOMNode $other) {}
+    public function isSameNode(\DOMNode $other) {}
+    public function lookupPrefix($namespaceURI) {}
+    public function isDefaultNamespace($namespaceURI) {}
+    public function lookupNamespaceUri($prefix) {}
+    public function isEqualNode(\DOMNode $arg) {}
+    public function getFeature($feature, $version) {}
+    public function setUserData($key, $data, $handler) {}
+    public function getUserData($key) {}
+    public function getNodePath() {}
+    public function getLineNo() {}
+    public function C14N($exclusive = null, $with_comments = null, array $xpath = null, array $ns_prefixes = null) {}
+    public function C14NFile($uri, $exclusive = null, $with_comments = null, array $xpath = null, array $ns_prefixes = null) {}
+}
+
+class DOMNodeList implements \Traversable, \Countable {
+
+    // properties
+    public $length;
+
+    // methods
+    public function item($index) {}
+    public function count() {}
+}
+
+class DOMNotation extends \DOMNode {
+
+    // properties
+    public $publicId;
+    public $systemId;
+}
+
+class DOMProcessingInstruction extends \DOMNode {
+
+    // properties
+    public $data;
+    public $target;
+
+    // methods
+    public function __construct($name, $value = null) {}
+}
+
+class DOMStringExtend {
+
+    // methods
+    public function findOffset16($offset32) {}
+    public function findOffset32($offset16) {}
+}
+
+class DOMStringList {
+
+    // methods
+    public function item($index) {}
+}
+
+class DOMText extends \DOMCharacterData {
+
+    // properties
+    public $wholeText;
+
+    // methods
+    public function splitText($offset) {}
+    public function isWhitespaceInElementContent() {}
+    public function isElementContentWhitespace() {}
+    public function replaceWholeText($content) {}
+    public function __construct($value = null) {}
+}
+
+class DOMTypeinfo {
+}
+
+class DOMUserDataHandler {
+
+    // methods
+    public function handle() {}
+}
+
+class DOMXPath {
+
+    // properties
+    public $document;
+
+    // methods
+    public function __construct(\DOMDocument $doc) {}
+    public function registerNamespace($prefix, $uri) {}
+    public function query($expr, \DOMNode $context = null, $registerNodeNS = null) {}
+    public function evaluate($expr, \DOMNode $context = null, $registerNodeNS = null) {}
+    public function registerPhpFunctions() {}
+}
+
+function dom_import_simplexml($node) {}
+const DOMSTRING_SIZE_ERR = 2;
+const DOM_HIERARCHY_REQUEST_ERR = 3;
+const DOM_INDEX_SIZE_ERR = 1;
+const DOM_INUSE_ATTRIBUTE_ERR = 10;
+const DOM_INVALID_ACCESS_ERR = 15;
+const DOM_INVALID_CHARACTER_ERR = 5;
+const DOM_INVALID_MODIFICATION_ERR = 13;
+const DOM_INVALID_STATE_ERR = 11;
+const DOM_NAMESPACE_ERR = 14;
+const DOM_NOT_FOUND_ERR = 8;
+const DOM_NOT_SUPPORTED_ERR = 9;
+const DOM_NO_DATA_ALLOWED_ERR = 6;
+const DOM_NO_MODIFICATION_ALLOWED_ERR = 7;
+const DOM_PHP_ERR = 0;
+const DOM_SYNTAX_ERR = 12;
+const DOM_VALIDATION_ERR = 16;
+const DOM_WRONG_DOCUMENT_ERR = 4;
+const XML_ATTRIBUTE_CDATA = 1;
+const XML_ATTRIBUTE_DECL_NODE = 16;
+const XML_ATTRIBUTE_ENTITY = 6;
+const XML_ATTRIBUTE_ENUMERATION = 9;
+const XML_ATTRIBUTE_ID = 2;
+const XML_ATTRIBUTE_IDREF = 3;
+const XML_ATTRIBUTE_IDREFS = 4;
+const XML_ATTRIBUTE_NMTOKEN = 7;
+const XML_ATTRIBUTE_NMTOKENS = 8;
+const XML_ATTRIBUTE_NODE = 2;
+const XML_ATTRIBUTE_NOTATION = 10;
+const XML_CDATA_SECTION_NODE = 4;
+const XML_COMMENT_NODE = 8;
+const XML_DOCUMENT_FRAG_NODE = 11;
+const XML_DOCUMENT_NODE = 9;
+const XML_DOCUMENT_TYPE_NODE = 10;
+const XML_DTD_NODE = 14;
+const XML_ELEMENT_DECL_NODE = 15;
+const XML_ELEMENT_NODE = 1;
+const XML_ENTITY_DECL_NODE = 17;
+const XML_ENTITY_NODE = 6;
+const XML_ENTITY_REF_NODE = 5;
+const XML_HTML_DOCUMENT_NODE = 13;
+const XML_LOCAL_NAMESPACE = 18;
+const XML_NAMESPACE_DECL_NODE = 18;
+const XML_NOTATION_NODE = 12;
+const XML_PI_NODE = 7;
+const XML_TEXT_NODE = 3;
+}
index ba1efb9..662a0e0 100644 (file)
@@ -40,6 +40,11 @@ class Mail {
         */
        public function send( $recipients, array $headers, $body ) {
        }
+       /**
+        * @return string
+        */
+       public function getMessage() {
+       }
 }
 
 class Mail_smtp extends Mail {
index 75eedcc..1599dce 100644 (file)
@@ -147,7 +147,7 @@ class FileDeleteForm {
         * Really delete the file
         *
         * @param Title &$title
-        * @param File &$file
+        * @param LocalFile &$file
         * @param string &$oldimage Archive name
         * @param string $reason Reason of the deletion
         * @param bool $suppress Whether to mark all deleted versions as restricted
@@ -167,7 +167,7 @@ class FileDeleteForm {
                if ( $oldimage ) {
                        $page = null;
                        $status = $file->deleteOld( $oldimage, $reason, $suppress, $user );
-                       if ( $status->ok ) {
+                       if ( $status->isOK() ) {
                                // Need to do a log item
                                $logComment = wfMessage( 'deletedrevision', $oldimage )->inContentLanguage()->text();
                                if ( trim( $reason ) != '' ) {
index c60b8c6..539758f 100644 (file)
 
 namespace MediaWiki\Navigation;
 
-use MediaWiki\Linker\LinkTarget;
-use MessageLocalizer;
 use Html;
+use MessageLocalizer;
+use Title;
 
 /**
  * Helper class for generating prev/next links for paging.
+ * @todo Use LinkTarget instead of Title
  *
  * @since 1.34
  */
@@ -36,6 +37,9 @@ class PrevNextNavigationRenderer {
         */
        private $messageLocalizer;
 
+       /**
+        * @param MessageLocalizer $messageLocalizer
+        */
        public function __construct( MessageLocalizer $messageLocalizer ) {
                $this->messageLocalizer = $messageLocalizer;
        }
@@ -43,15 +47,19 @@ class PrevNextNavigationRenderer {
        /**
         * Generate (prev x| next x) (20|50|100...) type links for paging
         *
-        * @param LinkTarget $title LinkTarget object to link
+        * @param Title $title Title object to link
         * @param int $offset
         * @param int $limit
         * @param array $query Optional URL query parameter string
         * @param bool $atend Optional param for specified if this is the last page
         * @return string
         */
-       public function buildPrevNextNavigation( LinkTarget $title, $offset, $limit,
-                                                                                        array $query = [], $atend = false
+       public function buildPrevNextNavigation(
+               Title $title,
+               $offset,
+               $limit,
+               array $query = [],
+               $atend = false
        ) {
                # Make 'previous' link
                $prev = $this->messageLocalizer->msg( 'prevn' )->title( $title )
@@ -76,6 +84,8 @@ class PrevNextNavigationRenderer {
 
                # Make links to set number of items per page
                $numLinks = [];
+               // @phan-suppress-next-next-line PhanUndeclaredMethod
+               // @fixme MessageLocalizer doesn't have a getLanguage() method!
                $lang = $this->messageLocalizer->getLanguage();
                foreach ( [ 20, 50, 100, 250, 500 ] as $num ) {
                        $numLinks[] = $this->numLink( $title, $offset, $num, $query,
@@ -89,7 +99,7 @@ class PrevNextNavigationRenderer {
        /**
         * Helper function for buildPrevNextNavigation() that generates links
         *
-        * @param LinkTarget $title LinkTarget object to link
+        * @param Title $title Title object to link
         * @param int $offset
         * @param int $limit
         * @param array $query Extra query parameters
@@ -98,7 +108,7 @@ class PrevNextNavigationRenderer {
         * @param string $class Value of the "class" attribute of the link
         * @return string HTML fragment
         */
-       private function numLink( LinkTarget $title, $offset, $limit, array $query, $link,
+       private function numLink( Title $title, $offset, $limit, array $query, $link,
                                                          $tooltipMsg, $class
        ) {
                $query = [ 'limit' => $limit, 'offset' => $offset ] + $query;
index 1703565..14639aa 100644 (file)
@@ -995,6 +995,8 @@ class OutputPage extends ContextSource {
         * @param Title $t
         */
        public function setTitle( Title $t ) {
+               // @phan-suppress-next-next-line PhanUndeclaredMethod
+               // @fixme Not all implementations of IContextSource have this method!
                $this->getContext()->setTitle( $t );
        }
 
index 85749c6..3718d66 100644 (file)
@@ -8,12 +8,14 @@ namespace MediaWiki\Rest;
  *
  * run() must be declared in the subclass. It cannot be declared as abstract
  * here because it has a variable parameter list.
+ * @todo Declare it as abstract after dropping HHVM
  *
  * @package MediaWiki\Rest
  */
 class SimpleHandler extends Handler {
        public function execute() {
                $params = array_values( $this->getRequest()->getPathParams() );
+               // @phan-suppress-next-line PhanUndeclaredMethod
                return $this->run( ...$params );
        }
 }
index e9136cb..8bb2c89 100644 (file)
@@ -37,6 +37,7 @@ use Wikimedia\Assert\Assert;
  *
  * @since 1.31
  * @since 1.32 Renamed from MediaWiki\Storage\MutableRevisionRecord
+ * @property MutableRevisionSlots $mSlots
  */
 class MutableRevisionRecord extends RevisionRecord {
 
@@ -78,8 +79,6 @@ class MutableRevisionRecord extends RevisionRecord {
                $slots = new MutableRevisionSlots();
 
                parent::__construct( $title, $slots, $dbDomain );
-
-               $this->mSlots = $slots; // redundant, but nice for static analysis
        }
 
        /**
index 7246238..fd555f6 100644 (file)
@@ -882,6 +882,7 @@ class PageUpdater {
                // TODO: introduce something like an UnsavedRevisionFactory service instead!
                /** @var MutableRevisionRecord $rev */
                $rev = $this->derivedDataUpdater->getRevision();
+               '@phan-var MutableRevisionRecord $rev';
 
                $rev->setPageId( $title->getArticleID() );
 
index f621e66..547b28c 100644 (file)
@@ -3212,6 +3212,7 @@ class Title implements LinkTarget, IDBAccessObject {
                //        splitTitleString method, but the only implementation (MediaWikiTitleCodec) does
                /** @var MediaWikiTitleCodec $titleCodec */
                $titleCodec = MediaWikiServices::getInstance()->getTitleParser();
+               '@phan-var MediaWikiTitleCodec $titleCodec';
                // MalformedTitleException can be thrown here
                $parts = $titleCodec->splitTitleString( $this->mDbkeyform, $this->mDefaultNamespace );
 
index f696985..895b5a7 100644 (file)
@@ -29,6 +29,8 @@ use Wikimedia\Rdbms\IResultWrapper;
 /**
  * The TitleArray class only exists to provide the newFromResult method at pre-
  * sent.
+ *
+ * @method int count()
  */
 abstract class TitleArray implements Iterator {
        /**
index 8a5d7c9..254f7a8 100644 (file)
@@ -118,7 +118,9 @@ class RevertAction extends FormAction {
                $this->useTransactionalTimeLimit();
 
                $old = $this->getRequest()->getText( 'oldimage' );
+               /** @var LocalFile $localFile */
                $localFile = $this->page->getFile();
+               '@phan-var LocalFile $localFile';
                $oldFile = OldLocalFile::newFromArchiveName( $this->getTitle(), $localFile->getRepo(), $old );
 
                $source = $localFile->getArchiveVirtualUrl( $old );
index 0e13d70..ad171c6 100644 (file)
@@ -42,6 +42,7 @@ class ApiDelete extends ApiBase {
                $pageObj = $this->getTitleOrPageId( $params, 'fromdbmaster' );
                $titleObj = $pageObj->getTitle();
                if ( !$pageObj->exists() &&
+                       // @phan-suppress-next-line PhanUndeclaredMethod
                        !( $titleObj->getNamespace() == NS_FILE && self::canDeleteFile( $pageObj->getFile() ) )
                ) {
                        $this->dieWithError( 'apierror-missingtitle' );
@@ -156,6 +157,7 @@ class ApiDelete extends ApiBase {
        ) {
                $title = $page->getTitle();
 
+               // @phan-suppress-next-line PhanUndeclaredMethod There's no right typehint for it
                $file = $page->getFile();
                if ( !self::canDeleteFile( $file ) ) {
                        return self::delete( $page, $user, $reason, $tags );
index 8049cd8..81ee9b9 100644 (file)
@@ -26,6 +26,7 @@
  * ApiResult.
  * @since 1.25
  * @ingroup API
+ * @phan-file-suppress PhanUndeclaredMethod Undeclared methods in IApiMessage
  */
 class ApiErrorFormatter {
        /** @var Title Dummy title to silence warnings from MessageCache::parse() */
index 851373d..1c7f63d 100644 (file)
@@ -104,8 +104,10 @@ class ApiExpandTemplates extends ApiBase {
                        $parser->startExternalParse( $titleObj, $options, Parser::OT_PREPROCESS );
                        $dom = $parser->preprocessToDom( $params['text'] );
                        if ( is_callable( [ $dom, 'saveXML' ] ) ) {
+                               // @phan-suppress-next-line PhanUndeclaredMethod
                                $xml = $dom->saveXML();
                        } else {
+                               // @phan-suppress-next-line PhanUndeclaredMethod
                                $xml = $dom->__toString();
                        }
                        if ( isset( $prop['parsetree'] ) ) {
index c4977f4..953c4d8 100644 (file)
@@ -150,6 +150,7 @@ class ApiFeedWatchlist extends ApiBase {
 
                        if ( $e instanceof ApiUsageException ) {
                                foreach ( $e->getStatusValue()->getErrors() as $error ) {
+                                       // @phan-suppress-next-line PhanUndeclaredMethod
                                        $msg = ApiMessage::create( $error )
                                                ->inLanguage( $this->getLanguage() );
                                        $errorTitle = $this->msg( 'api-feed-error-title', $msg->getApiCode() );
index ccb26a8..1f8b012 100644 (file)
@@ -104,6 +104,7 @@ class ApiImageRotate extends ApiBase {
                        $tmpFile = MediaWikiServices::getInstance()->getTempFSFileFactory()
                                ->newTempFSFile( 'rotate_', $ext );
                        $dstPath = $tmpFile->getPath();
+                       // @phan-suppress-next-line PhanUndeclaredMethod
                        $err = $handler->rotate( $file, [
                                'srcPath' => $srcPath,
                                'dstPath' => $dstPath,
@@ -113,6 +114,7 @@ class ApiImageRotate extends ApiBase {
                                $comment = wfMessage(
                                        'rotate-comment'
                                )->numParams( $rotation )->inContentLanguage()->text();
+                               // @phan-suppress-next-line PhanUndeclaredMethod
                                $status = $file->upload(
                                        $dstPath,
                                        $comment,
index 574d83b..efa4b04 100644 (file)
@@ -167,6 +167,7 @@ class ApiMain extends ApiBase {
         * @param IContextSource|WebRequest|null $context If this is an instance of
         *    FauxRequest, errors are thrown and no printing occurs
         * @param bool $enableWrite Should be set to true if the api may modify data
+        * @suppress PhanUndeclaredMethod
         */
        public function __construct( $context = null, $enableWrite = false ) {
                if ( $context === null ) {
index 147b3bd..528a8b5 100644 (file)
@@ -23,6 +23,7 @@
  * @since 1.27
  * @ingroup API
  * @phan-file-suppress PhanTraitParentReference
+ * @phan-file-suppress PhanUndeclaredMethod
  */
 trait ApiMessageTrait {
 
index 0ba4a0e..7fcb818 100644 (file)
@@ -71,6 +71,7 @@ class ApiOpenSearch extends ApiBase {
 
                        case 'xml':
                                $printer = $this->getMain()->createPrinterByName( 'xml' . $this->fm );
+                               '@phan-var ApiFormatXML $printer';
                                $printer->setRootElement( 'SearchSuggestion' );
                                return $printer;
 
@@ -112,7 +113,7 @@ class ApiOpenSearch extends ApiBase {
         * @param string $search the search query
         * @param array $params api request params
         * @return array search results. Keys are integers.
-        * @phan-return array<array{title:Title,extract:false,image:false,url:string}>
+        * @phan-return array<array{title:Title,redirect_from:?Title,extract:false,extract_trimmed:false,image:false,url:string}>
         *  Note that phan annotations don't support keys containing a space.
         */
        private function search( $search, array $params ) {
index a7390e6..40edafa 100644 (file)
@@ -491,6 +491,7 @@ class ApiParse extends ApiBase {
 
                        $parser = MediaWikiServices::getInstance()->getParser();
                        $parser->startExternalParse( $titleObj, $popts, Parser::OT_PREPROCESS );
+                       // @phan-suppress-next-line PhanUndeclaredMethod
                        $xml = $parser->preprocessToDom( $this->content->getText() )->__toString();
                        $result_array['parsetree'] = $xml;
                        $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'parsetree';
index bdb0dc2..c78e445 100644 (file)
@@ -223,7 +223,9 @@ class ApiQuery extends ApiBase {
                // Filter modules based on continue parameter
                $continuationManager = new ApiContinuationManager( $this, $allModules, $propModules );
                $this->setContinuationManager( $continuationManager );
+               /** @var ApiQueryBase[] $modules */
                $modules = $continuationManager->getRunModules();
+               '@phan-var ApiQueryBase[] $modules';
 
                if ( !$continuationManager->isGeneratorDone() ) {
                        // Query modules may optimize data requests through the $this->getPageSet()
@@ -242,7 +244,6 @@ class ApiQuery extends ApiBase {
                $cacheMode = $this->mPageSet->getCacheMode();
 
                // Execute all unfinished modules
-               /** @var ApiQueryBase $module */
                foreach ( $modules as $module ) {
                        $params = $module->extractRequestParams();
                        $cacheMode = $this->mergeCacheMode(
index c5a8d08..f9da9a3 100644 (file)
@@ -305,6 +305,8 @@ class ApiQueryBlocks extends ApiQueryBase {
                        $id = $restriction->getBlockId();
                        switch ( $restriction->getType() ) {
                                case 'page':
+                                       /** @var \MediaWiki\Block\Restriction\PageRestriction $restriction */
+                                       '@phan-var \MediaWiki\Block\Restriction\PageRestriction $restriction';
                                        $value = [ 'id' => $restriction->getValue() ];
                                        if ( $restriction->getTitle() ) {
                                                self::addTitleInfo( $value, $restriction->getTitle() );
index 5e737c3..97a9b0a 100644 (file)
@@ -523,6 +523,8 @@ class ApiQueryImageInfo extends ApiQueryBase {
                                                        $vals['thumbmime'] = $mime;
                                                }
                                        } elseif ( $mto && $mto->isError() ) {
+                                               /** @var MediaTransformError $mto */
+                                               '@phan-var MediaTransformError $mto';
                                                $vals['thumberror'] = $mto->toText();
                                        }
                                }
@@ -562,6 +564,7 @@ class ApiQueryImageInfo extends ApiQueryBase {
                        // Thus there should be no issue with format=xml.
                        $format = new FormatMetadata;
                        $format->setSingleLanguage( !$opts['multilang'] );
+                       // @phan-suppress-next-line PhanUndeclaredMethod
                        $format->getContext()->setLanguage( $opts['language'] );
                        $extmetaArray = $format->fetchExtendedMetadata( $file );
                        if ( $opts['extmetadatafilter'] ) {
@@ -581,6 +584,8 @@ class ApiQueryImageInfo extends ApiQueryBase {
                }
 
                if ( $archive && $file->isOld() ) {
+                       /** @var OldLocalFile $file */
+                       '@phan-var OldLocalFile $file';
                        $vals['archivename'] = $file->getArchiveName();
                }
 
index 0d284c0..7c92b35 100644 (file)
@@ -501,6 +501,8 @@ abstract class ApiQueryRevisionsBase extends ApiQueryGeneratorBase {
 
                if ( $this->fld_parsetree || ( $this->fld_content && $this->generateXML ) ) {
                        if ( $content->getModel() === CONTENT_MODEL_WIKITEXT ) {
+                               /** @var WikitextContent $content */
+                               '@phan-var WikitextContent $content';
                                $t = $content->getText(); # note: don't set $text
 
                                $parser = MediaWikiServices::getInstance()->getParser();
@@ -511,8 +513,10 @@ abstract class ApiQueryRevisionsBase extends ApiQueryGeneratorBase {
                                );
                                $dom = $parser->preprocessToDom( $t );
                                if ( is_callable( [ $dom, 'saveXML' ] ) ) {
+                                       // @phan-suppress-next-line PhanUndeclaredMethod
                                        $xml = $dom->saveXML();
                                } else {
+                                       // @phan-suppress-next-line PhanUndeclaredMethod
                                        $xml = $dom->__toString();
                                }
                                $vals['parsetree'] = $xml;
@@ -534,6 +538,8 @@ abstract class ApiQueryRevisionsBase extends ApiQueryGeneratorBase {
 
                        if ( $this->expandTemplates && !$this->parseContent ) {
                                if ( $content->getModel() === CONTENT_MODEL_WIKITEXT ) {
+                                       /** @var WikitextContent $content */
+                                       '@phan-var WikitextContent $content';
                                        $text = $content->getText();
 
                                        $text = MediaWikiServices::getInstance()->getParser()->preprocess(
index 06060b1..39bcbf3 100644 (file)
@@ -43,6 +43,7 @@ class RememberMeAuthenticationRequest extends AuthenticationRequest {
        public function __construct() {
                /** @var SessionProvider $provider */
                $provider = SessionManager::getGlobalSession()->getProvider();
+               '@phan-var SessionProvider $provider';
                $this->expiration = $provider->getRememberUserDuration();
        }
 
index 83b59c7..e27ebac 100644 (file)
@@ -223,6 +223,8 @@ class BlockManager {
                        if ( $block instanceof SystemBlock ) {
                                $systemBlocks[] = $block;
                        } elseif ( $block->getType() === DatabaseBlock::TYPE_AUTO ) {
+                               /** @var DatabaseBlock $block */
+                               '@phan-var DatabaseBlock $block';
                                if ( !isset( $databaseBlocks[$block->getParentBlockId()] ) ) {
                                        $databaseBlocks[$block->getParentBlockId()] = $block;
                                }
index 45aab46..78d6722 100644 (file)
@@ -87,7 +87,9 @@ class PageRestriction extends AbstractRestriction {
         * @inheritDoc
         */
        public static function newFromRow( \stdClass $row ) {
+               /** @var self $restriction */
                $restriction = parent::newFromRow( $row );
+               '@phan-var self $restriction';
 
                // If the page_namespace and the page_title were provided, add the title to
                // the restriction.
index d717fe7..5dddd78 100644 (file)
@@ -70,7 +70,7 @@ interface Restriction {
         *
         * @since 1.33
         * @param \stdClass $row
-        * @return self
+        * @return static
         */
        public static function newFromRow( \stdClass $row );
 
index 4401378..59f59d1 100644 (file)
@@ -8,6 +8,7 @@ use Wikimedia\Rdbms\IDatabase;
  * but 'Bot' is unchecked, hidebots=1 will be sent.
  *
  * @since 1.29
+ * @method ChangesListBooleanFilter[] getFilters()
  */
 class ChangesListBooleanFilterGroup extends ChangesListFilterGroup {
        /**
@@ -55,6 +56,7 @@ class ChangesListBooleanFilterGroup extends ChangesListFilterGroup {
         * Registers a filter in this group
         *
         * @param ChangesListBooleanFilter $filter
+        * @suppress PhanParamSignaturePHPDocMismatchHasParamType,PhanParamSignatureMismatch
         */
        public function registerFilter( ChangesListBooleanFilter $filter ) {
                $this->filters[$filter->getName()] = $filter;
index ec86307..5f0cd22 100644 (file)
@@ -32,6 +32,7 @@ use Wikimedia\Rdbms\IDatabase;
  * Represents a filter group (used on ChangesListSpecialPage and descendants)
  *
  * @since 1.29
+ * @method registerFilter($filter)
  */
 abstract class ChangesListFilterGroup {
        /**
index e06f081..b18ae61 100644 (file)
@@ -155,6 +155,7 @@ class ChangesListStringOptionsFilterGroup extends ChangesListFilterGroup {
         * Registers a filter in this group
         *
         * @param ChangesListStringOptionsFilter $filter
+        * @suppress PhanParamSignaturePHPDocMismatchHasParamType,PhanParamSignatureMismatch
         */
        public function registerFilter( ChangesListStringOptionsFilter $filter ) {
                $this->filters[$filter->getName()] = $filter;
index 89f8f76..fc53d13 100644 (file)
 
 /**
  * Generic list for change tagging.
+ *
+ * @property ChangeTagsLogItem $current
+ * @method ChangeTagsLogItem next()
+ * @method ChangeTagsLogItem reset()
+ * @method ChangeTagsLogItem current()
+ * @phan-file-suppress PhanParamSignatureMismatch
  */
 abstract class ChangeTagsList extends RevisionListBase {
        function __construct( IContextSource $context, Title $title, array $ids ) {
index 71dd35c..54a57a5 100644 (file)
@@ -155,7 +155,9 @@ class TextContent extends AbstractContent {
         * @return string|bool The raw text, or false if the conversion failed.
         */
        public function getWikitextForTransclusion() {
+               /** @var WikitextContent $wikitext */
                $wikitext = $this->convert( CONTENT_MODEL_WIKITEXT, 'lossy' );
+               '@phan-var WikitextContent $wikitext';
 
                if ( $wikitext ) {
                        return $wikitext->getText();
@@ -214,7 +216,8 @@ class TextContent extends AbstractContent {
         */
        public function diff( Content $that, Language $lang = null ) {
                $this->checkModelID( $that->getModel() );
-
+               /** @var self $that */
+               '@phan-var self $that';
                // @todo could implement this in DifferenceEngine and just delegate here?
 
                if ( !$lang ) {
index e3dc187..e48dd51 100644 (file)
@@ -45,6 +45,7 @@ class TextContentHandler extends ContentHandler {
        public function serializeContent( Content $content, $format = null ) {
                $this->checkFormat( $format );
 
+               // @phan-suppress-next-line PhanUndeclaredMethod
                return $content->getText();
        }
 
index 1427e2b..a5be21c 100644 (file)
@@ -68,6 +68,7 @@ class UnknownContentHandler extends ContentHandler {
         */
        public function serializeContent( Content $content, $format = null ) {
                /** @var UnknownContent $content */
+               '@phan-var UnknownContent $content';
                return $content->getData();
        }
 
index 70b638b..a760a1b 100644 (file)
@@ -89,6 +89,8 @@ class WikitextContent extends TextContent {
                                "document uses $myModelId but " .
                                "section uses $sectionModelId." );
                }
+               /** @var self $with $oldtext */
+               '@phan-var self $with';
 
                $oldtext = $this->getText();
                $text = $with->getText();
index 3380364..3716971 100644 (file)
@@ -161,6 +161,7 @@ class DeferredUpdates {
                        if ( isset( $queue[$class] ) ) {
                                /** @var MergeableUpdate $existingUpdate */
                                $existingUpdate = $queue[$class];
+                               '@phan-var MergeableUpdate $existingUpdate';
                                $existingUpdate->merge( $update );
                                // Move the update to the end to handle things like mergeable purge
                                // updates that might depend on the prior updates in the queue running
index 935172a..ef8058c 100644 (file)
@@ -67,6 +67,7 @@ class TextSlotDiffRenderer extends SlotDiffRenderer {
                /** @var TextSlotDiffRenderer $slotDiffRenderer */
                $slotDiffRenderer = ContentHandler::getForModelID( CONTENT_MODEL_TEXT )
                        ->getSlotDiffRenderer( RequestContext::getMain() );
+               '@phan-var TextSlotDiffRenderer $slotDiffRenderer';
                return $slotDiffRenderer->getTextDiff( $oldText, $newText );
        }
 
index 3ab88e2..ec0b344 100644 (file)
@@ -30,7 +30,6 @@
 use MediaWiki\MediaWikiServices as MediaWikiServicesAlias;
 use MediaWiki\Storage\RevisionRecord;
 use Wikimedia\Rdbms\IResultWrapper;
-use Wikimedia\Rdbms\IDatabase;
 
 /**
  * @ingroup SpecialPage Dump
@@ -68,7 +67,7 @@ class WikiExporter {
        /** @var XmlDumpWriter */
        private $writer;
 
-       /** @var IDatabase */
+       /** @var Database */
        protected $db;
 
        /** @var array|int */
@@ -87,7 +86,7 @@ class WikiExporter {
        }
 
        /**
-        * @param IDatabase $db
+        * @param Database $db
         * @param int|array $history One of WikiExporter::FULL, WikiExporter::CURRENT,
         *   WikiExporter::RANGE or WikiExporter::STABLE, or an associative array:
         *   - offset: non-inclusive offset at which to start the query
index 0003506..e697ef2 100644 (file)
@@ -658,6 +658,8 @@ class XmlDumpWriter {
         */
        function writeUpload( $file, $dumpContents = false ) {
                if ( $file->isOld() ) {
+                       /** @var OldLocalFile $file */
+                       '@phan-var OldLocalFile $file';
                        $archiveName = "      " .
                                Xml::element( 'archivename', null, $file->getArchiveName() ) . "\n";
                } else {
index d14e0de..0d5776b 100644 (file)
@@ -1172,6 +1172,7 @@ abstract class File implements IDBAccessObject {
                        $thumb = false;
                } elseif ( $thumb->isError() ) { // transform error
                        /** @var MediaTransformError $thumb */
+                       '@phan-var MediaTransformError $thumb';
                        $this->lastError = $thumb->toText();
                        // Ignore errors if requested
                        if ( $wgIgnoreImageErrors && !( $flags & self::RENDER_NOW ) ) {
index 0ef6034..4751a59 100644 (file)
@@ -1868,6 +1868,7 @@ class LocalFile extends File {
                                : FSFile::getSha1Base36FromPath( $srcPath );
                        /** @var FileBackendDBRepoWrapper $wrapperBackend */
                        $wrapperBackend = $repo->getBackend();
+                       '@phan-var FileBackendDBRepoWrapper $wrapperBackend';
                        $dst = $wrapperBackend->getPathForSHA1( $sha1 );
                        $status = $repo->quickImport( $src, $dst );
                        if ( $flags & File::DELETE_SOURCE ) {
@@ -1937,6 +1938,7 @@ class LocalFile extends File {
                                        $oldTitleFile->purgeEverything();
                                        foreach ( $archiveNames as $archiveName ) {
                                                /** @var OldLocalFile $oldTitleFile */
+                                               '@phan-var OldLocalFile $oldTitleFile';
                                                $oldTitleFile->purgeOldThumbnails( $archiveName );
                                        }
                                        $newTitleFile->purgeEverything();
index 21980b9..137119d 100644 (file)
@@ -126,8 +126,10 @@ class LocalFileMoveBatch {
        public function execute() {
                $repo = $this->file->repo;
                $status = $repo->newGood();
+               /** @var LocalFile $destFile */
                $destFile = MediaWikiServices::getInstance()->getRepoGroup()->getLocalRepo()
                        ->newFile( $this->target );
+               '@phan-var LocalFile $destFile';
 
                $this->file->lock();
                $destFile->lock(); // quickly fail if destination is not available
index b77c17e..1e4460a 100644 (file)
@@ -5,6 +5,7 @@
  * (defined in htmlform.Element.js) picks up the extra config when constructed using OO.ui.infuse().
  *
  * Currently only supports passing 'hide-if' data.
+ * @phan-file-suppress PhanUndeclaredMethod
  */
 trait HTMLFormElement {
 
index 3a2f982..3885c03 100644 (file)
@@ -373,7 +373,7 @@ abstract class MWHttpRequest implements LoggerAwareInterface {
        /**
         * Take care of whatever is necessary to perform the URI request.
         *
-        * @return StatusValue
+        * @return Status
         * @note currently returns Status for B/C
         */
        public function execute() {
index 4be13b0..e5f4b57 100644 (file)
@@ -114,6 +114,7 @@ class ImportableUploadRevisionImporter implements UploadRevisionImporter {
                                $user
                        );
                } else {
+                       '@phan-var LocalFile $file';
                        $flags = 0;
                        $status = $file->upload(
                                $source,
index 8b94d97..ac8c9e6 100644 (file)
@@ -177,6 +177,7 @@ abstract class DatabaseInstaller {
         * This will return a cached connection if one is available.
         *
         * @return Status
+        * @suppress PhanUndeclaredMethod
         */
        public function getConnection() {
                if ( $this->db ) {
@@ -341,6 +342,7 @@ abstract class DatabaseInstaller {
        public function setupSchemaVars() {
                $status = $this->getConnection();
                if ( $status->isOK() ) {
+                       // @phan-suppress-next-line PhanUndeclaredMethod
                        $status->value->setSchemaVars( $this->getSchemaVars() );
                } else {
                        $msg = __METHOD__ . ': unexpected error while establishing'
index 8a9cd05..e1df844 100644 (file)
@@ -1233,6 +1233,7 @@ abstract class DatabaseUpdater {
                $cl = $this->maintenance->runChild(
                        RebuildLocalisationCache::class, 'rebuildLocalisationCache.php'
                );
+               '@phan-var RebuildLocalisationCache $cl';
                $this->output( "Rebuilding localisation cache...\n" );
                $cl->setForce();
                $cl->execute();
@@ -1292,6 +1293,7 @@ abstract class DatabaseUpdater {
                        $task = $this->maintenance->runChild(
                                MigrateImageCommentTemp::class, 'migrateImageCommentTemp.php'
                        );
+                       // @phan-suppress-next-line PhanUndeclaredMethod
                        $task->setForce();
                        $ok = $task->execute();
                        $this->output( $ok ? "done.\n" : "errors were encountered.\n" );
@@ -1329,6 +1331,7 @@ abstract class DatabaseUpdater {
                if ( $this->db->fieldExists( 'archive', 'ar_text', __METHOD__ ) ) {
                        $this->output( "Migrating archive ar_text to modern storage.\n" );
                        $task = $this->maintenance->runChild( MigrateArchiveText::class, 'migrateArchiveText.php' );
+                       // @phan-suppress-next-line PhanUndeclaredMethod
                        $task->setForce();
                        if ( $task->execute() ) {
                                $this->applyPatch( 'patch-drop-ar_text.sql', false,
index 289a721..ccc548b 100644 (file)
@@ -731,6 +731,7 @@ abstract class Installer {
                if ( !$status->isOK() ) {
                        return $status;
                }
+               // @phan-suppress-next-line PhanUndeclaredMethod
                $status->value->insert(
                        'site_stats',
                        [
index 69d03bd..383f8d8 100644 (file)
@@ -131,6 +131,7 @@ class MysqlInstaller extends DatabaseInstaller {
                 * @var Database $conn
                 */
                $conn = $status->value;
+               '@phan-var Database $conn';
 
                // Check version
                return static::meetsMinimumRequirement( $conn->getServerVersion() );
index c33d3dd..0d516b4 100644 (file)
@@ -29,6 +29,7 @@ use MediaWiki\MediaWikiServices;
  *
  * @ingroup Deployment
  * @since 1.17
+ * @property DatabaseMysqlBase $db
  */
 class MysqlUpdater extends DatabaseUpdater {
        protected function getCoreUpdateList() {
index d6a5145..9a3d4a3 100644 (file)
@@ -353,6 +353,7 @@ class PostgresInstaller extends DatabaseInstaller {
                        if ( !$status->isOK() ) {
                                return $status;
                        }
+                       // @phan-suppress-next-line PhanUndeclaredMethod
                        $exists = $status->value->roleExists( $this->getVar( 'wgDBuser' ) );
                }
 
@@ -507,6 +508,7 @@ class PostgresInstaller extends DatabaseInstaller {
                }
                /** @var DatabasePostgres $conn */
                $conn = $status->value;
+               '@phan-var DatabasePostgres $conn';
 
                // Create the schema if necessary
                $schema = $this->getVar( 'wgDBmwschema' );
@@ -542,7 +544,9 @@ class PostgresInstaller extends DatabaseInstaller {
                if ( !$status->isOK() ) {
                        return $status;
                }
+               /** @var DatabasePostgres $conn */
                $conn = $status->value;
+               '@phan-var DatabasePostgres $conn';
 
                $safeuser = $conn->addIdentifierQuotes( $this->getVar( 'wgDBuser' ) );
                $safepass = $conn->addQuotes( $this->getVar( 'wgDBpassword' ) );
@@ -599,6 +603,7 @@ class PostgresInstaller extends DatabaseInstaller {
 
                /** @var DatabasePostgres $conn */
                $conn = $status->value;
+               '@phan-var DatabasePostgres $conn';
 
                if ( $conn->tableExists( 'archive' ) ) {
                        $status->warning( 'config-install-tables-exist' );
index db26c0b..b6e90a9 100644 (file)
@@ -188,7 +188,9 @@ class WebInstaller extends Installer {
 
                # Special case for Creative Commons partner chooser box.
                if ( $this->request->getVal( 'SubmitCC' ) ) {
+                       /** @var WebInstallerOptions $page */
                        $page = $this->getPageByName( 'Options' );
+                       '@phan-var WebInstallerOptions $page';
                        $this->output->useShortHeader();
                        $this->output->allowFrames();
                        $page->submitCC();
@@ -197,7 +199,9 @@ class WebInstaller extends Installer {
                }
 
                if ( $this->request->getVal( 'ShowCC' ) ) {
+                       /** @var WebInstallerOptions $page */
                        $page = $this->getPageByName( 'Options' );
+                       '@phan-var WebInstallerOptions $page';
                        $this->output->useShortHeader();
                        $this->output->allowFrames();
                        $this->output->addHTML( $page->getCCDoneBox() );
index 991e484..51d4250 100644 (file)
@@ -168,6 +168,7 @@ class WebInstallerOutput {
                foreach ( $moduleNames as $moduleName ) {
                        /** @var ResourceLoaderFileModule $module */
                        $module = $resourceLoader->getModule( $moduleName );
+                       '@phan-var ResourceLoaderFileModule $module';
                        if ( !$module ) {
                                // T98043: Don't fatal, but it won't look as pretty.
                                continue;
index dc75541..9edaccc 100644 (file)
@@ -120,6 +120,7 @@ class ImageHistoryList extends ContextSource {
                $lang = $this->getLanguage();
                $pm = MediaWikiServices::getInstance()->getPermissionManager();
                $timestamp = wfTimestamp( TS_MW, $file->getTimestamp() );
+               // @phan-suppress-next-line PhanUndeclaredMethod
                $img = $iscur ? $file->getName() : $file->getArchiveName();
                $userId = $file->getUser( 'id' );
                $userText = $file->getUser( 'text' );
index d3f0638..2f6d4da 100644 (file)
@@ -29,6 +29,7 @@ use Wikimedia\Rdbms\ResultWrapper;
  * @ingroup Media
  *
  * @property WikiFilePage $mPage Set by overwritten newPage() in this class
+ * @method WikiFilePage getPage()
  */
 class ImagePage extends Article {
        /** @var File|false */
index 2cb1fc0..52b2719 100644 (file)
 
 /**
  * Interface for type hinting (accepts WikiPage, Article, ImagePage, CategoryPage)
+ *
+ * @method array getActionOverrides()
+ * @method string getUserText($audience=1,User $user=null)
+ * @method string getTimestamp()
+ * @method Title getTitle()
  */
 interface Page {
 }
index 327dd77..d4f66f7 100644 (file)
@@ -21,6 +21,7 @@
 
 /**
  * @ingroup Parser
+ * @property string[] $out
  */
 // phpcs:ignore Squiz.Classes.ValidClassName.NotCamelCaps
 class PPDPart_Hash extends PPDPart {
index adc0bc0..68f1bb2 100644 (file)
  * @ingroup Parser
  */
 class PPDStack {
-       public $stack, $rootAccum;
+       /** @var PPDStackElement[] */
+       public $stack;
+       public $rootAccum;
 
        /**
-        * @var PPDStack|false
+        * @var PPDStackElement|false
         */
        public $top;
        public $out;
index 816548c..750049d 100644 (file)
@@ -21,6 +21,7 @@
 
 /**
  * @ingroup Parser
+ * @property PPDPart_Hash[] $parts
  */
 // phpcs:ignore Squiz.Classes.ValidClassName.NotCamelCaps
 class PPDStackElement_Hash extends PPDStackElement {
@@ -39,7 +40,6 @@ class PPDStackElement_Hash extends PPDStackElement {
         */
        public function breakSyntax( $openingCount = false ) {
                if ( $this->open == "\n" ) {
-                       // @phan-suppress-next-line PhanTypeMismatchArgumentInternal
                        $accum = array_merge( [ $this->savedPrefix ], $this->parts[0]->out );
                } else {
                        if ( $openingCount === false ) {
@@ -61,7 +61,7 @@ class PPDStackElement_Hash extends PPDStackElement {
                                } else {
                                        $accum[++$lastIndex] = '|';
                                }
-                               // @phan-suppress-next-line PhanTypeMismatchForeach
+
                                foreach ( $part->out as $node ) {
                                        if ( is_string( $node ) && is_string( $accum[$lastIndex] ) ) {
                                                $accum[$lastIndex] .= $node;
index 00bfe98..ac3a266 100644 (file)
@@ -23,6 +23,7 @@
  * An expansion frame, used as a context to expand the result of preprocessToObj()
  * @deprecated since 1.34, use PPFrame_Hash
  * @ingroup Parser
+ * @phan-file-suppress PhanUndeclaredMethod
  */
 // phpcs:ignore Squiz.Classes.ValidClassName.NotCamelCaps
 class PPFrame_DOM implements PPFrame {
index 53b1761..ae7f8a2 100644 (file)
@@ -22,6 +22,7 @@
 /**
  * @deprecated since 1.34, use PPNode_Hash_{Tree,Text,Array,Attr}
  * @ingroup Parser
+ * @phan-file-suppress PhanUndeclaredMethod
  */
 // phpcs:ignore Squiz.Classes.ValidClassName.NotCamelCaps
 class PPNode_DOM implements PPNode {
index 962313e..5c55124 100644 (file)
@@ -6192,7 +6192,9 @@ class Parser {
         */
        private static function normalizeSectionName( $text ) {
                # T90902: ensure the same normalization is applied for IDs as to links
+               /** @var MediaWikiTitleCodec $titleParser */
                $titleParser = MediaWikiServices::getInstance()->getTitleParser();
+               '@phan-var MediaWikiTitleCodec $titleParser';
                try {
 
                        $parts = $titleParser->splitTitleString( "#$text" );
index f7f37ac..9f4b7c7 100644 (file)
@@ -628,7 +628,9 @@ class Preprocessor_Hash extends Preprocessor {
                                }
                                $i += $count;
                        } elseif ( $found == 'close' ) {
+                               /** @var PPDStackElement_Hash $piece */
                                $piece = $stack->top;
+                               '@phan-var PPDStackElement_Hash $piece';
                                # lets check if there are enough characters for closing brace
                                $maxCount = $piece->count;
                                if ( $piece->close === '}-' && $curChar === '}' ) {
index f3d8d03..389b8c3 100644 (file)
@@ -59,6 +59,7 @@ class LayeredParameterizedPassword extends ParameterizedPassword {
                        // Construct pseudo-hash based on params and arguments
                        /** @var ParameterizedPassword $passObj */
                        $passObj = $this->factory->newFromType( $type );
+                       '@phan-var ParameterizedPassword $passObj';
 
                        $params = '';
                        $args = '';
@@ -72,6 +73,7 @@ class LayeredParameterizedPassword extends ParameterizedPassword {
 
                        // Hash the last hash with the next type in the layer
                        $passObj = $this->factory->newFromCiphertext( $existingHash );
+                       '@phan-var ParameterizedPassword $passObj';
                        $passObj->crypt( $lastHash );
 
                        // Move over the params and args
@@ -114,6 +116,7 @@ class LayeredParameterizedPassword extends ParameterizedPassword {
                        // Construct pseudo-hash based on params and arguments
                        /** @var ParameterizedPassword $passObj */
                        $passObj = $this->factory->newFromType( $type );
+                       '@phan-var ParameterizedPassword $passObj';
 
                        $params = '';
                        $args = '';
@@ -127,6 +130,7 @@ class LayeredParameterizedPassword extends ParameterizedPassword {
 
                        // Hash the last hash with the next type in the layer
                        $passObj = $this->factory->newFromCiphertext( $existingHash );
+                       '@phan-var ParameterizedPassword $passObj';
                        $passObj->crypt( $lastHash );
 
                        // Move over the params and args
index f5fa4c7..c89dc15 100644 (file)
@@ -152,7 +152,9 @@ class PoolCounterRedis extends PoolCounter {
                if ( !$status->isOK() ) {
                        return $status;
                }
+               /** @var RedisConnRef $conn */
                $conn = $status->value;
+               '@phan-var RedisConnRef $conn';
 
                // phpcs:disable Generic.Files.LineLength
                static $script =
@@ -238,7 +240,9 @@ LUA;
                if ( !$status->isOK() ) {
                        return $status;
                }
+               /** @var RedisConnRef $conn */
                $conn = $status->value;
+               '@phan-var RedisConnRef $conn';
 
                $now = microtime( true );
                try {
index c672b7b..8a82add 100644 (file)
@@ -1688,11 +1688,15 @@ class DefaultPreferencesFactory implements PreferencesFactory {
         * Save the form data and reload the page
         *
         * @param array $formData
-        * @param HTMLForm $form
+        * @param PreferencesFormOOUI $form
         * @param array $formDescriptor
         * @return Status
         */
-       protected function submitForm( array $formData, HTMLForm $form, array $formDescriptor ) {
+       protected function submitForm(
+               array $formData,
+               PreferencesFormOOUI $form,
+               array $formDescriptor
+       ) {
                $res = $this->saveFormData( $formData, $form, $formDescriptor );
 
                if ( $res === true ) {
index 09f5688..64a504a 100644 (file)
@@ -26,6 +26,7 @@
  * @ingroup Profiler
  *
  * @since 1.25
+ * @property ProfilerXhprof $collector
  */
 class ProfilerOutputDump extends ProfilerOutput {
 
index ab9830f..5b03ad0 100644 (file)
@@ -23,10 +23,11 @@ use MediaWiki\Storage\RevisionRecord;
 
 /**
  * Item class for a filearchive table row
+ *
+ * @property ArchivedFile $file
+ * @property RevDelArchivedFileList $list
  */
 class RevDelArchivedFileItem extends RevDelFileItem {
-       /** @var RevDelArchivedFileList $list */
-       /** @var ArchivedFile $file */
        /** @var LocalFile */
        protected $lockFile;
 
index ca7bc04..334dccf 100644 (file)
@@ -110,8 +110,10 @@ class RevDelFileList extends RevDelList {
        }
 
        public function doPostCommitUpdates( array $visibilityChangeMap ) {
+               /** @var LocalFile $file */
                $file = MediaWikiServices::getInstance()->getRepoGroup()->getLocalRepo()
                        ->newFile( $this->title );
+               '@phan-var LocalFile $file';
                $file->purgeCache();
                $file->purgeDescription();
 
index dc43aed..74dd7bc 100644 (file)
@@ -27,6 +27,12 @@ use MediaWiki\Storage\RevisionRecord;
  * needs to be able to make a query from a set of identifiers to pull
  * relevant rows, to return RevDelItem subclasses wrapping them, and
  * to wrap bulk update operations.
+ *
+ * @property RevDelItem $current
+ * @method RevDelItem next()
+ * @method RevDelItem reset()
+ * @method RevDelItem current()
+ * @phan-file-suppress PhanParamSignatureMismatch
  */
 abstract class RevDelList extends RevisionListBase {
        function __construct( IContextSource $context, Title $title, array $ids ) {
index a5859e5..f61d378 100644 (file)
@@ -23,6 +23,8 @@ use MediaWiki\Storage\RevisionRecord;
 
 /**
  * Item class for a live revision table row
+ *
+ * @property RevDelRevisionList $list
  */
 class RevDelRevisionItem extends RevDelItem {
        /** @var Revision */
index f36a7b5..7361265 100644 (file)
@@ -7,6 +7,7 @@
  * This trait can be used directly by extensions providing a SearchEngine.
  *
  * @ingroup Search
+ * @phan-file-suppress PhanUndeclaredMethod
  */
 trait SearchResultSetTrait {
        /**
index 64c2b84..a0b024e 100644 (file)
@@ -54,7 +54,7 @@ class PHPSessionHandler implements \SessionHandlerInterface {
        /** @var array Track original session fields for later modification check */
        protected $sessionFieldCache = [];
 
-       protected function __construct( SessionManagerInterface $manager ) {
+       protected function __construct( SessionManager $manager ) {
                $this->setEnableFlags(
                        \RequestContext::getMain()->getConfig()->get( 'PHPSessionHandling' )
                );
@@ -106,9 +106,9 @@ class PHPSessionHandler implements \SessionHandlerInterface {
 
        /**
         * Install a session handler for the current web request
-        * @param SessionManagerInterface $manager
+        * @param SessionManager $manager
         */
-       public static function install( SessionManagerInterface $manager ) {
+       public static function install( SessionManager $manager ) {
                if ( self::$instance ) {
                        $manager->setupPHPSessionHandler( self::$instance );
                        return;
index a7bbcce..882eb39 100644 (file)
@@ -156,6 +156,7 @@ class SessionInfo {
                        $this->idIsSafe = $data['idIsSafe'];
                        $this->forceUse = $data['forceUse'] && $this->provider;
                } else {
+                       // @phan-suppress-next-line PhanUndeclaredMethod
                        $this->id = $this->provider->getManager()->generateSessionId();
                        $this->idIsSafe = true;
                        $this->forceUse = false;
index fc117a8..fcc428d 100644 (file)
@@ -86,8 +86,7 @@ final class SessionManager implements SessionManagerInterface {
 
        /**
         * Get the global SessionManager
-        * @return SessionManagerInterface
-        *  (really a SessionManager, but this is to make IDEs less confused)
+        * @return self
         */
        public static function singleton() {
                if ( self::$instance === null ) {
index 3e8972c..70df73b 100644 (file)
@@ -376,6 +376,7 @@ class SkinTemplate extends Skin {
                                        /** @var CreditsAction $action */
                                        $action = Action::factory(
                                                'credits', $this->getWikiPage(), $this->getContext() );
+                                       '@phan-var CreditsAction $action';
                                        $tpl->set( 'credits',
                                                $action->getCredits( $wgMaxCredits, $wgShowCreditsIfMax ) );
                                } else {
index 62818a1..ce80c1a 100644 (file)
@@ -760,6 +760,7 @@ abstract class LoginSignupSpecialPage extends AuthManagerSpecialPage {
                $isLoggedIn = $this->getUser()->isLoggedIn();
                $continuePart = $this->isContinued() ? 'continue-' : '';
                $anotherPart = $isLoggedIn ? 'another-' : '';
+               // @phan-suppress-next-line PhanUndeclaredMethod
                $expiration = $this->getRequest()->getSession()->getProvider()->getRememberUserDuration();
                $expirationDays = ceil( $expiration / ( 3600 * 24 ) );
                $secureLoginLink = '';
index f2c9644..8134c9a 100644 (file)
@@ -568,6 +568,7 @@ class SpecialPageFactory {
                                return $title;
                        }
 
+                       // @phan-suppress-next-line PhanUndeclaredMethod
                        $context->setTitle( $page->getPageTitle( $par ) );
                } elseif ( !$page->isIncludable() ) {
                        return false;
index 3a266f2..07214af 100644 (file)
@@ -423,6 +423,8 @@ class SpecialBlock extends FormSpecialPage {
                                foreach ( $block->getRestrictions() as $restriction ) {
                                        switch ( $restriction->getType() ) {
                                                case PageRestriction::TYPE:
+                                                       /** @var PageRestriction $restriction */
+                                                       '@phan-var PageRestriction $restriction';
                                                        if ( $restriction->getTitle() ) {
                                                                $pageRestrictions[] = $restriction->getTitle()->getPrefixedText();
                                                        }
index ceba987..ef1b3d8 100644 (file)
@@ -83,8 +83,10 @@ class SpecialExpandTemplates extends SpecialPage {
                                $dom = $parser->preprocessToDom( $input );
 
                                if ( method_exists( $dom, 'saveXML' ) ) {
+                                       // @phan-suppress-next-line PhanUndeclaredMethod
                                        $xml = $dom->saveXML();
                                } else {
+                                       // @phan-suppress-next-line PhanUndeclaredMethod
                                        $xml = $dom->__toString();
                                }
                        }
index 30f4655..0bfe185 100644 (file)
@@ -197,26 +197,36 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
                $user = $this->getUser();
 
                $significance = $this->getFilterGroup( 'significance' );
+               /** @var ChangesListBooleanFilter $hideMinor */
                $hideMinor = $significance->getFilter( 'hideminor' );
+               '@phan-var ChangesListBooleanFilter $hideMinor';
                $hideMinor->setDefault( $user->getBoolOption( 'hideminor' ) );
 
                $automated = $this->getFilterGroup( 'automated' );
+               /** @var ChangesListBooleanFilter $hideBots */
                $hideBots = $automated->getFilter( 'hidebots' );
+               '@phan-var ChangesListBooleanFilter $hideBots';
                $hideBots->setDefault( true );
 
+               /** @var ChangesListStringOptionsFilterGroup|null $reviewStatus */
                $reviewStatus = $this->getFilterGroup( 'reviewStatus' );
+               '@phan-var ChangesListStringOptionsFilterGroup|null $reviewStatus';
                if ( $reviewStatus !== null ) {
                        // Conditional on feature being available and rights
                        if ( $user->getBoolOption( 'hidepatrolled' ) ) {
                                $reviewStatus->setDefault( 'unpatrolled' );
                                $legacyReviewStatus = $this->getFilterGroup( 'legacyReviewStatus' );
+                               /** @var ChangesListBooleanFilter $legacyHidePatrolled */
                                $legacyHidePatrolled = $legacyReviewStatus->getFilter( 'hidepatrolled' );
+                               '@phan-var ChangesListBooleanFilter $legacyHidePatrolled';
                                $legacyHidePatrolled->setDefault( true );
                        }
                }
 
                $changeType = $this->getFilterGroup( 'changeType' );
+               /** @var ChangesListBooleanFilter $hideCategorization */
                $hideCategorization = $changeType->getFilter( 'hidecategorization' );
+               '@phan-var ChangesListBooleanFilter $hideCategorization';
                if ( $hideCategorization !== null ) {
                        // Conditional on feature being available
                        $hideCategorization->setDefault( $user->getBoolOption( 'hidecategorization' ) );
index 32be932..075b5df 100644 (file)
@@ -493,6 +493,7 @@ class SpecialUndelete extends SpecialPage {
                $buttonFields = [];
 
                if ( $isText ) {
+                       '@phan-var TextContent $content';
                        // TODO: MCR: make this work for multiple slots
                        // source view for textual content
                        $sourceView = Xml::element( 'textarea', [
index a45ccca..5747f67 100644 (file)
@@ -86,6 +86,7 @@ class UserrightsPage extends SpecialPage {
         *
         * @param string|null $par String if any subpage provided, else null
         * @throws UserBlockedError|PermissionsError
+        * @suppress PhanUndeclaredMethod
         */
        public function execute( $par ) {
                $user = $this->getUser();
@@ -479,10 +480,12 @@ class UserrightsPage extends SpecialPage {
                        $this->getOutput()->addWikiTextAsInterface( $status->getWikiText() );
 
                        return;
-               } else {
-                       $user = $status->value;
                }
 
+               /** @var User $user */
+               $user = $status->value;
+               '@phan-var User $user';
+
                $groups = $user->getGroups();
                $groupMemberships = $user->getGroupMemberships();
                $this->showEditUserGroupsForm( $user, $groups, $groupMemberships );
index f5239b4..3d56330 100644 (file)
@@ -148,6 +148,7 @@ class SpecialWatchlist extends ChangesListSpecialPage {
 
        /**
         * @inheritDoc
+        * @suppress PhanUndeclaredMethod
         */
        protected function registerFilters() {
                parent::registerFilters();
index 6faf22b..63cff94 100644 (file)
@@ -266,6 +266,7 @@ class BlockListPager extends TablePager {
 
                        switch ( $restriction->getType() ) {
                                case PageRestriction::TYPE:
+                                       '@phan-var PageRestriction $restriction';
                                        if ( $restriction->getTitle() ) {
                                                $items[$restriction->getType()][] = Html::rawElement(
                                                        'li',
index df5edef..c3cbc6d 100644 (file)
@@ -514,6 +514,7 @@ class BotPassword implements IDBAccessObject {
                        $throttle->clear( $user->getName(), $request->getIP() );
                }
                return self::loginHook( $user, $bp,
+                       // @phan-suppress-next-line PhanUndeclaredMethod
                        Status::newGood( $provider->newSessionForRequest( $user, $bp, $request ) ) );
        }
 
index b2d6077..f3a8810 100644 (file)
@@ -34,6 +34,7 @@ class AvroValidator {
         * @return string|string[] An error or list of errors in the
         *  provided $datum. When no errors exist the empty array is
         *  returned.
+        * @suppress PhanUndeclaredMethod
         */
        public static function getErrors( AvroSchema $schema, $datum ) {
                switch ( $schema->type ) {
index 7ee6a65..16a6e1a 100644 (file)
@@ -55,7 +55,7 @@ class Language {
        const SUPPORTED = 'mwfile';
 
        /**
-        * @var LanguageConverter
+        * @var LanguageConverter|FakeConverter
         */
        public $mConverter;
 
@@ -457,7 +457,6 @@ class Language {
        }
 
        function __construct() {
-               // @phan-suppress-next-line PhanTypeMismatchProperty
                $this->mConverter = new FakeConverter( $this );
                // Set the code to the name of the descendant
                if ( static::class === 'Language' ) {
index 350aa67..9886425 100644 (file)
@@ -1044,6 +1044,7 @@ class LanguageConverter {
                                $revision = Revision::newFromTitle( $title );
                                if ( $revision ) {
                                        if ( $revision->getContentModel() == CONTENT_MODEL_WIKITEXT ) {
+                                               // @phan-suppress-next-line PhanUndeclaredMethod
                                                $txt = $revision->getContent( RevisionRecord::RAW )->getText();
                                        }
 
index 130d1fb..81bee4c 100644 (file)
@@ -1324,6 +1324,7 @@ abstract class Maintenance {
                        $res = $dbw->select( 'content', 'content_address', [], __METHOD__, [ 'DISTINCT' ] );
                        $blobStore = MediaWikiServices::getInstance()->getBlobStore();
                        foreach ( $res as $row ) {
+                               // @phan-suppress-next-line PhanUndeclaredMethod
                                $textId = $blobStore->getTextIdFromAddress( $row->content_address );
                                if ( $textId ) {
                                        $cur[] = $textId;
index b0ee966..8fb0d68 100644 (file)
@@ -39,7 +39,10 @@ class AddSite extends Maintenance {
         */
        public function execute() {
                $siteStore = MediaWikiServices::getInstance()->getSiteStore();
-               $siteStore->reset();
+               if ( method_exists( $siteStore, 'reset' ) ) {
+                       // @phan-suppress-next-line PhanUndeclaredMethod
+                       $siteStore->reset();
+               }
 
                $globalId = $this->getArg( 0 );
                $group = $this->getArg( 1 );
@@ -81,6 +84,7 @@ class AddSite extends Maintenance {
                $siteStore->saveSites( [ $site ] );
 
                if ( method_exists( $siteStore, 'reset' ) ) {
+                       // @phan-suppress-next-line PhanUndeclaredMethod
                        $siteStore->reset();
                }
 
index bcf7023..6faeee8 100644 (file)
@@ -23,8 +23,6 @@
 
 require __DIR__ . '/../commandLine.inc';
 
-use Wikimedia\Rdbms\IMaintainableDatabase;
-
 /**
  * Maintenance script that upgrade for log_id/log_deleted fields in a
  * replication-safe way.
@@ -34,14 +32,14 @@ use Wikimedia\Rdbms\IMaintainableDatabase;
 class UpdateLogging {
 
        /**
-        * @var IMaintainableDatabase
+        * @var Database
         */
        public $dbw;
        public $batchSize = 1000;
        public $minTs = false;
 
        function execute() {
-               $this->dbw = $this->getDB( DB_MASTER );
+               $this->dbw = wfGetDB( DB_MASTER );
                $logging = $this->dbw->tableName( 'logging' );
                $logging_1_10 = $this->dbw->tableName( 'logging_1_10' );
                $logging_pre_1_10 = $this->dbw->tableName( 'logging_pre_1_10' );
index 55ffcb8..62d6680 100644 (file)
@@ -58,6 +58,7 @@ class CheckLess extends Maintenance {
                        "$IP/tests/phpunit/phpunit.php",
                        "$IP/tests/phpunit/suites/LessTestSuite.php"
                ];
+               // @phan-suppress-next-line PhanUndeclaredMethod
                $textUICommand->run( $argv );
        }
 }
index d255348..b4bfff0 100644 (file)
@@ -147,6 +147,7 @@ class CleanupUploadStash extends Maintenance {
        protected function doOperations( FileRepo $tempRepo, array $ops ) {
                $status = $tempRepo->getBackend()->doQuickOperations( $ops );
                if ( !$status->isOK() ) {
+                       // @phan-suppress-next-line PhanUndeclaredMethod
                        $this->error( print_r( $status->getErrorsArray(), true ) );
                }
        }
index 2f0bcdf..3f55878 100644 (file)
@@ -144,6 +144,8 @@ class CompareParsers extends DumpIterator {
                        return;
                }
 
+               /** @var WikitextContent $content */
+               '@phan-var WikitextContent $content';
                $text = strval( $content->getText() );
 
                $output1 = $parser1->parse( $text, $title, $this->options );
index 02152f7..23c46bc 100644 (file)
@@ -117,6 +117,7 @@ class ConvertLinks extends Maintenance {
                }
 
                $res = $dbw->query( "SELECT l_from FROM $links LIMIT 1" );
+               // @phan-suppress-next-line PhanUndeclaredMethod
                if ( $dbw->fieldType( $res, 0 ) == "int" ) {
                        $this->output( "Schema already converted\n" );
 
index d010073..7b2ef17 100644 (file)
@@ -68,6 +68,7 @@ class DeleteArchivedFiles extends Maintenance {
 
                        /** @var LocalFile $file */
                        $file = $repo->newFile( $row->fa_name );
+                       '@phan-var LocalFile $file';
                        try {
                                $file->lock();
                        } catch ( LocalFileLockError $e ) {
index 49fadaa..24e88bc 100644 (file)
@@ -109,6 +109,7 @@ class EraseArchivedFile extends Maintenance {
                                $this->output( "Deleted version '$key' ($ts) of file '$name'\n" );
                        } else {
                                $this->output( "Failed to delete version '$key' ($ts) of file '$name'\n" );
+                               // @phan-suppress-next-line PhanUndeclaredMethod
                                $this->output( print_r( $status->getErrorsArray(), true ) );
                        }
                } else {
index 0ff3622..cda16fe 100644 (file)
@@ -211,6 +211,7 @@ TEXT
                        }
                        $this->uploadCount++;
                        // $this->report();
+                       // @phan-suppress-next-line PhanUndeclaredMethod
                        $this->progress( "upload: " . $revision->getFilename() );
 
                        if ( !$this->dryRun ) {
index f5d9359..e4d1f09 100644 (file)
@@ -332,6 +332,7 @@ class ImportImages extends Maintenance {
 
                                if ( $this->hasOption( 'dry' ) ) {
                                        $this->output( "done.\n" );
+                                       // @phan-suppress-next-line PhanUndeclaredMethod
                                } elseif ( $image->recordUpload2(
                                        $archive->value,
                                        $summary,
index ee1f59c..05688df 100644 (file)
@@ -88,7 +88,9 @@ class NukeNS extends Maintenance {
                                        $dbw->query( "DELETE FROM $tbl_pag WHERE page_id = $id" );
                                        $this->commitTransaction( $dbw, __METHOD__ );
                                        // Delete revisions as appropriate
+                                       /** @var NukePage $child */
                                        $child = $this->runChild( NukePage::class, 'nukePage.php' );
+                                       '@phan-var NukePage $child';
                                        $child->deleteRevisions( $revs );
                                        $this->purgeRedundantText( true );
                                        $n_deleted++;
index 9f77fda..5d6a19f 100644 (file)
@@ -151,6 +151,8 @@ class PopulateImageSha1 extends LoggedUpdateMaintenance {
                        }
                        // Upgrade the old file versions...
                        foreach ( $file->getHistory() as $oldFile ) {
+                               /** @var OldLocalFile $oldFile */
+                               '@phan-var OldLocalFile $oldFile';
                                $sha1 = $oldFile->getRepo()->getFileSha1( $oldFile->getPath() );
                                if ( strval( $sha1 ) !== '' ) { // file on disk and hashed properly
                                        if ( $isRegen && $oldFile->getSha1() !== $sha1 ) {
index b9e084e..963bfec 100644 (file)
@@ -87,6 +87,8 @@ class PreprocessDump extends DumpIterator {
                if ( $content->getModel() !== CONTENT_MODEL_WIKITEXT ) {
                        return;
                }
+               /** @var WikitextContent $content */
+               '@phan-var WikitextContent $content';
 
                try {
                        $this->mPreprocessor->preprocessToObj( strval( $content->getText() ), 0 );
index e57e977..68fb643 100644 (file)
@@ -72,7 +72,7 @@ class PPFuzzTester {
                                $passed = 'passed';
                        } catch ( Exception $e ) {
                                $testReport = self::$currentTest->getReport();
-                               $exceptionReport = $e->getText();
+                               $exceptionReport = $e instanceof MWException ? $e->getText() : (string)$e;
                                $hash = md5( $testReport );
                                file_put_contents( "results/ppft-$hash.in", serialize( self::$currentTest ) );
                                file_put_contents( "results/ppft-$hash.fail",
index dfce202..bfbee9b 100644 (file)
@@ -76,7 +76,7 @@ class ImageBuilder extends Maintenance {
        }
 
        /**
-        * @return FileRepo
+        * @return LocalRepo
         */
        function getRepo() {
                if ( !isset( $this->repo ) ) {
@@ -203,7 +203,8 @@ class ImageBuilder extends Maintenance {
                                $filename = $altname;
                                $this->output( "Estimating transcoding... $altname\n" );
                        } else {
-                               # @todo FIXME: create renameFile()
+                               // @fixme create renameFile()
+                               // @phan-suppress-next-line PhanUndeclaredMethod See comment above...
                                $filename = $this->renameFile( $filename );
                        }
                }
index d8a8808..060f327 100644 (file)
@@ -106,7 +106,9 @@ class CheckStorage {
                                        [],
                                        [ 'content' => [ 'INNER JOIN', [ 'content_id = slot_content_id' ] ] ]
                                );
+                               /** @var \MediaWiki\Storage\SqlBlobStore $blobStore */
                                $blobStore = MediaWikiServices::getInstance()->getBlobStore();
+                               '@phan-var \MediaWiki\Storage\SqlBlobStore $blobStore';
                                foreach ( $res as $row ) {
                                        $textId = $blobStore->getTextIdFromAddress( $row->content_address );
                                        if ( $textId ) {
index a3534f8..94ec207 100755 (executable)
@@ -27,7 +27,6 @@
 
 require_once __DIR__ . '/Maintenance.php';
 
-use Wikimedia\Rdbms\IMaintainableDatabase;
 use Wikimedia\Rdbms\DatabaseSqlite;
 
 /**
@@ -160,7 +159,8 @@ class UpdateMediaWiki extends Maintenance {
                $dbDomain = WikiMap::getCurrentWikiDbDomain()->getId();
                $this->output( "Going to run database updates for $dbDomain\n" );
                if ( $db->getType() === 'sqlite' ) {
-                       /** @var IMaintainableDatabase|DatabaseSqlite $db */
+                       /** @var DatabaseSqlite $db */
+                       '@phan-var DatabaseSqlite $db';
                        $this->output( "Using SQLite file: '{$db->getDbFilePath()}'\n" );
                }
                $this->output( "Depending on the size of your database this may take a while!\n" );
index c9fb780..18c71a3 100644 (file)
@@ -34,6 +34,7 @@ class UpdateExtensionJsonSchema extends Maintenance {
                while ( $json['manifest_version'] !== ExtensionRegistry::MANIFEST_VERSION ) {
                        $json['manifest_version'] += 1;
                        $func = "updateTo{$json['manifest_version']}";
+                       // @phan-suppress-next-line PhanUndeclaredMethod
                        $this->$func( $json );
                }
 
index 5f7f9d5..038ef23 100644 (file)
@@ -36,7 +36,7 @@ use Wikimedia\Rdbms\IMaintainableDatabase;
  */
 class UserDupes {
        /**
-        * @var IMaintainableDatabase
+        * @var Database
         */
        private $db;
        private $reassigned;
index 00046d3..544c071 100644 (file)
@@ -95,8 +95,10 @@ class WrapOldPasswords extends Maintenance {
                                $user = User::newFromId( $row->user_id );
                                /** @var ParameterizedPassword $password */
                                $password = $passwordFactory->newFromCiphertext( $row->user_password );
+                               '@phan-var ParameterizedPassword $password';
                                /** @var LayeredParameterizedPassword $layeredPassword */
                                $layeredPassword = $passwordFactory->newFromType( $layeredType );
+                               '@phan-var LayeredParameterizedPassword $layeredPassword';
                                $layeredPassword->partialCrypt( $password );
 
                                $updateUsers[] = $user;