diff options
author | Orgad Shaneh <orgad.shaneh@audiocodes.com> | 2015-03-05 22:19:41 +0200 |
---|---|---|
committer | Orgad Shaneh <orgads@gmail.com> | 2015-03-09 13:27:12 +0000 |
commit | dbb9891f43291e3ffd015f3cc84d9389d01e170e (patch) | |
tree | 456ad73baa086ed7ba4939b923a92581325593ed /src/plugins/cppeditor/cppquickfixes.cpp | |
parent | 683540bee70187d830f0c2873d5cd9ebf5be2bc5 (diff) | |
download | qt-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.cpp | 86 |
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)); |