void QuickOpenPlugin::quickOpenDeclaration() { if(jumpToSpecialObject()) return; KDevelop::DUChainReadLocker lock( DUChain::lock() ); Declaration* decl = cursorDeclaration(); if(!decl) { qCDebug(PLUGIN_QUICKOPEN) << "Found no declaration for cursor, cannot jump"; return; } decl->activateSpecialization(); IndexedString u = decl->url(); KTextEditor::Cursor c = decl->rangeInCurrentRevision().start(); if(u.isEmpty()) { qCDebug(PLUGIN_QUICKOPEN) << "Got empty url for declaration" << decl->toString(); return; } lock.unlock(); core()->documentController()->openDocument(u.toUrl(), c); }
void AdaptSignatureAssistant::parseJobFinished(KDevelop::ParseJob* job) { if (job->document().toUrl() != m_document || !m_view) { return; } clearActions(); DUChainReadLocker lock; Declaration *functionDecl = getDeclarationAtCursor(KTextEditor::Cursor(m_view.data()->cursorPosition()), m_document); if (!functionDecl || functionDecl->identifier() != m_declarationName) { clangDebug() << "No function found at" << m_document << m_view.data()->cursorPosition(); return; } DUContext *functionCtxt = DUChainUtils::getFunctionContext(functionDecl); if (!functionCtxt) { clangDebug() << "No function context found for" << functionDecl->toString(); return; } #if 0 // TODO: Port if (QtFunctionDeclaration * classFun = dynamic_cast<QtFunctionDeclaration*>(functionDecl)) { if (classFun->isSignal()) { // do not offer to change signature of a signal, as the implementation will be generated by moc return; } } #endif //ParseJob having finished, get the signature that was modified Signature newSignature = getDeclarationSignature(functionDecl, functionCtxt, false); //Check for changes between m_oldSignature and newSignature, use oldPositions to store old<->new param index mapping QList<int> oldPositions; if (!getSignatureChanges(newSignature, oldPositions)) { reset(); return; //No changes to signature } QList<RenameAction*> renameActions; if (m_editingDefinition) { setDefaultParams(newSignature, oldPositions); //restore default parameters before updating the declarations } else { renameActions = getRenameActions(newSignature, oldPositions); //rename as needed when updating the definition } IAssistantAction::Ptr action(new AdaptSignatureAction(m_otherSideId, m_otherSideTopContext, m_oldSignature, newSignature, m_editingDefinition, renameActions)); connect(action.data(), &IAssistantAction::executed, this, &AdaptSignatureAssistant::reset); addAction(action); emit actionsChanged(); }
void TestDUChain::testAutoTypeDeduction() { TestFile file("const volatile auto foo = 5;\n", "cpp"); QVERIFY(file.parseAndWait()); DUChainReadLocker lock; DUContext* ctx = file.topContext().data(); QVERIFY(ctx); QCOMPARE(ctx->localDeclarations().size(), 1); QCOMPARE(ctx->findDeclarations(QualifiedIdentifier("foo")).size(), 1); Declaration* decl = ctx->findDeclarations(QualifiedIdentifier("foo"))[0]; QCOMPARE(decl->identifier(), Identifier("foo")); #if CINDEX_VERSION_MINOR < 31 QEXPECT_FAIL("", "No type deduction here unfortunately, missing API in Clang", Continue); #endif QVERIFY(decl->type<IntegralType>()); #if CINDEX_VERSION_MINOR < 31 QCOMPARE(decl->toString(), QStringLiteral("const volatile auto foo")); #else QCOMPARE(decl->toString(), QStringLiteral("const volatile int foo")); #endif }
void ADLTypeVisitor::endVisit(const FunctionType * /*type*/) { // return type and argument types are handled by FunctionType::accept0 // here we process the namespace of the function name (or containing class), if any /* at the bottom of 3.4.2.2 we find the following: In addition, if the argument is the name or address of a set of overloaded functions and/or function tem- plates, its associated classes and namespaces are the union of those associated with each of the members of the set: the namespace in which the function or function template is defined and the classes and namespaces associated with its (non-dependent) parameter types and return type. */ if (m_helper.m_possibleFunctionName.data() && m_helper.m_possibleFunctionName.data()->isFunctionDeclaration()) { Declaration * declaration = m_helper.m_possibleFunctionName.data(); #ifdef DEBUG_ADL qCDebug(CPPDUCHAIN) << " function name = " << declaration->toString() << " ; identifier = " << declaration->qualifiedIdentifier().toString(); #endif // start going towards the global scope until we match an interesting name // note that calling addDeclarationScopeIdentifier does not work because for some reason // for function names DUContext::scopeIdentifier returns the function name instead of the // name of the function's scope DUContext* context = declaration->context(); while (context) { if (Declaration* decl = context->owner()) { if (context->type() == DUContext::Namespace) { m_helper.addAssociatedNamespace(decl->qualifiedIdentifier()); break; } else if (context->type() == DUContext::Class) { m_helper.addAssociatedClass(decl); break; } } context = context->parentContext(); } } }