[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