CppEditor: Extend Q_PROPERTY quickfix

... to also generate the RESET function.

Fixes: QTCREATORBUG-11809
Change-Id: I94789227230a67f074ff5fdc76ad8113d2870dd6
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
Christian Kandeler
2020-07-20 17:47:59 +02:00
parent 1183810506
commit affd4ee658
2 changed files with 107 additions and 7 deletions

View File

@@ -1552,11 +1552,11 @@ void CppEditorPlugin::test_quickfix_data()
QTest::newRow("InsertQtPropertyMembers") QTest::newRow("InsertQtPropertyMembers")
<< CppQuickFixFactoryPtr(new InsertQtPropertyMembers) << CppQuickFixFactoryPtr(new InsertQtPropertyMembers)
<< _("struct XmarksTheSpot {\n" << _("struct XmarksTheSpot {\n"
" @Q_PROPERTY(int it READ getIt WRITE setIt NOTIFY itChanged)\n" " @Q_PROPERTY(int it READ getIt WRITE setIt RESET resetIt NOTIFY itChanged)\n"
"};\n" "};\n"
) )
<< _("struct XmarksTheSpot {\n" << _("struct XmarksTheSpot {\n"
" Q_PROPERTY(int it READ getIt WRITE setIt NOTIFY itChanged)\n" " Q_PROPERTY(int it READ getIt WRITE setIt RESET resetIt NOTIFY itChanged)\n"
"\n" "\n"
"public:\n" "public:\n"
" int getIt() const\n" " int getIt() const\n"
@@ -1573,6 +1573,10 @@ void CppEditorPlugin::test_quickfix_data()
" m_it = it;\n" " m_it = it;\n"
" emit itChanged(m_it);\n" " emit itChanged(m_it);\n"
" }\n" " }\n"
" void resetIt()\n"
" {\n"
" setIt({}); // TODO: Adapt to use your actual default value\n"
" }\n"
"\n" "\n"
"signals:\n" "signals:\n"
" void itChanged(int it);\n" " void itChanged(int it);\n"
@@ -1582,6 +1586,67 @@ void CppEditorPlugin::test_quickfix_data()
"};\n" "};\n"
); );
QTest::newRow("InsertQtPropertyMembersResetWithoutSet")
<< CppQuickFixFactoryPtr(new InsertQtPropertyMembers)
<< _("struct XmarksTheSpot {\n"
" @Q_PROPERTY(int it READ getIt RESET resetIt NOTIFY itChanged)\n"
"};\n"
)
<< _("struct XmarksTheSpot {\n"
" Q_PROPERTY(int it READ getIt RESET resetIt NOTIFY itChanged)\n"
"\n"
"public:\n"
" int getIt() const\n"
" {\n"
" return m_it;\n"
" }\n"
"\n"
"public slots:\n"
" void resetIt()\n"
" {\n"
" static const int defaultValue{}; // TODO: Adapt to use your actual default value\n"
" if (m_it == defaultValue)\n"
" return;\n"
"\n"
" m_it = defaultValue;\n"
" emit itChanged(m_it);\n"
" }\n"
"\n"
"signals:\n"
" void itChanged(int it);\n"
"\n"
"private:\n"
" int m_it;\n"
"};\n"
);
QTest::newRow("InsertQtPropertyMembersResetWithoutSetAndNotify")
<< CppQuickFixFactoryPtr(new InsertQtPropertyMembers)
<< _("struct XmarksTheSpot {\n"
" @Q_PROPERTY(int it READ getIt RESET resetIt)\n"
"};\n"
)
<< _("struct XmarksTheSpot {\n"
" Q_PROPERTY(int it READ getIt RESET resetIt)\n"
"\n"
"public:\n"
" int getIt() const\n"
" {\n"
" return m_it;\n"
" }\n"
"\n"
"public slots:\n"
" void resetIt()\n"
" {\n"
" static const int defaultValue{}; // TODO: Adapt to use your actual default value\n"
" m_it = defaultValue;\n"
" }\n"
"\n"
"private:\n"
" int m_it;\n"
"};\n"
);
QTest::newRow("InsertQtPropertyMembersPrivateBeforePublic") QTest::newRow("InsertQtPropertyMembersPrivateBeforePublic")
<< CppQuickFixFactoryPtr(new InsertQtPropertyMembers) << CppQuickFixFactoryPtr(new InsertQtPropertyMembers)
<< _("class XmarksTheSpot {\n" << _("class XmarksTheSpot {\n"

View File

@@ -5022,19 +5022,21 @@ public:
GenerateGetter = 1 << 0, GenerateGetter = 1 << 0,
GenerateSetter = 1 << 1, GenerateSetter = 1 << 1,
GenerateSignal = 1 << 2, GenerateSignal = 1 << 2,
GenerateStorage = 1 << 3 GenerateStorage = 1 << 3,
GenerateReset = 1 << 4
}; };
InsertQtPropertyMembersOp(const CppQuickFixInterface &interface, InsertQtPropertyMembersOp(const CppQuickFixInterface &interface,
int priority, QtPropertyDeclarationAST *declaration, Class *klass, int generateFlags, int priority, QtPropertyDeclarationAST *declaration, Class *klass, int generateFlags,
const QString &getterName, const QString &setterName, const QString &signalName, const QString &getterName, const QString &setterName, const QString &resetName,
const QString &storageName) const QString &signalName, const QString &storageName)
: CppQuickFixOperation(interface, priority) : CppQuickFixOperation(interface, priority)
, m_declaration(declaration) , m_declaration(declaration)
, m_class(klass) , m_class(klass)
, m_generateFlags(generateFlags) , m_generateFlags(generateFlags)
, m_getterName(getterName) , m_getterName(getterName)
, m_setterName(setterName) , m_setterName(setterName)
, m_resetName(resetName)
, m_signalName(signalName) , m_signalName(signalName)
, m_storageName(storageName) , m_storageName(storageName)
{ {
@@ -5065,6 +5067,7 @@ public:
} }
// setter declaration // setter declaration
InsertionLocation setterLoc;
if (m_generateFlags & GenerateSetter) { if (m_generateFlags & GenerateSetter) {
QString setterDeclaration; QString setterDeclaration;
QTextStream setter(&setterDeclaration); QTextStream setter(&setterDeclaration);
@@ -5081,11 +5084,36 @@ public:
setter << m_storageName << " = " << baseName << ";\nemit " << m_signalName setter << m_storageName << " = " << baseName << ";\nemit " << m_signalName
<< '(' << m_storageName << ");\n}\n"; << '(' << m_storageName << ");\n}\n";
} }
InsertionLocation setterLoc = locator.methodDeclarationInClass(file->fileName(), m_class, InsertionPointLocator::PublicSlot); setterLoc = locator.methodDeclarationInClass(file->fileName(), m_class, InsertionPointLocator::PublicSlot);
QTC_ASSERT(setterLoc.isValid(), return); QTC_ASSERT(setterLoc.isValid(), return);
insertAndIndent(file, &declarations, setterLoc, setterDeclaration); insertAndIndent(file, &declarations, setterLoc, setterDeclaration);
} }
// reset declaration
if (m_generateFlags & GenerateReset) {
QString declaration;
QTextStream stream(&declaration);
stream << "void " << m_resetName << "()\n{\n";
if (m_generateFlags & GenerateSetter) {
stream << m_setterName << "({}); // TODO: Adapt to use your actual default value\n";
} else {
stream << "static const " << typeName << " defaultValue{}; "
"// TODO: Adapt to use your actual default value\n";
if (!m_signalName.isEmpty())
stream << "if (" << m_storageName << " == defaultValue)\nreturn;\n\n";
stream << m_storageName << " = defaultValue;\n";
if (!m_signalName.isEmpty())
stream << "emit " << m_signalName << '(' << m_storageName << ");\n";
}
stream << "}\n";
const InsertionLocation loc = setterLoc.isValid()
? InsertionLocation(setterLoc.fileName(), {}, {}, setterLoc.line(), 1)
: locator.methodDeclarationInClass(file->fileName(), m_class,
InsertionPointLocator::PublicSlot);
QTC_ASSERT(loc.isValid(), return);
insertAndIndent(file, &declarations, loc, declaration);
}
// signal declaration // signal declaration
if (m_generateFlags & GenerateSignal) { if (m_generateFlags & GenerateSignal) {
const QString declaration = QLatin1String("void ") + m_signalName + QLatin1Char('(') const QString declaration = QLatin1String("void ") + m_signalName + QLatin1Char('(')
@@ -5124,6 +5152,7 @@ private:
int m_generateFlags; int m_generateFlags;
QString m_getterName; QString m_getterName;
QString m_setterName; QString m_setterName;
QString m_resetName;
QString m_signalName; QString m_signalName;
QString m_storageName; QString m_storageName;
}; };
@@ -5156,6 +5185,7 @@ void InsertQtPropertyMembers::match(const CppQuickFixInterface &interface,
const QString propertyName = file->textOf(qtPropertyDeclaration->property_name); const QString propertyName = file->textOf(qtPropertyDeclaration->property_name);
QString getterName; QString getterName;
QString setterName; QString setterName;
QString resetName;
QString signalName; QString signalName;
int generateFlags = 0; int generateFlags = 0;
QtPropertyDeclarationItemListAST *it = qtPropertyDeclaration->property_declaration_item_list; QtPropertyDeclarationItemListAST *it = qtPropertyDeclaration->property_declaration_item_list;
@@ -5167,6 +5197,9 @@ void InsertQtPropertyMembers::match(const CppQuickFixInterface &interface,
} else if (!qstrcmp(tokenString, "WRITE")) { } else if (!qstrcmp(tokenString, "WRITE")) {
setterName = file->textOf(it->value->expression); setterName = file->textOf(it->value->expression);
generateFlags |= InsertQtPropertyMembersOp::GenerateSetter; generateFlags |= InsertQtPropertyMembersOp::GenerateSetter;
} else if (!qstrcmp(tokenString, "RESET")) {
resetName = file->textOf(it->value->expression);
generateFlags |= InsertQtPropertyMembersOp::GenerateReset;
} else if (!qstrcmp(tokenString, "NOTIFY")) { } else if (!qstrcmp(tokenString, "NOTIFY")) {
signalName = file->textOf(it->value->expression); signalName = file->textOf(it->value->expression);
generateFlags |= InsertQtPropertyMembersOp::GenerateSignal; generateFlags |= InsertQtPropertyMembersOp::GenerateSignal;
@@ -5187,6 +5220,8 @@ void InsertQtPropertyMembers::match(const CppQuickFixInterface &interface,
generateFlags &= ~InsertQtPropertyMembersOp::GenerateGetter; generateFlags &= ~InsertQtPropertyMembersOp::GenerateGetter;
else if (name == setterName) else if (name == setterName)
generateFlags &= ~InsertQtPropertyMembersOp::GenerateSetter; generateFlags &= ~InsertQtPropertyMembersOp::GenerateSetter;
else if (name == resetName)
generateFlags &= ~InsertQtPropertyMembersOp::GenerateReset;
else if (name == signalName) else if (name == signalName)
generateFlags &= ~InsertQtPropertyMembersOp::GenerateSignal; generateFlags &= ~InsertQtPropertyMembersOp::GenerateSignal;
} else if (member->asDeclaration()) { } else if (member->asDeclaration()) {
@@ -5200,7 +5235,7 @@ void InsertQtPropertyMembers::match(const CppQuickFixInterface &interface,
return; return;
result << new InsertQtPropertyMembersOp(interface, path.size() - 1, qtPropertyDeclaration, c, result << new InsertQtPropertyMembersOp(interface, path.size() - 1, qtPropertyDeclaration, c,
generateFlags, getterName, setterName, generateFlags, getterName, setterName, resetName,
signalName, storageName); signalName, storageName);
} }