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

Stefan Merettig stefan-merettig at nuriaproject.org
Tue Sep 10 19:27:48 CEST 2013


Hi,

> Other people have suggested adding the info to the Q_PROPERTY 
> expansion.
> This would avoid a sequence of Q_INFO / Q_PROPERTY pairs in the class 
> that
> might be difficult to read:
> 
> 	Q_INFO("foo", "bar")
> 	Q_PROPERTY(int bar READ bar)
> 	Q_INFO("foo", "baz")
> 	Q_PROPERTY(int baz READ baz)

Right. I'd be fine with supporting something like
   Q_PROPERTY( ... INFO "foo" = "bar")
Though IMO that's way less easy to read. Would be fine as alternative 
syntax.
(Sidenote: In this case, multiple INFO's should be allowed to appear)

>>     key -> value mapping, not two values for "a".
> 
> Why?

Because that's my definition of having multiple values for a single 
key,
something which the ML was against. The current preview on gerrit 
supports
that already and has everything on-board which is needed for a addition
like allowing multiple values per key. Letting the user who uses the 
meta
information in the end try to figure out if there are more than one
values for a single key sounds tedious and bogus. We could as well do 
it in
QMetaInfo then without introducing any complexity. (Proposal:
   class QMetaInfo {
     const char *name() const;
     const char *value(int index = 0) const;
     int valueCount() const;
   };
)

>>     other hand it's redundant, as Q_INFO doesn't have any benefits 
>> over
>>     Q_CLASSINFO anymore.
> 
> I prefer Q_CLASSINFO.

Alright, I'm fine with that as long the features of Q_INFO and 
Q_CLASSINFO are
the same basically. If Q_INFO supports multiple values per key though 
I'd like
to see both.

> How do you associate the method ID or property ID with an info?
That's simple actually. I take my preview code as example. As we know 
which
object types can be annotated, I have a hard-coded sequence which is:
   Class, signals, slots, Q_INVOKABLEs, c'tors, Q_PROPERTYs, enums
Each category has as much entries as the meta system knows about them, 
so
if we have 5 slots, there are 5 entries for this category. The 'Class' 
category
has a constant item count of one. This creates a table, where each 
object
stores 'start index' and 'count'. 'start index' points to the first 
entry
which stores the Q_INFO data, and count shows how many Q_INFO 
annotations this
object has. Now, at this 'start index', we have another table in the 
form:
   name, flags, argc, values ...
'name' is the annotation name, 'flags' is unused (always zero) and 
'argc' tells
the reader how many values this annotation has - Thus 'values' is of 
dynamic
length. This introduces a minor performance penality while reading 
annotations
of the same object, but nothing else.
This sounds complicated at first, but first API tests with Q_INFO 
access
integrated into QMetaObject show that it's actually nice to work with.

For visualization, see this moc'd example:
Header file: http://pastebin.com/wYihYjPt (Note: Still the old syntax)
meta data table: http://pastebin.com/i1AHpzFa

I paid greater attention to not break anything else. The change in the 
header
is no big deal in this case as the parser will simply skip it. The 
whole
Q_INFO meta data is only stored if it's used anywhere at least once. If 
it's
not used, then both fields in the header are zero.

If only a single value per key is allowed we could of course simplify 
the
payload table. Though this doesn't come with any real benefits. The 
only
difference between allowing:
   Q_INFO("foo", "bar") Q_INFO("foo", "baz") void myFunc();
and
   Q_INFO("foo" ARGS "bar", "baz") void myFunc();
is that the first one is more verbose and offers a opportunity for a 
typo.
That's my two cents on that discussion.




More information about the Development mailing list