Upgrade phan config to 0.7.1
authorDaimona Eaytoy <daimona.wiki@gmail.com>
Sun, 1 Sep 2019 14:00:35 +0000 (16:00 +0200)
committerDaimona Eaytoy <daimona.wiki@gmail.com>
Wed, 4 Sep 2019 08:20:53 +0000 (08:20 +0000)
This allows us to remove many suppressions for phan false positives.

Bug: T231636
Depends-On: I82a279e1f7b0fdefd3bb712e46c7d0665429d065
Change-Id: I5c251e9584a1ae9fb1577afcafb5001e0dcd41c7

45 files changed:
.phan/config.php
composer.json
includes/GlobalFunctions.php
includes/Revision/RevisionRenderer.php
includes/actions/HistoryAction.php
includes/api/ApiExpandTemplates.php
includes/api/ApiMain.php
includes/api/ApiQueryBacklinks.php
includes/api/ApiQueryRevisionsBase.php
includes/auth/AuthenticationRequest.php
includes/block/Restriction/AbstractRestriction.php
includes/changes/ChangesList.php
includes/config/EtcdConfig.php
includes/content/ContentHandler.php
includes/diff/DiffEngine.php
includes/export/ExportProgressFilter.php
includes/filerepo/RepoGroup.php
includes/filerepo/file/LocalFile.php
includes/htmlform/fields/HTMLAutoCompleteSelectField.php
includes/http/MWHttpRequest.php
includes/libs/MappedIterator.php
includes/libs/filebackend/fileiteration/SwiftFileBackendList.php
includes/libs/http/MultiHttpClient.php
includes/libs/objectcache/HashBagOStuff.php
includes/libs/objectcache/wancache/WANObjectCache.php
includes/libs/rdbms/loadmonitor/LoadMonitor.php
includes/media/ExifBitmapHandler.php
includes/parser/Parser.php
includes/parser/ParserDiffTest.php
includes/rcfeed/FormattedRCFeed.php
includes/resourceloader/ResourceLoaderClientHtml.php
includes/resourceloader/ResourceLoaderOOUIImageModule.php
includes/session/SessionManager.php
includes/shell/Shell.php
includes/skins/BaseTemplate.php
includes/specials/SpecialUncategorizedcategories.php
includes/specials/pagers/BlockListPager.php
includes/title/NamespaceInfo.php
includes/user/User.php
languages/Language.php
maintenance/Maintenance.php
maintenance/benchmarks/benchmarkTidy.php
maintenance/convertExtensionToRegistration.php
maintenance/importImages.php
maintenance/storage/orphanStats.php

index 47f4512..0ae6fcf 100644 (file)
@@ -90,6 +90,9 @@ $cfg['exclude_analysis_directory_list'] = [
        'includes/libs/jsminplus.php',
 ];
 
