Как документировать сгенерированные макросами классы с Doxygen?

Я использую макросы для генерации классов следующим образом:

generator.h:

class CLASS_NAME : public parent
{
    //generate variables with names given by CLASS_VARIABLES using complicated
    //Boost.Preprocessor stuff.
};

#undef CLASS_NAME
#undef CLASS_VARIABLES

myclass.h:

#define CLASS_NAME MyClass
#define CLASS_VARIABLES (a, b, c, x, y, z)
#include "generator.h"

Фактический класс является более сложным и использует различные макросы Boost.Preprocessor. Есть ли способ автоматически задокументировать сгенерированные классы с помощью Doxygen, добавив комментарии в generator.h, или в качестве альтернативы сгенерировать пример класса с документацией? Я попытался включить ENABLE_PREPROCESSING и MACRO_EXPANSION, но этого недостаточно.

4 ответа

Решение

Это не сработает. Препроцессор Doxygen на самом деле не выполняет полноценное включение файла (он ищет только во включенных файлах определения макросов; в противном случае директива ENABLE_PREPROCESSING была бы совершенно бесполезной!). Итак #include "generator.h" не имеет никакого эффекта

Если вы физически замените #include директива с содержимым включенного файла, он будет работать. (Не очень полезно, я знаю).

Другой способ сделать это - изменить ваши файлы следующим образом:

generator.h:

#define DEFCLASS class CLASS_NAME : public parent \
{ \
   ... whatever ... \
};

myclass.h:

#define CLASS_NAME MyClass
#define CLASS_VARIABLES (a, b, c, x, y, z)
#include "generator.h"
DEFCLASS

но это не будет работать, если вы используете DEFCLASS более одного раза для исходного файла (вероятно, ошибка / дефект Doxygen).

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

... препроцессор анализирует, но фактически не включает в себя код, когда обнаруживает #include (за исключением #include, найденного внутри блоков { ... })

Другое недокументированное, но интуитивное предварительное условие, которое я обнаружил в ходе экспериментов, заключается в том, что любой { ... } блок, в котором находится #include, должен сам по себе документироваться. Например, запуск Doxygen для следующего тестового файла с использованием Boost.Preprocessor сгенерирует записи для структур FOO::A, FOO::B, а также FOO::C, при условии, что MACRO_EXPANSION включен в файле конфигурации, требуемый режим извлечения установлен на "Все объекты", а папка надстройки правильно установлена ​​в INCLUDE_PATH:

#include <boost/preprocessor/iteration/local.hpp>
#include <boost/preprocessor/tuple/elem.hpp>

#define STRUCTS (A, B, C)

namespace FOO {
    #define BOOST_PP_LOCAL_MACRO(n) struct BOOST_PP_TUPLE_ELEM(3,n, STRUCTS) {};
    #define BOOST_PP_LOCAL_LIMITS (0,2)
    #include BOOST_PP_LOCAL_ITERATE()
}

Тем не менее, удаление FOO размещение структур в анонимном пространстве имен не приведет к документации. Итак, если вы можете перенести #include "generator.h" в явном пространстве имен это будет работать.

А как насчет параграфа "Документация в других местах" в http://www.stack.nl/~dimitri/doxygen/docblocks.html

/*! \class CLASS_NAME
    \brief An auto generated class

    A more detailed class description.
*/

/*! \fn CLASS_NAME::CLASS_NAME()
    \brief Default constuctor
*/

Я бы рекомендовал помещать сгенерированные классы в отдельный заголовок и просто документировать заголовок. В лучшем случае сгенерированные классы - это больше детали реализации.

Другим вариантом будет сценарий что-то вверх. Использование вашего любимого языка сценариев или что-то вроде гепарда не будет ужасным.

Я предполагаю, что ваш генератор выглядит чем-то простым, чтобы генерировать котельную пластину или черты или что-то еще

GENERATE_CLASS(Foo);
GENERATE_CLASS(Bar);

Что-то в этом роде - довольно разумный корм.

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