Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I document an accessor function with the same name as a Q_PROPERTY?

Tags:

c++

qt

doxygen

TL;DR: How can I generate doxygen documentation for an accessor that has the same name as a property declared with Q_PROPERTY?


Qt's property system makes it possible to use Qt's meta-object-system on given properties:

// example class and documentation
class Widget : public QObject {
  Q_OBJECT
  Q_PROPERTY(int size READ size WRITE setSize NOTIFY sizeChanged)

public:
  Widget(QObject * parent = nullptr) : QObject(parent){}
  int size() const;

public slots:
  void setSize(int new_size);

signals:
  void sizeChanged(int); //!< signals a size change

private:
  int m_size = 0; //!< the Widget's size, see #size.
};

If one now uses doxygen in the implementation

//! @property size is the size of our widget

//! @brief Set the widget's size to @a new_size.
void Widget::setSize(int new_size) { 
  if(new_size != m_size) {
    m_size = new_size; 
    emit sizeChanged(m_size);
  }
}

//! @brief Returns the widget's size.
int Widget::size() const {
  return m_size;
}

Only setSize's documetaion gets generated correctly. size()'s documentation gets mistaken for the property's documentation. The code above acts as if

//! @property size
//! @brief Returns the widget's size.
int Widget::size() const {
  return m_size;
}

was used. Neither @fn Widget::size()const nor any other doxygen special command seems to help: size()'s generated documentation stays empty and ends up in the size (property) documentation instead.

Is this a bug, or am I missing something?

like image 692
Zeta Avatar asked Mar 09 '18 11:03

Zeta


1 Answers

This is a known bug or rather unimplemented feature. As of today, it's not possible to document a property and a getter if they have the same name. The getter's documentation will always end up in the property's one.

The reason for this is doxygen's findmember implementation. If you use doxygen -d findmembers you can see that both size (the property) and size() (the function) "match":

findMemberDocumentation(): root->type=`int' root->inside=`' root->name=`Widget::size' root->args=`() const ' section=6000000 root->spec=0 root->mGrpId=-1
findMember(root=0x197efe0,funcDecl=`int Widget::size() const ',related=`',overload=0,isFunc=1 mGrpId=-1 tArgList=(nil) (#=0) spec=0 lang=200
findMember() Parse results:
  namespaceName=`'
  className=`Widget`
  funcType=`int'
  funcSpec=`'
  funcName=`size'
  funcArgs=`() const'
  funcTempList=`'
  funcDecl=`int Widget::size'
  related=`'
  exceptions=`'
  isRelated=0
  isMemberOf=0
  isFriend=0
  isFunc=1

1. funcName=`size'
2. member name exists (2 members with this name)
3. member definition found, scope needed=`Widget' scope=`Widget' args=`' fileName=/tmp/test/example.cpp
4. class definition Widget found
5. matching `'`() const' className=Widget namespaceName=
6. match results of matchArguments2 = 1

You can even reproduce this with another non-const variant int size(). You will end up with three members that have the same name. Doxygen cannot handle properties and functions with the same name at the moment and does not document the getters in this case.

If you don't need the property documentation, you can disable the Q_PROPERTY macro in your Doxyfile (as documented):

ENABLE_PREPROCESSING  = YES
MACRO_EXPANSION       = YES
PREDEFINED            = Q_PROPERTY(x)= 

That way the lexer won't scan Q_PROPERTY.

like image 147
Zeta Avatar answered Oct 24 '22 11:10

Zeta