+// NOTE: If you're facing an issue which you cannot easily fix, DO NOT add it here. Suppress it
+// either in-line with @phan-suppress-next-line and similar, at block-level (via @suppress), or at
+// file-level (with @phan-file-suppress), so that it stays enabled for the rest of the codebase.
 $cfg['suppress_issue_types'] = array_merge( $cfg['suppress_issue_types'], [
        // approximate error count: 19
        "PhanParamReqAfterOpt", // False positives with nullables (phan issue #3159). Use real nullables
@@ -97,12 +100,17 @@ $cfg['suppress_issue_types'] = array_merge( $cfg['suppress_issue_types'], [
        // approximate error count: 110
        "PhanParamTooMany", // False positives with variargs. Unsuppress after dropping HHVM
 
-       // approximate error count: 60
+       // approximate error count: 45
        "PhanTypeMismatchArgument",
-       // approximate error count: 752
+       // approximate error count: 693
        "PhanUndeclaredProperty",
 ] );
 
+// This helps a lot in discovering bad code, but unfortunately it will always fail for
+// hooks + pass by reference, see phan issue #2943.
+// @todo Enable when the issue above is resolved and we update our config!
+$cfg['redundant_condition_detection'] = false;
+
 $cfg['ignore_undeclared_variables_in_global_scope'] = true;
 // @todo It'd be great if we could just make phan read these from DefaultSettings, to avoid
 // duplicating the types.
@@ -125,6 +133,9 @@ $cfg['globals_type_map'] = array_merge( $cfg['globals_type_map'], [
        'wgWANObjectCaches' => 'array[]',
        'wgLocalInterwikis' => 'string[]',
        'wgDebugLogGroups' => 'string|false|array{destination:string,sample?:int,level:int}',
+       'wgCookiePrefix' => 'string|false',
+       'wgOut' => 'OutputPage',
+       'wgExtraNamespaces' => 'string[]',
 ] );
 
 return $cfg;
index dad3c5c..13c8993 100644 (file)
@@ -77,7 +77,7 @@
                "wikimedia/avro": "1.8.0",
                "wikimedia/testing-access-wrapper": "~1.0",
                "wmde/hamcrest-html-matchers": "^0.1.0",
-               "mediawiki/mediawiki-phan-config": "0.6.1",
+               "mediawiki/mediawiki-phan-config": "0.7.1",
                "symfony/yaml": "3.4.28",
                "johnkary/phpunit-speedtrap": "^1.0 | ^2.0"
        },
index 2cde173..38daab5 100644 (file)
@@ -2135,7 +2135,6 @@ function wfShellExec( $cmd, &$retval = null, $environ = [],
        }
 
        $includeStderr = isset( $options['duplicateStderr'] ) && $options['duplicateStderr'];
-       // @phan-suppress-next-line PhanTypeInvalidDimOffset
        $profileMethod = $options['profileMethod'] ?? wfGetCaller();
 
        try {
@@ -2200,7 +2199,6 @@ function wfShellWikiCmd( $script, array $parameters = [], array $options = [] )
        // Give site config file a chance to run the script in a wrapper.
        // The caller may likely want to call wfBasename() on $script.
        Hooks::run( 'wfShellWikiCmd', [ &$script, &$parameters, &$options ] );
-       // @phan-suppress-next-line PhanTypeInvalidDimOffset
        $cmd = [ $options['php'] ?? $wgPhpCli ];
        if ( isset( $options['wrapper'] ) ) {
                $cmd[] = $options['wrapper'];
@@ -2897,7 +2895,6 @@ function wfUnpack( $format, $data, $length = false ) {
        $result = unpack( $format, $data );
        Wikimedia\restoreWarnings();
 
-       // @phan-suppress-next-line PhanTypeComparisonFromArray Phan issue #3160
        if ( $result === false ) {
                // If it cannot extract the packed data.
                throw new MWException( "unpack could not unpack binary data" );
index ea90255..5d09e01 100644 (file)
@@ -109,7 +109,6 @@ class RevisionRenderer {
                        throw new InvalidArgumentException( 'Mismatching wiki ID ' . $rev->getWikiId() );
                }
 
-               // @phan-suppress-next-line PhanTypeInvalidDimOffset
                $audience = $hints['audience']
                        ?? ( $forUser ? RevisionRecord::FOR_THIS_USER : RevisionRecord::FOR_PUBLIC );
 
@@ -123,7 +122,6 @@ class RevisionRenderer {
                        $options = ParserOptions::newCanonical( $forUser ?: 'canonical' );
                }
 
-               // @phan-suppress-next-line PhanTypeInvalidDimOffset
                $useMaster = $hints['use-master'] ?? false;
 
                $dbIndex = $useMaster
index 385ccc9..db874f2 100644 (file)
@@ -95,6 +95,7 @@ class HistoryAction extends FormlessAction {
        private function preCacheMessages() {
                // Precache various messages
                if ( !isset( $this->message ) ) {
+                       $this->message = [];
                        $msgs = [ 'cur', 'last', 'pipe-separator' ];
                        foreach ( $msgs as $msg ) {
                                $this->message[$msg] = $this->msg( $msg )->escaped();
index 1c7f63d..a5e7437 100644 (file)
@@ -103,6 +103,7 @@ class ApiExpandTemplates extends ApiBase {
                if ( isset( $prop['parsetree'] ) || $params['generatexml'] ) {
                        $parser->startExternalParse( $titleObj, $options, Parser::OT_PREPROCESS );
                        $dom = $parser->preprocessToDom( $params['text'] );
+                       // @phan-suppress-next-line PhanUndeclaredMethodInCallable
                        if ( is_callable( [ $dom, 'saveXML' ] ) ) {
                                // @phan-suppress-next-line PhanUndeclaredMethod
                                $xml = $dom->saveXML();
index efa4b04..a9fe258 100644 (file)
@@ -1708,7 +1708,7 @@ class ApiMain extends ApiBase {
         * @return string
         */
        protected function encodeRequestLogValue( $s ) {
-               static $table;
+               static $table = [];
                if ( !$table ) {
                        $chars = ';@$!*(),/:';
                        $numChars = strlen( $chars );
@@ -1914,6 +1914,10 @@ class ApiMain extends ApiBase {
                ];
        }
 
+       /**
+        * @inheritDoc
+        * @phan-param array{nolead?:bool,headerlevel?:int,tocnumber?:int[]} $options
+        */
        public function modifyHelp( array &$help, array $options, array &$tocData ) {
                // Wish PHP had an "array_insert_before". Instead, we have to manually
                // reindex the array to get 'permissions' in the right place.
index 6c1eb0f..d21f111 100644 (file)
@@ -326,7 +326,6 @@ class ApiQueryBacklinks extends ApiQueryGeneratorBase {
        /**
         * @param ApiPageSet $resultPageSet
         * @return void
-        * @suppress PhanTypeInvalidDimOffset
         */
        private function run( $resultPageSet = null ) {
                $this->params = $this->extractRequestParams( false );
index 7c92b35..90e5480 100644 (file)
@@ -512,6 +512,7 @@ abstract class ApiQueryRevisionsBase extends ApiQueryGeneratorBase {
                                        Parser::OT_PREPROCESS
                                );
                                $dom = $parser->preprocessToDom( $t );
+                               // @phan-suppress-next-line PhanUndeclaredMethodInCallable
                                if ( is_callable( [ $dom, 'saveXML' ] ) ) {
                                        // @phan-suppress-next-line PhanUndeclaredMethod
                                        $xml = $dom->saveXML();
index 1a2442c..e7527d1 100644 (file)
@@ -376,7 +376,7 @@ abstract class AuthenticationRequest {
         * @return AuthenticationRequest
         */
        public static function __set_state( $data ) {
-               // @phan-suppress-next-line PhanTypeInstantiateAbstract
+               // @phan-suppress-next-line PhanTypeInstantiateAbstractStatic
                $ret = new static();
                foreach ( $data as $k => $v ) {
                        $ret->$k = $v;
index a010e83..e08b877 100644 (file)
@@ -99,7 +99,7 @@ abstract class AbstractRestriction implements Restriction {
         * @inheritDoc
         */
        public static function newFromRow( \stdClass $row ) {
-               // @phan-suppress-next-line PhanTypeInstantiateAbstract
+               // @phan-suppress-next-line PhanTypeInstantiateAbstractStatic
                return new static( $row->ir_ipb_id, $row->ir_value );
        }
 
index 0382d73..a48e191 100644 (file)
@@ -161,6 +161,7 @@ class ChangesList extends ContextSource {
         */
        private function preCacheMessages() {
                if ( !isset( $this->message ) ) {
+                       $this->message = [];
                        foreach ( [
                                'cur', 'diff', 'hist', 'enhancedrc-history', 'last', 'blocklink', 'history',
                                'semicolon-separator', 'pipe-separator' ] as $msg
index 09d0189..f3d3849 100644 (file)
@@ -161,6 +161,7 @@ class EtcdConfig implements Config, LoggerAwareInterface {
                                                if ( is_array( $etcdResponse['config'] ) ) {
                                                        // Avoid having all servers expire cache keys at the same time
                                                        $expiry = microtime( true ) + $this->baseCacheTTL;
+                                                       // @phan-suppress-next-line PhanTypeMismatchArgumentInternal
                                                        $expiry += mt_rand( 0, 1e6 ) / 1e6 * $this->skewCacheTTL;
                                                        $data = [
                                                                'config' => $etcdResponse['config'],
index f1df087..9fbb72c 100644 (file)
@@ -1102,7 +1102,7 @@ abstract class ContentHandler {
         * @param Revision|Content $undoafter Must be from an earlier revision than $undo
         * @param bool $undoIsLatest Set true if $undo is from the current revision (since 1.32)
         *
-        * @return mixed Content on success, false on failure
+        * @return Content|false Content on success, false on failure
         */
        public function getUndoContent( $current, $undo, $undoafter, $undoIsLatest = false ) {
                Assert::parameterType( Revision::class . '|' . Content::class, $current, '$current' );
index 6ebec1c..6fa40ea 100644 (file)
@@ -363,7 +363,6 @@ class DiffEngine {
                         */
                        $max = min( $this->m, $this->n );
                        for ( $forwardBound = 0; $forwardBound < $max
-                               // @phan-suppress-next-line PhanTypeInvalidDimOffset
                                && $this->from[$forwardBound] === $this->to[$forwardBound];
                                ++$forwardBound
                        ) {
index 9b1571f..5dd3e4c 100644 (file)
@@ -30,6 +30,10 @@ class ExportProgressFilter extends DumpFilter {
         */
        private $progress;
 
+       /**
+        * @param DumpOutput &$sink
+        * @param BackupDumper &$progress
+        */
        function __construct( &$sink, &$progress ) {
                parent::__construct( $sink );
                $this->progress = $progress;
index 96df29f..f61ca3b 100644 (file)
@@ -116,7 +116,6 @@ class RepoGroup {
         *                   be found.
         *   latest:         If true, load from the latest available data into File objects
         * @phan-param array{time?:mixed,ignoreRedirect?:bool,private?:bool,latest?:bool} $options
-        * @suppress PhanTypeInvalidDimOffset
         * @return File|bool False if title is not found
         */
        function findFile( $title, $options = [] ) {
index 4751a59..3090632 100644 (file)
@@ -1092,7 +1092,6 @@ class LocalFile extends File {
                array_shift( $urls ); // don't purge directory
 
                // Give media handler a chance to filter the file purge list
-               // @phan-suppress-next-line PhanTypeInvalidDimOffset
                if ( !empty( $options['forThumbRefresh'] ) ) {
                        $handler = $this->getHandler();
                        if ( $handler ) {
index 41c0b3c..63e77ce 100644 (file)
@@ -29,8 +29,6 @@
  * The old name of autocomplete-data[-messages] was autocomplete[-messages] which is still
  * recognized but deprecated since MediaWiki 1.29 since it conflicts with how autocomplete is
  * used in HTMLTextField.
- *
- * @phan-file-suppress PhanTypeMismatchProperty This is doing weird things with mClass
  */
 class HTMLAutoCompleteSelectField extends HTMLTextField {
        protected $autocompleteData = [];
@@ -168,7 +166,6 @@ class HTMLAutoCompleteSelectField extends HTMLTextField {
 
                        $ret = $select->getHTML() . "<br />\n";
 
-                       // @phan-suppress-next-line PhanTypeMismatchDimEmpty
                        $this->mClass[] = 'mw-htmlform-hide-if';
                }
 
@@ -181,7 +178,6 @@ class HTMLAutoCompleteSelectField extends HTMLTextField {
                        }
                }
 
-               // @phan-suppress-next-line PhanTypeMismatchDimEmpty
                $this->mClass[] = 'mw-htmlform-autocomplete';
                $ret .= parent::getInputHTML( $valInSelect ? '' : $value );
                $this->mClass = $oldClass;
index 3885c03..d1c14ae 100644 (file)
@@ -103,7 +103,6 @@ abstract class MWHttpRequest implements LoggerAwareInterface {
                $this->url = wfExpandUrl( $url, PROTO_HTTP );
                $this->parsedUrl = wfParseUrl( $this->url );
 
-               // @phan-suppress-next-line PhanTypeInvalidDimOffset
                $this->logger = $options['logger'] ?? new NullLogger();
 
                if ( !$this->parsedUrl || !Http::isValidURI( $this->url ) ) {
index 9d53a86..0e53038 100644 (file)
@@ -61,7 +61,6 @@ class MappedIterator extends FilterIterator {
                }
                parent::__construct( $baseIterator );
                $this->vCallback = $vCallback;
-               // @phan-suppress-next-line PhanTypeInvalidDimOffset
                $this->aCallback = $options['accept'] ?? null;
        }
 
index bcde8d9..92105c3 100644 (file)
@@ -33,7 +33,7 @@ abstract class SwiftFileBackendList implements Iterator {
        /** @var array List of path or (path,stat array) entries */
        protected $bufferIter = [];
 
-       /** @var string List items *after* this path */
+       /** @var string|null List items *after* this path */
        protected $bufferAfter = null;
 
        /** @var int */
@@ -108,6 +108,7 @@ abstract class SwiftFileBackendList implements Iterator {
                $this->pos = 0;
                $this->bufferAfter = null;
                $this->bufferIter = $this->pageFromList(
+                       // @phan-suppress-next-line PhanTypeMismatchArgumentPropertyReferenceReal
                        $this->container, $this->dir, $this->bufferAfter, self::PAGE_SIZE, $this->params
                ); // updates $this->bufferAfter
        }
index 17352f0..2e3aa70 100644 (file)
@@ -402,7 +402,6 @@ class MultiHttpClient implements LoggerAwareInterface {
                                $name = strtolower( $name );
                                $value = trim( $value );
                                if ( isset( $req['response']['headers'][$name] ) ) {
-                                       // @phan-suppress-next-line PhanTypeInvalidDimOffset
                                        $req['response']['headers'][$name] .= ', ' . $value;
                                } else {
                                        $req['response']['headers'][$name] = $value;
index 0f7011d..348f300 100644 (file)
@@ -50,7 +50,6 @@ class HashBagOStuff extends MediumSpecificBagOStuff {
         * @codingStandardsIgnoreStart
         * @phan-param array{logger?:Psr\Log\LoggerInterface,asyncHandler?:callable,keyspace?:string,reportDupes?:bool,syncTimeout?:int,segmentationSize?:int,segmentedValueMaxSize?:int,maxKeys?:int} $params
         * @codingStandardsIgnoreEnd
-        * @suppress PhanTypeInvalidDimOffset
         */
        function __construct( $params = [] ) {
                $params['segmentationSize'] = $params['segmentationSize'] ?? INF;
index 2ce216d..a090e16 100644 (file)
@@ -585,7 +585,6 @@ class WANObjectCache implements IExpiringStore, IStoreKeyEncoder, LoggerAwareInt
         * @note Options added in 1.33: creating
         * @note Options added in 1.34: version, walltime
         * @return bool Success
-        * @suppress PhanTypeInvalidDimOffset
         */
        final public function set( $key, $value, $ttl = self::TTL_INDEFINITE, array $opts = [] ) {
                $now = $this->getCurrentTime();
@@ -1258,7 +1257,6 @@ class WANObjectCache implements IExpiringStore, IStoreKeyEncoder, LoggerAwareInt
         * @note Options added in 1.31: staleTTL, graceTTL
         * @note Options added in 1.33: touchedCallback
         * @note Callable type hints are not used to avoid class-autoloading
-        * @suppress PhanTypeInvalidDimOffset
         */
        final public function getWithSetCallback( $key, $ttl, $callback, array $opts = [] ) {
                $version = $opts['version'] ?? null;
@@ -1450,7 +1448,6 @@ class WANObjectCache implements IExpiringStore, IStoreKeyEncoder, LoggerAwareInt
                                $this->setInterimValue( $key, $value, $lockTSE, $version, $walltime );
                        } else {
                                $finalSetOpts = [
-                                       // @phan-suppress-next-line PhanTypeInvalidDimOffset
                                        'since' => $setOpts['since'] ?? $preCallbackTime,
                                        'version' => $version,
                                        'staleTTL' => $staleTTL,
@@ -2328,6 +2325,7 @@ class WANObjectCache implements IExpiringStore, IStoreKeyEncoder, LoggerAwareInt
 
                $chance = ( 1 - $curTTL / $lowTTL );
 
+               // @phan-suppress-next-line PhanTypeMismatchArgumentInternal
                return mt_rand( 1, 1e9 ) <= 1e9 * $chance;
        }
 
@@ -2370,6 +2368,7 @@ class WANObjectCache implements IExpiringStore, IStoreKeyEncoder, LoggerAwareInt
                // Ramp up $chance from 0 to its nominal value over RAMPUP_TTL seconds to avoid stampedes
                $chance *= ( $timeOld <= self::$RAMPUP_TTL ) ? $timeOld / self::$RAMPUP_TTL : 1;
 
+               // @phan-suppress-next-line PhanTypeMismatchArgumentInternal
                return mt_rand( 1, 1e9 ) <= 1e9 * $chance;
        }
 
index 19550f4..c3f8879 100644 (file)
@@ -107,6 +107,7 @@ class LoadMonitor implements ILoadMonitor {
 
                $key = $this->getCacheKey( $serverIndexes );
                # Randomize TTLs to reduce stampedes (4.0 - 5.0 sec)
+               // @phan-suppress-next-line PhanTypeMismatchArgumentInternal
                $ttl = mt_rand( 4e6, 5e6 ) / 1e6;
                # Keep keys around longer as fallbacks
                $staleTTL = 60;
index 874e872..9058340 100644 (file)
@@ -26,8 +26,6 @@
  * All metadata related, since both JPEG and TIFF support Exif.
  *
  * @ingroup Media
- * @phan-file-suppress PhanUndeclaredConstant Phan doesn't read constants in MediaHandler
- *   when accessed via self::
  */
 class ExifBitmapHandler extends BitmapHandler {
        const BROKEN_FILE = '-1'; // error extracting metadata
index 5c55124..b27338c 100644 (file)
@@ -4271,7 +4271,6 @@ class Parser {
         * @param bool $isMain
         * @return mixed|string
         * @private
-        * @suppress PhanTypeInvalidDimOffset
         */
        public function formatHeadings( $text, $origText, $isMain = true ) {
                # Inhibit editsection links if requested in the page
@@ -5578,7 +5577,6 @@ class Parser {
                Hooks::run( 'ParserMakeImageParams', [ $title, $file, &$params, $this ] );
 
                # Linker does the rest
-               // @phan-suppress-next-line PhanTypeInvalidDimOffset
                $time = $options['time'] ?? false;
                $ret = Linker::makeImageLink( $this, $title, $file, $params['frame'], $params['handler'],
                        $time, $descQuery, $this->mOptions->getThumbSize() );
index 93f4246..bd610de 100644 (file)
@@ -40,6 +40,7 @@ class ParserDiffTest {
                if ( !is_null( $this->parsers ) ) {
                        return;
                }
+               $this->parsers = [];
 
                if ( isset( $this->conf['shortOutput'] ) ) {
                        $this->shortOutput = $this->conf['shortOutput'];
index 9b5b29e..d0b7ae3 100644 (file)
@@ -61,7 +61,6 @@ 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 PhanTypeMismatchReturn
                        return;
                        // @codeCoverageIgnoreEnd
                }
index 8303896..151b5fd 100644 (file)
@@ -427,7 +427,6 @@ JAVASCRIPT;
                                $idx = -1;
                                foreach ( $grpModules as $name => $module ) {
                                        $shouldEmbed = $module->shouldEmbedModule( $context );
-                                       // @phan-suppress-next-line PhanTypeInvalidDimOffset
                                        if ( !$moduleSets || $moduleSets[$idx][0] !== $shouldEmbed ) {
                                                $moduleSets[++$idx] = [ $shouldEmbed, [] ];
                                        }
index 9c204fc..55e9e53 100644 (file)
@@ -137,7 +137,6 @@ class ResourceLoaderOOUIImageModule extends ResourceLoaderImageModule {
                                        $dataPath->getRemoteBasePath()
                                );
                        } else {
-                               // @phan-suppress-next-line PhanTypeSuspiciousStringExpression
                                $path = dirname( $dataPath ) . '/' . $path;
                        }
                };
index 1da0ceb..09cdf72 100644 (file)
@@ -286,7 +286,6 @@ final class SessionManager implements SessionManagerInterface {
                                        "$provider returned empty session info with id flagged unsafe"
                                );
                        }
-                       // @phan-suppress-next-line PhanTypeInvalidDimOffset
                        $compare = $infos ? SessionInfo::compare( $infos[0], $info ) : -1;
                        if ( $compare > 0 ) {
                                continue;
index 74d77a8..478a615 100644 (file)
@@ -238,7 +238,6 @@ class Shell {
                // Give site config file a chance to run the script in a wrapper.
                // The caller may likely want to call wfBasename() on $script.
                Hooks::run( 'wfShellWikiCmd', [ &$script, &$parameters, &$options ] );
-               // @phan-suppress-next-line PhanTypeInvalidDimOffset
                $cmd = [ $options['php'] ?? $wgPhpCli ];
                if ( isset( $options['wrapper'] ) ) {
                        $cmd[] = $options['wrapper'];
index bee4aff..cd63796 100644 (file)
@@ -516,7 +516,6 @@ abstract class BaseTemplate extends QuickTemplate {
                if ( isset( $item['itemtitle'] ) ) {
                        $attrs['title'] = $item['itemtitle'];
                }
-               // @phan-suppress-next-line PhanTypeInvalidDimOffset
                return Html::rawElement( $options['tag'] ?? 'li', $attrs, $html );
        }
 
index 2dcb77f..60cbff1 100644 (file)
@@ -47,6 +47,7 @@ class UncategorizedCategoriesPage extends UncategorizedPagesPage {
         */
        private function getExceptionList() {
                if ( $this->exceptionList === null ) {
+                       $this->exceptionList = [];
                        $exList = $this->msg( 'uncategorized-categories-exceptionlist' )
                                ->inContentLanguage()->plain();
                        $proposedTitles = explode( "\n", $exList );
index 63cff94..4441a33 100644 (file)
@@ -74,7 +74,7 @@ class BlockListPager extends TablePager {
         * @param string $name
         * @param string $value
         * @return string
-        * @suppress PhanTypeArraySuspiciousNullable,PhanTypeArraySuspicious
+        * @suppress PhanTypeArraySuspicious
         */
        function formatValue( $name, $value ) {
                static $msg = null;
index 105eeaa..365ec4d 100644 (file)
@@ -341,7 +341,7 @@ class NamespaceInfo {
         * Returns array of all defined namespaces with their canonical
         * (English) names.
         *
-        * @return array
+        * @return string[]
         */
        public function getCanonicalNamespaces() {
                if ( $this->canonicalNamespaces === null ) {
@@ -396,6 +396,7 @@ class NamespaceInfo {
         */
        public function getValidNamespaces() {
                if ( is_null( $this->validNamespaces ) ) {
+                       $this->validNamespaces = [];
                        foreach ( array_keys( $this->getCanonicalNamespaces() ) as $ns ) {
                                if ( $ns >= 0 ) {
                                        $this->validNamespaces[] = $ns;
index ad6b5b8..7068879 100644 (file)
@@ -249,7 +249,8 @@ class User implements IDBAccessObject, UserIdentity {
                        return $this->$name;
                } else {
                        wfLogWarning( 'tried to get non-visible property' );
-                       return null;
+                       $null = null;
+                       return $null;
                }
        }
 
index 16a6e1a..51ff8d5 100644 (file)
@@ -527,7 +527,6 @@ class Language {
                        }
 
                        # Sometimes a language will be localised but not actually exist on this wiki.
-                       // @phan-suppress-next-line PhanTypeMismatchForeach
                        foreach ( $this->namespaceNames as $key => $text ) {
                                if ( !isset( $validNamespaces[$key] ) ) {
                                        unset( $this->namespaceNames[$key] );
@@ -536,7 +535,6 @@ class Language {
 
                        # The above mixing may leave namespaces out of canonical order.
                        # Re-order by namespace ID number...
-                       // @phan-suppress-next-line PhanTypeMismatchArgumentInternal
                        ksort( $this->namespaceNames );
 
                        Hooks::run( 'LanguageGetNamespaces', [ &$this->namespaceNames ] );
@@ -3237,7 +3235,6 @@ class Language {
                $fallbackChain = array_reverse( $fallbackChain );
                foreach ( $fallbackChain as $code ) {
                        if ( isset( $newWords[$code] ) ) {
-                               // @phan-suppress-next-line PhanTypeMismatchProperty
                                $this->mMagicExtensions = $newWords[$code] + $this->mMagicExtensions;
                        }
                }
index d899590..6d6dbe5 100644 (file)
@@ -89,7 +89,11 @@ abstract class Maintenance {
        // Const for getStdin()
        const STDIN_ALL = 'all';
 
-       // Array of desired/allowed params
+       /**
+        * Array of desired/allowed params
+        * @var array[]
+        * @phan-var array<string,array{desc:string,require:bool,withArg:string,shortName:string,multiOccurrence:bool}>
+        */
        protected $mParams = [];
 
        // Array of mapping short parameters to long ones
@@ -128,9 +132,17 @@ abstract class Maintenance {
         */
        protected $mBatchSize = null;
 
-       // Generic options added by addDefaultParams()
+       /**
+        * Generic options added by addDefaultParams()
+        * @var array[]
+        * @phan-var array<string,array{desc:string,require:bool,withArg:string,shortName:string,multiOccurrence:bool}>
+        */
        private $mGenericParameters = [];
-       // Generic options which might or not be supported by the script
+       /**
+        * Generic options which might or not be supported by the script
+        * @var array[]
+        * @phan-var array<string,array{desc:string,require:bool,withArg:string,shortName:string,multiOccurrence:bool}>
+        */
        private $mDependantParameters = [];
 
        /**
index 558fec8..357bf1b 100644 (file)
@@ -59,6 +59,7 @@ class BenchmarkTidy extends Benchmarker {
                $min = $times[0];
                $max = end( $times );
                if ( $n % 2 ) {
+                       // @phan-suppress-next-line PhanTypeMismatchDimFetch
                        $median = $times[ ( $n - 1 ) / 2 ];
                } else {
                        $median = ( $times[$n / 2] + $times[$n / 2 - 1] ) / 2;
index 737e65f..409ecdf 100644 (file)
@@ -279,7 +279,6 @@ class ConvertExtensionToRegistration extends Maintenance {
        /**
         * @param string $realName
         * @param array[] $value
-        * @suppress PhanTypeInvalidDimOffset
         */
        protected function handleResourceModules( $realName, $value ) {
                $defaults = [];
index e4d1f09..7f8e16a 100644 (file)
@@ -358,7 +358,7 @@ class ImportImages extends Maintenance {
                                                # Protect the file
                                                $this->output( "\nWaiting for replica DBs...\n" );
                                                // Wait for replica DBs.
-                                               sleep( 2.0 ); # Why this sleep?
+                                               sleep( 2 ); # Why this sleep?
                                                wfWaitForSlaves();
 
                                                $this->output( "\nSetting image restrictions ... " );
index 60f88ba..6a04b98 100644 (file)
@@ -38,7 +38,7 @@ class OrphanStats extends Maintenance {
                        "Show some statistics on the blob_orphans table, created with trackBlobs.php" );
        }
 
-       protected function &getDB( $cluster, $groups = [], $wiki = false ) {
+       protected function getDB( $cluster, $groups = [], $wiki = false ) {
                $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
                $lb = $lbFactory->getExternalLB( $cluster );