JakubMisek
I was able to create a minimal reproduction successfully with these two files:
.phpstorm.meta.php
<?php
namespace PHPSTORM_META {
override(\Mage::getSingleton(), map([
'stock/movement_collector' => \MWE_Stock_Model_Movement_Collector::class,
]));
}
index.php
<?php
final class Mage
{
/**
* Retrieve model object singleton
*
* @param string $modelClass
* @param array $arguments
* @return Mage_Core_Model_Abstract
*/
public static function getSingleton($modelClass='', array $arguments=array())
{
switch ($modelClass) {
case 'stock/movement_collector':
$registryKey = '_singleton/stock/movement_collector';
$className = \MWE_Stock_Model_Movement_Collector::class;
break;
default:
die('Unknown model class: ' . $modelClass);
}
if (!isset(self::$_registry[$registryKey])) {
self::register($registryKey, new $className());
}
return self::$_registry[$registryKey];
}
}
class MWE_Stock_Model_Movement { }
class MWE_Stock_Model_Movement_Collector
{
/**
* @param MWE_Stock_Model_Movement $movement
* @throws Exception
*/
public function add(MWE_Stock_Model_Movement $movement)
{
return;
}
}
#[\AllowDynamicProperties]
class Varien_Object { }
abstract class Mage_Core_Model_Abstract extends Varien_Object { }
/**
* AdminNotification Inbox model
*
* @method Mage_AdminNotification_Model_Resource_Inbox _getResource()
* @method Mage_AdminNotification_Model_Resource_Inbox getResource()
* @method int getSeverity()
* @method Mage_AdminNotification_Model_Inbox setSeverity(int $value)
* @method string getDateAdded()
* @method Mage_AdminNotification_Model_Inbox setDateAdded(string $value)
* @method string getTitle()
* @method Mage_AdminNotification_Model_Inbox setTitle(string $value)
* @method string getDescription()
* @method Mage_AdminNotification_Model_Inbox setDescription(string $value)
* @method string getUrl()
* @method Mage_AdminNotification_Model_Inbox setUrl(string $value)
* @method int getIsRead()
* @method Mage_AdminNotification_Model_Inbox setIsRead(int $value)
* @method int getIsRemove()
* @method Mage_AdminNotification_Model_Inbox setIsRemove(int $value)
*
* @category Mage
* @package Mage_AdminNotification
* @author Magento Core Team <core@magentocommerce.com>
*/
class Mage_AdminNotification_Model_Inbox extends Mage_Core_Model_Abstract
{
/**
* Add new message
*
* @param int $severity
* @param string $title
* @param string|array $description
* @param string $url
* @param bool $isInternal
* @return $this
*/
public function add($severity, $title, $description, $url = '', $isInternal = true)
{
return $this;
}
}
$movement = new MWE_Stock_Model_Movement();
Mage::getSingleton('stock/movement_collector')->add($movement);

EDIT: Removing the @return Mage_Core_Model_Abstract on the getSingleton method fixes it - but still I think it should not infer a class just because it a parent class of a return value - or at least I'd like that to be optional as I'm sure it will show up in other places.