// Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 #include "clangtoolsplugin.h" #include "clangtool.h" #include "clangtoolsconstants.h" #include "clangtoolsprojectsettings.h" #include "clangtoolsprojectsettingswidget.h" #include "documentclangtoolrunner.h" #include "documentquickfixfactory.h" #include "settingswidget.h" #ifdef WITH_TESTS #include "readexporteddiagnosticstest.h" #include "clangtoolspreconfiguredsessiontests.h" #include "clangtoolsunittests.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace Core; using namespace ProjectExplorer; namespace ClangTools { namespace Internal { static ProjectPanelFactory *m_projectPanelFactoryInstance = nullptr; ProjectPanelFactory *projectPanelFactory() { return m_projectPanelFactoryInstance; } class ClangToolsPluginPrivate { public: ClangToolsPluginPrivate() : quickFixFactory( [this](const Utils::FilePath &filePath) { return runnerForFilePath(filePath); }) {} DocumentClangToolRunner *runnerForFilePath(const Utils::FilePath &filePath) { for (DocumentClangToolRunner *runner : qAsConst(documentRunners)) { if (runner->filePath() == filePath) return runner; } return nullptr; } ClangTool clangTool; ClangToolsOptionsPage optionsPage; QMap documentRunners; DocumentQuickFixFactory quickFixFactory; }; ClangToolsPlugin::~ClangToolsPlugin() { delete d; } bool ClangToolsPlugin::initialize(const QStringList &arguments, QString *errorString) { Q_UNUSED(arguments) Q_UNUSED(errorString) TaskHub::addCategory(taskCategory(), tr("Clang Tools")); // Import tidy/clazy diagnostic configs from CppEditor now // instead of at opening time of the settings page ClangToolsSettings::instance(); d = new ClangToolsPluginPrivate; registerAnalyzeActions(); auto panelFactory = m_projectPanelFactoryInstance = new ProjectPanelFactory; panelFactory->setPriority(100); panelFactory->setId(Constants::PROJECT_PANEL_ID); panelFactory->setDisplayName(tr("Clang Tools")); panelFactory->setCreateWidgetFunction( [](Project *project) { return new ClangToolsProjectSettingsWidget(project); }); ProjectPanelFactory::registerFactory(panelFactory); connect(Core::EditorManager::instance(), &Core::EditorManager::currentEditorChanged, this, &ClangToolsPlugin::onCurrentEditorChanged); return true; } void ClangToolsPlugin::onCurrentEditorChanged() { for (Core::IEditor *editor : Core::EditorManager::visibleEditors()) { IDocument *document = editor->document(); if (d->documentRunners.contains(document)) continue; auto runner = new DocumentClangToolRunner(document); connect(runner, &DocumentClangToolRunner::destroyed, this, [this, document]() { d->documentRunners.remove(document); }); d->documentRunners[document] = runner; } } void ClangToolsPlugin::registerAnalyzeActions() { ActionManager::registerAction(d->clangTool.startAction(), Constants::RUN_ON_PROJECT); Command *cmd = ActionManager::registerAction(d->clangTool.startOnCurrentFileAction(), Constants::RUN_ON_CURRENT_FILE); ActionContainer *mtoolscpp = ActionManager::actionContainer(CppEditor::Constants::M_TOOLS_CPP); if (mtoolscpp) mtoolscpp->addAction(cmd); Core::ActionContainer *mcontext = Core::ActionManager::actionContainer( CppEditor::Constants::M_CONTEXT); if (mcontext) mcontext->addAction(cmd, CppEditor::Constants::G_CONTEXT_FIRST); // add button to tool bar of C++ source files connect(EditorManager::instance(), &EditorManager::editorOpened, this, [this, cmd](IEditor *editor) { if (editor->document()->filePath().isEmpty() || !Utils::mimeTypeForName(editor->document()->mimeType()).inherits("text/x-c++src")) return; auto *textEditor = qobject_cast(editor); if (!textEditor) return; TextEditor::TextEditorWidget *widget = textEditor->editorWidget(); if (!widget) return; const QIcon icon = Utils::Icon({{":/debugger/images/debugger_singleinstructionmode.png", Utils::Theme::IconsBaseColor}}) .icon(); QAction *action = widget->toolBar()->addAction(icon, tr("Analyze File"), [this, editor]() { d->clangTool.startTool(editor->document()->filePath()); }); cmd->augmentActionWithShortcutToolTip(action); }); } QVector ClangToolsPlugin::createTestObjects() const { QVector tests; #ifdef WITH_TESTS tests << new PreconfiguredSessionTests; tests << new ClangToolsUnitTests; tests << new ReadExportedDiagnosticsTest; #endif return tests; } } // namespace Internal } // namespace ClangTools