void TypeCorrection::executeSpecifyTypeAction() { QAction* action = qobject_cast<QAction*>(sender()); if ( ! action ) { qCWarning(KDEV_PYTHON_CODEGEN) << "slot not invoked by triggering a QAction, should not happen"; // :) return; } DUChainReadLocker lock; IndexedDeclaration decl = action->data().value<IndexedDeclaration>(); if ( ! decl.isValid() ) { decl = Helper::declarationUnderCursor(); } if ( ! decl.isValid() ) { qCWarning(KDEV_PYTHON_CODEGEN) << "No declaration found!"; return; } CorrectionFileGenerator::HintType hintType; if ( decl.data()->isFunctionDeclaration() ) { hintType = CorrectionFileGenerator::FunctionReturnHint; } else if ( decl.data()->kind() == Declaration::Instance ) { hintType = CorrectionFileGenerator::LocalVariableHint; } else { qCWarning(KDEV_PYTHON_CODEGEN) << "Correction requested for something that's not a local variable or function."; return; } CorrectionAssistant *dialog = new CorrectionAssistant(decl, hintType); dialog->setAttribute(Qt::WA_DeleteOnClose); dialog->setWindowTitle("Specify type for " + decl.data()->identifier().toString()); connect(dialog, &QDialog::accepted, this, &TypeCorrection::accepted); m_ui->setupUi(dialog); connect(m_ui->buttonBox, &QDialogButtonBox::accepted, dialog, &QDialog::accept); connect(m_ui->buttonBox, &QDialogButtonBox::rejected, dialog, &QDialog::reject); if ( hintType == CorrectionFileGenerator::FunctionReturnHint ) { m_ui->kindLabel->setText(i18n("Function return type")); } else if ( hintType == CorrectionFileGenerator::LocalVariableHint ) { m_ui->kindLabel->setText(i18n("Local variable")); } m_ui->identifierLabel->setText(decl.data()->qualifiedIdentifier().toString()); m_ui->typeText->setFocus(); dialog->resize(560, 180); lock.unlock(); dialog->show(); }
void TypeCorrection::accepted() { CorrectionAssistant *dialog = qobject_cast<CorrectionAssistant*>(sender()); Q_ASSERT(dialog); if ( ! dialog ) { qCWarning(KDEV_PYTHON_CODEGEN) << "accepted() called without a sender"; return; } DUChainReadLocker lock; IndexedDeclaration decl; decl = dialog->declaration(); if ( ! decl.isValid() ) { decl = Helper::declarationUnderCursor(); } if ( ! decl.isValid() ) { qCWarning(KDEV_PYTHON_CODEGEN) << "No declaration found!"; return; } auto correctionFile = Helper::getLocalCorrectionFile(decl.data()->topContext()->url().toUrl()); if ( correctionFile.isEmpty() ) { KMessageBox::error(0, i18n("Sorry, cannot create hints for files which are not part of a project.")); return; } CorrectionFileGenerator generator(correctionFile.path()); CorrectionFileGenerator::HintType hintType = dialog->hintType(); generator.addHint(m_ui->typeText->text(), m_ui->importsText->text().split(',', QString::SkipEmptyParts), decl.data(), hintType); qCDebug(KDEV_PYTHON_CODEGEN) << "Forcing a reparse on " << decl.data()->topContext()->url(); ICore::self()->languageController()->backgroundParser()->addDocument(IndexedString(decl.data()->topContext()->url()), TopDUContext::ForceUpdate); ICore::self()->languageController()->backgroundParser()->addDocument(IndexedString(correctionFile), TopDUContext::ForceUpdate); }
void TestCppCodegen::testUpdateIndices() { /// @todo Extend this test to make sure t hat all kinds of declarations retain their indices when they are updated { InsertIntoDUChain code1("duchaintest_1.h", "class QW{}; struct A { struct Member2; struct Member1; }; class Oq{};"); InsertIntoDUChain code3("duchaintest_3.h", "#include <duchaintest_1.h>\n struct C : public A { Member1 m1; Member2 m2; A test(int arg) { int v1; \n{}\n { int v2, *v3; }} int test(); };"); qWarning() << "********************* Parsing step 1"; code3.parse(TopDUContext::AllDeclarationsContextsUsesAndAST); DUChainReadLocker lock; IndexedDeclaration CDecl = code3.getDeclaration("C"); QVERIFY(CDecl.isValid()); IndexedDeclaration ADecl = code3.getDeclaration("A"); QVERIFY(ADecl.isValid()); IndexedDeclaration C_m1 = code3.getDeclaration("C::m1"); QVERIFY(C_m1.isValid()); IndexedDeclaration C_m2 = code3.getDeclaration("C::m2"); QVERIFY(C_m2.isValid()); QVERIFY(CDecl.declaration()->internalContext()); QCOMPARE(CDecl.declaration()->internalContext()->localDeclarations().size(), 4); IndexedDeclaration C_test = CDecl.declaration()->internalContext()->localDeclarations()[2]; QVERIFY(C_test.isValid()); DUContext* testCtx = C_test.data()->internalContext(); QVERIFY(testCtx); QCOMPARE(testCtx->localDeclarations().size(), 1); IndexedDeclaration C_test_v1 = testCtx->localDeclarations()[0]; QCOMPARE(testCtx->childContexts().size(), 2); DUContext* child = testCtx->childContexts()[1]; QCOMPARE(child->localDeclarations().size(), 2); IndexedDeclaration C_test_v2 = child->localDeclarations()[0]; IndexedDeclaration C_test_v3 = child->localDeclarations()[1]; QCOMPARE(C_test_v1.declaration()->identifier(), Identifier("v1")); QCOMPARE(C_test_v2.declaration()->identifier(), Identifier("v2")); QCOMPARE(C_test_v3.declaration()->identifier(), Identifier("v3")); QCOMPARE(C_m1.declaration()->identifier(), Identifier("m1")); QCOMPARE(C_m2.declaration()->identifier(), Identifier("m2")); QCOMPARE(C_test.declaration()->identifier(), Identifier("test")); QCOMPARE(CDecl.declaration()->identifier(), Identifier("C")); QCOMPARE(ADecl.declaration()->identifier(), Identifier("A")); lock.unlock(); code1.m_insertedCode.setText("struct A { struct Member2; struct Member1; };"); code3.m_insertedCode.setText("#include <duchaintest_1.h>\n class Q{}; struct C : public A { Member2 m2; int c; A test(int arg) { int w1; int v1;\n\n { int *v3; }} int test(); };"); code3.parse(TopDUContext::AllDeclarationsContextsAndUses | TopDUContext::ForceUpdateRecursive, true); lock.lock(); QVERIFY(ADecl.declaration()); QCOMPARE(ADecl.declaration()->identifier(), Identifier("A")); QVERIFY(CDecl.declaration()); QCOMPARE(CDecl.declaration()->identifier(), Identifier("C")); QVERIFY(!C_m1.declaration()); QVERIFY(C_m2.declaration()); QCOMPARE(C_m2.declaration()->identifier(), Identifier("m2")); QVERIFY(C_test.declaration()); QCOMPARE(C_test.declaration()->identifier(), Identifier("test")); QVERIFY(C_test_v1.declaration()); QCOMPARE(C_test_v1.declaration()->identifier(), Identifier("v1")); QVERIFY(!C_test_v2.declaration()); QVERIFY(C_test_v3.declaration()); QCOMPARE(C_test_v3.declaration()->identifier(), Identifier("v3")); } }