Переопределить PHP-докблок / аннотацию метода без перегрузки (автозаполнение PhpStorm)
Это вопрос о поведении автозаполнения в PhpStorm (и, возможно, других IDE) в сочетании с докблоками PHP.
У меня есть группы классов в моем приложении. Во-первых, существуют отдельные классы для различных продуктов (CarProduct, FoodProduct и т. Д.), Все они наследуются от BaseProduct, и аналог для отдельных контрактов (CarContract, FoodContract и т. Д.), Все они наследуются от BaseContract.
<?php
class BaseContract
{
/** @var BaseProduct */
private $product;
/**
* @return BaseProduct
*/
public function getProduct()
{
return $this->product;
}
}
Теперь у меня есть экземпляр CarContract, и я хочу получить определенную информацию о CarProduct:
<?php
/* PhpStorm thinks, this is BaseProduct */
$product = $carContract->getProduct();
/* hence, getSpeed() is not available for PhpStorm */
$product->getSpeed();
Автозаполнение не работает, как мне нравится. Есть два обходных пути для этого, но оба не хороши:
- Перегрузка getProduct() в подклассе, только с обновленным
@return
docblocks - добавлять
/** @var CarProduct $product */
везде, где я получаю доступ к продукту CarContract
Есть ли "обычный" способ решить что-то подобное или мои обходные пути - единственные решения?
1 ответ
PhpStorm на самом деле не позволяет / не поддерживает выполнение чего-то подобного: иметь такой же именованный класс, определенный в другом месте, и просто использовать его как ссылку для переопределения определений реального класса. Вы можете сделать это... но IDE выдаст предупреждение с "несколькими определениями одного и того же класса", и это может привести к странному поведению / неожиданным предупреждениям...
Вот билет, который запрашивает такую функцию: https://youtrack.jetbrains.com/issue/WI-851 - смотрите его (звезда / голосование / комментарий), чтобы получать уведомления о любом прогрессе.
Ваши варианты: вы можете предоставить правильный тип подсказки локально (для локальной переменной), используя @var
- вы уже знаете это, и это первое, что вы подумали бы о:
<?php
/** @var \CarProduct $product */
$product = $carContract->getProduct();
$product->getSpeed();
Другой возможный способ: вместо переопределения фактического метода.. вы можете попробовать сделать то же самое, но с @method
PHPDoc - будет работать с вашим кодом:
<?php
/**
* My Car Product class
*
* @method \CarProduct getProduct() Bla-bla optional description
*/
class CarContract extends BaseContract ...