Поддержка IntelliSense для COM-интерфейсов, содержащихся в библиотеке типов.

Есть ли способ получить нормальную функциональность IntelliSense в PhpStorm для типов, содержащихся в библиотеке типов COM?

В FoxPro я получаю полную поддержку IntelliSense, как только переменная объявляется как COM-интерфейс (она извлекает информацию из реестра); в Delphi и Visual Studio я могу заставить среду IDE создать некоторые артефакты импорта для библиотек типов (модуль импорта, сборка взаимодействия), чтобы IntelliSense работал. Однако пока мне не удалось найти способ заставить IntelliSense работать с библиотеками типов в PhpStorm.

Все упоминания библиотек типов COM, которые я нашел, относятся только к способности PHP загружать константы (com_load_typelib()), но мне нужна информация о методах и параметрах. Я был бы не против сгенерировать файлы для PhpStorm из моих библиотек типов или даже вручную создать некоторые определения для интерфейсов COM, которые я использую чаще всего. Однако мне действительно нужен нормальный IntelliSense для COM-интерфейсов, чтобы не сойти с ума.

Есть ли способ очистить эту кошку?

1 ответ

Решение

Как предлагает LazyOne, ручной подход может быть таким же простым, как написание объявления-заглушки и сброс файла php где-нибудь в дереве проекта или пути поиска (например, в соответствующем каталоге заглушек):

      <?php
/** allows observing the server lock/object counts and unloadability state of a COM module that uses the
 * Zrbj.COM.ComServerLocking infrastructure
 * @property-read int $Revision revision of the observer module implementation
 * @property-read string $ServerDLL executable which houses the code for this observer object
 */
interface ISrvDllObserver
{
    /** server lock count information (ICounterInfo) for this object's own server module */
    public function GetCountsForOwnModule (): ICounterInfo;

    /** server lock count information (ICounterInfo) for a loaded COM module that uses Zrbj.COM.ComServerLocking.
     * @param string $module_name basename without file extension is sufficient unless there are multiple loaded
     * modules with the same basename; use path and/or file extension to disambiguate
     */
    public function GetCountsForLoadedModule (string $module_name): ICounterInfo;
}

С этого момента IntelliSense работает отлично.

Ручной процесс может дать отличные результаты, но он чрезвычайно трудоемок. Я вспомнил объект со сценариями для обработки библиотек типов, который поставлялся с FoxPro и более ранними версиями Visual Studio, tlbinf32.dll(+). ProgID для начала.

Единственная сохранившаяся ссылка на этот инструмент, которую я смог найти на microsoft.com, - это эта старая статья:

Visual Basic: проверка компонентов COM с помощью библиотеки информационных объектов TypeLib

Инструмент по-прежнему поставляется с Visual Studio, но теперь вызывается и больше не документируется. vstlbinf.dll все еще относится к старому tlbinf32.chmв качестве файла справки, но он больше не поставляется. Старая документация по-прежнему полезна для понимания объектной модели, даже если она относится к версии, которая старше на два десятилетия. (Примечание: может потребоваться зарегистрировать DLL вручную.)

Поэтому я взял Delphi и приступил к укрощению. Это оказалось не намного проще, чем работать с ITypeLib, ITypeInfo и т. д. напрямую, но преимущество в том, что TLI.TLIApplication может использоваться с любого языка сценариев, включая сам PHP.

Вот пример информации, которую можно извлечь из библиотеки типов COM для использования в заглушке PHP:

      <?php
// 'k:\VS2019\Community\Common7\IDE\vstlbinf.dll' (2021-04-21 10:05:35)
// processed 2021-05-02 22:39:10 by Zrbj.COM.PhpStubs.pas rev. 2021-05-02
//
// Library: TLI
// Version: 1.0
// LIBID  : {8B217740-717D-11CE-AB5B-D41203C10000}
// Comment: TypeLib Information
// 32 interface(s) and 3 coclass(es)
//
// coclasses:
// * {8B217752-717D-11CE-AB5B-D41203C10000} -> _SearchHelper (ProgID TLI.SearchHelper)
//   'Helper object for GetMembersWithSubString and multiple TypeLibs'
// * {8B217746-717D-11CE-AB5B-D41203C10000} -> _TypeLibInfo (ProgID TLI.TypeLibInfo)
//   'TypeLib information'
// * {8B21775E-717D-11CE-AB5B-D41203C10000} -> _TLIApplication (ProgID TLI.TLIApplication)
//   'TLIApplication object'

/// {8B21774B-717D-11CE-AB5B-D41203C10000} dual nonextensible dispatchable
/** VarType information for parameters and return types
 * @property-read TypeInfo $TypeInfo Type information for VT_PTR VarType
 * @property-read int $TypeInfoNumber TypeInfo number for 0 VarType (Cheaper than TypeInfo property)
 * @property-read variant $TypedVariant Get a variant with this VarType
 * @property-read bool $IsExternalType Is TypeInfo external to this library
 * @property-read TypeLibInfo $TypeLibInfoExternal External typelib. Same as TypeInfo.Parent.
 * @property-read int $PointerLevel Dereferencing level of type
 * @property-read int $VarType VarType of Parameter
 * @property-read int $ElementPointerLevel Dereferencing level for type of an array element
 */
interface VarTypeInfo
{
    /** Get bounds for VT_VECTOR array. LBound in column 1, UBound in column 2. */
    public function ArrayBounds (int $Bounds): int;
}

/// {8B217749-717D-11CE-AB5B-D41203C10000} dual nonextensible dispatchable
/** Parameter Information
 * @property-read string $Name Name of the object
 * @property-read bool $Optional Optional Parameter
 * @property-read VarTypeInfo $VarTypeInfo VarTypeInfo object for this parameter
 * @property-read bool $Default Default Parameter
 * @property-read variant $DefaultValue Default value
 * @property-read bool $HasCustomData Check if custom data is available
 * @property-read CustomDataCollection $CustomDataCollection Custom data GUIDs and Values
 * @property-read int $Flags Parameter Flags
 */
interface ParameterInfo
{
}

...

Явно отсутствуют комментарии к параметрам, потому что их нет в Microsoft IDL или библиотеках типов. Но в целом результат обработки библиотек типов в PHP-заглушки кажется вполне удовлетворительным и, безусловно, значительно упрощает работу с COM-объектами в PHP.

Другие вопросы по тегам