summaryrefslogtreecommitdiff
path: root/src/plugins/cppeditor/cppquickfixes.cpp
diff options
context:
space:
mode:
authorOrgad Shaneh <orgad.shaneh@audiocodes.com>2015-03-05 22:19:41 +0200
committerOrgad Shaneh <orgads@gmail.com>2015-03-09 13:27:12 +0000
commitdbb9891f43291e3ffd015f3cc84d9389d01e170e (patch)
tree456ad73baa086ed7ba4939b923a92581325593ed /src/plugins/cppeditor/cppquickfixes.cpp
parent683540bee70187d830f0c2873d5cd9ebf5be2bc5 (diff)
downloadqt-creator-dbb9891f43291e3ffd015f3cc84d9389d01e170e.tar.gz
CppEditor: Support implicit pointers in Qt5 connect conversion
Task-number: QTCREATORBUG-14104 Change-Id: I157dbcb0e06ed1bf49d2df01bdbad215e35a4c3a Reviewed-by: Nikolai Kosjar <nikolai.kosjar@theqtcompany.com>
Diffstat (limited to 'src/plugins/cppeditor/cppquickfixes.cpp')
-rw-r--r--src/plugins/cppeditor/cppquickfixes.cpp86
1 files changed, 81 insertions, 5 deletions
diff --git a/src/plugins/cppeditor/cppquickfixes.cpp b/src/plugins/cppeditor/cppquickfixes.cpp
index 3c252082d1..d71303eb25 100644
--- a/src/plugins/cppeditor/cppquickfixes.cpp
+++ b/src/plugins/cppeditor/cppquickfixes.cpp
@@ -5578,10 +5578,75 @@ Symbol *skipForwardDeclarations(const QList<Symbol *> &symbols)
return 0;
}
+bool findRawAccessFunction(Class *klass, PointerType *pointerType, QString *objAccessFunction)
+{
+ QList<Function *> candidates;
+ for (auto it = klass->memberBegin(), end = klass->memberEnd(); it != end; ++it) {
+ if (Function *func = (*it)->asFunction()) {
+ const Name *funcName = func->name();
+ if (!funcName->isOperatorNameId()
+ && !funcName->isConversionNameId()
+ && func->returnType().type() == pointerType
+ && func->isConst()
+ && func->argumentCount() == 0) {
+ candidates << func;
+ }
+ }
+ }
+ const Name *funcName = 0;
+ switch (candidates.size()) {
+ case 0:
+ return false;
+ case 1:
+ funcName = candidates.first()->name();
+ break;
+ default:
+ // Multiple candidates - prefer a function named data
+ foreach (Function *func, candidates) {
+ if (!strcmp(func->name()->identifier()->chars(), "data")) {
+ funcName = func->name();
+ break;
+ }
+ }
+ if (!funcName)
+ funcName = candidates.first()->name();
+ }
+ const Overview oo = CppCodeStyleSettings::currentProjectCodeStyleOverview();
+ *objAccessFunction = QLatin1Char('.') + oo.prettyName(funcName) + QLatin1String("()");
+ return true;
+}
+
+PointerType *determineConvertedType(NamedType *namedType, const LookupContext &context,
+ Scope *scope, QString *objAccessFunction)
+{
+ if (!namedType)
+ return 0;
+ if (ClassOrNamespace *binding = context.lookupType(namedType->name(), scope)) {
+ if (Symbol *objectClassSymbol = skipForwardDeclarations(binding->symbols())) {
+ if (Class *klass = objectClassSymbol->asClass()) {
+ for (auto it = klass->memberBegin(), end = klass->memberEnd(); it != end; ++it) {
+ if (Function *func = (*it)->asFunction()) {
+ if (const ConversionNameId *conversionName =
+ func->name()->asConversionNameId()) {
+ if (PointerType *type = conversionName->type()->asPointerType()) {
+ if (findRawAccessFunction(klass, type, objAccessFunction))
+ return type;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
Class *senderOrReceiverClass(const CppQuickFixInterface &interface,
const CppRefactoringFilePtr &file,
const ExpressionAST *objectPointerAST,
- Scope *objectPointerScope)
+ Scope *objectPointerScope,
+ QString *objAccessFunction)
{
const LookupContext &context = interface.context();
@@ -5602,6 +5667,10 @@ Class *senderOrReceiverClass(const CppQuickFixInterface &interface,
QTC_ASSERT(objectPointerTypeBase, return 0);
PointerType *objectPointerType = objectPointerTypeBase->asPointerType();
+ if (!objectPointerType) {
+ objectPointerType = determineConvertedType(objectPointerTypeBase->asNamedType(), context,
+ objectPointerScope, objAccessFunction);
+ }
QTC_ASSERT(objectPointerType, return 0);
Type *objectTypeBase = objectPointerType->elementType().type(); // Dereference
@@ -5624,7 +5693,8 @@ bool findConnectReplacement(const CppQuickFixInterface &interface,
const ExpressionAST *objectPointerAST,
const QtMethodAST *methodAST,
const CppRefactoringFilePtr &file,
- QString *replacement)
+ QString *replacement,
+ QString *objAccessFunction)
{
// Get name of method
if (!methodAST->declarator || !methodAST->declarator->core_declarator)
@@ -5640,7 +5710,8 @@ bool findConnectReplacement(const CppQuickFixInterface &interface,
// Lookup object pointer type
Scope *scope = file->scopeAt(methodAST->firstToken());
- Class *objectClass = senderOrReceiverClass(interface, file, objectPointerAST, scope);
+ Class *objectClass = senderOrReceiverClass(interface, file, objectPointerAST, scope,
+ objAccessFunction);
QTC_ASSERT(objectClass, return false);
// Look up member function in call, including base class members.
@@ -5762,17 +5833,22 @@ void ConvertQt4Connect::match(const CppQuickFixInterface &interface, QuickFixOpe
const CppRefactoringFilePtr file = interface.currentFile();
QString newSignal;
- if (!findConnectReplacement(interface, arg1, arg2, file, &newSignal))
+ QString senderAccessFunc;
+ if (!findConnectReplacement(interface, arg1, arg2, file, &newSignal, &senderAccessFunc))
continue;
QString newMethod;
- if (!findConnectReplacement(interface, arg3, arg4, file, &newMethod))
+ QString receiverAccessFunc;
+ if (!findConnectReplacement(interface, arg3, arg4, file, &newMethod, &receiverAccessFunc))
continue;
ChangeSet changes;
+ changes.replace(file->endOf(arg1), file->endOf(arg1), senderAccessFunc);
changes.replace(file->startOf(arg2), file->endOf(arg2), newSignal);
if (!arg3)
newMethod.prepend(QLatin1String("this, "));
+ else
+ changes.replace(file->endOf(arg3), file->endOf(arg3), receiverAccessFunc);
changes.replace(file->startOf(arg4), file->endOf(arg4), newMethod);
result.append(new ConvertQt4ConnectOperation(interface, changes));