aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Kandeler <[email protected]>2025-02-12 16:29:15 +0100
committerChristian Kandeler <[email protected]>2025-02-13 11:47:38 +0000
commit92b0256bd34796a85832c3133026224fad878dcf (patch)
tree362ad4034cd61588df90540776f450388e40abd9
parente7114956ac4cccc8327991b72c43edfb897a8b34 (diff)
CppEditor: Fix qualification of return type in getter quickfix
We need to differentiate between "inside class" and "outside class" contexts. Fixes: QTCREATORBUG-32473 Change-Id: Idc763b35f69e85be6f088767b7c96c7e4bfab1e2 Reviewed-by: Christian Stenger <[email protected]>
-rw-r--r--src/plugins/cppeditor/quickfixes/cppcodegenerationquickfixes.cpp86
1 files changed, 78 insertions, 8 deletions
diff --git a/src/plugins/cppeditor/quickfixes/cppcodegenerationquickfixes.cpp b/src/plugins/cppeditor/quickfixes/cppcodegenerationquickfixes.cpp
index d3fad82ba93..fea0490353f 100644
--- a/src/plugins/cppeditor/quickfixes/cppcodegenerationquickfixes.cpp
+++ b/src/plugins/cppeditor/quickfixes/cppcodegenerationquickfixes.cpp
@@ -1883,9 +1883,26 @@ void GetterSetterRefactoringHelper::performGeneration(ExistingGetterSetterData d
return; // Maybe report error to the user
}
}
- const FullySpecifiedType returnTypeHeader = [&] {
- if (!getSetTemplate.returnTypeTemplate.has_value())
- return m_settings->returnByConstRef ? parameterType : memberVariableType;
+
+ enum class HeaderContext { InsideClass, OutsideClass };
+ const auto getReturnTypeHeader = [&](HeaderContext headerContext) {
+ Control *control = m_operation->currentFile()->cppDocument()->control();
+ if (!getSetTemplate.returnTypeTemplate.has_value()) {
+ const FullySpecifiedType &t = m_settings->returnByConstRef ? parameterType
+ : memberVariableType;
+ if (headerContext == HeaderContext::InsideClass)
+ return t;
+ LookupContext context(m_operation->currentFile()->cppDocument(), m_changes.snapshot());
+ SubstitutionEnvironment env;
+ env.setContext(context);
+ env.switchScope(m_class);
+ ClassOrNamespace *targetCoN = context.lookupType(m_class->enclosingScope());
+ if (!targetCoN)
+ targetCoN = context.globalNamespace();
+ UseMinimalNames q(targetCoN);
+ env.enter(&q);
+ return rewriteType(t, &env, control);
+ }
QString typeTemplate = getSetTemplate.returnTypeTemplate.value();
if (returnTypeTemplateParameter.has_value())
typeTemplate.replace(Pattern::TEMPLATE_PARAMETER_PATTERN,
@@ -1893,10 +1910,11 @@ void GetterSetterRefactoringHelper::performGeneration(ExistingGetterSetterData d
if (typeTemplate.contains(Pattern::TYPE_PATTERN))
typeTemplate.replace(Pattern::TYPE_PATTERN,
overview.prettyType(data.declarationSymbol->type()));
- Control *control = m_operation->currentFile()->cppDocument()->control();
std::string utf8TypeName = typeTemplate.toUtf8().toStdString();
return FullySpecifiedType(control->namedType(control->identifier(utf8TypeName.c_str())));
- }();
+ };
+ const FullySpecifiedType returnTypeHeader = getReturnTypeHeader(HeaderContext::OutsideClass);
+ const FullySpecifiedType returnTypeClass = getReturnTypeHeader(HeaderContext::InsideClass);
// getter declaration
if (generateFlags & Flag::GenerateGetter) {
@@ -1904,7 +1922,7 @@ void GetterSetterRefactoringHelper::performGeneration(ExistingGetterSetterData d
// but here the 'this->' is not needed
const QString returnExpression = QString{getSetTemplate.returnExpression}.replace("this->",
"");
- QString getterInClassDeclaration = overview.prettyType(returnTypeHeader, data.getterName)
+ QString getterInClassDeclaration = overview.prettyType(returnTypeClass, data.getterName)
+ QLatin1String("()");
if (isMemberVariableStatic)
getterInClassDeclaration.prepend(QLatin1String("static "));
@@ -2162,7 +2180,7 @@ void GetterSetterRefactoringHelper::performGeneration(ExistingGetterSetterData d
// signal declaration
if (generateFlags & Flag::GenerateSignal) {
- const auto &parameter = overview.prettyType(returnTypeHeader, data.qPropertyName);
+ const auto &parameter = overview.prettyType(returnTypeClass, data.qPropertyName);
const QString newValue = m_settings->signalWithNewValue ? parameter : QString();
const QString declaration = QString("void %1(%2);\n").arg(data.signalName, newValue);
addHeaderCode(InsertionPointLocator::Signals, declaration);
@@ -2183,7 +2201,7 @@ void GetterSetterRefactoringHelper::performGeneration(ExistingGetterSetterData d
if (generateFlags & Flag::GenerateProperty || generateFlags & Flag::GenerateConstantProperty) {
// Use the returnTypeHeader as base because of custom types in getSetTemplates.
// Remove const reference from type.
- FullySpecifiedType type = returnTypeHeader;
+ FullySpecifiedType type = returnTypeClass;
if (ReferenceType *ref = type.type()->asReferenceType())
type = ref->elementType();
type.setConst(false);
@@ -4275,6 +4293,58 @@ void Foo::setBar(const custom<N2::test> &newBar)
GenerateGetterSetter factory;
QuickFixOperationTest({CppTestDocument::create("file.h", input, {})}, &factory);
}
+
+ void testGetterSetterReturnTypeClassScope()
+ {
+ const QByteArray headerInput = R"cpp(
+class Foo
+{
+public:
+ enum Bar { b1, b2 };
+
+private:
+ Bar @m_bar;
+};
+)cpp";
+ const QByteArray headerOutput = R"cpp(
+class Foo
+{
+public:
+ enum Bar { b1, b2 };
+
+ Bar bar() const;
+ void setBar(Bar newBar);
+
+private:
+ Bar m_bar;
+};
+)cpp";
+ const QByteArray srcInput = "#include \"foo.h\"\n";
+ const QByteArray srcOutput = R"cpp(#include "foo.h"
+
+Foo::Bar Foo::bar() const
+{
+ return m_bar;
+}
+
+void Foo::setBar(Bar newBar)
+{
+ m_bar = newBar;
+}
+)cpp";
+
+ QList<TestDocumentPtr> testDocuments{
+ CppTestDocument::create("foo.h", headerInput, headerOutput),
+ CppTestDocument::create("foo.cpp", srcInput, srcOutput),
+ };
+
+ // QuickFixSettings s;
+ // s->getterOutsideClassFrom = 0;
+ // s->getterInCppFileFrom = 0;
+
+ GenerateGetterSetter factory;
+ QuickFixOperationTest(testDocuments, &factory, ProjectExplorer::HeaderPaths(), 2);
+ }
};
class GenerateGettersSettersTest : public QObject