[Development] [Feature] Q_INFO: Annotations for classes, methods, properties and enums

Stefan Merettig stefan-merettig at nuriaproject.org
Sun Sep 1 13:20:10 CEST 2013


The meta object compiler currently supports something it calls 'method
tags', where it collects identifiers it doesn't know in front of 
methods:

    #ifndef Q_MOC_RUN
    # define MYTAG
    #endif
    ...
    MYTAG void myFunction ();

While this feature is already helpful for simple scenarios, it is quite
limited as it doesn't support arguments at all (It throws a syntax
error if a user tries to do this).

To overcome this I'd like to add a macro called Q_INFO (As proposed by
Richard):

    #define Q_INFO(...)

It is up to debate what structure the argument should have. The
following
ideas were proposed:
    1) Q_INFO("myTag" LIST "foo" "bar" END)
    2) Q_INFO("myTag" ARGS "foo", "bar") // Or ARGUMENTS instead of ARGS
    3) Q_INFO(myTag ("foo", "bar")) // Alternative: The name is "quoted"

I prefer 2) as it's simple and clean. 1) is overly verbose and LIST
doesn't clarify which list and 3) looks hacky and may confuse users
("Is myTag a function?", "When is it invoked?", ...).

For clarification: Arguments are optional.

WHAT CAN BE ANNOTATED?

Q_INFO can be prefixed to ...
1) Classes
2) Methods (Signals, slots, Q_INVOKABLE methods)
3) Properties
4) Enums which are exported through Q_ENUMS()
    Note: The Q_INFO macro is prefixed to the enum itself in this case!

WHY as in USE-CASE EXAMPLE

Pretend you have a library which provides a RPC server with a user
management component. You write a QObject class which shall implement
all slots  you want to expose. Not every user should be able to invoke
every slot, thus you use the annotation mechanism which lets you define
the desired behaviour right there, in the header.

    Q_INFO("Awesome.RpcServer.path" ARGS "services/stuff")
    class MyServices : public QObject {
      Q_INFO("Awesome.RpcServer.isPublic" ARGS "false")
      Q_PROPERTY(int activeUserCount READ activeUserCount)
      ...
      public slots:
      Q_INFO("Awesome.RpcServer.requiredPermissions" ARGS "admin")
      Q_INFO("Awesome.RpcServer.onlyAuthenticatedUsers")
      bool deleteUser (QString user);
      ...
    };

WHY NO C++11 ATTRIBUTES?

C++11 introduced something it calls generalized attributes, the most
famous one being 'noreturn'. Problem is that the standard doesn't let
the user  write their own custom ones - Although some compilers have
extensions to do  this, or just show a warning. A warning is a show
stopper already, and using extensions is ugly on itself already. On top
of this, the RTTI doesn't expose this information later, making every 
use
in dynamic programming impossible.

COMPATIBILITY

Q_INFO is a independent mechanism. All changes are backwards 
compatible.

NEEDED CHANGES

1) The meta object compiler (moc) needs to be extended to support this
    feature.
2) qglobal.h needs to be adjusted to carry #define Q_INFO(...)
3) At least another class needs to be introduced to Qt. I'd like to
    call it QMetaInfo, though I'm fine with a different name if anyone
    thinks that  this name is bad for some reason. Other QMeta* classes
    need to be adjusted.

On top of that some internal Qt classes need to be made aware of this
feature. For a more complete list, please see the commit messages in 
the
patch set.

TECHNOLOGY PREVIEW

Thiago mentioned that a modified moc would be helpful, so I worked on
it. You can view the patch set here:
https://codereview.qt-project.org/#change,64287

A moc with my modifications supports Q_INFO everywhere I'd like it to
be available. No changes were made outside moc's tree though.

Have a nice day,
Stefan Merettig.



More information about the Development mailing list