forked from qt-creator/qt-creator
CppEditor: Do not crash on anonymous classes
While performing generate getters and setters we crashed when using members of anonymous classes. Change-Id: I27dc8da950345aa4e26ddb1da3914edcffad5af3 Reviewed-by: Christian Kandeler <christian.kandeler@qt.io> Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
@@ -3273,6 +3273,58 @@ void QuickfixTest::testGenerateGetterSetterOnlySetter()
|
|||||||
QuickFixOperationTest(testDocuments, &factory, ProjectExplorer::HeaderPaths(), 0);
|
QuickFixOperationTest(testDocuments, &factory, ProjectExplorer::HeaderPaths(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QuickfixTest::testGenerateGetterSetterAnonymousClass()
|
||||||
|
{
|
||||||
|
QList<TestDocumentPtr> testDocuments;
|
||||||
|
QByteArray original;
|
||||||
|
QByteArray expected;
|
||||||
|
QuickFixSettings s;
|
||||||
|
s->setterInCppFileFrom = 1;
|
||||||
|
s->setterParameterNameTemplate = "value";
|
||||||
|
|
||||||
|
// Header File
|
||||||
|
original = R"(
|
||||||
|
class {
|
||||||
|
int @m_foo;
|
||||||
|
} bar;
|
||||||
|
)";
|
||||||
|
expected = R"(
|
||||||
|
class {
|
||||||
|
int m_foo;
|
||||||
|
|
||||||
|
public:
|
||||||
|
int foo() const
|
||||||
|
{
|
||||||
|
return m_foo;
|
||||||
|
}
|
||||||
|
void setFoo(int value)
|
||||||
|
{
|
||||||
|
if (m_foo == value)
|
||||||
|
return;
|
||||||
|
m_foo = value;
|
||||||
|
emit fooChanged();
|
||||||
|
}
|
||||||
|
void resetFoo()
|
||||||
|
{
|
||||||
|
setFoo({}); // TODO: Adapt to use your actual default defaultValue
|
||||||
|
}
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void fooChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Q_PROPERTY(int foo READ foo WRITE setFoo RESET resetFoo NOTIFY fooChanged)
|
||||||
|
} bar;
|
||||||
|
)";
|
||||||
|
testDocuments << CppTestDocument::create("file.h", original, expected);
|
||||||
|
|
||||||
|
// Source File
|
||||||
|
testDocuments << CppTestDocument::create("file.cpp", {}, {});
|
||||||
|
|
||||||
|
GenerateGetterSetter factory;
|
||||||
|
QuickFixOperationTest(testDocuments, &factory, ProjectExplorer::HeaderPaths(), 4);
|
||||||
|
}
|
||||||
|
|
||||||
void QuickfixTest::testGenerateGetterSetterInlineInHeaderFile()
|
void QuickfixTest::testGenerateGetterSetterInlineInHeaderFile()
|
||||||
{
|
{
|
||||||
QList<TestDocumentPtr> testDocuments;
|
QList<TestDocumentPtr> testDocuments;
|
||||||
|
|||||||
@@ -113,6 +113,7 @@ private slots:
|
|||||||
void testGenerateGetterSetterGeneralTests();
|
void testGenerateGetterSetterGeneralTests();
|
||||||
void testGenerateGetterSetterOnlyGetter();
|
void testGenerateGetterSetterOnlyGetter();
|
||||||
void testGenerateGetterSetterOnlySetter();
|
void testGenerateGetterSetterOnlySetter();
|
||||||
|
void testGenerateGetterSetterAnonymousClass();
|
||||||
void testGenerateGetterSetterInlineInHeaderFile();
|
void testGenerateGetterSetterInlineInHeaderFile();
|
||||||
void testGenerateGetterSetterOnlySetterHeaderFileWithIncludeGuard();
|
void testGenerateGetterSetterOnlySetterHeaderFileWithIncludeGuard();
|
||||||
void testGenerateGetterFunctionAsTemplateArg();
|
void testGenerateGetterFunctionAsTemplateArg();
|
||||||
|
|||||||
@@ -3907,7 +3907,12 @@ void GetterSetterRefactoringHelper::performGeneration(ExistingGetterSetterData d
|
|||||||
else
|
else
|
||||||
getterInClassDeclaration += QLatin1String(" const");
|
getterInClassDeclaration += QLatin1String(" const");
|
||||||
getterInClassDeclaration.prepend(m_settings->getterAttributes + QLatin1Char(' '));
|
getterInClassDeclaration.prepend(m_settings->getterAttributes + QLatin1Char(' '));
|
||||||
|
|
||||||
auto getterLocation = m_settings->determineGetterLocation(1);
|
auto getterLocation = m_settings->determineGetterLocation(1);
|
||||||
|
// if we have an anonymous class we must add code inside the class
|
||||||
|
if (data.clazz->name()->isAnonymousNameId())
|
||||||
|
getterLocation = CppQuickFixSettings::FunctionLocation::InsideClass;
|
||||||
|
|
||||||
if (getterLocation == CppQuickFixSettings::FunctionLocation::InsideClass) {
|
if (getterLocation == CppQuickFixSettings::FunctionLocation::InsideClass) {
|
||||||
getterInClassDeclaration += QLatin1String("\n{\nreturn ") + returnExpression
|
getterInClassDeclaration += QLatin1String("\n{\nreturn ") + returnExpression
|
||||||
+ QLatin1String(";\n}\n");
|
+ QLatin1String(";\n}\n");
|
||||||
@@ -4026,6 +4031,10 @@ void GetterSetterRefactoringHelper::performGeneration(ExistingGetterSetterData d
|
|||||||
body += "}";
|
body += "}";
|
||||||
|
|
||||||
auto setterLocation = m_settings->determineSetterLocation(body.count('\n') - 2);
|
auto setterLocation = m_settings->determineSetterLocation(body.count('\n') - 2);
|
||||||
|
// if we have an anonymous class we must add code inside the class
|
||||||
|
if (data.clazz->name()->isAnonymousNameId())
|
||||||
|
setterLocation = CppQuickFixSettings::FunctionLocation::InsideClass;
|
||||||
|
|
||||||
if (setterLocation == CppQuickFixSettings::FunctionLocation::CppFile && !hasSourceFile())
|
if (setterLocation == CppQuickFixSettings::FunctionLocation::CppFile && !hasSourceFile())
|
||||||
setterLocation = CppQuickFixSettings::FunctionLocation::OutsideClass;
|
setterLocation = CppQuickFixSettings::FunctionLocation::OutsideClass;
|
||||||
|
|
||||||
@@ -4100,6 +4109,10 @@ void GetterSetterRefactoringHelper::performGeneration(ExistingGetterSetterData d
|
|||||||
body.replace(QRegularExpression("\\b" + parameterName + "\\b"), "defaultValue");
|
body.replace(QRegularExpression("\\b" + parameterName + "\\b"), "defaultValue");
|
||||||
// body.count('\n') - 2 : do not count the 2 at start
|
// body.count('\n') - 2 : do not count the 2 at start
|
||||||
auto resetLocation = m_settings->determineSetterLocation(body.count('\n') - 2);
|
auto resetLocation = m_settings->determineSetterLocation(body.count('\n') - 2);
|
||||||
|
// if we have an anonymous class we must add code inside the class
|
||||||
|
if (data.clazz->name()->isAnonymousNameId())
|
||||||
|
resetLocation = CppQuickFixSettings::FunctionLocation::InsideClass;
|
||||||
|
|
||||||
if (resetLocation == CppQuickFixSettings::FunctionLocation::CppFile && !hasSourceFile())
|
if (resetLocation == CppQuickFixSettings::FunctionLocation::CppFile && !hasSourceFile())
|
||||||
resetLocation = CppQuickFixSettings::FunctionLocation::OutsideClass;
|
resetLocation = CppQuickFixSettings::FunctionLocation::OutsideClass;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user