Как да документирам свойство, декларирано в различен файл с помощта на Doxygen?

Използвам mogenerator за генериране на Core Data класове. Mogenerator произвежда машинни класове и човешки класове. Разработчикът не трябва да променя машинно генерираните класове, тъй като те се генерират при всяко извикване на mogenerator. Човешките класове обаче могат да бъдат модифицирани според желанията на разработчика.

Машинните класове съдържат декларацията на всяко свойство на обекта Core Data. В Doxygen как се документира свойство, дефинирано във файл A от файл B?

РЕДАКТИРАНЕ: Добавен пример за илюстриране на въпроса

Пример:

В крайна сметка целта тук е да има нещо подобно на примера по-долу.

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 bock):

@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

Можете да препращате към achor (напр. файлове, пространства от имена, класове, функции, променливи, enum и т.н.), като използвате 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.

Вижте приетия отговор на въпроса Референтни статични const променливи, декларирани в пространство от имена за повече информация относно префикса на глобалното пространство от имена ::.

person Chris    schedule 11.01.2012