diff --git a/plugins/clazy/jobparameters.cpp b/plugins/clazy/jobparameters.cpp index 41b64852d4..19940c6f8b 100644 --- a/plugins/clazy/jobparameters.cpp +++ b/plugins/clazy/jobparameters.cpp @@ -1,371 +1,375 @@ /* This file is part of KDevelop Copyright 2018 Anton Anikin This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "jobparameters.h" #include "debug.h" #include "globalsettings.h" #include "projectsettings.h" #include "utils.h" #include #include #include #include #include #include #include #include namespace Clazy { JobGlobalParameters::JobGlobalParameters() : JobGlobalParameters(GlobalSettings::executablePath(), GlobalSettings::docsPath()) { } JobGlobalParameters::JobGlobalParameters(const QUrl& executablePath, const QUrl& docsPath) { m_executablePath = executablePath.toLocalFile(); m_docsPath = docsPath.toLocalFile(); QFileInfo info; if (m_executablePath.isEmpty()) { if (defaultExecutablePath().toLocalFile().isEmpty()) { m_error = i18n( "clazy-standalone path cannot be detected. " "Set the path manually if Clazy is already installed."); } else { m_error = i18n("clazy-standalone path is empty."); } return; } info.setFile(m_executablePath); if (!info.exists()) { m_error = i18n("clazy-standalone path '%1' does not exists.", m_executablePath); return; } if (!info.isFile() || !info.isExecutable()) { m_error = i18n("clazy-standalone path '%1' is not an executable.", m_executablePath); return; } // ============================================================================================= if (m_docsPath.isEmpty()) { if (defaultDocsPath().toLocalFile().isEmpty()) { m_error = i18n( "Clazy documentation path cannot be detected. " "Set the path manually if Clazy is already installed."); } else { m_error = i18n("Clazy documentation path is empty."); } return; } info.setFile(m_docsPath); if (!info.exists()) { m_error = i18n("Clazy documentation path '%1' does not exists.", m_docsPath); return; } if (!info.isDir()) { m_error = i18n("Clazy documentation path '%1' is not a directory.", m_docsPath); return; } m_error.clear(); } QUrl JobGlobalParameters::defaultExecutablePath() { return QUrl::fromLocalFile(QStandardPaths::findExecutable(QStringLiteral("clazy-standalone"))); } QUrl JobGlobalParameters::defaultDocsPath() { const QString subPathsCandidates[2]{ // since clazy 1.4 QStringLiteral("doc/clazy"), // before QStringLiteral("clazy/doc"), }; for (auto subPath : subPathsCandidates) { const auto docsPath = QStandardPaths::locate(QStandardPaths::GenericDataLocation, subPath, QStandardPaths::LocateDirectory); if (!docsPath.isEmpty()) { return QUrl::fromLocalFile(QDir(docsPath).canonicalPath()); } } return {}; } bool JobGlobalParameters::isValid() const { return m_error.isEmpty(); } QString JobGlobalParameters::error() const { return m_error; } JobParameters::JobParameters(KDevelop::IProject* project) : JobParameters(project, QString()) { } JobParameters::JobParameters(KDevelop::IProject* project, const QString& checkPath) : m_checkPath(checkPath) { Q_ASSERT(project); auto projectRootPath = project->path().toLocalFile(); + auto projectCanonicalRootPath = QFileInfo(projectRootPath).canonicalFilePath(); auto buildPath = project->buildSystemManager()->buildDirectory(project->projectItem()); m_projectBuildPath = buildPath.toLocalFile(); buildPath.addPath(QStringLiteral("compile_commands.json")); auto commandsFilePath = buildPath.toLocalFile(); if (!QFile::exists(commandsFilePath)) { m_error = i18n("Compile commands file '%1' does not exist.", commandsFilePath); return; } + + const auto pathInfo = QFileInfo(m_checkPath); + const bool checkPathIsFile = pathInfo.isFile(); + const auto canonicalPathToCheck = checkPathIsFile ? pathInfo.canonicalFilePath() : QStringLiteral(""); if (!m_checkPath.isEmpty()) { const auto allFiles = compileCommandsFiles(commandsFilePath, m_error); if (!m_error.isEmpty()) { return; } - if (m_checkPath == projectRootPath) { + if (canonicalPathToCheck == projectCanonicalRootPath) { m_sources = allFiles; } else { - const bool checkPathIsFile = QFileInfo(m_checkPath).isFile(); for (auto& file : allFiles) { if (checkPathIsFile) { - if (file == m_checkPath) { + if (file == canonicalPathToCheck) { m_sources.clear(); - m_sources += m_checkPath; + m_sources += canonicalPathToCheck; break; } - } else if (file.startsWith(m_checkPath)) { + } else if (file.startsWith(m_checkPath) || file.startsWith(canonicalPathToCheck)) { m_sources += file; } } } } ProjectSettings projectSettings; projectSettings.setSharedConfig(project->projectConfiguration()); projectSettings.load(); { // blocks changed() signal from setters QSignalBlocker blocker(this); setChecks(projectSettings.checks()); setOnlyQt(projectSettings.onlyQt()); setQtDeveloper(projectSettings.qtDeveloper()); setQt4Compat(projectSettings.qt4Compat()); setVisitImplicitCode(projectSettings.visitImplicitCode()); setIgnoreIncludedFiles(projectSettings.ignoreIncludedFiles()); setHeaderFilter(projectSettings.headerFilter()); setEnableAllFixits(projectSettings.enableAllFixits()); setNoInplaceFixits(projectSettings.noInplaceFixits()); setExtraAppend(projectSettings.extraAppend()); setExtraPrepend(projectSettings.extraPrepend()); setExtraClazy(projectSettings.extraClazy()); } if (m_sources.isEmpty()) { m_error = i18n("Nothing to check: compile commands file '%1' contains no matching items.", commandsFilePath); } } QString JobParameters::defaultChecks() { return QStringLiteral("level1"); } QString JobParameters::checkPath() const { return m_checkPath; } const QStringList& JobParameters::sources() const { return m_sources; } QString JobParameters::projectBuildPath() const { return m_projectBuildPath; } QStringList JobParameters::commandLine() const { QStringList arguments; arguments << m_executablePath; if (!m_checks.isEmpty()) { arguments << QStringLiteral("-checks=%1").arg(m_checks); } if (m_onlyQt) { arguments << QStringLiteral("-only-qt"); } if (m_qtDeveloper) { arguments << QStringLiteral("-qt-developer"); } if (m_qt4Compat) { arguments << QStringLiteral("-qt4-compat"); } if (m_visitImplicitCode) { arguments << QStringLiteral("-visit-implicit-code"); } if (m_ignoreIncludedFiles) { arguments << QStringLiteral("-ignore-included-files"); } if (!m_headerFilter.isEmpty()) { arguments << QStringLiteral("-header-filter=%1").arg(m_headerFilter); } if (m_enableAllFixits) { arguments << QStringLiteral("-enable-all-fixits"); } if (m_noInplaceFixits) { arguments << QStringLiteral("-no-inplace-fixits"); } if (!m_extraAppend.isEmpty()) { arguments << QStringLiteral("-extra-arg=%1").arg(m_extraAppend); } if (!m_extraPrepend.isEmpty()) { arguments << QStringLiteral("-extra-arg-before=%1").arg(m_extraPrepend); } if (!m_extraClazy.isEmpty()) { arguments << KShell::splitArgs(m_extraClazy); } arguments << QStringLiteral("-p"); arguments << m_projectBuildPath; return arguments; } template void JobParameters::setValue(T& currentValue, const T& newValue) { if (currentValue != newValue) { currentValue = newValue; emit changed(); } } void JobParameters::setChecks(const QString& checks) { if (checks.isEmpty()) { setValue(m_checks, defaultChecks()); } else { setValue(m_checks, checks); } } void JobParameters::setOnlyQt(bool onlyQt) { setValue(m_onlyQt, onlyQt); } void JobParameters::setQtDeveloper(bool qtDeveloper) { setValue(m_qtDeveloper, qtDeveloper); } void JobParameters::setQt4Compat(bool qt4Compat) { setValue(m_qt4Compat, qt4Compat); } void JobParameters::setVisitImplicitCode(bool visitImplicitCode) { setValue(m_visitImplicitCode, visitImplicitCode); } void JobParameters::setIgnoreIncludedFiles(bool ignoreIncludedFiles) { setValue(m_ignoreIncludedFiles, ignoreIncludedFiles); } void JobParameters::setHeaderFilter(const QString& headerFilter) { setValue(m_headerFilter, headerFilter); } void JobParameters::setEnableAllFixits(bool enableAllFixits) { setValue(m_enableAllFixits, enableAllFixits); } void JobParameters::setNoInplaceFixits(bool noInplaceFixits) { setValue(m_noInplaceFixits, noInplaceFixits); } void JobParameters::setExtraAppend(const QString& extraAppend) { setValue(m_extraAppend, extraAppend); } void JobParameters::setExtraPrepend(const QString& extraPrepend) { setValue(m_extraPrepend, extraPrepend); } void JobParameters::setExtraClazy(const QString& extraClazy) { setValue(m_extraClazy, extraClazy); } }