Bug: T231636
Depends-On: I58e67c2b38389df874438deada4239510d21654f
Change-Id: I6e5fba7bd273219b1206559420b5bdb78734aa84
38 files changed:
"PhanParamTooMany",
// approximate error count: 63
"PhanTypeArraySuspicious",
"PhanParamTooMany",
// approximate error count: 63
"PhanTypeArraySuspicious",
- // approximate error count: 28
- "PhanTypeArraySuspiciousNullable",
// approximate error count: 88
"PhanTypeInvalidDimOffset",
// approximate error count: 60
"PhanTypeMismatchArgument",
// approximate error count: 88
"PhanTypeInvalidDimOffset",
// approximate error count: 60
"PhanTypeMismatchArgument",
- // approximate error count: 40
- "PhanTypeMismatchProperty",
// approximate error count: 36
"PhanUndeclaredConstant",
// approximate error count: 219
// approximate error count: 36
"PhanUndeclaredConstant",
// approximate error count: 219
if ( isset( $ctx['forwarded_for'] ) ||
isset( $ctx['client_ip'] ) ||
isset( $ctx['from'] ) ) {
if ( isset( $ctx['forwarded_for'] ) ||
isset( $ctx['client_ip'] ) ||
isset( $ctx['from'] ) ) {
+ // @phan-suppress-next-line PhanTypeArraySuspiciousNullable
$ctx['proxy'] = $_SERVER['REMOTE_ADDR'];
}
$ctx['proxy'] = $_SERVER['REMOTE_ADDR'];
}
* @todo document
*/
class OutputPage extends ContextSource {
* @todo document
*/
class OutputPage extends ContextSource {
- /** @var array Should be private. Used with addMeta() which adds "<meta>" */
+ /** @var string[][] Should be private. Used with addMeta() which adds "<meta>" */
protected $mMetatags = [];
/** @var array */
protected $mMetatags = [];
/** @var array */
/** @var NamespaceInfo */
private $nsInfo;
/** @var NamespaceInfo */
private $nsInfo;
- /** @var string[] Cached results of getAllRights() */
- private $allRights = false;
+ /** @var string[]|null Cached results of getAllRights() */
+ private $allRights;
/** @var string[][] Cached user rights */
private $usersRights = null;
/** @var string[][] Cached user rights */
private $usersRights = null;
* @return string[] Array of permission names
*/
public function getAllPermissions() {
* @return string[] Array of permission names
*/
public function getAllPermissions() {
- if ( $this->allRights === false ) {
+ if ( $this->allRights === null ) {
if ( count( $this->options->get( 'AvailableRights' ) ) ) {
$this->allRights = array_unique( array_merge(
$this->coreRights,
if ( count( $this->options->get( 'AvailableRights' ) ) ) {
$this->allRights = array_unique( array_merge(
$this->coreRights,
/** @var bool Whether a page has any subpages */
private $mHasSubpages;
/** @var bool Whether a page has any subpages */
private $mHasSubpages;
- /** @var bool The (string) language code of the page's language and content code. */
- private $mPageLanguage = false;
+ /** @var array|null The (string) language code of the page's language and content code. */
+ private $mPageLanguage;
/** @var string|bool|null The page language code from the database, null if not saved in
* the database or false if not loaded, yet.
/** @var string|bool|null The page language code from the database, null if not saved in
* the database or false if not loaded, yet.
$this->mLatestID = false;
$this->mContentModel = false;
$this->mEstimateRevisions = null;
$this->mLatestID = false;
$this->mContentModel = false;
$this->mEstimateRevisions = null;
- $this->mPageLanguage = false;
+ $this->mPageLanguage = null;
$this->mDbPageLanguage = false;
$this->mIsBigDeletion = null;
}
$this->mDbPageLanguage = false;
$this->mIsBigDeletion = null;
}
/** @var array Maps extension paths to info arrays */
private static $extensionInfo = null;
/** @var array Maps extension paths to info arrays */
private static $extensionInfo = null;
- /** @var int[][][] Cache for self::filterIDs() */
+ /** @var stdClass[][] Cache for self::filterIDs() */
private static $filterIDsCache = [];
/** $var array Map of web UI block messages to corresponding API messages and codes */
private static $filterIDsCache = [];
/** $var array Map of web UI block messages to corresponding API messages and codes */
/** @var Title $newTitle */
foreach ( $titles as $id => $newTitle ) {
/** @var Title $newTitle */
foreach ( $titles as $id => $newTitle ) {
- if ( !isset( $titles[$id - 1] ) ) {
- $titles[$id - 1] = $oldTitle;
- }
+ $titles[ $id - 1 ] = $titles[ $id - 1 ] ?? $oldTitle;
$redirValues[] = [
'from' => $titles[$id - 1]->getPrefixedText(),
$redirValues[] = [
'from' => $titles[$id - 1]->getPrefixedText(),
* @param string $search the search query
* @param array $params api request params
* @return array search results. Keys are integers.
* @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}>
+ * Note that phan annotations don't support keys containing a space.
*/
private function search( $search, array $params ) {
$searchEngine = $this->buildSearchEngine( $params );
*/
private function search( $search, array $params ) {
$searchEngine = $this->buildSearchEngine( $params );
if ( is_string( $r['extract'] ) && $r['extract'] !== '' ) {
$item['Description'] = $r['extract'];
}
if ( is_string( $r['extract'] ) && $r['extract'] !== '' ) {
$item['Description'] = $r['extract'];
}
+ // @phan-suppress-next-line PhanTypeArraySuspiciousNullable
if ( is_array( $r['image'] ) && isset( $r['image']['source'] ) ) {
$item['Image'] = array_intersect_key( $r['image'], $imageKeys );
}
if ( is_array( $r['image'] ) && isset( $r['image']['source'] ) ) {
$item['Image'] = array_intersect_key( $r['image'], $imageKeys );
}
- $fit = $result->addValue( [ 'query', $this->getModuleName() ],
- null, $data[$u] );
+ // @phan-suppress-next-line PhanTypeArraySuspiciousNullable
+ $fit = $result->addValue( [ 'query', $this->getModuleName() ], null, $data[$u] );
if ( !$fit ) {
if ( $useNames ) {
$this->setContinueEnumParameter( 'users',
if ( !$fit ) {
if ( $useNames ) {
$this->setContinueEnumParameter( 'users',
}
$options['sensitive'] = !empty( $options['sensitive'] );
}
$options['sensitive'] = !empty( $options['sensitive'] );
+ // @phan-suppress-next-line PhanTypeArraySuspiciousNullable
+ $type = $options['type'];
if ( !array_key_exists( $name, $merged ) ) {
$merged[$name] = $options;
if ( !array_key_exists( $name, $merged ) ) {
$merged[$name] = $options;
- } elseif ( $merged[$name]['type'] !== $options['type'] ) {
+ } elseif ( $merged[$name]['type'] !== $type ) {
throw new \UnexpectedValueException( "Field type conflict for \"$name\", " .
throw new \UnexpectedValueException( "Field type conflict for \"$name\", " .
- "\"{$merged[$name]['type']}\" vs \"{$options['type']}\""
+ "\"{$merged[$name]['type']}\" vs \"$type\""
);
} else {
if ( isset( $options['options'] ) ) {
);
} else {
if ( isset( $options['options'] ) ) {
* Function that gets called when initialization is done.
*
* @since 1.20
* Function that gets called when initialization is done.
*
* @since 1.20
- protected $onInitHandler = false;
+ protected $onInitHandler;
/**
* Elements to build a cache key with.
/**
* Elements to build a cache key with.
$this->hasCached = is_array( $cachedChunks );
$this->cachedChunks = $this->hasCached ? $cachedChunks : [];
$this->hasCached = is_array( $cachedChunks );
$this->cachedChunks = $this->hasCached ? $cachedChunks : [];
- if ( $this->onInitHandler !== false ) {
+ if ( $this->onInitHandler !== null ) {
call_user_func( $this->onInitHandler, $this->hasCached );
}
}
call_user_func( $this->onInitHandler, $this->hasCached );
}
}
$class = $wgParserConf['class'];
if ( $class == ParserDiffTest::class ) {
# Uncloneable
$class = $wgParserConf['class'];
if ( $class == ParserDiffTest::class ) {
# Uncloneable
+ // @phan-suppress-next-line PhanTypeMismatchProperty
$this->mParser = new $class( $wgParserConf );
} else {
$this->mParser = clone $parser;
$this->mParser = new $class( $wgParserConf );
} else {
$this->mParser = clone $parser;
*/
class LCStoreCDB implements LCStore {
*/
class LCStoreCDB implements LCStore {
+ /** @var Reader[]|false[] */
private $readers;
/** @var Writer */
private $readers;
/** @var Writer */
*/
public $mTitle = false;
/**
*/
public $mTitle = false;
/**
*/
private $mPerformer = false;
*/
private $mPerformer = false;
? count( $data['query']['redirects'] ) - 1
: -1;
if ( $lastRedirect >= 0 ) {
? count( $data['query']['redirects'] ) - 1
: -1;
if ( $lastRedirect >= 0 ) {
+ // @phan-suppress-next-line PhanTypeArraySuspiciousNullable
$newtitle = Title::newFromText( $data['query']['redirects'][$lastRedirect]['to'] );
$img = new self( $newtitle, $repo, $info, true );
$img->redirectedFrom( $title->getDBkey() );
$newtitle = Title::newFromText( $data['query']['redirects'][$lastRedirect]['to'] );
$img = new self( $newtitle, $repo, $info, true );
$img->redirectedFrom( $title->getDBkey() );
protected $mHideBadImages;
/**
protected $mHideBadImages;
/**
- * @var Parser Registered parser object for output callbacks
+ * @var Parser|false Registered parser object for output callbacks
/** @var array */
protected $mAttribs = [];
/** @var array */
protected $mAttribs = [];
- /** @var bool */
- private static $modeMapping = false;
+ /** @var array */
+ private static $modeMapping;
/**
* Get a new image gallery. This is the method other callers
/**
* Get a new image gallery. This is the method other callers
}
private static function loadModes() {
}
private static function loadModes() {
- if ( self::$modeMapping === false ) {
+ if ( self::$modeMapping === null ) {
self::$modeMapping = [
'traditional' => TraditionalImageGallery::class,
'nolines' => NolinesImageGallery::class,
self::$modeMapping = [
'traditional' => TraditionalImageGallery::class,
'nolines' => NolinesImageGallery::class,
* 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.
* 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 = [];
*/
class HTMLAutoCompleteSelectField extends HTMLTextField {
protected $autocompleteData = [];
protected $handler = null;
protected $sink = null;
protected $handler = null;
protected $sink = null;
protected $guzzleOptions = [ 'http_errors' => false ];
/**
protected $guzzleOptions = [ 'http_errors' => false ];
/**
$stat = $this->getFileStat( $params );
}
$stat = $this->getFileStat( $params );
}
+ // @phan-suppress-next-line PhanTypeArraySuspiciousNullable
return $stat['xattr'];
} else {
return false;
return $stat['xattr'];
} else {
return false;
* @see https://dev.mysql.com/doc/refman/5.6/en/replication-gtids-concepts.html
*/
class MySQLMasterPos implements DBMasterPos {
* @see https://dev.mysql.com/doc/refman/5.6/en/replication-gtids-concepts.html
*/
class MySQLMasterPos implements DBMasterPos {
- /** @var int One of (BINARY_LOG, GTID_MYSQL, GTID_MARIA) */
+ /** @var string One of (BINARY_LOG, GTID_MYSQL, GTID_MARIA) */
private $style;
/** @var string|null Base name of all Binary Log files */
private $binLog;
private $style;
/** @var string|null Base name of all Binary Log files */
private $binLog;
/** @var DatabaseDomain Local DB domain ID and default for selectDB() calls */
private $localDomain;
/** @var DatabaseDomain Local DB domain ID and default for selectDB() calls */
private $localDomain;
- /** @var Database[][][] Map of (connection category => server index => IDatabase[]) */
+ /**
+ * @var IDatabase[][][]|Database[][][] Map of (connection category => server index => IDatabase[])
+ */
private $conns;
/** @var array[] Map of (server index => server config array) */
private $conns;
/** @var array[] Map of (server index => server config array) */
private $tableAliases = [];
/** @var string[] Map of (index alias => index) */
private $indexAliases = [];
private $tableAliases = [];
/** @var string[] Map of (index alias => index) */
private $indexAliases = [];
- /** @var array[] Map of (name => callable) */
+ /** @var callable[] Map of (name => callable) */
private $trxRecurringCallbacks = [];
/** @var bool[] Map of (domain => whether to use "temp tables only" mode) */
private $tempTablesOnlyMode = [];
private $trxRecurringCallbacks = [];
/** @var bool[] Map of (domain => whether to use "temp tables only" mode) */
private $tempTablesOnlyMode = [];
* Exif::getFilteredData() or BitmapMetadataHandler )
* @return array
* @since 1.23
* Exif::getFilteredData() or BitmapMetadataHandler )
* @return array
* @since 1.23
+ * @suppress PhanTypeArraySuspiciousNullable
*/
public function makeFormattedData( $tags ) {
$resolutionunit = !isset( $tags['ResolutionUnit'] ) || $tags['ResolutionUnit'] == 2 ? 2 : 3;
*/
public function makeFormattedData( $tags ) {
$resolutionunit = !isset( $tags['ResolutionUnit'] ) || $tags['ResolutionUnit'] == 2 ? 2 : 3;
$this->numServerShards = count( $this->serverInfos );
} else {
// Default to using the main wiki's database servers
$this->numServerShards = count( $this->serverInfos );
} else {
// Default to using the main wiki's database servers
- $this->serverInfos = false;
+ $this->serverInfos = [];
$this->numServerShards = 1;
$this->attrMap[self::ATTR_SYNCWRITES] = self::QOS_SYNCWRITES_BE;
}
$this->numServerShards = 1;
$this->attrMap[self::ATTR_SYNCWRITES] = self::QOS_SYNCWRITES_BE;
}
*/
public $mLatest = false;
*/
public $mLatest = false;
- /** @var PreparedEdit Map of cache fields (text, parser output, ect) for a proposed/new edit */
+ /**
+ * @var PreparedEdit|false Map of cache fields (text, parser output, ect) for a proposed/new edit
+ */
public $mPreparedEdit = false;
/**
public $mPreparedEdit = false;
/**
protected $modules = self::INHERIT_VALUE;
protected $language = self::INHERIT_VALUE;
protected $direction = self::INHERIT_VALUE;
protected $modules = self::INHERIT_VALUE;
protected $language = self::INHERIT_VALUE;
protected $direction = self::INHERIT_VALUE;
if ( $this->modules === self::INHERIT_VALUE ) {
return $this->context->getModules();
}
if ( $this->modules === self::INHERIT_VALUE ) {
return $this->context->getModules();
}
- // @phan-suppress-next-line PhanTypeMismatchReturn
protected $direction;
protected $hash;
protected $userObj;
protected $direction;
protected $hash;
protected $userObj;
+ /** @var ResourceLoaderImage|false */
+ /**
+ * @param string $name
+ * @param string $value
+ * @return string
+ * @suppress PhanTypeArraySuspiciousNullable
+ */
function formatValue( $name, $value ) {
static $msg = null;
if ( $msg === null ) {
function formatValue( $name, $value ) {
static $msg = null;
if ( $msg === null ) {
- /**
- * @var string[]
- * @var string[] Cached results of getAllRights()
- */
- protected static $mAllRights = false;
-
/** Cache variables */
// @{
/** @var int */
/** Cache variables */
// @{
/** @var int */
protected $startToken;
/**
protected $startToken;
/**
- * @var array List of tokens that are members of the current expect sequence
+ * @var array[]|string[] List of tokens that are members of the current expect sequence
* @param string $profile The currently selected profile
* @param string $term The user provided search terms
* @return string HTML
* @param string $profile The currently selected profile
* @param string $term The user provided search terms
* @return string HTML
+ * @suppress PhanTypeArraySuspiciousNullable
*/
protected function profileTabsHtml( $profile, $term ) {
$bareterm = $this->startsWithImage( $term )
*/
protected function profileTabsHtml( $profile, $term ) {
$bareterm = $this->startsWithImage( $term )
public $mVariants, $mCode, $mLoaded = false;
public $mMagicExtensions = [];
public $mVariants, $mCode, $mLoaded = false;
public $mMagicExtensions = [];
- private $mHtmlCode = null, $mParentLanguage = false;
+ private $mHtmlCode = null;
+ /** @var Language|false */
+ private $mParentLanguage = false;
public $dateFormatStrings = [];
public $mExtendedSpecialPageAliases;
public $dateFormatStrings = [];
public $mExtendedSpecialPageAliases;
}
function __construct() {
}
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' ) {
$this->mConverter = new FakeConverter( $this );
// Set the code to the name of the descendant
if ( static::class === 'Language' ) {
$fallbackChain = array_reverse( $fallbackChain );
foreach ( $fallbackChain as $code ) {
if ( isset( $newWords[$code] ) ) {
$fallbackChain = array_reverse( $fallbackChain );
foreach ( $fallbackChain as $code ) {
if ( isset( $newWords[$code] ) ) {
+ // @phan-suppress-next-line PhanTypeMismatchProperty
$this->mMagicExtensions = $newWords[$code] + $this->mMagicExtensions;
}
}
$this->mMagicExtensions = $newWords[$code] + $this->mMagicExtensions;
}
}
public $mTablesLoaded = false;
/**
public $mTablesLoaded = false;
/**
- * @var ReplacementArray[]
- * @phan-var array<string,ReplacementArray>
+ * @var ReplacementArray[]|bool[]
}
$this->mTablesLoaded = true;
}
$this->mTablesLoaded = true;
- $this->mTables = false;
$cache = ObjectCache::getInstance( $wgLanguageConverterCacheType );
$cacheKey = $cache->makeKey( 'conversiontables', $this->mMainLanguageCode );
if ( $fromCache ) {
$cache = ObjectCache::getInstance( $wgLanguageConverterCacheType );
$cacheKey = $cache->makeKey( 'conversiontables', $this->mMainLanguageCode );
if ( $fromCache ) {
// backends in FileBackendMultiWrite (since they get writes second, they have
// higher timestamps). However, when copying the other way, this hits loads of
// false positives (possibly 100%) and wastes a bunch of time on GETs/PUTs.
// backends in FileBackendMultiWrite (since they get writes second, they have
// higher timestamps). However, when copying the other way, this hits loads of
// false positives (possibly 100%) and wastes a bunch of time on GETs/PUTs.
+ // @phan-suppress-next-line PhanTypeArraySuspiciousNullable
$same = ( $srcStat['mtime'] <= $dstStat['mtime'] );
} else {
// This is the slowest method which does many per-file HEADs (unless an object
$same = ( $srcStat['mtime'] <= $dstStat['mtime'] );
} else {
// This is the slowest method which does many per-file HEADs (unless an object
/**
* A resource pointing to a sitemap file
*
/**
* A resource pointing to a sitemap file
*
public $uploads = false;
protected $uploadCount = 0;
public $imageBasePath = false;
public $uploads = false;
protected $uploadCount = 0;
public $imageBasePath = false;
+ /** @var array|false */
public $nsFilter = false;
function __construct() {
public $nsFilter = false;
function __construct() {
protected $spawnProc = false;
/**
protected $spawnProc = false;
/**
- protected $spawnWrite = false;
- protected $spawnRead = false;
if ( $this->spawnRead ) {
fclose( $this->spawnRead );
}
if ( $this->spawnRead ) {
fclose( $this->spawnRead );
}
- $this->spawnRead = false;
+ $this->spawnRead = null;
if ( $this->spawnWrite ) {
fclose( $this->spawnWrite );
}
if ( $this->spawnWrite ) {
fclose( $this->spawnWrite );
}
- $this->spawnWrite = false;
+ $this->spawnWrite = null;
if ( $this->spawnErr ) {
fclose( $this->spawnErr );
}
if ( $this->spawnErr ) {
fclose( $this->spawnErr );
}
/** @var RecompressTracked */
public $parent;
public $blobClass;
/** @var RecompressTracked */
public $parent;
public $blobClass;
- /** @var ConcatenatedGzipHistoryBlob */
+ /** @var ConcatenatedGzipHistoryBlob|false */
public $cgz;
public $referrers;
public $cgz;
public $referrers;