diff --git a/languages/clang/CMakeLists.txt b/languages/clang/CMakeLists.txt --- a/languages/clang/CMakeLists.txt +++ b/languages/clang/CMakeLists.txt @@ -84,6 +84,8 @@ util/clangdebug.cpp util/clangtypes.cpp util/clangutils.cpp + + clangdebugwidget.cpp ) include_directories( diff --git a/languages/clang/clangdebugwidget.h b/languages/clang/clangdebugwidget.h new file mode 100644 --- /dev/null +++ b/languages/clang/clangdebugwidget.h @@ -0,0 +1,61 @@ +/* + This file is part of KDevelop + + Copyright 2016 Aleix Pol Gonzalez + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef CLANGDEBUGWIDGET_H +#define CLANGDEBUGWIDGET_H + +#include "clangprivateexport.h" + +#include +#include +#include + +class ClangDocumentDebugWidget; +class QComboBox; +class QStackedLayout; + +class KDEVCLANGPRIVATE_EXPORT ClangDebugWidget : public QWidget +{ +Q_OBJECT +private Q_SLOTS: + void addText(const QUrl& url, const QString & t); + +public: + static ClangDebugWidget* self(); + + template + static void sendDebug(const QUrl& url, const T& data) { + QString string; + QDebug(&string) << data; + sendText(url, string); + } + +private: + static void sendText(const QUrl& url, const QString &text); + ClangDebugWidget (QWidget* parent = nullptr); + void switchDocument(int comboIndex); + + QHash m_views; + QComboBox* m_combo; + QStackedLayout* m_layout; +}; + +#endif // CLANGDEBUGWIDGET_H diff --git a/languages/clang/clangdebugwidget.cpp b/languages/clang/clangdebugwidget.cpp new file mode 100644 --- /dev/null +++ b/languages/clang/clangdebugwidget.cpp @@ -0,0 +1,137 @@ +/* + This file is part of KDevelop + + Copyright 2016 Aleix Pol Gonzalez + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "clangdebugwidget.h" +#include +#include +#include +#include +#include + +#include "duchain/clangparsingenvironmentfile.h" + +#include +#include +#include +#include +#include + +using namespace KDevelop; + +class ClangDocumentDebugWidget : public QWidget +{ +public: + ClangDocumentDebugWidget(const Path &url, QWidget* w) + : QWidget(w) + , m_url(url) + { + setLayout(new QVBoxLayout); + m_edit = new QTextEdit(this); + layout()->addWidget(m_edit); + m_randomClangInfo = new QTextEdit(this); + layout()->addWidget(m_randomClangInfo); + + } + + void addText(const QString &text) + { + m_edit->setPlainText(m_edit->toPlainText()+QLatin1Char('\n')+text); + } + + void showEvent(QShowEvent* ev) override + { + QString infoText; + + const Path::List incs = IDefinesAndIncludesManager::manager()->includes(m_url.toLocalFile()); + infoText += QStringLiteral("Includes:\n"); + foreach(const Path& inc, incs) { + infoText.append(inc.toUrl().toDisplayString()); + infoText.append(QLatin1Char('\n')); + } + + const auto defs = IDefinesAndIncludesManager::manager()->defines(m_url.toLocalFile()); + infoText += QStringLiteral("\nDefines:\n"); + for(auto it=defs.constBegin(), itEnd=defs.constEnd(); it!=itEnd; ++it) { + infoText.append(QStringLiteral("-D%1=%2").arg(it.key(), it.value())); + infoText.append(QLatin1Char('\n')); + } + m_randomClangInfo->setText(infoText); + } + +private: + const Path m_url; + QTextEdit* m_edit; + QTextEdit* m_randomClangInfo; +}; + +ClangDebugWidget::ClangDebugWidget(QWidget* parent) + : QWidget(parent) +{ + connect(ICore::self(), &ICore::aboutToShutdown, this, &QObject::deleteLater); + + auto mainLayout = new QVBoxLayout(this); + m_combo = new QComboBox(this); + m_layout = new QStackedLayout(this); + m_layout->setStackingMode(QStackedLayout::StackOne); + + mainLayout->addWidget(m_combo); + mainLayout->addLayout(m_layout); + + setLayout(mainLayout); + + connect(m_combo, static_cast(&QComboBox::activated), this, &ClangDebugWidget::switchDocument); +} + +ClangDebugWidget* ClangDebugWidget::self() +{ + static ClangDebugWidget* self = nullptr; + if (!self) + self = new ClangDebugWidget; + return self; +} + +void ClangDebugWidget::addText(const QUrl& url, const QString& t) +{ + if (!isVisible()) + return; + + auto view = m_views[url]; + if (!view) { + view = new ClangDocumentDebugWidget(Path(url), this); + m_views.insert(url, view); + m_layout->addWidget(view); + + m_combo->addItem(url.toDisplayString(), qVariantFromValue(view)); + } + + view->addText(t); +} + +void ClangDebugWidget::sendText(const QUrl& url, const QString& text) +{ + auto s = self(); + QMetaObject::invokeMethod(s, "addText", Qt::QueuedConnection, Q_ARG(QUrl, url), Q_ARG(QString, text)); +} + +void ClangDebugWidget::switchDocument(int comboIndex) +{ + m_layout->setCurrentIndex(comboIndex); +} diff --git a/languages/clang/clangsupport.cpp b/languages/clang/clangsupport.cpp --- a/languages/clang/clangsupport.cpp +++ b/languages/clang/clangsupport.cpp @@ -39,8 +39,10 @@ #include #include #include +#include #include +#include "clangdebugwidget.h" #include "codegen/clangrefactoring.h" #include "codegen/adaptsignatureassistant.h" #include "duchain/documentfinderhelpers.h" @@ -203,6 +205,15 @@ connect(ICore::self()->documentController(), &IDocumentController::documentActivated, this, &ClangSupport::documentActivated); + + + QAction* action = new QAction(i18n("Open Debug")); + actionCollection()->setDefaultShortcut(action, Qt::ControlModifier | Qt::MetaModifier | Qt::Key_D); + actionCollection()->addAction(QStringLiteral("clang_debug"), action); + + auto debug = ClangDebugWidget::self(); + connect(ICore::self(), &ICore::aboutToShutdown, debug, &QObject::deleteLater); + connect(action, &QAction::triggered, debug, &QWidget::show); } ClangSupport::~ClangSupport() diff --git a/languages/clang/duchain/clanghelpers.cpp b/languages/clang/duchain/clanghelpers.cpp --- a/languages/clang/duchain/clanghelpers.cpp +++ b/languages/clang/duchain/clanghelpers.cpp @@ -20,6 +20,7 @@ */ #include "clanghelpers.h" +#include #include #include @@ -177,6 +178,7 @@ { DUChainWriteLocker lock; context->setProblems(problems); + ClangDebugWidget::sendDebug(context->url().toUrl(), problems); } Builder::visit(session.unit(), file, includedFiles, update); diff --git a/languages/clang/duchain/parsesession.cpp b/languages/clang/duchain/parsesession.cpp --- a/languages/clang/duchain/parsesession.cpp +++ b/languages/clang/duchain/parsesession.cpp @@ -22,6 +22,7 @@ */ #include "parsesession.h" +#include #include #include "clangproblem.h" #include "clangdiagnosticevaluator.h" @@ -244,6 +245,7 @@ } out << " " << tuUrl.byteArray().constData() << "\n"; } + ClangDebugWidget::sendDebug(tuUrl.toUrl(), clangArguments << tuUrl.c_str()); const CXErrorCode code = clang_parseTranslationUnit2( index->index(), tuUrl.byteArray().constData(),