Как документировать сгенерированные макросами классы с 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);
Что-то в этом роде - довольно разумный корм.