diff --git a/codecompletion/context.cpp b/codecompletion/context.cpp --- a/codecompletion/context.cpp +++ b/codecompletion/context.cpp @@ -148,7 +148,7 @@ qCWarning(KDEV_PYTHON_CODECOMPLETION) << "Tried: " << m_guessTypeOfExpression; return resultingItems; } - functionCalled = Helper::functionDeclarationForCalledDeclaration(v->lastDeclaration()).first.data(); + functionCalled = Helper::functionForCalled(v->lastDeclaration().data()).declaration; auto current = Helper::resolveAliasDeclaration(functionCalled); QList calltips; diff --git a/codecompletion/items/functiondeclaration.cpp b/codecompletion/items/functiondeclaration.cpp --- a/codecompletion/items/functiondeclaration.cpp +++ b/codecompletion/items/functiondeclaration.cpp @@ -137,11 +137,11 @@ { qCDebug(KDEV_PYTHON_CODECOMPLETION) << "FunctionDeclarationCompletionItem executed"; KTextEditor::Document* document = view->document(); - DeclarationPointer resolvedDecl(Helper::resolveAliasDeclaration(declaration().data())); + auto resolvedDecl = Helper::resolveAliasDeclaration(declaration().data()); DUChainReadLocker lock; - QPair fdecl = Helper::functionDeclarationForCalledDeclaration(resolvedDecl); + auto functionDecl = Helper::functionForCalled(resolvedDecl).declaration; lock.unlock(); - if ( ! fdecl.first && (! resolvedDecl || ! resolvedDecl->abstractType() + if ( ! functionDecl && (! resolvedDecl || ! resolvedDecl->abstractType() || resolvedDecl->abstractType()->whichType() != AbstractType::TypeStructure) ) { qCritical(KDEV_PYTHON_CODECOMPLETION) << "ERROR: could not get declaration data, not executing completion item!"; return; @@ -151,18 +151,18 @@ KTextEditor::Range checkSuffix(word.end().line(), word.end().column(), word.end().line(), document->lineLength(word.end().line())); if ( m_doNotCall || document->text(checkSuffix).trimmed().startsWith('(') || document->text(checkPrefix).trimmed().endsWith('@') - || (fdecl.first && Helper::findDecoratorByName(fdecl.first.data(), QLatin1String("property"))) ) + || (functionDecl && Helper::findDecoratorByName(functionDecl, QLatin1String("property"))) ) { // don't insert brackets if they're already there, // the item is a decorator, or if it's an import item. suffix.clear(); } // place cursor behind bracktes by default int skip = 2; - if ( fdecl.first ) { + if ( functionDecl ) { bool needsArguments = false; - int argumentCount = fdecl.first->type()->arguments().length(); - if ( fdecl.first->context()->type() == KDevelop::DUContext::Class ) { + int argumentCount = functionDecl->type()->arguments().length(); + if ( functionDecl->context()->type() == KDevelop::DUContext::Class ) { // it's a member function, so it has the implicit self // TODO static methods needsArguments = argumentCount > 1; diff --git a/duchain/declarationbuilder.cpp b/duchain/declarationbuilder.cpp --- a/duchain/declarationbuilder.cpp +++ b/duchain/declarationbuilder.cpp @@ -931,17 +931,16 @@ void DeclarationBuilder::addArgumentTypeHints(CallAst* node, DeclarationPointer function) { DUChainReadLocker lock; - QPair called = Helper::functionDeclarationForCalledDeclaration(function); - FunctionDeclaration::Ptr lastFunctionDeclaration = called.first; - bool isConstructor = called.second; + auto funcInfo = Helper::functionForCalled(function.data()); + auto lastFunctionDeclaration = funcInfo.declaration; if ( ! lastFunctionDeclaration ) { return; } if ( lastFunctionDeclaration->topContext()->url() == IndexedString(Helper::getDocumentationFile()) ) { return; } - DUContext* args = DUChainUtils::getArgumentContext(lastFunctionDeclaration.data()); + DUContext* args = DUChainUtils::getArgumentContext(lastFunctionDeclaration); FunctionType::Ptr functiontype = lastFunctionDeclaration->type(); if ( ! args || ! functiontype ) { return; @@ -952,7 +951,7 @@ // Look for the "self" in the argument list, the type of that should not be updated. bool hasSelfArgument = false; - if ( ( lastFunctionDeclaration->context()->type() == DUContext::Class || isConstructor ) + if ( ( lastFunctionDeclaration->context()->type() == DUContext::Class || funcInfo.isConstructor ) && ! parameters.isEmpty() && ! lastFunctionDeclaration->isStatic() ) { // ... unless for some reason the function only has *vararg, **kwarg as arguments diff --git a/duchain/expressionvisitor.cpp b/duchain/expressionvisitor.cpp --- a/duchain/expressionvisitor.cpp +++ b/duchain/expressionvisitor.cpp @@ -153,15 +153,12 @@ DUChainReadLocker lock; actualDeclaration = Helper::resolveAliasDeclaration(actualDeclaration); ClassDeclaration* classDecl = dynamic_cast(actualDeclaration); - QPair d = Helper::functionDeclarationForCalledDeclaration( - DeclarationPointer(actualDeclaration)); - FunctionDeclaration* funcDecl = d.first.data(); - bool isConstructor = d.second; + auto function = Helper::functionForCalled(actualDeclaration); lock.unlock(); - if ( funcDecl && funcDecl->type() ) { + if ( function.declaration && function.declaration->type() ) { // try to deduce type from a decorator - checkForDecorators(node, funcDecl, classDecl, isConstructor); + checkForDecorators(node, function.declaration, classDecl, function.isConstructor); } else if ( classDecl ) { return encounter(classDecl->abstractType(), DeclarationPointer(classDecl)); diff --git a/duchain/helpers.h b/duchain/helpers.h --- a/duchain/helpers.h +++ b/duchain/helpers.h @@ -137,16 +137,16 @@ static KDevelop::IndexedDeclaration declarationUnderCursor(bool allowUse = true); - using FuncInfo = QPair; + struct FuncInfo { FunctionDeclaration* declaration; bool isConstructor; }; /** * @brief Finds whether the specified called declaration is a function declaration, and if not, * checks for a class declaration; then returns the constructor * - * @param ptr the declaration to check + * @param called the declaration to check * @return the function pointer which was found, or an invalid pointer, and a bool * which is true when it is a constructor **/ - static FuncInfo functionDeclarationForCalledDeclaration(DeclarationPointer ptr); + static FuncInfo functionForCalled(Declaration* called); template static const Decorator* findDecoratorByName(T* inDeclaration, const QString& name) { const int count = inDeclaration->decoratorsSize(); diff --git a/duchain/helpers.cpp b/duchain/helpers.cpp --- a/duchain/helpers.cpp +++ b/duchain/helpers.cpp @@ -158,19 +158,19 @@ })); } -Helper::FuncInfo Helper::functionDeclarationForCalledDeclaration(DeclarationPointer ptr) +Helper::FuncInfo Helper::functionForCalled(Declaration* called ) { - if ( ! ptr ) { - return FuncInfo(); + if ( ! called ) { + return { nullptr, false }; } - else if ( auto functionDecl = FunctionDeclarationPointer(ptr) ) { - return FuncInfo(functionDecl, false); + else if ( called->isFunctionDeclaration() ) { + return { static_cast( called ), false }; } else { // not a function -- try looking for a constructor static const IndexedIdentifier initIdentifier(KDevelop::Identifier("__init__")); - auto attr = accessAttribute(ptr->abstractType(), initIdentifier, ptr->topContext()); - return FuncInfo(FunctionDeclarationPointer(attr), true); + auto attr = accessAttribute( called->abstractType(), initIdentifier, called->topContext()); + return { dynamic_cast(attr), true }; } } diff --git a/duchain/usebuilder.cpp b/duchain/usebuilder.cpp --- a/duchain/usebuilder.cpp +++ b/duchain/usebuilder.cpp @@ -95,16 +95,14 @@ if ( declaration && declaration->abstractType() && declaration->abstractType()->whichType() == AbstractType::TypeStructure ) { if ( node->belongsToCall ) { DUChainReadLocker lock; - QPair< Python::FunctionDeclarationPointer, bool > constructor = Helper:: - functionDeclarationForCalledDeclaration(DeclarationPointer(declaration)); + auto constructor = Helper::functionForCalled(declaration); lock.unlock(); - bool isConstructor = constructor.second; - if ( isConstructor ) { + if ( constructor.isConstructor ) { RangeInRevision constructorRange; // TODO fixme! this does not necessarily use the opening bracket as it should constructorRange.start = CursorInRevision(node->endLine, node->endCol + 1); constructorRange.end = CursorInRevision(node->endLine, node->endCol + 2); - UseBuilderBase::newUse(node, constructorRange, DeclarationPointer(constructor.first)); + UseBuilderBase::newUse(node, constructorRange, DeclarationPointer(constructor.declaration)); } } }