C++: Parse MEMBER in Q_PROPERTY()

MEMBER was added in Qt5.

Task-number: QTCREATORBUG-10068

Change-Id: Ic6c15a0e5ee8981ab98e4c12fc1521dc281b731f
Reviewed-by: Erik Verbruggen <erik.verbruggen@digia.com>
This commit is contained in:
Nikolai Kosjar
2013-10-08 13:42:39 +02:00
parent c5dfcce948
commit 0e4deaba23
6 changed files with 82 additions and 25 deletions

View File

@@ -2002,6 +2002,8 @@ bool Bind::visit(QtPropertyDeclarationAST *ast)
flags |= QtPropertyDeclaration::ReadFunction; flags |= QtPropertyDeclaration::ReadFunction;
} else if (name == "WRITE") { } else if (name == "WRITE") {
flags |= QtPropertyDeclaration::WriteFunction; flags |= QtPropertyDeclaration::WriteFunction;
} else if (name == "MEMBER") {
flags |= QtPropertyDeclaration::MemberVariable;
} else if (name == "RESET") { } else if (name == "RESET") {
flags |= QtPropertyDeclaration::ResetFunction; flags |= QtPropertyDeclaration::ResetFunction;
} else if (name == "NOTIFY") { } else if (name == "NOTIFY") {

View File

@@ -2138,10 +2138,11 @@ bool Parser::parseAccessDeclaration(DeclarationAST *&node)
/* /*
Q_PROPERTY(type name Q_PROPERTY(type name
READ getFunction (READ getFunction [WRITE setFunction]
[WRITE setFunction] | MEMBER memberName [(READ getFunction | WRITE setFunction)])
[RESET resetFunction] [RESET resetFunction]
[NOTIFY notifySignal] [NOTIFY notifySignal]
[REVISION int]
[DESIGNABLE bool] [DESIGNABLE bool]
[SCRIPTABLE bool] [SCRIPTABLE bool]
[STORED bool] [STORED bool]
@@ -2155,7 +2156,8 @@ bool Parser::parseAccessDeclaration(DeclarationAST *&node)
Furthermore, the only restriction on the order of the items in between the Furthermore, the only restriction on the order of the items in between the
parenthesis is that the type is the first parameter and the name comes after parenthesis is that the type is the first parameter and the name comes after
the type. the type. Especially, there seems to be no restriction on the READ/WRITE/MEMBER
order.
*/ */
bool Parser::parseQtPropertyDeclaration(DeclarationAST *&node) bool Parser::parseQtPropertyDeclaration(DeclarationAST *&node)
{ {
@@ -2201,6 +2203,7 @@ bool Parser::parseQtPropertyDeclaration(DeclarationAST *&node)
switch (peekAtQtContextKeyword()) { switch (peekAtQtContextKeyword()) {
case Token_READ: case Token_READ:
case Token_WRITE: case Token_WRITE:
case Token_MEMBER:
case Token_RESET: case Token_RESET:
case Token_NOTIFY: case Token_NOTIFY:
case Token_REVISION: case Token_REVISION:

View File

@@ -63,7 +63,20 @@ static inline int classify5(const char *s) {
} }
static inline int classify6(const char *s) { static inline int classify6(const char *s) {
if (s[0] == 'N') { if (s[0] == 'M') {
if (s[1] == 'E') {
if (s[2] == 'M') {
if (s[3] == 'B') {
if (s[4] == 'E') {
if (s[5] == 'R') {
return Token_MEMBER;
}
}
}
}
}
}
else if (s[0] == 'N') {
if (s[1] == 'O') { if (s[1] == 'O') {
if (s[2] == 'T') { if (s[2] == 'T') {
if (s[3] == 'I') { if (s[3] == 'I') {

View File

@@ -18,7 +18,8 @@ enum {
Token_CONSTANT, Token_CONSTANT,
Token_DESIGNABLE, Token_DESIGNABLE,
Token_SCRIPTABLE, Token_SCRIPTABLE,
Token_REVISION Token_REVISION,
Token_MEMBER
}; };
CPLUSPLUS_EXPORT int classifyQtContextKeyword(const char *s, int n); CPLUSPLUS_EXPORT int classifyQtContextKeyword(const char *s, int n);

View File

@@ -556,18 +556,19 @@ public:
NoFlags = 0, NoFlags = 0,
ReadFunction = 1 << 0, ReadFunction = 1 << 0,
WriteFunction = 1 << 1, WriteFunction = 1 << 1,
ResetFunction = 1 << 2, MemberVariable = 1 << 2,
NotifyFunction = 1 << 3, ResetFunction = 1 << 3,
DesignableFlag = 1 << 4, NotifyFunction = 1 << 4,
DesignableFunction = 1 << 5, DesignableFlag = 1 << 5,
ScriptableFlag = 1 << 6, DesignableFunction = 1 << 6,
ScriptableFunction = 1 << 7, ScriptableFlag = 1 << 7,
StoredFlag = 1 << 8, ScriptableFunction = 1 << 8,
StoredFunction = 1 << 9, StoredFlag = 1 << 9,
UserFlag = 1 << 10, StoredFunction = 1 << 10,
UserFunction = 1 << 11, UserFlag = 1 << 11,
ConstantFlag = 1 << 12, UserFunction = 1 << 12,
FinalFlag = 1 << 13 ConstantFlag = 1 << 13,
FinalFlag = 1 << 14
}; };
public: public:

View File

@@ -152,6 +152,10 @@ private slots:
void cpp_constructor_multiple_args(); void cpp_constructor_multiple_args();
void cpp_constructor_function_try_catch(); void cpp_constructor_function_try_catch();
// Q_PROPERTY
void cpp_qproperty();
void cpp_qproperty_data();
// objc++ // objc++
void objc_simple_class(); void objc_simple_class();
void objc_attributes_followed_by_at_keyword(); void objc_attributes_followed_by_at_keyword();
@@ -1235,6 +1239,39 @@ void tst_AST::cpp_constructor_function_try_catch()
QVERIFY(funDecl->parameter_declaration_clause->parameter_declaration_list != 0); QVERIFY(funDecl->parameter_declaration_clause->parameter_declaration_list != 0);
} }
void tst_AST::cpp_qproperty()
{
QFETCH(QByteArray, source);
QVERIFY(!source.isEmpty());
const QByteArray sourceWithinClass = "class C { " + source + " };";
QSharedPointer<TranslationUnit> unit(parseDeclaration(sourceWithinClass, false, true));
QVERIFY(unit->ast());
QCOMPARE(diag.errorCount, 0);
}
void tst_AST::cpp_qproperty_data()
{
QTest::addColumn<QByteArray>("source");
QTest::newRow("read-final")
<< QByteArray("Q_PROPERTY(bool focus READ hasFocus FINAL)");
QTest::newRow("read-write-final")
<< QByteArray("Q_PROPERTY(bool focus READ hasFocus WRITE setFocus FINAL)");
QTest::newRow("member-final")
<< QByteArray("Q_PROPERTY(bool focus MEMBER m_focus FINAL)");
QTest::newRow("member-read-final")
<< QByteArray("Q_PROPERTY(bool focus MEMBER m_focus READ m_focus FINAL)");
QTest::newRow("member-read-write-final")
<< QByteArray("Q_PROPERTY(bool focus MEMBER m_focus READ hasFocus WRITE setFocus FINAL)");
QTest::newRow("all")
<< QByteArray("Q_PROPERTY(bool focus MEMBER m_focus READ hasFocus WRITE setFocus"
" RESET resetFocus NOTIFY focusChanged REVISION 1 DESIGNABLE true"
" SCRIPTABLE true STORED true USER true CONSTANT FINAL)");
}
void tst_AST::objc_simple_class() void tst_AST::objc_simple_class()
{ {
QSharedPointer<TranslationUnit> unit(parseDeclaration("\n" QSharedPointer<TranslationUnit> unit(parseDeclaration("\n"