Beispiel #1
0
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();
}
Beispiel #3
0
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
}
Beispiel #4
0
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();
        }
    }
}