Как задокументировать свойство, объявленное в другом файле, с помощью Doxygen?

Я использую mogenerator для создания Основные данные. Mogenerator производит машинные классы и человеческие классы. Разработчик не должен модифицировать сгенерированные машиной классы, так как они генерируются каждый раз, когда вызывается mogenerator. Однако человеческие классы могут быть изменены по желанию разработчика.

Машинные классы содержат объявление каждого свойства объекта Core Data. Как в Doxygen документировать свойство, определенное в файле A, из файла B?

EDIT: добавлен пример для иллюстрации вопроса

Пример:

В конечном счете, цель здесь получить что-то похожее на пример ниже.

FileA.h (изменить нельзя)

@interface FileA : NSObject
{
   NSString* myProperty;
}
@end

ФайлB.h

#include "FileA.h"

@interface FileB : FileA
{
   /**
    * @property myProperty
    *
    * This is the documentation of "myProperty" 
    * defined in FileA but documented in FileB
    */
}
@end

Пробовал (блок документации внутри блока @interface FileB @end):

@property myProperty — Doxygen не связывает документацию с ресурсом.

\property myProperty — Doxygen не связывает документацию со свойством.

@property FileA::myProperty — Doxygen не связывает документацию со свойством и генерирует; предупреждение: для FileB::myProperty не найден однозначно соответствующий член класса

\property FileA::myProperty — то же самое

Решение

ФайлB.h

#include "FileA.h"

   /**
    * @property FileA::myProperty
    *
    * This is the documentation of "myProperty" 
    * defined in FileA but documented in FileB
    *
    * Documentation block MUST BE outside FileB class
    *
    */

@interface FileB : FileA
{
}
@end

person David Andreoletti    schedule 11.01.2012    source источник
comment
Почему бы вам не попробовать \property FileA::myProperty и сообщить нам, что получится?   -  person Chris    schedule 12.01.2012
comment
Использование вами @interface FileB : FileA не соответствует документации для \interface команда. Кроме того, вы указываете в своем решении, что блок документации ДОЛЖЕН БЫТЬ вне класса FileB. Этого не должно быть - это говорит о том, что что-то еще не работает должным образом.   -  person Chris    schedule 12.01.2012
comment
Также обратите внимание, что вы можете использовать @ или \ в качестве префикса для команд Doxygen, поэтому \property и @property — это одно и то же, нет необходимости различать их. Когда вы использовали @property FileA::myProperty, вы говорите, что получили предупреждение, что для FileB::myProperty не найден однозначно соответствующий член класса. Конечно, это должно быть FileA::myProperty?   -  person Chris    schedule 12.01.2012
comment
@Chris: блок документации ДОЛЖЕН БЫТЬ вне класса FileB. Этого не должно быть - это говорит о том, что что-то еще не работает должным образом. Любая идея ?   -  person David Andreoletti    schedule 12.01.2012
comment
@Chris: я знал о @ или \ в качестве префикса для команд Doxygen, но хотел убедиться, что у них нет какого-то недокументированного / странного поведения.   -  person David Andreoletti    schedule 12.01.2012
comment
В ответ на ваш первый комментарий: из вашего исходного фрагмента я не знаю, почему. Я все еще не думаю, что запись FileB : FileA верна. Если вы запустите Doxygen для двух примеров файлов, приведенных в моем ответе, будет ли он работать должным образом?   -  person Chris    schedule 12.01.2012
comment
давайте продолжим это обсуждение в чате   -  person David Andreoletti    schedule 13.01.2012


Ответы (2)


Неясно (для меня), хотите ли вы, чтобы FileA был задокументирован, но вы не можете вставить документацию в FileA.h, или вы хотите, чтобы FileA был недокументирован, но чтобы его члены появлялись в (документированном) производном классе FileB.

Если это первое, вы можете предоставить документацию для класса FileA в FileB.h, это будет выглядеть примерно так:

/**
 * @class FileA
 * Documentation for FileA
 *
 * @var FileA::myProperty
 * Documentation for myProperty
 */

/**
 * Documentation for FileB
 */
@interface FileB : FileA
{
}

@end

Это приведет к тому, что классы FileA и FileB появятся в сгенерированных документах, а myProperty задокументирован как член FileA.

Если это последнее, вы можете объявить myProperty членом FileB, но использовать защиту препроцессора, чтобы включить объявление только при создании документации, например:

/**
 * document FileB
 */
@interface FileB : FileA
{
#ifdef DOXYGEN
    /**
     * This is the documentation of "myProperty" 
     * defined in FileA but documented in FileB
     */
    NSString* myProperty;
#endif
}

@end

Это приведет к тому, что FileB будет задокументировано, как если бы myProperty был одним из его членов. Имейте в виду, что если объявление myProperty изменится в FileA, вам придется вручную обновить объявление FileB, чтобы отразить эти изменения.

person DRH    schedule 12.01.2012
comment
Идеальным решением был бы второй вариант: иметь недокументированный FileA, НО чтобы его члены/аксессоры отображались в (документированном) производном классе FileB. Это лучше с точки зрения разработчика, который читает документацию о FileB. В идеале FileA не существует в сознании разработчика (как и в документации) - person David Andreoletti; 12.01.2012
comment
В конце концов я выбрал предыдущее предложенное решение. Спасибо. - person David Andreoletti; 12.01.2012

Вы можете ссылаться на ачор (например, файлы, пространства имен, классы, функции, переменные, перечисления и т. д.), используя ref используя, например

\ref variable_name

Если переменная, которую вы хотите задокументировать, не находится в локальном пространстве имен или области видимости, вы можете добавить к имени переменной префикс namespace::, где namespace — это область или класс, в котором определена переменная, на которую вы ссылаетесь. Например, рассмотрим следующие два файла (измененные из примеров в руководстве Doxygen):

Файл 1:

///  A test class.
/**
  A more elaborate class description.
*/
class Test
{
  public:

  /// An enum.
  /** More detailed enum description. */
  enum TEnum {
               TVal1, ///< Enum value TVal1.
               TVal2, ///< Enum value TVal2.
               TVal3  ///< Enum value TVal3.
             }
      /// Enum pointer.
      /** Details. */
      *enumPtr,
      /// Enum variable.
      /** Details. */
      enumVar;

  /// A constructor.
  /**
    A more elaborate description of the constructor.
  */
  Test();
};

Файл 2:

//  Another test class.
/**
  This class depends on the variable \ref Test::TEnum, defined in another file.
  It doesn't, actually, but I've said it does.
*/
class AnotherTest
{
  public:

  /// A constructor
  AnotherTest();

};

Здесь TEnum определяется в классе Test в первом файле. Итак, во втором файле мы добавляем к имени переменной префикс класса, в котором она определена, то есть Test::TEnum.

См. принятый ответ на вопрос Ссылка на статические константные переменные, объявленные в пространстве имен для получения дополнительной информации о префиксе глобального пространства имен ::.

person Chris    schedule 11.01.2012