Как иметь тип в экстернах Closure Compiler без конструктора

Я пытаюсь сделать экстерны для компилятора закрытия Google для типов, у которых нет конструктора.

Я пробовал следующее, но это дает мне ошибку Bad type annotation. Unknown type WindowsMediaActiveX.Cdrom, потому что ничто не говорит компилятору, что WindowsMediaActiveX.Cdrom является типом, а не просто набором методов/свойств.

/**
 * @fileoverview Declares externs for the Windows media player ActiveX control.
 * @author Joshua Dwire
 * @suppress {duplicate}
 */

var WindowsMediaActiveX={};


/**
 * Methods and properties for accessing a CD or DVD in its drive.
 */
WindowsMediaActiveX.Cdrom={};


/**
 * Retrieves the CD or DVD drive letter.
 * @type {string}
 * @readonly
 */
WindowsMediaActiveX.Cdrom.prototype.driveSpecifier;



/**
 * Methods and properties for accessing a collection of CD or DVD drives.
 */
WindowsMediaActiveX.CdromCollection={};


/**
 * Retrieves the Cdrom object associated with a particular drive letter.
 * @param {string} driveSpecifier String containing the drive letter followed by a colon (":") character.
 * @returns {WindowsMediaActiveX.Cdrom}
 */
WindowsMediaActiveX.CdromCollection.prototype.getByDriveSpecifier=function(driveSpecifier){};

Я знаю, что могу измениться:

/**
 * Methods and properties for accessing a CD or DVD in its drive.
 */
WindowsMediaActiveX.Cdrom={};

to:

/**
 * Methods and properties for accessing a CD or DVD in its drive.
 * @constructor
 */
WindowsMediaActiveX.Cdrom=function(){};

но тогда компилятор не будет показывать предупреждение, если я или кто-то другой попытается использовать new WindowsMediaActiveX.Cdrom(). Любые идеи о том, как это определить?

Для тех из вас, кому нужна дополнительная информация, я работаю над медиаплеером, который будет использовать элемент управления Windows Media ActiveX для воспроизведения мультимедиа. Я также использую компилятор и библиотеку Google Closure. Мне нужно определить внешние элементы, чтобы проигрыватель работал правильно, но ни один из типов, используемых элементом управления ActiveX, не имеет конструкторов. Все они создаются другими методами или путем создания объекта в html. Как мне определить это во внешнем файле? Спасибо за вашу помощь.


person Joshua Dwire    schedule 02.11.2012    source источник
comment
Из любопытства, почему свойство .prototype устанавливается для произвольного объекта? Объекты не имеют прототипа по умолчанию (({}).prototype не определено), и они все равно не могут быть созданы для использования прототипа. Используют ли эти компоненты ActiveX некоторые прототипы способом, с которым я не знаком?   -  person August Lilleaas    schedule 02.11.2012
comment
Все объекты создаются чем-то другим, кроме нового ключевого слова. Компонент ActiveX создает все объекты, и мне нужно определить для них внешние элементы. Экстерны специфичны для Closure Compiler. Вы знакомы с Closure Compiler?   -  person Joshua Dwire    schedule 02.11.2012
comment
Так что ActiveX, вероятно, делает что-то вроде var f = function () {}; f.prototype = WindowsMediaActiveX.Cdrom.prototype; new f() под капотом? Я не удивлюсь, если Closure Compiler не поддерживает это с его специальным знанием свойства prototype. Мое использование компилятора было очень простым, и только с JS, совместимым с расширенным режимом (никаких причудливых хакерских вещей). Моим следующим шагом было бы задать вопрос в списке рассылки компилятора замыкания, размещенном в группах Google, там активно работают многие гуглеры.   -  person August Lilleaas    schedule 02.11.2012
comment
WindowsMediaActiveX.Cdrom — это просто то, что я определяю, поэтому у меня есть тип, на который можно ссылаться. На самом деле объекты будут созданы путем вставки HTML-кода (см. msdn.microsoft.com/en-us/library/windows/desktop/) или вызвав метод элемента player. Эти методы будут добавлены ActiveX. Дополнительные документы по Windows Media Player SDK см. в разделе msdn.microsoft.com/en-us/library/windows/desktop/. Я пошел вперед и разместил сообщение в группах Google, но мне придется подождать, пока мое сообщение будет одобрено.   -  person Joshua Dwire    schedule 02.11.2012


Ответы (1)


Типичная аннотация для этого шаблона:

/** @const */
var WindowsMediaActiveX = {};

/**
 * Methods and properties for accessing a CD or DVD in its drive.
 * @constructor
 * @private
 */
WindowsMediaActiveX.Cdrom=function(){};

Аннотация @private указывает на то, что конструктор не предназначен для прямого вызова. Однако компилятор сообщит о предупреждении только о прямых экземплярах типа, когда включена группа предупреждений accessControls (включена с предупреждениями VERBOSE).

Изменить: ответ обновлен, чтобы добавить требуемую аннотацию @const в пространство имен. В противном случае аннотации управления доступом будут игнорироваться.

person Chad Killingsworth    schedule 02.11.2012
comment
Спасибо за ответ, но это, похоже, не работает. Я добавил тег @private, поэтому объявление теперь выглядит точно так же, как в вашем ответе. Теперь я также передаю флаги --jscomp_error=accessControls, --jscomp_error=visibility и --warning_level=VERBOSE компилятору, но когда я вызываю var test=new WindowsMediaActiveX.Cdrom(), я все равно не получаю ошибки. С другой стороны, если я удалю тег @constructor из объявления, я получу ошибки, которые у меня были раньше. Игнорируется ли тег @private, потому что объявление находится во внешнем файле? - person Joshua Dwire; 02.11.2012
comment
Возможно. Хотя это похоже на ошибку. Позвольте мне провести некоторые испытания. - person Chad Killingsworth; 02.11.2012
comment
Если это поможет, вот информация о моей версии компилятора: Version: 20120917 (revision 2180) Built on: 2012/09/17 14:33 - person Joshua Dwire; 02.11.2012
comment
Если вы считаете, что это ошибка, я могу отправить отчет об ошибке по адресу code.google. .com/p/close-compiler/issues/list. - person Joshua Dwire; 02.11.2012
comment
Думаю, это следует считать ошибкой. Можете ли вы опубликовать его в трекере, пожалуйста? Посмотрим, как к этому отнесутся остальные члены команды. - person Chad Killingsworth; 03.11.2012
comment
Только что отправил отчет по адресу code.google.com/p/closure. -compiler/issues/detail?id=852 - person Joshua Dwire; 03.11.2012
comment
Есть идеи, как команда отреагировала на отчет? - person Joshua Dwire; 13.11.2012
comment
Да — @const требуется в пространстве имен. Тогда это должно работать. Ответ обновлен. - person Chad Killingsworth; 16.11.2012
comment
Это работает отлично. Любая идея, почему атрибут @const требуется? Это все-таки баг, или можно как-то закрыть отчет? - person Joshua Dwire; 16.11.2012
comment
Это ошибка. Оставьте отчет открытым. Это низкий приоритет, но, по крайней мере, мы можем его отслеживать. - person Chad Killingsworth; 17.11.2012